add border
This commit is contained in:
parent
2941d9a39c
commit
f58f3d0f86
@ -11,10 +11,14 @@ const friction = 0.99;
|
||||
const walkForce = 4000;
|
||||
const maxSpeed = 200;
|
||||
const handDistance = 50;
|
||||
const deathBallSize: f32 = 10;
|
||||
const deathBallSize: f32 = 13;
|
||||
const playerSize = 20;
|
||||
const virtualWidth = 300;
|
||||
const virtualHeight = 300;
|
||||
const virtualWidth = 350;
|
||||
const virtualHeight = 350;
|
||||
const safeRadius = 500;
|
||||
const spawnAreaWidth = 400;
|
||||
|
||||
const arenaRadius = safeRadius + spawnAreaWidth;
|
||||
|
||||
const enemyFriction = friction;
|
||||
|
||||
@ -244,7 +248,7 @@ pub fn deinit(self: *Self) void {
|
||||
self.pixel_effect.deinit();
|
||||
}
|
||||
|
||||
fn tickPlayer(self: *Self) void {
|
||||
fn updatePlayer(self: *Self) void {
|
||||
const dt = rl.GetFrameTime();
|
||||
var player = &self.player;
|
||||
var rope = &self.rope;
|
||||
@ -260,6 +264,12 @@ fn tickPlayer(self: *Self) void {
|
||||
player.acceleration = rl.Vector2Scale(player.acceleration, walkForce);
|
||||
}
|
||||
|
||||
if (player.position.length() > arenaRadius) {
|
||||
const push_strength = std.math.pow(f32, player.position.length() - arenaRadius + 10, 2);
|
||||
const push_direction = player.position.normalize().neg();
|
||||
player.acceleration = player.acceleration.add(push_direction.scale(push_strength));
|
||||
}
|
||||
|
||||
player.velocity = rl.Vector2Add(player.velocity, rl.Vector2Scale(player.acceleration, dt));
|
||||
player.velocity = rl.Vector2ClampValue(player.velocity, 0, maxSpeed);
|
||||
player.velocity = rl.Vector2Scale(player.velocity, std.math.pow(f32, (1 - friction), dt));
|
||||
@ -274,7 +284,7 @@ fn tickPlayer(self: *Self) void {
|
||||
rope.update(dt);
|
||||
}
|
||||
|
||||
fn tickEnemies(self: *Self) !void {
|
||||
fn updateEnemies(self: *Self) !void {
|
||||
var rng = self.prng.random();
|
||||
const dt = rl.GetFrameTime();
|
||||
var enemies = &self.enemies;
|
||||
@ -282,7 +292,7 @@ fn tickEnemies(self: *Self) !void {
|
||||
var rope = &self.rope;
|
||||
|
||||
self.enemyTimer -= dt;
|
||||
if (self.enemyTimer <= 0) {
|
||||
if (self.enemyTimer <= 0 and player.alive()) {
|
||||
self.enemyTimer = 0.5 + rng.float(f32) * 2;
|
||||
self.spawnedEnemiesCount += 1;
|
||||
const enemyPosition = rl.Vector2.randomOnUnitCircle(rng).scale(400);
|
||||
@ -297,7 +307,7 @@ fn tickEnemies(self: *Self) !void {
|
||||
self.damagePlayer();
|
||||
}
|
||||
|
||||
if (enemy.vulnerable() and rl.Vector2Distance(enemy.position, deathBallPosition) < enemy.size + deathBallSize) {
|
||||
if (enemy.vulnerable() and player.alive() and rl.Vector2Distance(enemy.position, deathBallPosition) < enemy.size + deathBallSize) {
|
||||
self.damageEnemy(enemy);
|
||||
}
|
||||
|
||||
@ -402,8 +412,8 @@ fn tickUI(self: *Self) !void {
|
||||
const screen_box = UIBox.init(0 ,0, virtualWidth, virtualHeight);
|
||||
const font = rl.GetFontDefault();
|
||||
|
||||
try allocDrawText(allocator, "{d}", .{self.spawnedEnemiesCount}, 10, 10, 12, rl.RED);
|
||||
try allocDrawText(allocator, "{d}", .{self.killCount}, 10, 30, 12, rl.GREEN);
|
||||
// try allocDrawText(allocator, "{d}", .{self.spawnedEnemiesCount}, 10, 10, 12, rl.RED);
|
||||
// try allocDrawText(allocator, "{d}", .{self.killCount}, 10, 30, 12, rl.GREEN);
|
||||
|
||||
const minutes_text = try std.fmt.allocPrint(allocator, "{d:.0}", .{self.timePassed/60});
|
||||
defer allocator.free(minutes_text);
|
||||
@ -417,9 +427,9 @@ fn tickUI(self: *Self) !void {
|
||||
const minutes_text_z = try std.mem.concatWithSentinel(allocator, u8, &.{ minutes_text }, 0);
|
||||
defer allocator.free(minutes_text_z);
|
||||
|
||||
const font_size = 12;
|
||||
const font_size = 20;
|
||||
const time_passed_width: f32 = @floatFromInt(rl.MeasureText(minutes_text_z, font_size) + rl.MeasureText(":000", font_size));
|
||||
const time_passed_pos = screen_box.center_top().add(.{ .x = -time_passed_width/2, .y = 30 });
|
||||
const time_passed_pos = screen_box.center_top().add(.{ .x = -time_passed_width/2, .y = 10 });
|
||||
rl.DrawTextEx(
|
||||
font,
|
||||
time_passed_text,
|
||||
@ -430,7 +440,7 @@ fn tickUI(self: *Self) !void {
|
||||
);
|
||||
|
||||
if (!self.player.alive()) {
|
||||
const modal_size = rl.Vector2{ .x = 200, .y = 400 };
|
||||
const modal_size = rl.Vector2{ .x = 200, .y = 200 };
|
||||
const modal = screen_box.box(
|
||||
screen_box.center() - modal_size.x/2,
|
||||
screen_box.middle() - modal_size.y/2,
|
||||
@ -448,11 +458,20 @@ fn tickUI(self: *Self) !void {
|
||||
rl.BLACK
|
||||
);
|
||||
|
||||
if (self.ui.button("Restart?", content.left(), content.top() + 70, content.width, 30)) {
|
||||
try allocDrawText(
|
||||
allocator,
|
||||
"Kills: {d}", .{self.killCount},
|
||||
@intFromFloat(content.left() + 10),
|
||||
@intFromFloat(content.top() + 60),
|
||||
30,
|
||||
rl.BLACK
|
||||
);
|
||||
|
||||
if (self.ui.button("Restart?", content.left(), content.bottom() - 70, content.width, 30)) {
|
||||
self.reset();
|
||||
}
|
||||
|
||||
if (self.ui.button("Exit?", content.left(), content.top() + 120, content.width, 30)) {
|
||||
if (self.ui.button("Exit?", content.left(), content.bottom() - 30, content.width, 30)) {
|
||||
self.should_close = true;
|
||||
}
|
||||
} else if (self.paused) {
|
||||
@ -497,7 +516,7 @@ fn drawPlayer(self: *Self) void {
|
||||
var player = &self.player;
|
||||
const handPosition = player.getHandPosition();
|
||||
|
||||
const healthWidth = 5;
|
||||
const healthWidth = 7;
|
||||
const healthPercent = @as(f32, @floatFromInt(player.health)) / @as(f32, @floatFromInt(player.maxHealth));
|
||||
var healthColor = rl.GREEN;
|
||||
if (player.invincibility > 0 and @rem(player.invincibility, 0.2) < 0.1) {
|
||||
@ -513,9 +532,10 @@ fn drawPlayer(self: *Self) void {
|
||||
);
|
||||
for (0..(player.health+1)) |i| {
|
||||
const percent = @as(f32, @floatFromInt(i)) / @as(f32, @floatFromInt(player.maxHealth));
|
||||
rl.DrawLineV(
|
||||
rl.DrawLineEx(
|
||||
player.position,
|
||||
player.position.add((rl.Vector2{ .x = playerSize + healthWidth, .y = 0 }).rotate(percent * 2 * rl.PI)),
|
||||
5,
|
||||
rl.BLACK
|
||||
);
|
||||
}
|
||||
@ -533,83 +553,100 @@ fn drawPlayer(self: *Self) void {
|
||||
);
|
||||
}
|
||||
|
||||
fn rgba(r: u8, g: u8, b: u8, a: u8) rl.Color {
|
||||
return rl.Color{ .r = r, .g = g, .b = b, .a = a };
|
||||
}
|
||||
|
||||
fn rgb(r: u8, g: u8, b: u8) rl.Color {
|
||||
return rgba(r, g, b, 255);
|
||||
}
|
||||
|
||||
fn drawWorld(self: *Self) void {
|
||||
rl.rlSetLineWidth(1);
|
||||
var enemies = &self.enemies;
|
||||
var rope = &self.rope;
|
||||
const deathBallPosition = rope.nodePositions.get(rope.nodePositions.len-1);
|
||||
|
||||
rl.ClearBackground(rl.BLACK);
|
||||
rl.DrawCircle(0, 0, arenaRadius, rl.BROWN);
|
||||
rl.DrawCircle(0, 0, 5, rl.GOLD);
|
||||
|
||||
rl.DrawCircleLines(0, 0, safeRadius, rl.WHITE);
|
||||
rl.DrawCircleLines(0, 0, safeRadius + spawnAreaWidth, rl.WHITE);
|
||||
|
||||
self.drawPlayer();
|
||||
|
||||
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),
|
||||
enemy.size,
|
||||
color
|
||||
);
|
||||
}
|
||||
|
||||
rl.rlDrawRenderBatchActive();
|
||||
rl.rlSetLineWidth(3);
|
||||
for (0..(rope.nodePositions.len-1)) |i| {
|
||||
var node1: rl.Vector2 = rope.nodePositions.get(i);
|
||||
var node2: rl.Vector2 = rope.nodePositions.get(i+1);
|
||||
rl.DrawLine(
|
||||
@intFromFloat(node1.x),
|
||||
@intFromFloat(node1.y),
|
||||
@intFromFloat(node2.x),
|
||||
@intFromFloat(node2.y),
|
||||
rgb(106, 7, 17)
|
||||
);
|
||||
}
|
||||
rl.rlDrawRenderBatchActive();
|
||||
rl.rlSetLineWidth(1);
|
||||
|
||||
for (rope.nodePositions.slice()) |node| {
|
||||
rl.DrawCircle(
|
||||
@intFromFloat(node.x),
|
||||
@intFromFloat(node.y),
|
||||
5,
|
||||
rgb(194, 12, 30)
|
||||
);
|
||||
}
|
||||
|
||||
rl.DrawCircle(
|
||||
@intFromFloat(deathBallPosition.x),
|
||||
@intFromFloat(deathBallPosition.y),
|
||||
deathBallSize,
|
||||
rgb(239, 48, 67)
|
||||
);
|
||||
}
|
||||
|
||||
pub fn tick(self: *Self) !void {
|
||||
const dt = rl.GetFrameTime();
|
||||
|
||||
self.camera.offset.x = virtualWidth/2;
|
||||
self.camera.offset.y = virtualHeight/2;
|
||||
self.camera.zoom = 0.4;
|
||||
self.camera.target = rl.Vector2Lerp(self.camera.target, self.player.position, 10 * dt);
|
||||
|
||||
var enemies = &self.enemies;
|
||||
var rope = &self.rope;
|
||||
|
||||
if (self.player.input.isPausePressed()) {
|
||||
if (self.player.input.isPausePressed() and self.player.alive()) {
|
||||
self.togglePaused();
|
||||
}
|
||||
|
||||
if (!self.paused) {
|
||||
self.tickPlayer();
|
||||
try self.tickEnemies();
|
||||
self.camera.offset.x = virtualWidth/2;
|
||||
self.camera.offset.y = virtualHeight/2;
|
||||
self.camera.zoom = 0.4;
|
||||
self.camera.target = rl.Vector2Lerp(self.camera.target, self.player.position, 10 * dt);
|
||||
|
||||
self.updatePlayer();
|
||||
try self.updateEnemies();
|
||||
|
||||
if (self.player.alive()) {
|
||||
self.timePassed += rl.GetFrameTime();
|
||||
}
|
||||
}
|
||||
|
||||
const deathBallPosition = rope.nodePositions.get(rope.nodePositions.len-1);
|
||||
|
||||
self.pixel_effect.begin();
|
||||
rl.ClearBackground(rl.BROWN);
|
||||
rl.BeginMode2D(self.camera);
|
||||
{
|
||||
rl.DrawCircle(0, 0, 5, rl.GOLD);
|
||||
|
||||
self.drawPlayer();
|
||||
|
||||
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),
|
||||
enemy.size,
|
||||
color
|
||||
);
|
||||
}
|
||||
|
||||
const rope_color = rl.PURPLE;
|
||||
for (0..(rope.nodePositions.len-1)) |i| {
|
||||
var node1: rl.Vector2 = rope.nodePositions.get(i);
|
||||
var node2: rl.Vector2 = rope.nodePositions.get(i+1);
|
||||
rl.DrawLine(
|
||||
@intFromFloat(node1.x),
|
||||
@intFromFloat(node1.y),
|
||||
@intFromFloat(node2.x),
|
||||
@intFromFloat(node2.y),
|
||||
rope_color
|
||||
);
|
||||
}
|
||||
|
||||
for (rope.nodePositions.slice()) |node| {
|
||||
rl.DrawCircle(
|
||||
@intFromFloat(node.x),
|
||||
@intFromFloat(node.y),
|
||||
5,
|
||||
rope_color
|
||||
);
|
||||
}
|
||||
|
||||
rl.DrawCircle(
|
||||
@intFromFloat(deathBallPosition.x),
|
||||
@intFromFloat(deathBallPosition.y),
|
||||
deathBallSize,
|
||||
rl.RED
|
||||
);
|
||||
}
|
||||
self.drawWorld();
|
||||
rl.EndMode2D();
|
||||
self.pixel_effect.end();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user