Setup 2D Camera for shake effect.
This commit is contained in:
+50
-7
@@ -1,10 +1,9 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
|
import "core:math/rand"
|
||||||
import rl "vendor:raylib"
|
import rl "vendor:raylib"
|
||||||
|
|
||||||
// VIEWPORT_W :: 1280
|
|
||||||
// VIEWPORT_H :: 720
|
|
||||||
VIEWPORT_W :: 640
|
VIEWPORT_W :: 640
|
||||||
VIEWPORT_H :: 360
|
VIEWPORT_H :: 360
|
||||||
WINDOW_TITLE :: "Pong"
|
WINDOW_TITLE :: "Pong"
|
||||||
@@ -31,6 +30,11 @@ Game :: struct {
|
|||||||
should_close: bool,
|
should_close: bool,
|
||||||
audio: Audio_Manager,
|
audio: Audio_Manager,
|
||||||
|
|
||||||
|
// Camera state for screen effects / screen shake
|
||||||
|
camera: rl.Camera2D,
|
||||||
|
shake_intensity: f32,
|
||||||
|
shake_timer: f32,
|
||||||
|
|
||||||
// resolution state
|
// resolution state
|
||||||
window_w: i32,
|
window_w: i32,
|
||||||
window_h: i32,
|
window_h: i32,
|
||||||
@@ -78,6 +82,14 @@ game_init :: proc(game: ^Game) {
|
|||||||
|
|
||||||
game.crt_shader = rl.LoadShader(nil, "assets/shaders/crt.fs")
|
game.crt_shader = rl.LoadShader(nil, "assets/shaders/crt.fs")
|
||||||
|
|
||||||
|
// Setup 2D camera matching the 640x360 viewport center
|
||||||
|
game.camera = rl.Camera2D{
|
||||||
|
target = rl.Vector2{VIEWPORT_W / 2.0, VIEWPORT_H / 2.0},
|
||||||
|
offset = rl.Vector2{VIEWPORT_W / 2.0, VIEWPORT_H / 2.0},
|
||||||
|
rotation = 0.0,
|
||||||
|
zoom = 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
game.should_close = false
|
game.should_close = false
|
||||||
set_root_scene(game, make_main_menu())
|
set_root_scene(game, make_main_menu())
|
||||||
}
|
}
|
||||||
@@ -86,6 +98,28 @@ game_update :: proc(game: ^Game) {
|
|||||||
dt := rl.GetFrameTime()
|
dt := rl.GetFrameTime()
|
||||||
input := poll_input()
|
input := poll_input()
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Update Camera Shake
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
base_center := rl.Vector2{VIEWPORT_W / 2.0, VIEWPORT_H / 2.0}
|
||||||
|
|
||||||
|
if game.shake_timer > 0 {
|
||||||
|
game.shake_timer -= dt
|
||||||
|
|
||||||
|
// Generate random offset within current intensity bounds
|
||||||
|
offset_x := (f32(rand.float32()) * 2.0 - 1.0) * game.shake_intensity
|
||||||
|
offset_y := (f32(rand.float32()) * 2.0 - 1.0) * game.shake_intensity
|
||||||
|
|
||||||
|
game.camera.target = base_center + rl.Vector2{offset_x, offset_y}
|
||||||
|
|
||||||
|
if game.shake_timer <= 0 {
|
||||||
|
game.shake_intensity = 0.0
|
||||||
|
game.camera.target = base_center
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
game.camera.target = base_center
|
||||||
|
}
|
||||||
|
|
||||||
active_scene := get_active_scene(game)
|
active_scene := get_active_scene(game)
|
||||||
if active_scene != nil {
|
if active_scene != nil {
|
||||||
scene_update(active_scene, game, input, dt)
|
scene_update(active_scene, game, input, dt)
|
||||||
@@ -105,12 +139,16 @@ game_render :: proc(game: ^Game) {
|
|||||||
rl.BeginTextureMode(game.viewport)
|
rl.BeginTextureMode(game.viewport)
|
||||||
rl.DrawTexture(game.bg_texture, 0, 0, rl.WHITE)
|
rl.DrawTexture(game.bg_texture, 0, 0, rl.WHITE)
|
||||||
|
|
||||||
// @note: fine for now but probably not a good idea...
|
// World/Scene objects rendered through 2D camera space
|
||||||
// Render all scenes in the stack from bottom to top
|
rl.BeginMode2D(game.camera)
|
||||||
for i in 0 ..< len(game.scene_stack) {
|
|
||||||
scene_render(&game.scene_stack[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// @note: fine for now but probably not a good idea...
|
||||||
|
// Render all scenes in the stack from bottom to top
|
||||||
|
for i in 0 ..< len(game.scene_stack) {
|
||||||
|
scene_render(&game.scene_stack[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.EndMode2D()
|
||||||
rl.EndTextureMode()
|
rl.EndTextureMode()
|
||||||
|
|
||||||
render_game_to_window(game)
|
render_game_to_window(game)
|
||||||
@@ -136,6 +174,11 @@ game_should_run :: proc(game: Game) -> bool {
|
|||||||
return !game.should_close && !rl.WindowShouldClose()
|
return !game.should_close && !rl.WindowShouldClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
game_trigger_shake :: proc(game: ^Game, intensity: f32, duration: f32 = 0.15) {
|
||||||
|
game.shake_intensity = max(game.shake_intensity, intensity)
|
||||||
|
game.shake_timer = duration
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Window Upscale Render
|
// Window Upscale Render
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user