usg/src/Game.zig

233 lines
5.8 KiB
Zig
Raw Normal View History

2022-06-28 12:42:28 +00:00
const std = @import("std");
const SDL = @import("sdl2");
const Grid = @import("Game/Grid.zig");
const Piece = @import("Game/Piece.zig");
const Bag = @import("Game/Bag.zig");
const Timer = @import("Timer.zig");
2022-07-13 20:59:54 +00:00
const State = @import("flow.zig").State;
2022-07-20 17:31:18 +00:00
const Action = @import("Action.zig");
2022-06-28 12:42:28 +00:00
const Renderer = @import("Game/Renderer.zig");
const movement = @import("Game/movement.zig");
2022-06-28 12:42:28 +00:00
const Self = @This();
2022-07-20 17:31:18 +00:00
// Codes to access action list
pub const ActionCode = enum(usize) {
right = 0,
left = 1,
down = 2,
hard = 3,
swap = 4,
rot_r = 5,
rot_l = 6,
2022-07-10 16:25:52 +00:00
};
2022-06-28 12:42:28 +00:00
grid: Grid,
renderer: Renderer,
2022-06-28 12:42:28 +00:00
2022-07-13 20:59:54 +00:00
state: State = State.game,
2022-06-30 15:38:20 +00:00
bag: Bag,
2022-07-05 18:26:57 +00:00
held: ?Piece.Type,
piece: Piece,
shadow: Piece,
2022-07-10 16:25:52 +00:00
action_list: [7]Action = .{
2022-07-20 17:31:18 +00:00
Action.init(SDL.SDL_SCANCODE_D, actionRight), // Right
Action.init(SDL.SDL_SCANCODE_A, actionLeft), // Left
Action.init(SDL.SDL_SCANCODE_S, actionDown), // Down
Action.init(SDL.SDL_SCANCODE_W, actionHard), // Instant Drop
Action.init(SDL.SDL_SCANCODE_SPACE, actionSwap), // Swap Piece
Action.init(SDL.SDL_SCANCODE_RIGHT, actionRotR), // Rotate
Action.init(SDL.SDL_SCANCODE_LEFT, actionRotL), // Rotate
2022-07-10 16:25:52 +00:00
},
2022-06-28 12:42:28 +00:00
2022-07-10 16:25:52 +00:00
timer_down: Timer,
2022-07-14 13:22:40 +00:00
timer_left_arr: Timer,
timer_left_das: Timer,
timer_right_arr: Timer,
timer_right_das: Timer,
2022-07-21 12:02:22 +00:00
timer_gravity: Timer,
2022-07-07 14:49:15 +00:00
pub fn init(renderer: *SDL.SDL_Renderer) Self {
var ret = Self{
2022-06-28 12:42:28 +00:00
.grid = Grid.init(),
2022-06-30 15:38:20 +00:00
.bag = Bag.init(),
.piece = undefined,
2022-07-05 18:26:57 +00:00
.shadow = undefined,
2022-06-28 12:42:28 +00:00
.held = null,
.renderer = Renderer.init(renderer),
2022-07-10 16:25:52 +00:00
2022-07-14 13:22:40 +00:00
.timer_down = Timer.init(50),
.timer_left_arr = Timer.init(50),
.timer_left_das = Timer.init(200),
.timer_right_arr = Timer.init(50),
.timer_right_das = Timer.init(200),
2022-07-21 12:02:22 +00:00
.timer_gravity = Timer.init(200),
2022-06-28 12:42:28 +00:00
};
2022-07-07 14:49:15 +00:00
2022-07-14 13:22:40 +00:00
// Get a piece from the bag
ret.piece = ret.bag.pop();
2022-06-30 15:38:20 +00:00
return ret;
2022-06-28 12:42:28 +00:00
}
2022-07-13 20:59:54 +00:00
pub fn tick(self: *Self) State {
2022-06-28 16:42:40 +00:00
2022-07-10 16:25:52 +00:00
// TIMERS
2022-07-14 13:22:40 +00:00
// Dropping a piece
2022-07-10 17:44:48 +00:00
if (self.piece.timer_dropped.finished()) {
self.piece.timer_dropped.stop();
self.piece.dropped = true;
2022-07-10 17:44:48 +00:00
}
2022-07-14 13:22:40 +00:00
// Repeat Right
// DAS
2022-07-20 17:31:18 +00:00
if (self.action_list[@enumToInt(ActionCode.right)].holding) {
2022-07-14 13:22:40 +00:00
if (!self.timer_right_das.started) {
self.timer_right_das.start();
}
} else {
// Stop both
self.timer_right_das.stop();
self.timer_right_arr.stop();
}
// ARR
if (self.timer_right_das.finished()) {
if (!self.timer_right_arr.started) {
self.timer_right_arr.start();
} else if (self.timer_right_arr.finished()) {
self.timer_right_arr.stop();
2022-07-20 17:31:18 +00:00
self.action_list[@enumToInt(ActionCode.right)].holding = false;
2022-07-14 13:22:40 +00:00
}
}
// Repeat Left
// DAS
2022-07-20 17:31:18 +00:00
if (self.action_list[@enumToInt(ActionCode.left)].holding) {
2022-07-14 13:22:40 +00:00
if (!self.timer_left_das.started) {
self.timer_left_das.start();
}
} else {
// Stop both
self.timer_left_das.stop();
self.timer_left_arr.stop();
}
// ARR
if (self.timer_left_das.finished()) {
if (!self.timer_left_arr.started) {
self.timer_left_arr.start();
} else if (self.timer_left_arr.finished()) {
self.timer_left_arr.stop();
2022-07-20 17:31:18 +00:00
self.action_list[@enumToInt(ActionCode.left)].holding = false;
2022-07-14 13:22:40 +00:00
}
}
// Repeat Down
2022-07-20 17:31:18 +00:00
if (self.action_list[@enumToInt(ActionCode.down)].holding) {
2022-07-10 16:25:52 +00:00
if (!self.timer_down.started) {
self.timer_down.start();
} else if (self.timer_down.finished()) {
self.timer_down.stop();
2022-07-20 17:31:18 +00:00
self.action_list[@enumToInt(ActionCode.down)].holding = false;
2022-07-10 16:25:52 +00:00
}
} else {
self.timer_down.stop();
2022-07-05 18:26:57 +00:00
}
2022-07-21 12:02:22 +00:00
// Gravity
if (!self.piece.timer_dropped.started) {
if (!self.timer_gravity.started) {
self.timer_gravity.start();
} else if (self.timer_gravity.finished()){
self.action_list[@enumToInt(ActionCode.down)].activate = true;
self.timer_gravity.start();
}
} else {
self.timer_gravity.stop();
}
2022-07-10 17:44:48 +00:00
// DROP
if (self.piece.dropped) {
self.grid = movement.drop(self.grid, self.piece);
// New Piece
self.piece = self.bag.pop();
}
2022-07-10 16:25:52 +00:00
// KEY EVENTS
var key_state = SDL.SDL_GetKeyboardState(null);
2022-07-05 18:26:57 +00:00
2022-07-10 16:25:52 +00:00
for (self.action_list) |*action| {
if (key_state[action.*.code] == 1 and !action.*.holding) {
action.*.holding = true;
action.*.activate = true;
}
if (key_state[action.*.code] == 0) {
action.*.holding = false;
}
2022-07-05 18:26:57 +00:00
2022-07-10 16:25:52 +00:00
// Action
if (action.*.activate) {
action.*.activate = false;
2022-07-20 17:31:18 +00:00
action.*.call(self);
2022-07-10 16:25:52 +00:00
}
2022-07-05 21:09:59 +00:00
}
2022-07-05 18:26:57 +00:00
// Update Shadow
2022-07-10 16:25:52 +00:00
{
self.shadow = movement.shadow(self.grid, self.piece);
self.shadow.color.a /= 4;
}
2022-07-05 18:26:57 +00:00
self.grid.clearLines();
self.renderer.render(self.*);
2022-07-13 20:59:54 +00:00
return self.state;
2022-07-05 18:26:57 +00:00
}
2022-07-10 16:25:52 +00:00
// ACTION CALLBACKS
fn actionDown(self: *Self) void {
self.piece = movement.moveDown(self.grid, self.piece);
}
fn actionRight(self: *Self) void {
self.piece = movement.moveRight(self.grid, self.piece);
}
fn actionLeft(self: *Self) void {
self.piece = movement.moveLeft(self.grid, self.piece);
}
fn actionHard(self: *Self) void {
self.piece = movement.hardDrop(self.grid, self.piece);
}
fn actionSwap(self: *Self) void {
2022-07-05 18:26:57 +00:00
if (self.held) |held_piece| {
if (!self.piece.swapped) {
self.held = self.piece.piece_type;
self.piece = Piece.init(held_piece);
self.piece.swapped = true;
}
} else {
self.held = self.piece.piece_type;
self.piece = self.bag.pop();
self.piece.swapped = true;
}
2022-06-28 12:42:28 +00:00
}
2022-07-10 16:25:52 +00:00
fn actionRotR(self: *Self) void {
self.piece = movement.rotateRight(self.grid, self.piece);
}
fn actionRotL(self: *Self) void {
self.piece = movement.rotateLeft(self.grid, self.piece);
}