diff options
| author | Flenk008 <frenk_0_0@hotmail.com> | 2023-03-15 18:58:25 +0100 | 
|---|---|---|
| committer | Flenk008 <frenk_0_0@hotmail.com> | 2023-03-15 18:58:25 +0100 | 
| commit | e79c36460f400991caa82598499c0ea7c37ebb90 (patch) | |
| tree | 1a9bb572243b6c807d2a702c80ee4969db906b9d /src | |
| parent | 8ddc75bc09a08227846f888fc4bef23ce578adc5 (diff) | |
Player-Enemy collision
Added player with enemy collision. Also changed input system to a vector system with friction and gravity. Jump also works. Enemy is 1 stationary object.
Diffstat (limited to 'src')
| -rw-r--r-- | src/demo.c | 175 | ||||
| -rw-r--r-- | src/engine/entity.c | 81 | ||||
| -rw-r--r-- | src/engine/entity.h | 25 | ||||
| -rw-r--r-- | src/engine/player_controller.c | 155 | ||||
| -rw-r--r-- | src/ppusim/input.c | 1 | 
5 files changed, 253 insertions, 184 deletions
@@ -1,26 +1,21 @@  #include <math.h>  #include "demo.h" -#include "entity.h"  #include "input.h" +#include "entity.h"  #include "ppu/ppu.h" -#define HH_DEMO_BALL_COUNT 1 -hh_s_ppu_loc_fam_entry g_hh_demo_balls[HH_DEMO_BALL_COUNT]; +#include "engine/maths.h" +#include "engine/camera.h" +#include "engine/entity.h" +#include "engine/draw_screen.h" +#include "engine/player_controller.h" +#include "engine/sprite_controller.h" -hh_s_entity_player g_hh_player_1 = { -	.pos_x		 = 31000, // 0b0000 0001 0011 0110 -	.pos_y		 = 21000, -	.radius		 = 8, -	.speed		 = 100, -	.direction_x = 1, -	.rotation	 = 8, -	.in_air		 = false, -}; -void hh_player_movement(); -uint16_t g_hh_pos_x; // 0b0000 0001 0011 0110 + +uint16_t g_hh_pos_x = 1000; // 0b0000 0001 0011 0110  uint16_t g_hh_pos_y;  uint8_t g_hh_left  = 0;  uint8_t g_hh_right = 0; @@ -29,67 +24,29 @@ uint8_t g_hh_down  = 0;  uint8_t g_hh_pos_x_bit[2];  uint8_t g_hh_pos_y_bit[2];  uint8_t g_hh_data_send[3]; -int g_hh_tile_x; +int g_hh_tile_size = 8;  int g_hh_tile_y; -void hh_demo_setup() { -	// load sprites -	hh_ppu_update_sprite(0, HH_DBG_SPRITE_BALL); -	hh_ppu_update_sprite(1, HH_DBG_SPRITE_CHECKERBOARD); - -	// background pattern -	hh_ppu_update_color(0, 1, (hh_ppu_rgb_color_t){0x4, 0x4, 0x4}); -	for (unsigned i = 0; i < HH_PPU_BG_CANVAS_TILES_H * HH_PPU_BG_CANVAS_TILES_V; i++) { -		hh_ppu_update_background(i, (hh_s_ppu_loc_bam_entry){ -										.horizontal_flip = false, -										.vertical_flip	 = false, -										.palette_index	 = 0, -										.tilemap_index	 = 1, -									}); -	} - -	// cool colors -	hh_ppu_update_color(1, 1, (hh_ppu_rgb_color_t){0xf, 0x0, 0xf}); -	hh_ppu_update_color(2, 1, (hh_ppu_rgb_color_t){0xf, 0xf, 0xf}); -	hh_ppu_update_color(3, 1, (hh_ppu_rgb_color_t){0xf, 0x0, 0x0}); -	hh_ppu_update_color(4, 1, (hh_ppu_rgb_color_t){0x0, 0xf, 0xf}); -	hh_ppu_update_color(5, 1, (hh_ppu_rgb_color_t){0x0, 0x0, 0xf}); - -	// balls -	for (unsigned i = 0; i < HH_DEMO_BALL_COUNT; i++) { -		g_hh_demo_balls[i].horizontal_flip = false; -		g_hh_demo_balls[i].vertical_flip   = false; -		g_hh_demo_balls[i].palette_index   = i + 1; -		g_hh_demo_balls[i].tilemap_index   = 0; -	} -} - -void hh_demo_loop(unsigned long frame) { -	hh_player_movement(); -	// input testing (no hitbox stuff) -	// g_hh_player_1.pos_x  += ((-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right)) * g_hh_player_1.speed; // -1 = L || 1 == R -	// g_hh_player_1.pos_y  += ((-1 * g_hh_controller_p1.dpad_up) + (1 * g_hh_controller_p1.dpad_down)) * g_hh_player_1.speed; // -1 = D || 1 == U +typedef struct { +	vec2 pos; +	uint8_t idx; +}hh_s_tiles; -	// adjust map size -	g_hh_pos_x = g_hh_player_1.pos_x / 100; -	g_hh_pos_y = g_hh_player_1.pos_y / 100; +hh_entity hh_g_player, hh_g_player_new; +void hh_demo_setup() { +	hh_setup_palettes(); +	hh_setup_screen(); +} -	// update player sprite on ppu -	g_hh_demo_balls[0].position_x = g_hh_pos_x; -	g_hh_demo_balls[0].position_y = g_hh_pos_y; -	hh_ppu_update_foreground(0, g_hh_demo_balls[0]); +void hh_demo_loop(unsigned long frame) { -	// set background pattern position -	hh_ppu_update_aux((hh_s_ppu_loc_aux){ -		.bg_shift_x = (frame / 2) % HH_PPU_SPRITE_WIDTH, -		.bg_shift_y = (frame / 8) % HH_PPU_SPRITE_HEIGHT, -		.fg_fetch	= 0, -		.sysreset	= 0, -	}); +	 +	hh_player_actions(); +	  }  // void sendData(uint8_t address, uint16_t data) { @@ -103,84 +60,8 @@ void hh_demo_loop(unsigned long frame) {  // 	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);  // } -void hh_player_movement() { -	int8_t directionX = (-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right); // -1 = L || 1 == R -	int8_t directionY = (-1 * g_hh_controller_p1.dpad_up) + (1 * g_hh_controller_p1.dpad_down);	   // -1 = D || 1 == U - -	uint8_t i, j; -	uint8_t rotation = 0; // 0-7 - -	// rotation calc -	for (i = -1; i < 2; i++) { -		for (j = -1; j < 2; j++) { -			if (directionX == i) { -				if (directionY == j) { -					if (i != 0 && j != 0) // dont update when player idle -					{ -						g_hh_player_1.rotation = rotation; -					} -				} -			} -			rotation++; -		} -	} -	// direction calc -	if (directionX != 0) // update direction if player is not idle -	{ -		g_hh_player_1.direction_x = directionX; -	} -	// collision map x-axis - -	// tile calc including radius and direction for background coliision - -	uint16_t tileColX; -	uint16_t tileColY = (g_hh_player_1.pos_y / 100) / 16; -	; - -	// remaining space between grid and exact -	uint8_t modTileX; -	uint8_t modTileY; - -	if (g_hh_player_1.in_air == false && directionX != 0) { -		if (directionX == 1) { -			tileColX = ((g_hh_player_1.pos_x / 100) + g_hh_player_1.radius) / 16; -			modTileX = (g_hh_player_1.pos_x + (100 * g_hh_player_1.radius)) % 1600; -		} else if (directionX == -1) { -			tileColX = ((g_hh_player_1.pos_x / 100) - g_hh_player_1.radius) / 16; -			modTileX = (g_hh_player_1.pos_x - (100 * g_hh_player_1.radius)) % 1600; -		} - -		if (HH_DEMO_HITBOX_TILEMAP[tileColY][tileColX + directionX] != 1) { -			g_hh_player_1.pos_x = g_hh_player_1.pos_x + (directionX * g_hh_player_1.speed); // NEW x set -		} - -		else if (HH_DEMO_HITBOX_TILEMAP[tileColY][tileColX + directionX] == 1) { -			if (modTileX < g_hh_player_1.speed) { -				g_hh_player_1.pos_x = g_hh_player_1.pos_x + (directionX * modTileX); // NEW x set -			} else { -				g_hh_player_1.pos_x = g_hh_player_1.pos_x + (directionX * g_hh_player_1.speed); // NEW x set -			} -		} - -	} else // if in air different all borders have to be checked -	{ -	} - - -	if(directionY != 0) -	{ -	//	g_hh_player_1.pos_y = g_hh_player_1.pos_y + (directionY * g_hh_player_1.speed * 2); // NEW x set -	} -	// collision map floor (y-axis) (falling) -	//  if falling no jump press (implement) -	/* -	tileColY = (( g_hh_player_1.pos_y / 100) + g_hh_player_1.radius) / 16; //bottom of player box -	modTileY = 1; -	if(HH_DEMO_HITBOX_TILEMAP[tileColY+1][tileColX] != 1) //rework after jumping -	{ -		g_hh_player_1.pos_y = g_hh_player_1.pos_y + 5 ;// NEW y set //makew var gravity -		//playerStat = falling; //for later use of graphics/sound -	} -	*/ -	// else if(HH_DEMO_HITBOX_TILEMAP[]) -} + + + + + diff --git a/src/engine/entity.c b/src/engine/entity.c index 153e7e1..535759d 100644 --- a/src/engine/entity.c +++ b/src/engine/entity.c @@ -43,4 +43,85 @@ void hh_solve_collision(vec2 pos_environment, hh_entity* entity){  	// 	entity->vel.x = 0;  	// }   } +hh_entity hh_background_collision (hh_entity temp_old_entity,hh_entity temp_new_entity){ +		temp_old_entity.is_grounded = false; +  +// solves x collision +	if (temp_old_entity.vel.x <= 0) { +		if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_old_entity.pos.y + 0})) ||  +			hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_old_entity.pos.y + 15}))) { +			temp_new_entity.pos.x = (temp_new_entity.pos.x & ~15) + 16, +			temp_new_entity.vel.x = 0; +		} +	} else { +		if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 16, .y=temp_old_entity.pos.y + 0})) ||  +			hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 16, .y=temp_old_entity.pos.y + 15}))) { +			temp_new_entity.pos.x = temp_new_entity.pos.x & ~15, // <-- magic comma, NOT TOUCHY +			temp_new_entity.vel.x = 0; +		} +	} + +	//solves y collision +	if (temp_old_entity.vel.y <= 0) { +		if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_new_entity.pos.y + 0})) ||  +			hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 15, .y=temp_new_entity.pos.y + 0}))) { +			temp_new_entity.pos.y = (temp_new_entity.pos.y & ~15) + 16, +			temp_new_entity.vel.y = 0; +		} +	} else { +		if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_new_entity.pos.y + 15})) ||  +			hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 15, .y=temp_new_entity.pos.y + 15}))) { +			temp_new_entity.pos.y = temp_new_entity.pos.y & ~15, +			temp_new_entity.vel.y = 0; +			temp_old_entity.is_grounded = true; +		} +	} +	temp_old_entity.pos = temp_new_entity.pos;  +	temp_old_entity.vel = temp_new_entity.vel; +	return temp_old_entity; +} + +hh_entity hh_enemy_collision(hh_entity temp_player, hh_entity temp_enemy){ +	 +	bool collide = hh_distance_circles( temp_player.pos,  temp_enemy.pos, temp_player.radius, temp_enemy.radius); + +	if (collide == true && temp_player.is_hit == false) +	{ +		temp_player.is_hit = true; +		//angle = atan2( tempEntity.pos_y - tempPlayer.pos_y, tempEntity.pos_x - tempPlayer.pos_x); +		if(temp_player.pos.x <= temp_enemy.pos.x) //player left of enemy -- creates flinch movement L or R +		{ +		//	printf("BONK-left!/n"); +			temp_player.vel.y = -5; +			temp_player.vel.x = -8; +		}	else { +		//	printf("BONK-right!/n"); +			temp_player.vel.y = -5; +			temp_player.vel.x = 8; +		} +		// ghost mode / invulnerable or other things on hit +		//	temp_player.hp--; +			 +	} else { +		temp_player.is_hit = false; +		 +	} + + +return temp_player; +} + + +bool hh_distance_circles (vec2 object_1, vec2 object_2, int radius_1, int radius_2){ +	int a_squared = (object_1.x - object_2.x) * (object_1.x - object_2.x); +	int b_squared = (object_1.y - object_2.y) * (object_1.y - object_2.y); +	int c_squared = a_squared + b_squared;  +	int radius = ( radius_1 + radius_2) * ( radius_1 + radius_2 ); + +		if( c_squared <= radius ){ +			return true; +		} else { +			return false; +		} +} diff --git a/src/engine/entity.h b/src/engine/entity.h index f45dae2..cad6ba4 100644 --- a/src/engine/entity.h +++ b/src/engine/entity.h @@ -2,6 +2,7 @@  #include <stdint.h>  #include <stdbool.h> +#include <stdio.h>  #include "ppu/types.h" @@ -32,6 +33,8 @@ typedef struct {  typedef struct {      vec2 pos, vel, vec;      bool is_grounded; +	 bool is_hit; +	 uint8_t radius;      int8_t hp;      int8_t speed;  	 hh_s_rendering render; @@ -55,3 +58,25 @@ bool hh_collision(vec2 pos1, vec2 pos2);  /// @param entity position  /// @return solved new entity position  void hh_solve_collision(vec2 pos_environment, hh_entity* entity); + +/// @brief solve collision of entity with background tiles +/// @param temp_old_entity old data of entity  +/// @param temp_new_entity new data of entity where it wants to go to +/// @return updated new entity where it actually can go to +hh_entity hh_background_collision (hh_entity temp_old_entity, hh_entity temp_new_entity); + +/// @brief solve collision of player with enemy  +/// @param temp_player data of player  +/// @param temp_enemy data of enemy +/// @return updated player with new stats if hitted with enemy +hh_entity hh_enemy_collision(hh_entity temp_player, hh_entity temp_enemy); + +/// @brief calculate if circles (entity) hit each other  +/// @param object_1 position of first object (entity) +/// @param object_2 position of second object (entity) +/// @param radius_1 radius of first object (entity) +/// @param radius_2 radius of second object (entity) +/// @return true if objects collids +bool hh_distance_circles (vec2 object_1, vec2 object_2, int radius_1, int radius_2); + + diff --git a/src/engine/player_controller.c b/src/engine/player_controller.c index 22f6eb6..d351bee 100644 --- a/src/engine/player_controller.c +++ b/src/engine/player_controller.c @@ -11,6 +11,8 @@ void hh_player_actions() {  		.hp = 4,  		.speed = 6,  		.is_grounded = false, +		.is_hit = false, +		.radius = 8,  		.pos = (vec2){32,32},  		.vel = (vec2){0,0},  		.vec = (vec2){0,0}, @@ -26,9 +28,113 @@ void hh_player_actions() {  		}  	}, player_new = {0}; + +	static hh_entity enemy={ +		.hp = 4, +		.speed = 6, +		.is_grounded = false, +		.is_hit = false, +		.radius = 8, +		.pos = (vec2){128,48}, +		.vel = (vec2){0,0}, +		.vec = (vec2){0,0}, +		.render = { +			.frame0 = 20, +			.palette = 7, +			.fam = (hh_s_ppu_loc_fam_entry){ +				.horizontal_flip = false, +				.vertical_flip = false, +				.palette_index = 7, +				.tilemap_index = 1, +			} +		} +	}; +	player_new = player;  	// hh_input_read(); +	static uint8_t hit = 0; +	int8_t hit_timer = 0; +	int8_t direction_x = (-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right); +	int8_t direction_y = (-1 * g_hh_controller_p1.dpad_up) + (1 * g_hh_controller_p1.dpad_down); + +	if(player.is_hit == true){ +		hit_timer = 9; +		player.is_hit = false;	 +	}  +	if(hit_timer > -10){ +			hit_timer--; +	} + +	if(hit_timer <= 0){ +		if(direction_x != 0){ +			if(player.vel.x > -1 * player.speed && player.vel.x < player.speed) { +				player.vel.x = player.vel.x + direction_x; +			} else { +				if (player.vel.x > 0) { +					player.vel.x--; +				} else if(player.vel.x < 0) { +					player.vel.x++;  +				} +			} +		} else { +			if (player.vel.x > 0) { +				player.vel.x--; +			} else if(player.vel.x < 0) { +			player.vel.x++;  +			} +		} +		 +		/* // movement Y (w-s) disable gravity to use this +		if(direction_y != 0){ +			if(player.vel.y > -4 && player.vel.y < 4 ) { +				player.vel.y =  player.vel.y + direction_y; +			} +		} else { +			if (player.vel.y > 0) { +				player.vel.y--; +			} else if(player.vel.y < 0) { +				player.vel.y++;  +			} +		}		 +		 +		*/ +	} else { +		if (player.vel.x > 0) { +			player.vel.x--; +		} else if(player.vel.x < 0) { +			player.vel.x++;  +		} +			player.vel.y++; +	} +	 + +	if (g_hh_controller_p1.button_primary && player.is_grounded == true) {//JUMP +	 	player.vel.y = -10; +		player.is_grounded = false; +	} else if (player.vel.y < 6){ +		 player.vel.y += 1; //gravity +	} + + + +	 +/*  	player.vel = (vec2){.x = (-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right),  	.y = (-1 * g_hh_controller_p1.dpad_up) + (1 * g_hh_controller_p1.dpad_down) }; + +		player_new.vel = (vec2){ +		.x = player.vel.x, +		.y = player.vel.y, +	}; +*/ + +		player_new.vel = (vec2){ +		.x = player.vel.x, +		.y = player.vel.y, +	}; + +		player_new = hh_enemy_collision(player, enemy); +	 +	  	// const int8_t maa = 3;  	// const int8_t mbb = -3;  	// if (g_hh_controller_p1.dpad_up) @@ -55,8 +161,8 @@ void hh_player_actions() {  	// player.vel.x = CLAMP(player.vel.x,-32,32);  	player_new.pos = (vec2){ -		.x = player.pos.x + player.vel.x, -		.y = player.pos.y + player.vel.y, +		.x = player.pos.x + player_new.vel.x, +		.y = player.pos.y + player_new.vel.y,  	}; @@ -96,41 +202,10 @@ void hh_player_actions() {  	// 		hh_solve_collision(tiles[i].pos, &player);  	// 	}  	// } - -	player_new.is_grounded = false; - -	// solves x collision -	if (player.vel.x <= 0) { -		if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player.pos.y + 0})) ||  -			hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player.pos.y + 15}))) { -			player_new.pos.x = (player_new.pos.x & ~15) + 16, -			player_new.vel.x = 0; -		} -	} else { -		if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 16, .y=player.pos.y + 0})) ||  -			hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 16, .y=player.pos.y + 15}))) { -			player_new.pos.x = player_new.pos.x & ~15, // <-- magic comma, NOT TOUCHY -			player_new.vel.x = 0; -		} -	} - -	//solves y collision -	if (player.vel.y <= 0) { -		if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player_new.pos.y + 0})) ||  -			hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player_new.pos.y + 15}))) { -			player_new.pos.y = (player_new.pos.y & ~15) + 16, -			player_new.vel.y = 0; -		} -	} else { -		if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player_new.pos.y + 16})) ||  -			hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 16, .y=player_new.pos.y + 15}))) { -			player_new.pos.y = player_new.pos.y & ~15, -			player_new.vel.y = 0; -			player_new.is_grounded = true; -		} -	} - -	player = player_new; +	 +	player =  hh_background_collision ( player, player_new); +	 +	//player = player_new;  	vec_cor cam_pos;//value in tiles  	// cam_pos = (vec2){0,0}; @@ -141,10 +216,16 @@ void hh_player_actions() {  	player.render.fam.position_x = (player.pos.x-cam_pos.x);  	player.render.fam.position_y = (player.pos.y-cam_pos.y); +	enemy.render.fam.position_x = (enemy.pos.x-cam_pos.x); +	enemy.render.fam.position_y = (enemy.pos.y-cam_pos.y);  	player.render.fam.tilemap_index = 2;//TODO: these two lines should be redundant  	player.render.fam.palette_index = 7;  	hh_ppu_update_foreground(0, player.render.fam); +	hh_ppu_update_foreground(1, enemy.render.fam); +  } + + diff --git a/src/ppusim/input.c b/src/ppusim/input.c index 08bc382..5323fb1 100644 --- a/src/ppusim/input.c +++ b/src/ppusim/input.c @@ -12,4 +12,5 @@ void hh_input_read() {  	g_hh_controller_p1.dpad_down  = kb[SDL_SCANCODE_S];  	g_hh_controller_p1.dpad_left  = kb[SDL_SCANCODE_A];  	g_hh_controller_p1.dpad_right = kb[SDL_SCANCODE_D]; +	g_hh_controller_p1.button_primary = kb[SDL_SCANCODE_SPACE];  }  |