Skip to content

Commit

Permalink
Add snake tutorial draft
Browse files Browse the repository at this point in the history
  • Loading branch information
edubart committed Apr 21, 2024
1 parent cdb9767 commit 5083c17
Show file tree
Hide file tree
Showing 16 changed files with 1,852 additions and 69 deletions.
1 change: 1 addition & 0 deletions demos/snake-tutorial/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!*.c
27 changes: 27 additions & 0 deletions demos/snake-tutorial/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
DATA_FILES=info.json sprites.png
CFLAGS=$(shell rivemu -quiet -no-window -sdk -workspace -exec riv-opt-flags -Ospeed)

all: snake-0.sqfs snake-1.sqfs snake-2.sqfs snake-3.sqfs snake-4.sqfs snake-5.sqfs snake-6.sqfs snake-7.sqfs snake-8.sqfs snake-8.sqfs

snake-%.elf: snake-%.c
rivemu -quiet -no-window -sdk -workspace -exec "gcc $< -o $@ $(CFLAGS) && riv-strip $@"

snake-%.sqfs: snake-%.elf $(DATA_FILES)
rivemu -quiet -no-window -sdk -workspace -exec "riv-mksqfs $(DATA_FILES) $< $@"

test:
rivemu -quiet -workspace -exec riv-jit-c ./snake-0.c
rivemu -quiet -workspace -exec riv-jit-c ./snake-1.c
rivemu -quiet -workspace -exec riv-jit-c ./snake-2.c
rivemu -quiet -workspace -exec riv-jit-c ./snake-3.c
rivemu -quiet -workspace -exec riv-jit-c ./snake-4.c
rivemu -quiet -workspace -exec riv-jit-c ./snake-5.c
rivemu -quiet -workspace -exec riv-jit-c ./snake-6.c
rivemu -quiet -workspace -exec riv-jit-c ./snake-7.c

lint:
gcc -fsyntax-only -fanalyzer -I../../libriv *.c
clang-tidy *.c -- -I../../libriv

clean:
rm -f *.sqfs *.elf
6 changes: 6 additions & 0 deletions demos/snake-tutorial/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "Snake",
"summary": "Snake game from tutorial",
"description": "Use arrow to move, the game ends when the snake hits itself or a wall!",
"tags": ["puzzle", "2d", "snake"]
}
Binary file added demos/snake-tutorial/snake
Binary file not shown.
28 changes: 28 additions & 0 deletions demos/snake-tutorial/snake-0.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Header including all RIV APIs
#include <riv.h>

// Called every frame to draw the game
void draw() {
// Clear screen
riv_clear(RIV_COLOR_DARKSLATE);
// Draw snake title
riv_draw_text(
"snake", // text to draw
RIV_SPRITESHEET_FONT_5X7, // sprite sheet id of the font
RIV_CENTER, // anchor point on the text bounding box
128, // anchor x
128, // anchor y
4, // text size multiplier
RIV_COLOR_LIGHTGREEN // text color
);
}

// Entry point
int main() {
// Main loop, keep presenting frames until user quit or game ends
do {
// Draw game graphics
draw();
} while(riv_present());
return 0;
}
34 changes: 34 additions & 0 deletions demos/snake-tutorial/snake-1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Customizing the resolution and frame rate

// Header including all RIV APIs
#include <riv.h>

// Called every frame to draw the game
void draw() {
// Clear screen
riv_clear(RIV_COLOR_DARKSLATE);
// Draw snake title
riv_draw_text(
"snake", // text to draw
RIV_SPRITESHEET_FONT_5X7, // sprite sheet id of the font
RIV_CENTER, // anchor point on the text bounding box
64, // anchor x
64, // anchor y
2, // text size multiplier
RIV_COLOR_LIGHTGREEN // text color
);
}

// Entry point
int main() {
// Set screen size and default frame rate
riv->width = 128;
riv->height = 128;
riv->target_fps = 8;
// Main loop, keep presenting frames until user quit or game ends
do {
// Draw game graphics
draw();
} while(riv_present());
return 0;
}
101 changes: 101 additions & 0 deletions demos/snake-tutorial/snake-2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Starting the game

// Header including all RIV APIs
#include <riv.h>

// Game state
bool started; // true when game has started
bool ended; // true when game has ended

// Called when game starts
void start_game() {
riv_printf("GAME START\n");
started = true;
}

// Called when game ends
void end_game() {
riv_printf("GAME OVER\n");
ended = true;
// Quit in 3 seconds
riv->quit_frame = riv->frame + 3*riv->target_fps;
}

// Update game logic
void update_game() {
// TODO: update game
end_game();
}

// Draw the game map
void draw_game() {
// TODO: draw game
}

// Draw game start screen
void draw_start_screen() {
// Draw snake title
riv_draw_text(
"snake", // text to draw
RIV_SPRITESHEET_FONT_5X7, // sprite sheet id of the font
RIV_CENTER, // anchor point on the text bounding box
64, // anchor x
64, // anchor y
2, // text size multiplier
RIV_COLOR_LIGHTGREEN // text color
);
// Make "press to start blink" by changing the color depending on the frame number
uint32_t col = (riv->frame % 2 == 0) ? RIV_COLOR_LIGHTRED : RIV_COLOR_DARKRED;
// Draw press to start
riv_draw_text("PRESS TO START", RIV_SPRITESHEET_FONT_5X7, RIV_CENTER, 64, 64+16, 1, col);
}

// Draw game over screen
void draw_end_screen() {
// Draw last game frame
draw_game();
// Draw GAME OVER
riv_draw_text("GAME OVER", RIV_SPRITESHEET_FONT_5X7, RIV_CENTER, 64, 64, 2, RIV_COLOR_RED);
}

// Called every frame to update game state
void update() {
if (!started) { // Game not started yet
// Let game start whenever a key has been pressed
if (riv->key_toggle_count > 0) {
start_game();
}
} else if (!ended) { // Game is progressing
update_game();
}
}

// Called every frame to draw the game
void draw() {
// Clear screen
riv_clear(RIV_COLOR_DARKSLATE);
// Draw different screens depending on the game state
if (!started) { // Game not started yet
draw_start_screen();
} else if (!ended) { // Game is progressing
draw_game();
} else { // Game ended
draw_end_screen();
}
}

// Entry point
int main() {
// Set screen size and default frame rate
riv->width = 128;
riv->height = 128;
riv->target_fps = 8;
// Main loop, keep presenting frames until user quit or game ends
do {
// Update game state
update();
// Draw game graphics
draw();
} while(riv_present());
return 0;
}
116 changes: 116 additions & 0 deletions demos/snake-tutorial/snake-3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Spawning the apple

// Header including all RIV APIs
#include <riv.h>

// Constants
enum {
MAP_SIZE = 16, // 16x16 tiles
TILE_SIZE = 8, // 8x8 pixels
};

// Game state
bool started; // true when game has started
bool ended; // true when game has ended
riv_vec2i apple_pos; // position of the current apple

// Spawn apple in a new position
bool respawn_apple() {
apple_pos = (riv_vec2i){riv_rand_uint(MAP_SIZE-1), riv_rand_uint(MAP_SIZE-1)};
return true;
}

// Called when game starts
void start_game() {
riv_printf("GAME START\n");
started = true;
respawn_apple();
}

// Called when game ends
void end_game() {
riv_printf("GAME OVER\n");
ended = true;
// Quit in 3 seconds
riv->quit_frame = riv->frame + 3*riv->target_fps;
}

// Update game logic
void update_game() {
// TODO: update game
end_game();
}

// Draw the game map
void draw_game() {
// Draw apple
riv_draw_rect_fill(apple_pos.x*TILE_SIZE, apple_pos.y*TILE_SIZE, TILE_SIZE, TILE_SIZE, RIV_COLOR_LIGHTRED);
}

// Draw game start screen
void draw_start_screen() {
// Draw snake title
riv_draw_text(
"snake", // text to draw
RIV_SPRITESHEET_FONT_5X7, // sprite sheet id of the font
RIV_CENTER, // anchor point on the text bounding box
64, // anchor x
64, // anchor y
2, // text size multiplier
RIV_COLOR_LIGHTGREEN // text color
);
// Make "press to start blink" by changing the color depending on the frame number
uint32_t col = (riv->frame % 2 == 0) ? RIV_COLOR_LIGHTRED : RIV_COLOR_DARKRED;
// Draw press to start
riv_draw_text("PRESS TO START", RIV_SPRITESHEET_FONT_5X7, RIV_CENTER, 64, 64+16, 1, col);
}

// Draw game over screen
void draw_end_screen() {
// Draw last game frame
draw_game();
// Draw GAME OVER
riv_draw_text("GAME OVER", RIV_SPRITESHEET_FONT_5X7, RIV_CENTER, 64, 64, 2, RIV_COLOR_RED);
}

// Called every frame to update game state
void update() {
if (!started) { // Game not started yet
// Let game start whenever a key has been pressed
if (riv->key_toggle_count > 0) {
start_game();
}
} else if (!ended) { // Game is progressing
update_game();
}
}

// Called every frame to draw the game
void draw() {
// Clear screen
riv_clear(RIV_COLOR_DARKSLATE);
// Draw different screens depending on the game state
if (!started) { // Game not started yet
draw_start_screen();
} else if (!ended) { // Game is progressing
draw_game();
} else { // Game ended
draw_end_screen();
}
}

// Entry point
int main() {
// Set screen size and default frame rate
riv->width = 128;
riv->height = 128;
riv->target_fps = 8;
// Main loop, keep presenting frames until user quit or game ends
do {
// Update game state
update();
// Draw game graphics
draw();
} while(riv_present());
return 0;
}
Loading

0 comments on commit 5083c17

Please sign in to comment.