Changed God mode.

- Paddle follows the ball (not restricted by its hardcoded speed).
- Bricks are spawned again after all bricks are destroyed, only when God mode is enabled.
This commit is contained in:
Sander Schobers 2020-06-13 10:22:57 +02:00
parent 6c2d724621
commit f5b3ff4f0c

View File

@ -107,6 +107,7 @@ pub const Game = struct {
pub const bricks_height = @intToFloat(f32, rows) * Brick.size.y + (@intToFloat(f32, rows) + 1) * Brick.gap;
pub const bricks_per_row: usize = 12;
pub const bricks_width = @intToFloat(f32, bricks_per_row) * Brick.size.x + (@intToFloat(f32, bricks_per_row) + 1) * Brick.gap;
pub const bricks_n: usize = rows * bricks_per_row;
pub const row_colors = [rows]Color{
ColorU8.rgb(171, 112, 234).toColor(),
ColorU8.rgb(239, 47, 115).toColor(),
@ -116,7 +117,7 @@ pub const Game = struct {
};
pub const rows: usize = 5;
bricks: [rows * bricks_per_row]Brick = undefined,
bricks: [bricks_n]Brick = undefined,
paddle: Paddle = Paddle{},
ball: Ball = Ball{},
particles: std.ArrayList(Particles),
@ -128,33 +129,51 @@ pub const Game = struct {
move_paddle_right: bool = false,
pub fn init(allocator: *std.mem.Allocator) Game {
var game = Game{
return Game{
.particles = std.ArrayList(Particles).init(allocator),
.bricks = Game.init_bricks(),
};
// game.allocator = allocator;
}
fn init_bricks() [bricks_n]Brick {
var bricks: [bricks_n]Brick = undefined;
const gap = Point.init(Brick.gap, Brick.gap);
const brick = Brick.size.add(gap);
const top_left = Game.area.min.add(gap);
for (game.bricks) |_, i| {
for (bricks) |_, i| {
const column = i % bricks_per_row;
const row = i / bricks_per_row;
const left = @intToFloat(f32, column) * brick.x + top_left.x;
const top = @intToFloat(f32, row) * brick.y + top_left.y;
game.bricks[i].bounds = Rectangle.init(left, top, left + Brick.size.x, top + Brick.size.y);
bricks[i].bounds = Rectangle.init(left, top, left + Brick.size.x, top + Brick.size.y);
}
return game;
return bricks;
}
pub fn destroy(self: *Game) void {
self.particles.deinit();
}
fn areAllBricksDestroyed(self: Game) bool {
for (self.bricks) |brick| {
// if (!brick.destroyed) { // this condition is not working, other workaround: if (destroyed) {} else { return false; }
const not_destroyed = !brick.destroyed;
if (not_destroyed) {
return false;
}
}
return true;
}
fn destroyBrick(self: *Game, row: usize, i: usize, bounce: Point) void {
const ii = row * bricks_per_row + i;
self.bricks[ii].destroyed = true;
self.score += @intCast(u32, (rows - row) * 5);
const particles = Particles.init(Game.row_colors[row], bounce);
self.particles.append(particles) catch unreachable;
if (self.god_mode and self.areAllBricksDestroyed()) {
self.bricks = Game.init_bricks();
}
}
pub fn keyDown(self: *Game, key: Key) void {
@ -225,13 +244,7 @@ pub const Game = struct {
}
}
// bottom of game area
if (Ball.passedMax(ball_position.y, Game.area.max.y)) {
if (self.god_mode) {
_ = self.ball.bounceBottomObstacle(Game.area.max.y);
} else {
self.game_over = true;
}
}
self.game_over = Ball.passedMax(ball_position.y, Game.area.max.y);
// bricks (per row)
var row: usize = 0;
@ -279,16 +292,20 @@ pub const Game = struct {
}
// move the paddle
if (self.move_paddle_left and !self.move_paddle_right) {
self.paddle.position.x -= Paddle.speed * increment;
if (self.paddle.position.x < Paddle.area.min.x) {
self.paddle.position.x = Paddle.area.min.x;
if (self.god_mode) {
self.paddle.position.x = math.max(Paddle.area.min.x, math.min(Paddle.area.max.x, self.ball.position.x));
} else {
if (self.move_paddle_left and !self.move_paddle_right) {
self.paddle.position.x -= Paddle.speed * increment;
if (self.paddle.position.x < Paddle.area.min.x) {
self.paddle.position.x = Paddle.area.min.x;
}
}
}
if (self.move_paddle_right and !self.move_paddle_left) {
self.paddle.position.x += Paddle.speed * increment;
if (self.paddle.position.x > Paddle.area.max.x) {
self.paddle.position.x = Paddle.area.max.x;
if (self.move_paddle_right and !self.move_paddle_left) {
self.paddle.position.x += Paddle.speed * increment;
if (self.paddle.position.x > Paddle.area.max.x) {
self.paddle.position.x = Paddle.area.max.x;
}
}
}