add player rotation and collisions
This commit is contained in:
parent
798ff9b409
commit
df576a3048
|
@ -12,7 +12,7 @@ find_package(Gint 2.1 REQUIRED)
|
|||
set(SOURCES
|
||||
src/main.c
|
||||
src/render.c
|
||||
# ...
|
||||
src/physics.c
|
||||
)
|
||||
set(ASSETS
|
||||
assets-cg/example.png
|
||||
|
|
20
src/duet.h
20
src/duet.h
|
@ -55,6 +55,10 @@ typedef struct {
|
|||
// Game
|
||||
//---
|
||||
|
||||
#define PLAYER_X 55
|
||||
#define PLAYER_R 35
|
||||
#define PLAYER_SIZE 6
|
||||
|
||||
typedef struct {
|
||||
float w, h; /* px */
|
||||
float x, y; /* px */
|
||||
|
@ -65,7 +69,7 @@ typedef struct {
|
|||
|
||||
#define RECT_TABLE_SIZE 20
|
||||
|
||||
struct game {
|
||||
typedef struct game {
|
||||
int dead;
|
||||
float time;
|
||||
level_t *level;
|
||||
|
@ -73,7 +77,7 @@ struct game {
|
|||
rect_t table[RECT_TABLE_SIZE];
|
||||
int cursor;
|
||||
float player_rota;
|
||||
};
|
||||
} game_t;
|
||||
|
||||
//---
|
||||
// Rendering
|
||||
|
@ -84,3 +88,15 @@ void dcircle(int x, int y, int r, int color, bool fill);
|
|||
void dtriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color);
|
||||
|
||||
void drectoid(rect_t const *r, int color);
|
||||
|
||||
void render_player(float angle);
|
||||
|
||||
//---
|
||||
// Physics
|
||||
//---
|
||||
|
||||
void player_position(float angle,
|
||||
float *x1, float *y1, float *x2, float *y2);
|
||||
|
||||
bool player_collision(game_t const *game);
|
||||
bool rect_circle_collide(rect_t const *r, int cx, int cy, int cr);
|
||||
|
|
62
src/main.c
62
src/main.c
|
@ -35,45 +35,83 @@ level_t level0 = {
|
|||
|
||||
int main(void)
|
||||
{
|
||||
volatile int need_frame;
|
||||
struct game game;
|
||||
volatile int need_frame = 1;
|
||||
|
||||
game_t game;
|
||||
float dt = 0;
|
||||
int timer;
|
||||
|
||||
__printf_enable_fp();
|
||||
|
||||
|
||||
memset(&game, 0x00, sizeof(struct game));
|
||||
memset(&game, 0x00, sizeof game);
|
||||
game.level = &level0;
|
||||
|
||||
/* Temporary level */
|
||||
game.table[0] = (rect_t){
|
||||
.w=80, .h=20, .x=440, .y=50, .vx=-100, .vy=0, .r=0, .vr=0.5
|
||||
};
|
||||
game.cursor = 1;
|
||||
|
||||
timer = timer_configure(TIMER_ANY, 33000, GINT_CALL_SET(&need_frame));
|
||||
timer_start(timer);
|
||||
|
||||
while (1) {
|
||||
/* Time management */
|
||||
|
||||
while (need_frame == 0) sleep();
|
||||
need_frame = 0;
|
||||
|
||||
dt = (1.0 / 30) * level0.tempo;
|
||||
game.time += 1.0 / 30;
|
||||
|
||||
/* Input analysis */
|
||||
|
||||
bool rotate_left=false, rotate_right=false;
|
||||
|
||||
key_event_t e;
|
||||
while ((e = pollevent()).type != KEYEV_NONE) {
|
||||
if (e.type == KEYEV_DOWN && e.key == KEY_MENU)
|
||||
gint_osmenu();
|
||||
}
|
||||
if (keydown(KEY_7)) {
|
||||
game.player_rota += dt;
|
||||
rotate_left = true;
|
||||
}
|
||||
if (keydown(KEY_0)) {
|
||||
game.player_rota -= dt;
|
||||
rotate_right = true;
|
||||
}
|
||||
|
||||
//TODO: physix
|
||||
/* Level generation */
|
||||
/* TODO */
|
||||
|
||||
dclear(C_BLACK);
|
||||
/* Physics */
|
||||
|
||||
// if(player_collision(&game))
|
||||
// break;
|
||||
|
||||
for(int i = 0; i < game.cursor; i++) {
|
||||
rect_t *r = &game.table[i];
|
||||
r->x += r->vx * dt;
|
||||
r->y += r->vy * dt;
|
||||
r->r += r->vr * dt;
|
||||
}
|
||||
|
||||
if(rotate_left)
|
||||
game.player_rota += M_PI * dt;
|
||||
if(rotate_right)
|
||||
game.player_rota -= M_PI * dt;
|
||||
|
||||
/* Rendering */
|
||||
|
||||
dclear(player_collision(&game) ? C_RED : C_BLACK);
|
||||
dprint(0, 0, C_WHITE, "game time: %.2fs", game.time);
|
||||
dprint(0, 11, C_WHITE, "player rota: %.2f rad", game.player_rota);
|
||||
dupdate();
|
||||
|
||||
while (need_frame == 0)
|
||||
sleep();
|
||||
need_frame = 0;
|
||||
for(int i = 0; i < game.cursor; i++)
|
||||
drectoid(&game.table[i], C_WHITE);
|
||||
render_player(game.player_rota);
|
||||
dupdate();
|
||||
}
|
||||
|
||||
timer_stop(timer);
|
||||
return (1);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#include "duet.h"
|
||||
|
||||
void player_position(float angle,
|
||||
float *x1, float *y1, float *x2, float *y2)
|
||||
{
|
||||
int x=PLAYER_X, y=DHEIGHT/2;
|
||||
|
||||
float sin, cos;
|
||||
sincosf(angle, &sin, &cos);
|
||||
|
||||
if(x1) *x1 = x + sin * PLAYER_R;
|
||||
if(y1) *y1 = y + cos * PLAYER_R;
|
||||
|
||||
if(x2) *x2 = x - sin * PLAYER_R;
|
||||
if(y2) *y2 = y - cos * PLAYER_R;
|
||||
}
|
||||
|
||||
bool player_collision(game_t const *game)
|
||||
{
|
||||
float x1, y1, x2, y2;
|
||||
player_position(game->player_rota, &x1, &y1, &x2, &y2);
|
||||
|
||||
for(int i = 0; i < game->cursor; i++) {
|
||||
if(rect_circle_collide(&game->table[i], x1, y1, PLAYER_SIZE))
|
||||
return true;
|
||||
if(rect_circle_collide(&game->table[i], x2, y2, PLAYER_SIZE))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rect_circle_collide(rect_t const *r, int cx0, int cy0, int cr)
|
||||
{
|
||||
/* Translate so that rectangle center is (0,0) */
|
||||
cx0 -= r->x;
|
||||
cy0 -= r->y;
|
||||
|
||||
/* Rotate so that rectangle is flat */
|
||||
float sin, cos;
|
||||
sincosf(-r->r, &sin, &cos);
|
||||
float cx = cx0 * cos + cy0 * sin;
|
||||
float cy = -cx0 * sin + cy0 * cos;
|
||||
|
||||
/* Determine point of rectangle closest to center of circle */
|
||||
float clx=cx, cly=cy;
|
||||
if(clx < -r->w/2) clx = -r->w/2;
|
||||
if(clx > r->w/2) clx = r->w/2;
|
||||
if(cly < -r->h/2) cly = r->h/2;
|
||||
if(cly > r->h/2) cly = r->h/2;
|
||||
|
||||
/* Determine whether that point is in the circle */
|
||||
return (clx - cx) * (clx - cx) + (cly - cy) * (cly - cy) <= cr * cr;
|
||||
}
|
12
src/render.c
12
src/render.c
|
@ -97,3 +97,15 @@ void drectoid(rect_t const *r, int color)
|
|||
dtriangle(x[0], y[0], x[1], y[1], x[2], y[2], color);
|
||||
dtriangle(x[2], y[2], x[3], y[3], x[0], y[0], color);
|
||||
}
|
||||
|
||||
void render_player(float angle)
|
||||
{
|
||||
int x=PLAYER_X, y=DHEIGHT/2;
|
||||
dcircle(x, y, PLAYER_R, C_WHITE, false);
|
||||
|
||||
float x1, y1, x2, y2;
|
||||
player_position(angle, &x1, &y1, &x2, &y2);
|
||||
|
||||
dcircle(x1, y1, PLAYER_SIZE, C_RGB(0, 16, 26), true);
|
||||
dcircle(x2, y2, PLAYER_SIZE, C_RGB(31, 6, 0), true);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue