Multiple scene rendering setup.
This commit is contained in:
+54
-53
@@ -2,26 +2,36 @@ package game
|
|||||||
|
|
||||||
import rl "vendor:raylib"
|
import rl "vendor:raylib"
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// Scene & Overlay Definitions
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
Scene_Gameplay :: struct {
|
||||||
|
level: Level,
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene_Menu :: struct {
|
||||||
|
// @todo: ui_canvas layout state
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene_PauseMenu :: struct {
|
||||||
|
// @todo: pause option state
|
||||||
|
}
|
||||||
|
|
||||||
Scene :: union {
|
Scene :: union {
|
||||||
Scene_Menu,
|
Scene_Menu,
|
||||||
Scene_Gameplay,
|
Scene_Gameplay,
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene_Menu :: struct {
|
Overlay_Scene :: union {
|
||||||
// Ui_Canvas
|
Scene_PauseMenu,
|
||||||
// as in a struct so that we cleanly have either Level or Ui_Canvas
|
|
||||||
}
|
|
||||||
|
|
||||||
Scene_Gameplay :: struct {
|
|
||||||
level: Level,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Scene Dispatchers
|
// Base Scene Dispatchers
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
scene_update :: proc(game: ^Game, input: Input_Event, dt: f32) {
|
scene_update :: proc(game: ^Game, input: Input_Event, dt: f32) {
|
||||||
switch &s in game.scene {
|
switch &s in game.scene {
|
||||||
case Scene_Menu: // update_menu(&s, game, dt)
|
case Scene_Menu: // update_menu(&s, game, input, dt)
|
||||||
case Scene_Gameplay: update_gameplay(&s, game, input, dt)
|
case Scene_Gameplay: update_gameplay(&s, game, input, dt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,27 +39,45 @@ scene_update :: proc(game: ^Game, input: Input_Event, dt: f32) {
|
|||||||
scene_render :: proc(game: ^Game) {
|
scene_render :: proc(game: ^Game) {
|
||||||
switch &s in game.scene {
|
switch &s in game.scene {
|
||||||
case Scene_Menu: // render_menu(s)
|
case Scene_Menu: // render_menu(s)
|
||||||
case Scene_Gameplay: render_gameplay(s, game.viewport, game.paused)
|
case Scene_Gameplay: render_gameplay(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Menu Scene
|
// Overlay Scene Dispatchers
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// @TODO:
|
overlay_update :: proc(game: ^Game, input: Input_Event, dt: f32) -> bool {
|
||||||
// update_menu :: proc
|
overlay := game.overlay_scene.? or_return
|
||||||
// if input.move_dir.y < 0 { // UP
|
|
||||||
// menu.selected_option = max(0, menu.selected_option - 1)
|
|
||||||
// } else if input.move_dir.y > 0 { // DOWN
|
|
||||||
// menu.selected_option = min(MAX_OPTIONS - 1, menu.selected_option + 1)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if input.confirm_pressed {
|
switch &o in overlay {
|
||||||
// // Execute menu selection
|
case Scene_PauseMenu:
|
||||||
// }
|
if input.pause_pressed {
|
||||||
|
game.overlay_scene = nil
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// @todo: handle overlay menu option selection (resume, settings, quit)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay_render :: proc(game: ^Game) -> bool {
|
||||||
|
overlay := game.overlay_scene.? or_return
|
||||||
|
|
||||||
|
switch &o in overlay {
|
||||||
|
case Scene_PauseMenu:
|
||||||
|
// Translucent dark tint across virtual canvas space
|
||||||
|
rl.DrawRectangleRec(rl.Rectangle{0, 0, VIEWPORT_W, VIEWPORT_H}, rl.Color{0, 0, 0, 140})
|
||||||
|
// Pause Menu UI elements
|
||||||
|
rl.DrawText("PAUSED", VIEWPORT_W / 2 - 80, VIEWPORT_H / 2 - 40, 40, rl.WHITE)
|
||||||
|
rl.DrawText("Press Q to Quit to Menu", VIEWPORT_W / 2 - 110, VIEWPORT_H / 2 + 10, 20, rl.LIGHTGRAY)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Gameplay Scene
|
// Gameplay Scene Procedures
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
init_gameplay_scene :: proc() -> Scene_Gameplay {
|
init_gameplay_scene :: proc() -> Scene_Gameplay {
|
||||||
return Scene_Gameplay{
|
return Scene_Gameplay{
|
||||||
@@ -59,41 +87,14 @@ init_gameplay_scene :: proc() -> Scene_Gameplay {
|
|||||||
|
|
||||||
update_gameplay :: proc(scene: ^Scene_Gameplay, game: ^Game, input: Input_Event, dt: f32) {
|
update_gameplay :: proc(scene: ^Scene_Gameplay, game: ^Game, input: Input_Event, dt: f32) {
|
||||||
if input.pause_pressed {
|
if input.pause_pressed {
|
||||||
game.paused = !game.paused
|
game.overlay_scene = Scene_PauseMenu{}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if game.paused do return
|
|
||||||
|
|
||||||
update_level(&scene.level, input, dt)
|
update_level(&scene.level, input, dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
render_gameplay :: proc(scene: Scene_Gameplay, viewport_texture: rl.RenderTexture2D, is_paused: bool) {
|
render_gameplay :: proc(scene: Scene_Gameplay) {
|
||||||
// Offscreen Pass: Render all game objects at low/fixed virtual resolution
|
|
||||||
rl.BeginTextureMode(viewport_texture)
|
|
||||||
rl.ClearBackground(rl.BLACK)
|
|
||||||
|
|
||||||
render_level(scene.level)
|
render_level(scene.level)
|
||||||
|
render_hud(scene.level)
|
||||||
if is_paused {
|
|
||||||
// UI coordinates aligned relative to internal 1280x720 viewport space
|
|
||||||
rl.DrawRectangleRec(rl.Rectangle{0,0, VIEWPORT_W, VIEWPORT_H}, rl.Color{0,0,0,140})
|
|
||||||
rl.DrawText("PAUSED", VIEWPORT_W / 2 - 80, VIEWPORT_H / 2 - 40, 40, rl.WHITE)
|
|
||||||
rl.DrawText("Press Q to Quit to Menu", VIEWPORT_W / 2 - 110, VIEWPORT_H / 2 + 10, 20, rl.LIGHTGRAY)
|
|
||||||
}
|
|
||||||
rl.EndTextureMode()
|
|
||||||
|
|
||||||
// Upscale Pass: Stretch render buffer onto actual window display
|
|
||||||
render_game_to_window(viewport_texture.texture)
|
|
||||||
}
|
|
||||||
|
|
||||||
render_game_to_window :: proc(texture: rl.Texture) {
|
|
||||||
rl.DrawTexturePro(
|
|
||||||
texture,
|
|
||||||
// src: OpenGL render targets have inverted Y coordinates (-height flips it)
|
|
||||||
rl.Rectangle{0, 0, f32(texture.width), -f32(texture.height)},
|
|
||||||
// dst: Scales viewport canvas to fill window res (WINDOW_WIDTHxWINDOW_HEIGHT)
|
|
||||||
rl.Rectangle{0, 0, f32(WINDOW_W), f32(WINDOW_H)},
|
|
||||||
rl.Vector2{},
|
|
||||||
0,
|
|
||||||
rl.WHITE
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user