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
typedef enum ActionType
{
ACTION_UP,
ACTION_UP=0,
ACTION_DOWN,
ACTION_LEFT,
ACTION_RIGHT,
ACTION_JUMP,
ACTION_NEXT_SPAWN,
ACTION_PREV_SPAWN,
ACTION_CONFIRM,
ACTION_EXIT,
}ActionType_t;
#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;
}
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_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_Q, ACTION_EXIT);
scene->data.tilemap.width = DEFAULT_MAP_WIDTH;
scene->data.tilemap.height = DEFAULT_MAP_HEIGHT;

View File

@ -1,5 +1,11 @@
#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)
{
sc_map_init_64(&scene->action_map, 32, 0);

View File

@ -7,11 +7,11 @@ typedef struct Scene Scene_t;
typedef struct GameEngine
{
Scene_t *scenes;
Scene_t **scenes;
unsigned int max_scenes;
unsigned int curr_scene;
}GameEngine_t;
void change_scene(GameEngine_t *engine);
void change_scene(GameEngine_t *engine, unsigned int idx);
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->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))
{
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;
}
@ -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_LEFT, ACTION_LEFT);
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)

78
main.c
View File

@ -1,39 +1,97 @@
#include "raylib.h"
#include "engine.h"
#include "scene_impl.h"
#include <stdio.h>
#define N_SCENES 3
Scene_t scenes[N_SCENES];
unsigned int current_scene;
Scene_t *scenes[N_SCENES];
static GameEngine_t engine =
{
.scenes = scenes,
.max_scenes = 2,
.curr_scene = 0
};
const int screenWidth = 800;
const int screenHeight = 450;
const int screenWidth = 1280;
const int screenHeight = 640;
static void load_assets(void)
{
}
// Maintain own queue to handle key presses
struct sc_queue_32 key_buffer;
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
//char dir[7];
sc_queue_init(&key_buffer);
InitWindow(screenWidth, screenHeight, "raylib");
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();
change_scene(&engine, 0);
//Camera2D camera = { 0 };
//camera.offset = (Vector2){0,0};
//camera.rotation = 0.0f;
//camera.zoom = 1.0f;
while (!WindowShouldClose())
{
// TODO: Handle keystrokes/input here
// TODO: Update Scene here or scene changes
// This entire key processing relies on the assumption that a pressed key will
// 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();
// TODO: Call the current scene Render function
render_scene(curr_scene);
ClearBackground(RAYWHITE);
EndDrawing();
if (curr_scene->state != SCENE_PLAYING)
{
sc_queue_clear(&key_buffer);
}
}
CloseWindow();
free_level_scene(&level_scene);
free_menu_scene(&menu_scene);
sc_queue_term(&key_buffer);
}