Implement basic scene switching

Changelog:
- Add confirm and exit actions
    - Exit action used in editor scene
    - Confirm action for menu scene
- Hardcode scene switching in editor and menu scene
- Implement scene change function
    - Scene is not resetted on switch
- Incorporate scene switchin into main function
scene_man
En Yi 2023-02-13 23:05:24 +08:00
parent 1612b4f648
commit 399c78c200
6 changed files with 111 additions and 13 deletions

View File

@ -2,12 +2,14 @@
#define __ACTIONS_H #define __ACTIONS_H
typedef enum ActionType typedef enum ActionType
{ {
ACTION_UP, ACTION_UP=0,
ACTION_DOWN, ACTION_DOWN,
ACTION_LEFT, ACTION_LEFT,
ACTION_RIGHT, ACTION_RIGHT,
ACTION_JUMP, ACTION_JUMP,
ACTION_NEXT_SPAWN, ACTION_NEXT_SPAWN,
ACTION_PREV_SPAWN, ACTION_PREV_SPAWN,
ACTION_CONFIRM,
ACTION_EXIT,
}ActionType_t; }ActionType_t;
#endif // __ACTIONS_H #endif // __ACTIONS_H

View File

@ -241,6 +241,14 @@ void level_do_action(Scene_t *scene, ActionType_t action, bool pressed)
current_spawn_selection &= 1; current_spawn_selection &= 1;
} }
break; break;
case ACTION_EXIT:
if(scene->engine != NULL)
{
change_scene(scene->engine, 0);
}
break;
default:
break;
} }
} }
} }
@ -272,6 +280,7 @@ void init_level_scene(LevelScene_t *scene)
sc_map_put_64(&scene->scene.action_map, KEY_SPACE, ACTION_JUMP); sc_map_put_64(&scene->scene.action_map, KEY_SPACE, ACTION_JUMP);
sc_map_put_64(&scene->scene.action_map, KEY_O, ACTION_PREV_SPAWN); sc_map_put_64(&scene->scene.action_map, KEY_O, ACTION_PREV_SPAWN);
sc_map_put_64(&scene->scene.action_map, KEY_P, ACTION_NEXT_SPAWN); sc_map_put_64(&scene->scene.action_map, KEY_P, ACTION_NEXT_SPAWN);
sc_map_put_64(&scene->scene.action_map, KEY_Q, ACTION_EXIT);
scene->data.tilemap.width = DEFAULT_MAP_WIDTH; scene->data.tilemap.width = DEFAULT_MAP_WIDTH;
scene->data.tilemap.height = DEFAULT_MAP_HEIGHT; scene->data.tilemap.height = DEFAULT_MAP_HEIGHT;

View File

@ -1,5 +1,11 @@
#include "engine.h" #include "engine.h"
void change_scene(GameEngine_t *engine, unsigned int idx)
{
engine->scenes[engine->curr_scene]->state = SCENE_ENDED;
engine->curr_scene = idx;
engine->scenes[engine->curr_scene]->state = SCENE_PLAYING;
}
void init_scene(Scene_t *scene, SceneType_t scene_type, system_func_t render_func, action_func_t action_func) void init_scene(Scene_t *scene, SceneType_t scene_type, system_func_t render_func, action_func_t action_func)
{ {
sc_map_init_64(&scene->action_map, 32, 0); sc_map_init_64(&scene->action_map, 32, 0);

View File

@ -7,11 +7,11 @@ typedef struct Scene Scene_t;
typedef struct GameEngine typedef struct GameEngine
{ {
Scene_t *scenes; Scene_t **scenes;
unsigned int max_scenes; unsigned int max_scenes;
unsigned int curr_scene; unsigned int curr_scene;
}GameEngine_t; }GameEngine_t;
void change_scene(GameEngine_t *engine); void change_scene(GameEngine_t *engine, unsigned int idx);
typedef enum SceneType typedef enum SceneType
{ {

View File

@ -47,6 +47,17 @@ static void menu_do_action(Scene_t *scene, ActionType_t action, bool pressed)
data->buttons[new_selection].state = STATE_FOCUSED; data->buttons[new_selection].state = STATE_FOCUSED;
data->selected_comp = new_selection; data->selected_comp = new_selection;
if (action == ACTION_CONFIRM && scene->engine != NULL)
{
switch(data->selected_comp)
{
case 0:
change_scene(scene->engine, 1);
break;
default:
break;
}
}
} }
} }
@ -83,6 +94,17 @@ static void gui_loop(Scene_t* scene)
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
{ {
data->buttons[i].pressed = true; data->buttons[i].pressed = true;
if (scene->engine != NULL)
{
switch(i)
{
case 0:
change_scene(scene->engine, 1);
break;
default:
break;
}
}
} }
data->selected_comp = i; data->selected_comp = i;
} }
@ -126,6 +148,7 @@ void init_menu_scene(MenuScene_t *scene)
sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN); sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN);
sc_map_put_64(&scene->scene.action_map, KEY_LEFT, ACTION_LEFT); sc_map_put_64(&scene->scene.action_map, KEY_LEFT, ACTION_LEFT);
sc_map_put_64(&scene->scene.action_map, KEY_RIGHT, ACTION_RIGHT); sc_map_put_64(&scene->scene.action_map, KEY_RIGHT, ACTION_RIGHT);
sc_map_put_64(&scene->scene.action_map, KEY_ENTER, ACTION_CONFIRM);
} }
void free_menu_scene(MenuScene_t *scene) void free_menu_scene(MenuScene_t *scene)

78
main.c
View File

@ -1,39 +1,97 @@
#include "raylib.h" #include "raylib.h"
#include "engine.h" #include "scene_impl.h"
#include <stdio.h>
#define N_SCENES 3 #define N_SCENES 3
Scene_t scenes[N_SCENES]; Scene_t *scenes[N_SCENES];
unsigned int current_scene; static GameEngine_t engine =
{
.scenes = scenes,
.max_scenes = 2,
.curr_scene = 0
};
const int screenWidth = 800; const int screenWidth = 1280;
const int screenHeight = 450; const int screenHeight = 640;
static void load_assets(void) static void load_assets(void)
{ {
} }
// Maintain own queue to handle key presses
struct sc_queue_32 key_buffer;
int main(void) int main(void)
{ {
// Initialization // Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
//char dir[7]; sc_queue_init(&key_buffer);
InitWindow(screenWidth, screenHeight, "raylib"); InitWindow(screenWidth, screenHeight, "raylib");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
init_memory_pools();
LevelScene_t level_scene;
init_level_scene(&level_scene);
level_scene.scene.engine = &engine;
MenuScene_t menu_scene;
init_menu_scene(&menu_scene);
menu_scene.scene.engine = &engine;
scenes[0] = &menu_scene.scene;
scenes[1] = &level_scene.scene;
load_assets(); load_assets();
change_scene(&engine, 0);
//Camera2D camera = { 0 }; //Camera2D camera = { 0 };
//camera.offset = (Vector2){0,0}; //camera.offset = (Vector2){0,0};
//camera.rotation = 0.0f; //camera.rotation = 0.0f;
//camera.zoom = 1.0f; //camera.zoom = 1.0f;
while (!WindowShouldClose()) while (!WindowShouldClose())
{ {
// TODO: Handle keystrokes/input here // This entire key processing relies on the assumption that a pressed key will
// TODO: Update Scene here or scene changes // appear in the polling of raylib
Scene_t * curr_scene = engine.scenes[engine.curr_scene];
unsigned int sz = sc_queue_size(&key_buffer);
// Process any existing pressed key
for (size_t i=0; i<sz; i++)
{
int button = sc_queue_del_first(&key_buffer);
ActionType_t action = sc_map_get_64(&curr_scene->action_map, button);
if (IsKeyReleased(button))
{
do_action(curr_scene, action, false);
}
else
{
do_action(curr_scene, action, true);
sc_queue_add_last(&key_buffer, button);
}
}
// Detect new key presses
while(true)
{
int button = GetKeyPressed();
if (button == 0) break;
ActionType_t action = sc_map_get_64(&curr_scene->action_map, button);
if (!sc_map_found(&curr_scene->action_map)) continue;
do_action(curr_scene, action, true);
sc_queue_add_last(&key_buffer, button);
}
update_scene(curr_scene);
update_entity_manager(&curr_scene->ent_manager);
// This is needed to advance time delta
BeginDrawing(); BeginDrawing();
// TODO: Call the current scene Render function render_scene(curr_scene);
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
EndDrawing(); EndDrawing();
if (curr_scene->state != SCENE_PLAYING)
{
sc_queue_clear(&key_buffer);
}
} }
CloseWindow(); CloseWindow();
free_level_scene(&level_scene);
free_menu_scene(&menu_scene);
sc_queue_term(&key_buffer);
} }