From 4897e4b8c6e3160d67a31575e01bc5a46c15c3ff Mon Sep 17 00:00:00 2001 From: bitscuit Date: Wed, 21 Dec 2022 08:55:05 +0100 Subject: [PATCH] added project code to repo --- Makefile | 10 ++++ bird.c | 18 ++++++ bird.h | 17 ++++++ config.h | 19 +++++++ flappy | Bin 0 -> 13960 bytes game.c | 126 +++++++++++++++++++++++++++++++++++++++++ game.h | 30 ++++++++++ main.c | 77 +++++++++++++++++++++++++ pipe.c | 17 ++++++ pipe.h | 16 ++++++ project.code-workspace | 7 +++ 11 files changed, 337 insertions(+) create mode 100644 Makefile create mode 100644 bird.c create mode 100644 bird.h create mode 100644 config.h create mode 100755 flappy create mode 100644 game.c create mode 100644 game.h create mode 100644 main.c create mode 100644 pipe.c create mode 100644 pipe.h create mode 100644 project.code-workspace diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a358e49 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +flappy: main.o game.o bird.o pipe.o + gcc -o flappy main.o game.o bird.o pipe.o -lcurses +main.o: main.c game.h config.h + gcc -c main.c +game.o: game.c game.h bird.h pipe.h config.h + gcc -c game.c +bird.o: bird.c bird.h config.h + gcc -c bird.c +pipe.o: pipe.c pipe.h config.h + gcc -c pipe.c \ No newline at end of file diff --git a/bird.c b/bird.c new file mode 100644 index 0000000..d48621c --- /dev/null +++ b/bird.c @@ -0,0 +1,18 @@ +#include "bird.h" + +bird* bird_create(){ + /* Allocate memory */ + bird* b = malloc(sizeof(bird)); + + /* Set values */ + b->pos_x = CAM_OFFSET_X; + b->pos_y = HEIGHT/2; + b->vel_x = BIRD_VEL_X; + b->vel_y = 0; + + return b; +} + +void bird_destroy(bird* b){ + free(b); +} \ No newline at end of file diff --git a/bird.h b/bird.h new file mode 100644 index 0000000..b9d2976 --- /dev/null +++ b/bird.h @@ -0,0 +1,17 @@ +#ifndef _H_BIRD +#define _H_BIRD + +#include +#include "config.h" + +typedef struct{ + float pos_x; + float pos_y; + float vel_x; + float vel_y; +} bird; + +bird* bird_create(); +void bird_destroy(bird* b); + +#endif \ No newline at end of file diff --git a/config.h b/config.h new file mode 100644 index 0000000..7d4a9e7 --- /dev/null +++ b/config.h @@ -0,0 +1,19 @@ +#ifndef _H_CONFIG +#define _H_CONFIG + +#define KEY_QUIT 'q' +#define KEY_JUMP ' ' + +#define FPS 10 +#define WIDTH 60 +#define HEIGHT 20 +#define CAM_OFFSET_X 10 + +#define BIRD_VEL_X 10.0F +#define BIRD_VEL_Y_JUMP 13.5F +#define BIRD_ACC_Y -30.0F + +#define PIPE_DISTANCE 16 +#define PIPE_HEIGHT 3 + +#endif \ No newline at end of file diff --git a/flappy b/flappy new file mode 100755 index 0000000000000000000000000000000000000000..539758502b7dfdeb8a5281fda183cf67ac44ab08 GIT binary patch literal 13960 zcmeHOeQ;FQb-$~XKw!`=Uyfo!c*dpy92S8wMi`ov;E9Jv!ZJwIuEEPnyFzOut+Kn~ ztA=VU%&=KxYiv)-WZZ;_sq1>2l(r;;Juyh&BAkg`*=}toaT1wgcNgJU4wxtjM*W@p z?%932+Lv@P{iA>M&gh+ce&^$!`~BYCtH0K(s|p+r!O1E9To5;SgNb;Rz*wX*AYQRt zOu%!Nm?_4AFO--m_nHJ!GmR+MOp6un1SPxW1tyS7XDU6W93jynCCf*)-fW^wh0r8G zb`^-KuGfxWjhLw?22cRl&F?P-70>jTtBKC{naUXE?pzN2*H$eDb;=$ z3s8P@sbt5{r%hNeWxM-eM{)j7lUpfnQ03XROR;JXrrZyUT0#xWmM&@uENlt2b?jQW zYx%N;%a(egVb2m-Z}LyNYuDGylE{r}3Mroso-mT{-~0QXt53~}zg7C|_?N%?_uu=@ zzfXCPbg3)3-(nKPXOd=pCTLo-?P!*VuL?vgKxLN|H=m6WP`tJ zgRcax;V(B$LcQkXg5U@7m#-bp0-qvEgL; z;O=&R01i=rf488xebHb{L}LM^+(?ScM6^8;YKt|AXvE(JeScdx+7b-5i&&_Ys(~6b zZud1dZ}&C%LoK4!-_jCp1m3vI?`sOR`CCGJNDYNIs@k^tQ6Iz^6zf;lZ`i1B^wq6f zUv;nVPEVOp$QaQi_+))hsVp{B(g%{ea7U(5rr3PnnYNi`S)g5m7esw(m27CgPxLgKaHyr+?YVZp8Y zeys(!?tAxJa4MVARtwH;N3v!Mj*dyEb_+f+jS8{Lf~!{~Debi2=+`9feZ^5UrGUzc2PJ1n<6Bc|1gP^?@{6-6Y&Vqlzf)7~mn=H7| zb*b1$6m`$ggz;E!tYCD&=z6vIOj={~&KIU@Vs!3{c)DhLkt4pDxN$OOMWYXPPFixMr`B&~L%i8{I{p zf*R!`M*PFr7ty6J5Q{FIyk&H-$>W;6U;5v2hI%o>!{tk)*nQ_eOE>ec!`|q-?lj`V zMql!)hU2X9=Ji-99DYqXoJ0=o{B^D(HPNxi=vuXwa`hC?BqOov9&pLYXu+g`$JwHF z;2jiBCk1x-3|yi&aY%ZTeEi+d9_@4x(ZO@ljr?l%|v zem5?Du5V=a{L}FP<1pldcG6I95~FZ_U;JFC*IVflQafpM*AE)q`k)bi$B6eQyFVWt z?J*MiNWi$mEHYM_soa$#JioQG*Jp$nq5FXTrI`)zyr4NlqW;=zE zn0z0pqhrx(XN~y3B^N^(URJ0u&i@{bL|v3Dz`WpC3*i4$0Pd5Q&={#-LL~c#N_&%9 z3=L2D{cx5Hn;w&Hvtm8)DBITTyp0%5rKdFVbrljLt|!fw_hWT2;-}#%X~f+``n~Q# zsuHpZuNxz!Zx9orKY3ExDb3pAe*FTp#L$t?WkGyUcBbRzJTS~5^BNRmImCSd&TKeD?9($S*-P(uFXQeg#|NH zg?{}SIZHi>M?$~WH&__&GtDT(YaF6uz(|Ph`&P!?$sj5g?|V6Z@Zdq3Ro#UX`$nAc z)9I-dKizk}5OeI@eAv_@h7HAu8aR5*==;EFIDTX#rgrr@;+2JV#q@jS7ipJ%Ez=6u zT!$W_;UF7awnR^Qn¬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 literal 0 HcmV?d00001 diff --git a/game.c b/game.c new file mode 100644 index 0000000..d7bac49 --- /dev/null +++ b/game.c @@ -0,0 +1,126 @@ +#include "game.h" + +game* game_create(){ + /* Allocate memory */ + game* g = malloc(sizeof(game)); + + /* Set vars */ + g->bird = bird_create(); + g->num_pipes = WIDTH/PIPE_DISTANCE + 1; + g->pipes = malloc(sizeof(pipe*)*g->num_pipes); + for(int i=0; inum_pipes; i++){ + g->pipes[i] = pipe_create(); + } + g->score = 0; + g->highscore = 0; + + /* Reset level */ + game_reset_level(g); + + return g; +} + +void game_reset_level(game* g){ + /* Reset bird */ + bird_destroy(g->bird); + g->bird = bird_create(); + + /* Reset pipes */ + for(int i=0; inum_pipes; i++){ + g->pipes[i]->pos_x = WIDTH + PIPE_DISTANCE*i; + g->pipes[i]->pos_y = rand()%(HEIGHT-PIPE_HEIGHT-2)+1; + g->pipes[i]->height = PIPE_HEIGHT; + } + + /* Reset other vars */ + g->score = 0; +} + +void game_destroy(game* g){ + /* Free memory */ + bird_destroy(g->bird); + for(int i=0; inum_pipes; i++){ + pipe_destroy(g->pipes[i]); + } + free(g->pipes); + free(g); +} + +void game_key_pressed(game* g, char key){ + if(key == KEY_JUMP){ + g->bird->vel_y = BIRD_VEL_Y_JUMP; + } +} + +int game_update(game* g, float dt){ + /* Update bird position */ + g->bird->vel_y += BIRD_ACC_Y * dt; + g->bird->pos_x += g->bird->vel_x * dt; + g->bird->pos_y += g->bird->vel_y * dt; + + /* Check for collisions */ + int bird_x = g->bird->pos_x; + for(int i=0; inum_pipes; i++){ + if(bird_x == g->pipes[i]->pos_x){ + int bird_y = g->bird->pos_y; + if(bird_y < g->pipes[i]->pos_y || bird_y >= g->pipes[i]->pos_y + g->pipes[i]->height){ + /* Collision */ + return STATE_COLLISION; + } + } + } + if(g->bird->pos_y < 0){ + return STATE_COLLISION; + } + + /* Move pipes */ + for(int i=0; inum_pipes; i++){ + /* Check if off screen */ + if(g->pipes[i]->pos_x < g->bird->pos_x-CAM_OFFSET_X){ + /* Move */ + g->pipes[i]->pos_x += g->num_pipes*PIPE_DISTANCE; + g->pipes[i]->pos_y = rand()%(HEIGHT-PIPE_HEIGHT-2)+1; + + /* Adjust score */ + g->score++; + } + } + + return STATE_OKAY; +} + +void game_render(game* g){ + /* Clear screen */ + clear(); + + /* Init vars */ + int delta_x = g->bird->pos_x - CAM_OFFSET_X; + + /* Draw ground */ + move(HEIGHT, 0); + for(int x=0; xpipes[i]->pos_y+g->pipes[i]->height+1; ybird->pos_y, CAM_OFFSET_X, 'v'); + + /* Draw score */ + char text[50]; + sprintf(text, "Score: %d\tBest: %d", g->score, g->highscore); + mvaddstr(HEIGHT+1, 1, text); +} \ No newline at end of file diff --git a/game.h b/game.h new file mode 100644 index 0000000..ae078f8 --- /dev/null +++ b/game.h @@ -0,0 +1,30 @@ +#ifndef _H_GAME +#define _H_GAME + +#include +#include +#include "bird.h" +#include "pipe.h" +#include "config.h" + +#define STATE_OKAY 0 +#define STATE_COLLISION 1 + +typedef struct{ + bird* bird; + pipe** pipes; + int num_pipes; + int score; + int highscore; +} game; + +game* game_create(); +void game_reset_level(game* g); +void game_destroy(game* g); + +void game_key_pressed(game* g, char key); +int game_update(game* g, float dt); +void game_render(game* g); + + +#endif \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..1a2447c --- /dev/null +++ b/main.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include "game.h" +#include "config.h" + +void msleep(int msec){ + struct timespec ts; + ts.tv_sec = msec/1000; + ts.tv_nsec = (msec%1000) * 1000000; + nanosleep(&ts, &ts); +} + +int main(int argc, char** argv){ + + /* Init curses */ + WINDOW* win; + win = initscr(); + noecho(); + keypad(win, TRUE); + nodelay(win, TRUE); + curs_set(FALSE); + + /* Init game */ + srand(time(NULL)); + game* g = game_create(); + + /* Game Loop */ + char c; + while(1){ + /* Get input */ + do{ + c = getch(); + if(c == KEY_QUIT) break; + if(c != ERR) game_key_pressed(g, c); + }while(c != ERR); + if(c == KEY_QUIT) break; + + /* Update */ + int state = game_update(g, 1.0F/(float)FPS); + + /* Render */ + game_render(g); + refresh(); + + /* Exit if collision */ + if(state == STATE_COLLISION){ + /* Update score */ + char is_best_score = 0; + if(g->score > g->highscore){ + g->highscore = g->score; + is_best_score = 1; + } + + /* Draw message */ + move(HEIGHT+2, 1); + addstr((is_best_score ? "New Highscore!" : "Game Over!")); + refresh(); + + /* Delay and restart */ + msleep(1000); + game_reset_level(g); + } + + /* Delay */ + msleep(1000/FPS); + } + + /* Cleanup */ + game_destroy(g); + delwin(win); + endwin(); + refresh(); + + return 0; +} \ No newline at end of file diff --git a/pipe.c b/pipe.c new file mode 100644 index 0000000..c5b4105 --- /dev/null +++ b/pipe.c @@ -0,0 +1,17 @@ +#include "pipe.h" + +pipe* pipe_create(){ + /* Allocate memory */ + pipe* p = malloc(sizeof(pipe)); + + /* Set values */ + p->pos_x = 0; + p->pos_y = 0; + p->height = PIPE_HEIGHT; + + return p; +} + +void pipe_destroy(pipe* p){ + free(p); +} \ No newline at end of file diff --git a/pipe.h b/pipe.h new file mode 100644 index 0000000..e88ab6a --- /dev/null +++ b/pipe.h @@ -0,0 +1,16 @@ +#ifndef _H_PIPE +#define _H_PIPE + +#include +#include "config.h" + +typedef struct { + int pos_x; + int pos_y; + int height; +} pipe; + +pipe* pipe_create(); +void pipe_destroy(pipe* p); + +#endif \ No newline at end of file diff --git a/project.code-workspace b/project.code-workspace new file mode 100644 index 0000000..362d7c2 --- /dev/null +++ b/project.code-workspace @@ -0,0 +1,7 @@ +{ + "folders": [ + { + "path": "." + } + ] +} \ No newline at end of file