add different kinds of enemies
This commit is contained in:
parent
eb305add94
commit
28b5a476bf
@ -8,9 +8,55 @@ const friction = 0.99;
|
||||
const walkForce = 4000;
|
||||
const maxSpeed = 200;
|
||||
const handDistance = 50;
|
||||
const deathBallSize: f32 = 10;
|
||||
const playerSize = 20;
|
||||
|
||||
const enemyFriction = friction;
|
||||
|
||||
const Enemy = struct {
|
||||
position: rl.Vector2,
|
||||
health: f32,
|
||||
color: rl.Color,
|
||||
size: f32,
|
||||
acceleration: f32,
|
||||
maxSpeed: f32,
|
||||
|
||||
invincibility: f32 = 0,
|
||||
stunned: f32 = 0,
|
||||
velocity: rl.Vector2 = .{ .x = 0, .y = 0 },
|
||||
|
||||
fn initWeak(position: rl.Vector2) Enemy {
|
||||
return Enemy{
|
||||
.position = position,
|
||||
.health = 1.0,
|
||||
.color = rl.YELLOW,
|
||||
.size = 10.0,
|
||||
.acceleration = 5000.0,
|
||||
.maxSpeed = 150,
|
||||
};
|
||||
}
|
||||
|
||||
fn initNormal(position: rl.Vector2) Enemy {
|
||||
return Enemy{
|
||||
.position = position,
|
||||
.health = 2.0,
|
||||
.color = rl.ORANGE,
|
||||
.size = 20.0,
|
||||
.acceleration = 4000,
|
||||
.maxSpeed = 100,
|
||||
};
|
||||
}
|
||||
|
||||
fn initStrong(position: rl.Vector2) Enemy {
|
||||
return Enemy{
|
||||
.position = position,
|
||||
.health = 5.0,
|
||||
.color = rl.ORANGE,
|
||||
.size = 50.0,
|
||||
.acceleration = 3000,
|
||||
.maxSpeed = 50,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const Player = struct {
|
||||
@ -147,6 +193,69 @@ pub fn deinit(self: Self) void {
|
||||
self.enemies.deinit();
|
||||
}
|
||||
|
||||
fn tickEnemies(self: *Self) !void {
|
||||
var rng = self.prng.random();
|
||||
const dt = rl.GetFrameTime();
|
||||
var enemies = &self.enemies;
|
||||
var player = &self.player;
|
||||
var rope = &self.rope;
|
||||
|
||||
self.enemyTimer -= dt;
|
||||
if (self.enemyTimer <= 0) {
|
||||
self.enemyTimer = 0.5 + rng.float(f32) * 2;
|
||||
self.spawnedEnemiesCount += 1;
|
||||
const enemyPosition = rl.Vector2.randomOnUnitCircle(rng).scale(400);
|
||||
try enemies.append(Enemy.initNormal(enemyPosition));
|
||||
}
|
||||
|
||||
for (enemies.items) |*enemy| {
|
||||
const toPlayer = player.position.sub(enemy.position);
|
||||
if (toPlayer.length() <= playerSize + enemy.size) {
|
||||
self.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (enemy.stunned == 0) {
|
||||
const directionToPlayer = toPlayer.normalize();
|
||||
enemy.velocity = enemy.velocity.add(directionToPlayer.scale(enemy.acceleration * dt));
|
||||
}
|
||||
|
||||
enemy.velocity = rl.Vector2ClampValue(enemy.velocity, 0, enemy.maxSpeed);
|
||||
enemy.velocity = rl.Vector2Scale(enemy.velocity, std.math.pow(f32, (1 - enemyFriction), dt));
|
||||
enemy.position = enemy.position.add(enemy.velocity.scale(dt));
|
||||
|
||||
enemy.invincibility = @max(0, enemy.invincibility - dt);
|
||||
enemy.stunned = @max(0, enemy.stunned - dt);
|
||||
}
|
||||
|
||||
const deathBallPosition = rope.nodePositions.get(rope.nodePositions.len-1);
|
||||
const deathBallVelocity = rope.nodeVelocities.get(rope.nodePositions.len-1);
|
||||
|
||||
{
|
||||
var i: usize = 0;
|
||||
while (i < enemies.items.len) {
|
||||
const enemy = &enemies.items[i];
|
||||
|
||||
if (enemy.invincibility == 0) {
|
||||
if (rl.Vector2Distance(enemy.position, deathBallPosition) < enemy.size + deathBallSize) {
|
||||
enemy.health -= 1;
|
||||
enemy.invincibility = 0.5;
|
||||
enemy.stunned = 0.75;
|
||||
enemy.velocity = deathBallVelocity.scale(20000);
|
||||
}
|
||||
|
||||
if (enemy.health == 0) {
|
||||
self.killCount += 1;
|
||||
_ = enemies.swapRemove(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(self: *Self) !void {
|
||||
rl.ClearBackground(rl.BLACK);
|
||||
|
||||
@ -158,21 +267,11 @@ pub fn tick(self: *Self) !void {
|
||||
self.camera.target = self.player.position;
|
||||
|
||||
const dt = rl.GetFrameTime();
|
||||
var rng = self.prng.random();
|
||||
var player = &self.player;
|
||||
var enemies = &self.enemies;
|
||||
var rope = &self.rope;
|
||||
var allocator = self.allocator;
|
||||
|
||||
self.enemyTimer -= dt;
|
||||
if (self.enemyTimer <= 0) {
|
||||
self.enemyTimer = 0.5 + rng.float(f32) * 2;
|
||||
self.spawnedEnemiesCount += 1;
|
||||
try enemies.append(Enemy{
|
||||
.position = rl.Vector2.randomOnUnitCircle(rng).scale(400)
|
||||
});
|
||||
}
|
||||
|
||||
player.handDirection = PlayerInput.getHandPosition();
|
||||
|
||||
const moveDir = PlayerInput.getWalkDirection();
|
||||
@ -185,45 +284,16 @@ pub fn tick(self: *Self) !void {
|
||||
|
||||
player.position = rl.Vector2Add(player.position, rl.Vector2Scale(player.velocity, dt));
|
||||
|
||||
const enemySize: f32 = 20;
|
||||
const deathBallSize: f32 = 10;
|
||||
const playerSize = 20;
|
||||
|
||||
const enemySpeed = 100;
|
||||
for (enemies.items) |*enemy| {
|
||||
const toPlayer = player.position.sub(enemy.position);
|
||||
if (toPlayer.length() <= playerSize + enemySize) {
|
||||
self.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
const directionToPlayer = toPlayer.normalize();
|
||||
enemy.position = enemy.position.add(directionToPlayer.scale(enemySpeed * dt));
|
||||
}
|
||||
|
||||
const handPosition = player.position.add(player.handDirection.scale(handDistance));
|
||||
|
||||
const rope_root_node: rl.Vector2 = rope.nodePositions.get(0);
|
||||
rope.nodePositions.set(0, rope_root_node.lerp(handPosition, 0.25));
|
||||
// rope.nodePositions.set(0, handPosition);
|
||||
|
||||
rope.update(dt);
|
||||
|
||||
const deathBallPosition = rope.nodePositions.get(rope.nodePositions.len-1);
|
||||
|
||||
{
|
||||
var i: usize = 0;
|
||||
while (i < enemies.items.len) {
|
||||
const enemy = &enemies.items[i];
|
||||
const distanceToDeathBall = enemy.position.sub(deathBallPosition).length();
|
||||
if (distanceToDeathBall < enemySize + deathBallSize) {
|
||||
self.killCount += 1;
|
||||
_ = enemies.swapRemove(i);
|
||||
continue;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
try self.tickEnemies();
|
||||
|
||||
{ // UI
|
||||
const enemyCountText = try std.fmt.allocPrintZ(allocator, "{d}", .{self.spawnedEnemiesCount});
|
||||
@ -267,11 +337,16 @@ pub fn tick(self: *Self) !void {
|
||||
);
|
||||
|
||||
for (enemies.items) |*enemy| {
|
||||
var color = enemy.color;
|
||||
if (enemy.invincibility > 0 and @rem(enemy.invincibility, 0.2) < 0.1) {
|
||||
color = rl.LIGHTGRAY;
|
||||
}
|
||||
|
||||
rl.DrawCircle(
|
||||
@intFromFloat(enemy.position.x),
|
||||
@intFromFloat(enemy.position.y),
|
||||
enemySize,
|
||||
rl.RED
|
||||
enemy.size,
|
||||
color
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user