mirror of
https://github.com/thepigeongenerator/tetris_clone.git
synced 2025-12-17 05:55:46 +01:00
add collision
This commit is contained in:
@@ -21,6 +21,8 @@ void game_init(GameData* const game_data) {
|
||||
for (uint8_t i = 0; i < ROWS; i++)
|
||||
game_data->row[i] = game_data->row_raw[i];
|
||||
|
||||
game_data->selected = (SelectedShape){TETROMINO_L, 0, 0};
|
||||
|
||||
// set a random seed using the system clock
|
||||
srand(time(NULL));
|
||||
}
|
||||
@@ -68,31 +70,13 @@ static void clear_rows(Row* row) {
|
||||
}
|
||||
}
|
||||
|
||||
static void update_input(GameData* game_data, const uint8_t* keys) {
|
||||
if (keys[SDL_SCANCODE_ESCAPE])
|
||||
stop();
|
||||
|
||||
if (keys[SDL_SCANCODE_DOWN] || keys[SDL_SCANCODE_S] || keys[SDL_SCANCODE_SPACE])
|
||||
game_data->selected.y++;
|
||||
|
||||
if (keys[SDL_SCANCODE_LEFT] || keys[SDL_SCANCODE_A])
|
||||
game_data->selected.x--;
|
||||
|
||||
if (keys[SDL_SCANCODE_RIGHT] || keys[SDL_SCANCODE_D])
|
||||
game_data->selected.x++;
|
||||
}
|
||||
|
||||
|
||||
// called every time the game's state is updated
|
||||
void game_update(GameData* game_data, const uint8_t* keys) {
|
||||
static int x = 0;
|
||||
if (!x) {
|
||||
x = 1;
|
||||
game_data->selected = (SelectedShape){TETROMINO_L, 0, 0};
|
||||
}
|
||||
if (keys[SDL_SCANCODE_ESCAPE])
|
||||
stop();
|
||||
|
||||
update_input(game_data, keys);
|
||||
|
||||
// tmp_set_random(game_data);
|
||||
dbg_set_all(game_data);
|
||||
place_update(game_data, keys);
|
||||
// dbg_set_all(game_data);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "../../window/colour.h"
|
||||
#include "../game.h"
|
||||
#include "SDL_scancode.h"
|
||||
#include "shapes.h"
|
||||
|
||||
// sets a shape to the screen
|
||||
@@ -27,6 +28,61 @@ static inline void set_shape(Row* row, const ShapeId id, const uint8_t pos_x, co
|
||||
set_shape_i(&row[pos_y], id, pos_x); // calls itself, but omitting the pos_y argument, instead opting for specifying the row
|
||||
}
|
||||
|
||||
static bool shape_intersects(const Row* rows, const ShapeId id, const uint8_t x, const uint8_t y) {
|
||||
const Shape shape = shape_from_id(id);
|
||||
|
||||
for (uint8_t y0 = 0; y0 < SHAPE_HEIGHT; y0++) {
|
||||
const ShapeRow shape_row = shape_get_row(shape, y0); // get the shape row
|
||||
if (shape_row == 0) continue; // if the row doesn't contain data; continue
|
||||
|
||||
for (uint8_t x0 = 0; x0 < SHAPE_WIDTH; x0++) {
|
||||
if (is_set(shape_row, x0) == false) continue; // if the bit isn't set at this index; continue
|
||||
const uint8_t x1 = x + x0;
|
||||
const uint8_t y1 = y + y0;
|
||||
|
||||
if (x1 < 0 || x1 >= COLUMNS) return true; // if X is out of bounds
|
||||
if (y1 < 0 || y1 >= ROWS) return true; // if Y is out of bounds
|
||||
if (rows[y1][x1].packed != 0) return true; // if there is a block here
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void place_update(GameData* const game_data, const uint8_t* const keys) {
|
||||
int8_t move = 0;
|
||||
|
||||
if (keys[SDL_SCANCODE_LEFT] || keys[SDL_SCANCODE_A])
|
||||
move |= 1;
|
||||
|
||||
if (keys[SDL_SCANCODE_RIGHT] || keys[SDL_SCANCODE_D])
|
||||
move |= 2;
|
||||
|
||||
if (keys[SDL_SCANCODE_DOWN] || keys[SDL_SCANCODE_S] || keys[SDL_SCANCODE_SPACE])
|
||||
move |= 4;
|
||||
|
||||
// set the shape if we moved vertically and collided
|
||||
if (!!(move & 4)) {
|
||||
const uint8_t y = game_data->selected.y + 1;
|
||||
if (shape_intersects(game_data->row, game_data->selected.id, game_data->selected.x, y)) {
|
||||
set_shape(game_data->row, game_data->selected.id, game_data->selected.x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
game_data->selected.y = y;
|
||||
}
|
||||
|
||||
// ignore if the movement cancles itself out
|
||||
if ((move & 3) == 0 || (move & 3) == 3)
|
||||
return;
|
||||
|
||||
const uint8_t x = game_data->selected.x + ((move & 3) == 1 ? -1 : 1);
|
||||
if (shape_intersects(game_data->row, game_data->selected.id, x, game_data->selected.y))
|
||||
return;
|
||||
|
||||
game_data->selected.x = x;
|
||||
printf("%i\n", x);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dbg_set_all(GameData* game_data) {
|
||||
for (uint8_t i = 0; i < TETROMINO_COUNT; i++)
|
||||
@@ -34,17 +90,3 @@ void dbg_set_all(GameData* game_data) {
|
||||
set_shape(game_data->row, i | (r << 3), r * 4, i * 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
void tmp_set_random(GameData* game_data) {
|
||||
static int finished = 0;
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
finished = 1;
|
||||
for (uint8_t y = 0; y <= ROWS - SHAPE_HEIGHT; y += SHAPE_HEIGHT) {
|
||||
for (uint8_t x = 0; x <= COLUMNS - SHAPE_WIDTH; x += SHAPE_WIDTH) {
|
||||
const ShapeId id = (rand() % TETROMINO_COUNT) | ((rand() % 4) << 3);
|
||||
set_shape(game_data->row, id, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../game.h"
|
||||
#include "shapes.h"
|
||||
|
||||
void place_update(GameData* game_data, const uint8_t* keys);
|
||||
|
||||
void tmp_set_random(GameData* game_data);
|
||||
#ifdef DEBUG
|
||||
void dbg_set_all(GameData* game_data);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user