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 walkForce = 4000;
|
||||||
const maxSpeed = 200;
|
const maxSpeed = 200;
|
||||||
const handDistance = 50;
|
const handDistance = 50;
|
||||||
|
const deathBallSize: f32 = 10;
|
||||||
|
const playerSize = 20;
|
||||||
|
|
||||||
|
const enemyFriction = friction;
|
||||||
|
|
||||||
const Enemy = struct {
|
const Enemy = struct {
|
||||||
position: rl.Vector2,
|
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 {
|
const Player = struct {
|
||||||
@ -147,6 +193,69 @@ pub fn deinit(self: Self) void {
|
|||||||
self.enemies.deinit();
|
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 {
|
pub fn tick(self: *Self) !void {
|
||||||
rl.ClearBackground(rl.BLACK);
|
rl.ClearBackground(rl.BLACK);
|
||||||
|
|
||||||
@ -158,21 +267,11 @@ pub fn tick(self: *Self) !void {
|
|||||||
self.camera.target = self.player.position;
|
self.camera.target = self.player.position;
|
||||||
|
|
||||||
const dt = rl.GetFrameTime();
|
const dt = rl.GetFrameTime();
|
||||||
var rng = self.prng.random();
|
|
||||||
var player = &self.player;
|
var player = &self.player;
|
||||||
var enemies = &self.enemies;
|
var enemies = &self.enemies;
|
||||||
var rope = &self.rope;
|
var rope = &self.rope;
|
||||||
var allocator = self.allocator;
|
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();
|
player.handDirection = PlayerInput.getHandPosition();
|
||||||
|
|
||||||
const moveDir = PlayerInput.getWalkDirection();
|
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));
|
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 handPosition = player.position.add(player.handDirection.scale(handDistance));
|
||||||
|
|
||||||
const rope_root_node: rl.Vector2 = rope.nodePositions.get(0);
|
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, rope_root_node.lerp(handPosition, 0.25));
|
||||||
// rope.nodePositions.set(0, handPosition);
|
|
||||||
|
|
||||||
rope.update(dt);
|
rope.update(dt);
|
||||||
|
|
||||||
const deathBallPosition = rope.nodePositions.get(rope.nodePositions.len-1);
|
const deathBallPosition = rope.nodePositions.get(rope.nodePositions.len-1);
|
||||||
|
|
||||||
{
|
try self.tickEnemies();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // UI
|
{ // UI
|
||||||
const enemyCountText = try std.fmt.allocPrintZ(allocator, "{d}", .{self.spawnedEnemiesCount});
|
const enemyCountText = try std.fmt.allocPrintZ(allocator, "{d}", .{self.spawnedEnemiesCount});
|
||||||
@ -267,11 +337,16 @@ pub fn tick(self: *Self) !void {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (enemies.items) |*enemy| {
|
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(
|
rl.DrawCircle(
|
||||||
@intFromFloat(enemy.position.x),
|
@intFromFloat(enemy.position.x),
|
||||||
@intFromFloat(enemy.position.y),
|
@intFromFloat(enemy.position.y),
|
||||||
enemySize,
|
enemy.size,
|
||||||
rl.RED
|
color
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user