test/snake/snake.c

changeset 260
2649d04f0287
parent 257
67d7b79997df
--- a/test/snake/snake.c	Fri Aug 08 20:51:14 2025 +0200
+++ b/test/snake/snake.c	Fri Aug 08 20:51:19 2025 +0200
@@ -44,7 +44,6 @@
 
 #define BACKDROP_SCENE asc_window_scene(0)
 #define MAIN_SCENE asc_window_scene(1)
-
 #define HUD_WIDTH 400
 
 enum MoveDirection {
@@ -167,7 +166,7 @@
     }
 }
 
-static void fps_counter_create(void) {
+static AscSceneNode *fps_counter_create(void) {
     AscSceneNode *node = asc_text(
         .name = "FPS Counter",
         .color = ASC_RGB(1, 1, 1),
@@ -176,6 +175,7 @@
     asc_behavior_add(node, .func = fps_counter_update, .interval = asc_seconds(1));
     asc_behavior_add(node, fps_counter_tie_to_corner);
     asc_ui_add_node(node);
+    return node;
 }
 
 
@@ -196,7 +196,7 @@
     return old_owner != new_owner;
 }
 
-static void game_field_create() {
+static GameField *game_field_create() {
     // TODO: create a more interesting map than just a basic grid
     AscSceneNode *node = asc_scene_node_empty();
     game_field = asc_scene_node_allocate_data(node, sizeof(GameField));
@@ -217,6 +217,7 @@
     }
     asc_scene_node_set_zindex(node, -2);
     asc_scene_add_node(MAIN_SCENE, node);
+    return game_field;
 }
 
 static asc_vec2u game_field_tile_at_position(asc_vec3f position) {
@@ -346,6 +347,29 @@
     }
 }
 
+static void player_controls(Player *player) {
+    if (asc_key_pressed(ASC_KEY(LEFT))) {
+        if (player->direction != MOVE_RIGHT) {
+            player->target_direction = MOVE_LEFT;
+        }
+    }
+    if (asc_key_pressed(ASC_KEY(RIGHT))) {
+        if (player->direction != MOVE_LEFT) {
+            player->target_direction = MOVE_RIGHT;
+        }
+    }
+    if (asc_key_pressed(ASC_KEY(UP))) {
+        if (player->direction != MOVE_DOWN) {
+            player->target_direction = MOVE_UP;
+        }
+    }
+    if (asc_key_pressed(ASC_KEY(DOWN))) {
+        if (player->direction != MOVE_UP) {
+            player->target_direction = MOVE_DOWN;
+        }
+    }
+}
+
 static void player_position(Player *pl, int x, int y) {
     pl->new_position.x = x;
     pl->new_position.y = y;
@@ -415,6 +439,16 @@
     return ASC_RECT(offset_x, offset_y, viewport_size, viewport_size);
 }
 
+#define GAME_STATE_MENU 0
+#define GAME_STATE_PLAYING 1
+#define GAME_STATE_GAME_OVER 2
+
+typedef struct {
+    int state;
+    GameField *field;
+    Player *players[4];
+} GameState;
+
 int main(void) {
     asc_context_initialize();
     if (asc_has_error()) {
@@ -453,18 +487,18 @@
         .clear_color = ASC_RGBi(0, 32, 16),
         .viewport_update_func = main_scene_viewport_update
     );
-
-    // backdrop for letterbox/pillarbox
     backdrop_create();
 
-    // the game field
-    game_field_create();
+    // create the fps counter
+    AscSceneNode *fps_counter = fps_counter_create();
+    asc_scene_node_hide(fps_counter);
 
-    // create UI elements
-    fps_counter_create();
-
-    // create player
-    Player *player = player_create();
+    // create the game state
+    GameState game = {0};
+    // TODO: add a main menu and start with the menu
+    game.state = GAME_STATE_PLAYING;
+    game.field = game_field_create();
+    game.players[0] = player_create();
 
     // Main Loop
     do {
@@ -477,26 +511,10 @@
             asc_context_quit();
         }
 
-        // player rotation
-        if (asc_key_pressed(ASC_KEY(LEFT))) {
-            if (player->direction != MOVE_RIGHT) {
-                player->target_direction = MOVE_LEFT;
-            }
-        }
-        if (asc_key_pressed(ASC_KEY(RIGHT))) {
-            if (player->direction != MOVE_LEFT) {
-                player->target_direction = MOVE_RIGHT;
-            }
-        }
-        if (asc_key_pressed(ASC_KEY(UP))) {
-            if (player->direction != MOVE_DOWN) {
-                player->target_direction = MOVE_UP;
-            }
-        }
-        if (asc_key_pressed(ASC_KEY(DOWN))) {
-            if (player->direction != MOVE_UP) {
-                player->target_direction = MOVE_DOWN;
-            }
+        // game states
+        if (game.state == GAME_STATE_PLAYING) {
+            // TODO: implement hot seat 1on1 multiplayer
+            player_controls(game.players[0]);
         }
 
         // debug-key for clearing the shader registry
@@ -505,6 +523,11 @@
             asc_dprintf("Shader cache cleared.");
         }
 
+        // show/hide the FPS counter
+        if (asc_key_pressed(ASC_KEY(F2))) {
+            asc_scene_node_toggle_visibility(fps_counter);
+        }
+
         // quit application on ESC key press
         if (asc_key_pressed(ASC_KEY(ESCAPE))) {
             asc_context_quit();

mercurial