working basic game state, state stack
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
arkanoid
 | 
			
		||||
core.*
 | 
			
		||||
							
								
								
									
										43
									
								
								game.odin
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								game.odin
									
									
									
									
									
								
							@ -1,11 +1,12 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import rl "vendor:raylib"
 | 
			
		||||
import "core:fmt"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Pad :: struct {
 | 
			
		||||
	position: Vec2, 
 | 
			
		||||
	width: Vec2,
 | 
			
		||||
	size: Vec2,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Ball :: struct {
 | 
			
		||||
@ -31,20 +32,40 @@ Game :: struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
game_init :: proc() -> Game {
 | 
			
		||||
	return Game{
 | 
			
		||||
		update = game_update,
 | 
			
		||||
		draw = game_draw,
 | 
			
		||||
		lives = 3,
 | 
			
		||||
		pad = Pad{
 | 
			
		||||
			position = {f32(WINDOW_WIDTH / 2), f32(WINDOW_HEIGHT - 40)}
 | 
			
		||||
		}
 | 
			
		||||
game_init :: proc() -> ^GameState {
 | 
			
		||||
	state := new(Game)
 | 
			
		||||
	state.variant = state
 | 
			
		||||
	state.draw = game_draw
 | 
			
		||||
	state.update = game_update
 | 
			
		||||
	state.lives = 3
 | 
			
		||||
	state.pad = Pad{
 | 
			
		||||
		position = {f32(WINDOW_WIDTH / 2), f32(WINDOW_HEIGHT - 40)},
 | 
			
		||||
		size = {80, 10},
 | 
			
		||||
	}
 | 
			
		||||
	return state
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
game_update :: proc(delta: f32) {
 | 
			
		||||
game_update :: proc(state: ^GameState, delta: f32) {
 | 
			
		||||
	game := transmute(^Game)state
 | 
			
		||||
 | 
			
		||||
	using game
 | 
			
		||||
 | 
			
		||||
	if rl.IsKeyDown(rl.KeyboardKey.LEFT) { 
 | 
			
		||||
		pad.position.x -= 100 * delta
 | 
			
		||||
		fmt.println(pad.position)
 | 
			
		||||
	}
 | 
			
		||||
	if rl.IsKeyDown(rl.KeyboardKey.RIGHT) {
 | 
			
		||||
		pad.position.x += 100 * delta
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
game_draw :: proc() {
 | 
			
		||||
game_draw :: proc(state: ^GameState) {
 | 
			
		||||
	game := transmute(^Game)state
 | 
			
		||||
 | 
			
		||||
	using game
 | 
			
		||||
 | 
			
		||||
	rl.ClearBackground(rl.RAYWHITE)
 | 
			
		||||
 | 
			
		||||
	rl.DrawRectangleV(pad.position, pad.size, rl.GREEN)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								main.odin
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								main.odin
									
									
									
									
									
								
							@ -1,13 +1,52 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import rl "vendor:raylib"
 | 
			
		||||
import "core:slice"
 | 
			
		||||
 | 
			
		||||
Vec2 :: [2]f32
 | 
			
		||||
Vec2i :: [2]i32
 | 
			
		||||
 | 
			
		||||
WINDOW_WIDTH : i32
 | 
			
		||||
WINDOW_HEIGHT : i32
 | 
			
		||||
WINDOW_WIDTH : i32 = 800
 | 
			
		||||
WINDOW_HEIGHT : i32 = 480
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
main :: proc() {
 | 
			
		||||
	rl.SetConfigFlags(rl.ConfigFlags{.BORDERLESS_WINDOWED_MODE, .VSYNC_HINT, .WINDOW_RESIZABLE})
 | 
			
		||||
	monitor := rl.GetCurrentMonitor()
 | 
			
		||||
	WINDOW_WIDTH = rl.GetMonitorWidth(monitor)
 | 
			
		||||
	WINDOW_HEIGHT = rl.GetMonitorHeight(monitor)
 | 
			
		||||
	rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "SinePong")
 | 
			
		||||
	rl.SetTargetFPS(9999)
 | 
			
		||||
 | 
			
		||||
	stack_init()
 | 
			
		||||
 | 
			
		||||
	defer {
 | 
			
		||||
		for s, i in state_stack {
 | 
			
		||||
			free(s)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	game := game_init()
 | 
			
		||||
	append(&state_stack, game)
 | 
			
		||||
 | 
			
		||||
	for (!rl.WindowShouldClose()) {
 | 
			
		||||
		if rl.IsWindowResized() {
 | 
			
		||||
			WINDOW_WIDTH = rl.GetScreenWidth()
 | 
			
		||||
			WINDOW_HEIGHT = rl.GetScreenHeight()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		current_state := state_stack[len(state_stack)-1]
 | 
			
		||||
		
 | 
			
		||||
		delta := rl.GetFrameTime()
 | 
			
		||||
 | 
			
		||||
		current_state->update(delta)
 | 
			
		||||
 | 
			
		||||
		{
 | 
			
		||||
			rl.BeginDrawing()
 | 
			
		||||
			defer rl.EndDrawing()
 | 
			
		||||
			current_state->draw()
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										36
									
								
								state.odin
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								state.odin
									
									
									
									
									
								
							@ -1,11 +1,14 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import "core:slice"
 | 
			
		||||
 | 
			
		||||
StateVariant :: union{^Game, ^Menu}
 | 
			
		||||
 | 
			
		||||
GameState :: struct {
 | 
			
		||||
	update: proc(f32),
 | 
			
		||||
	draw: proc(),
 | 
			
		||||
	update: proc(state: ^GameState, delta: f32),
 | 
			
		||||
	draw: proc(state: ^GameState),
 | 
			
		||||
	
 | 
			
		||||
	variant: union{^Game, ^Menu}
 | 
			
		||||
	variant: StateVariant
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
new_state :: proc($T: typeid) -> ^T {
 | 
			
		||||
@ -13,3 +16,30 @@ new_state :: proc($T: typeid) -> ^T {
 | 
			
		||||
	state.variant = state
 | 
			
		||||
	return state
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
STACK_SIZE :: 16
 | 
			
		||||
state_buf : [STACK_SIZE]^GameState
 | 
			
		||||
state_stack : [dynamic]^GameState
 | 
			
		||||
 | 
			
		||||
stack_init :: proc() {
 | 
			
		||||
	state_stack = slice.into_dynamic(state_buf[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
stack_push :: proc(state: ^GameState) -> (bool) {
 | 
			
		||||
	if len(state_stack) == STACK_SIZE {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	append(&state_stack, state)
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
stack_pop :: proc() -> (bool) {
 | 
			
		||||
	if len(state_stack) == 0 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	state := pop(&state_stack)
 | 
			
		||||
	free(state)
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user