Fixed collision detection if player moves parallel to line
This commit is contained in:
108
src/game.c
108
src/game.c
@@ -40,48 +40,81 @@ void game_init(game_t* game, uint16_t ticks_per_sec) {
|
||||
game->ticks_sum_sec = 0;
|
||||
}
|
||||
|
||||
//Checks if the player head (+pixels in moving direction) collides with the line with the points start & end
|
||||
bool game_check_line_collision(player_t* player, point_t start, point_t end, uint8_t pixels){
|
||||
|
||||
bool line_is_horizontal = (start.y == end.y);
|
||||
bool player_is_horizontal = (player->direction == left || player->direction == right);
|
||||
|
||||
if(line_is_horizontal == player_is_horizontal){ // if player moves parallel to the line, there is no point in checking
|
||||
return false; // no collision possible because parallel moving
|
||||
}
|
||||
if(line_is_horizontal == player_is_horizontal){ // if player moves parallel to the line
|
||||
|
||||
if(!player_is_horizontal && (player->position.x < min(start.x, end.x) || player->position.x > max(start.x, end.x))){
|
||||
return false; // if player is passing by horizontally, no collision possible
|
||||
}
|
||||
if(player_is_horizontal && start.y != player->position.y ) {
|
||||
return false; // player is not on the same height as the line, no collision possible
|
||||
}
|
||||
|
||||
if(player_is_horizontal && (player->position.y < min(start.y, end.y) || player->position.y > max(start.y, end.y))){
|
||||
return false; // if player is passing by vertically, no collision possible
|
||||
}
|
||||
if(!player_is_horizontal && start.x != player->position.x ) {
|
||||
return false; // player is not on the same column as the line, no collision possible
|
||||
}
|
||||
|
||||
switch(player->direction){
|
||||
case up:
|
||||
if(player->position.y > start.y && ((int16_t)player->position.y - pixels) <= start.y) {
|
||||
return true; // going up and hitting a line segment
|
||||
}
|
||||
break;
|
||||
case down:
|
||||
if(player->position.y < start.y && ((int16_t)player->position.y + pixels) >= start.y) {
|
||||
return true; // going down and hitting a line segment
|
||||
}
|
||||
break;
|
||||
case left:
|
||||
if(player->position.x > start.x && ((int16_t)player->position.x - pixels) <= start.x) {
|
||||
return true; // going left and hitting a line segment
|
||||
}
|
||||
break;
|
||||
case right:
|
||||
if(player->position.x < start.x && ((int16_t)player->position.x + pixels) >= start.x) {
|
||||
return true; // going right and hitting a line segment
|
||||
}
|
||||
break;
|
||||
switch(player->direction){
|
||||
case up:
|
||||
if(((int16_t)player->position.y - pixels) <= max(start.y,end.y) && ((int16_t)player->position.y - pixels) >= min(start.y,end.y)) {
|
||||
return true; // player head is inside of line
|
||||
}
|
||||
break;
|
||||
case down:
|
||||
if(((int16_t)player->position.y + pixels) >= min(start.y,end.y) && ((int16_t)player->position.y + pixels) <= max(start.y,end.y)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case left:
|
||||
if(((int16_t)player->position.x - pixels) <= max(start.x,end.x) && ((int16_t)player->position.x - pixels) >= min(start.x,end.x)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case right:
|
||||
if(((int16_t)player->position.x + pixels) >= min(start.x,end.x) && ((int16_t)player->position.x + pixels) <= max(start.x,end.x)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else { //Player moves antiparalell to the line
|
||||
|
||||
if(!player_is_horizontal && (player->position.x < min(start.x, end.x) || player->position.x > max(start.x, end.x))){
|
||||
return false; // if player is passing by horizontally, no collision possible
|
||||
}
|
||||
|
||||
if(player_is_horizontal && (player->position.y < min(start.y, end.y) || player->position.y > max(start.y, end.y))){
|
||||
return false; // if player is passing by vertically, no collision possible
|
||||
}
|
||||
|
||||
switch(player->direction){
|
||||
case up:
|
||||
if(player->position.y > start.y && ((int16_t)player->position.y - pixels) <= start.y) {
|
||||
return true; // going up and hitting a line segment
|
||||
}
|
||||
break;
|
||||
case down:
|
||||
if(player->position.y < start.y && ((int16_t)player->position.y + pixels) >= start.y) {
|
||||
return true; // going down and hitting a line segment
|
||||
}
|
||||
break;
|
||||
case left:
|
||||
if(player->position.x > start.x && ((int16_t)player->position.x - pixels) <= start.x) {
|
||||
return true; // going left and hitting a line segment
|
||||
}
|
||||
break;
|
||||
case right:
|
||||
if(player->position.x < start.x && ((int16_t)player->position.x + pixels) >= start.x) {
|
||||
return true; // going right and hitting a line segment
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check if the player head (+pixels in moving direction) collides with the game field boundary
|
||||
bool game_check_boundary_collision(game_t* game, player_t* player, uint8_t pixels){
|
||||
|
||||
// Check boundary collision
|
||||
@@ -111,6 +144,7 @@ bool game_check_boundary_collision(game_t* game, player_t* player, uint8_t pixel
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check if the player (+pixels in moving direction) collides with any other player (including itself)
|
||||
bool game_check_player_collision(game_t* game, player_t* player, uint8_t pixels){
|
||||
// Check for collisions with players (including self)
|
||||
for(int i = 0; i < PLAYER_COUNT; i++){
|
||||
@@ -138,7 +172,8 @@ bool game_check_player_collision(game_t* game, player_t* player, uint8_t pixels)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool game_check_collision(game_t* game, player_t* player, uint8_t pixels){ // Check boundary and player collisions
|
||||
//Check if the player (+pixels in moving direction) collides either with other players (including self) or the game field boundary
|
||||
bool game_check_collision(game_t* game, player_t* player, uint8_t pixels) {
|
||||
|
||||
// Check for collisions with boundarys
|
||||
if(game_check_boundary_collision(game, player, pixels)){
|
||||
@@ -153,6 +188,8 @@ bool game_check_collision(game_t* game, player_t* player, uint8_t pixels){ // Ch
|
||||
return false; // no collision!
|
||||
}
|
||||
|
||||
//Update the player state and draw the player. The player head will be moved by "pixels" in moving direction.
|
||||
//Returns true if the player state has changed
|
||||
bool game_player_update(game_t* game, player_t* player, uint8_t pixels){
|
||||
|
||||
bool direction_change = false;
|
||||
@@ -226,6 +263,7 @@ bool game_player_update(game_t* game, player_t* player, uint8_t pixels){
|
||||
return state_changed; // return state
|
||||
}
|
||||
|
||||
//Calculates two colors out of the 16 bits, passed in confbits.
|
||||
void game_get_color(uint16_t confbits, uint16_t* player1_color, uint16_t* player2_color) {
|
||||
|
||||
//we have 4 bits per player color, we use 1 bit for red, 2 for green, 1 for blue
|
||||
@@ -260,6 +298,8 @@ void game_get_color(uint16_t confbits, uint16_t* player1_color, uint16_t* player
|
||||
}
|
||||
}
|
||||
|
||||
//Calculates one step of the game, when the game is in the init state
|
||||
//Returns true if the function was blocking, and deltaTicks should be reset
|
||||
bool game_step_init(game_t* game) {
|
||||
|
||||
//Draw welcome bitmap
|
||||
@@ -276,6 +316,8 @@ bool game_step_init(game_t* game) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Calculates one step of the game, when the game is in the prestart state
|
||||
//Returns true if the function was blocking, and deltaTicks should be reset
|
||||
bool game_step_prestart(game_t* game) {
|
||||
|
||||
//Draw "Player x: Color" Strings
|
||||
@@ -427,6 +469,8 @@ bool game_step_prestart(game_t* game) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Calculates one step of the game, when the game is in the running state
|
||||
//Returns true if the function was blocking, and deltaTicks should be reset
|
||||
bool game_step_running(game_t* game, uint64_t delta_time)
|
||||
|
||||
{
|
||||
@@ -484,6 +528,8 @@ bool game_step_running(game_t* game, uint64_t delta_time)
|
||||
}
|
||||
}
|
||||
|
||||
//Calculates one step of the game, when the game is in the ended state
|
||||
//Returns true if the function was blocking, and deltaTicks should be reset
|
||||
bool game_step_ended(game_t* game) {
|
||||
|
||||
// Kill screen
|
||||
|
||||
Reference in New Issue
Block a user