Separate menu_list, working pause menu
This commit is contained in:
		@ -59,6 +59,10 @@ game_update :: proc(state: ^GameState, delta: f32) {
 | 
			
		||||
 | 
			
		||||
	using game
 | 
			
		||||
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.ESCAPE) {
 | 
			
		||||
		pause := pause_init(game)
 | 
			
		||||
		stack_push(pause)
 | 
			
		||||
	}
 | 
			
		||||
	pad_update(&game.pad, delta)
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.SPACE) {
 | 
			
		||||
		for &ball, i in balls {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										54
									
								
								menu.odin
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								menu.odin
									
									
									
									
									
								
							@ -21,19 +21,21 @@ menu_strings := [Menu_Buttons]cstring {
 | 
			
		||||
Menu :: struct {
 | 
			
		||||
	using state: GameState,
 | 
			
		||||
 | 
			
		||||
	menu_pos: Vec2,
 | 
			
		||||
	menu_element_offset: f32,
 | 
			
		||||
	active_element: Menu_Buttons,
 | 
			
		||||
	active_marker: Vec2,
 | 
			
		||||
	marker_tween: ^Tween,
 | 
			
		||||
	list: MenuList(Menu_Buttons),
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
menu_init :: proc(prev: ^GameState = nil) -> ^GameState {
 | 
			
		||||
	state := new(Menu)
 | 
			
		||||
	state.variant = state
 | 
			
		||||
	state.menu_pos = {300, 300}
 | 
			
		||||
	state.menu_element_offset = 60
 | 
			
		||||
	state.active_marker = state.menu_pos + Vec2{0, f32(state.active_element) * state.menu_element_offset}
 | 
			
		||||
	state.list = MenuList(Menu_Buttons){
 | 
			
		||||
		state = state,
 | 
			
		||||
		position = {300, 300},
 | 
			
		||||
		line_size = 60,
 | 
			
		||||
		font_size = 42,
 | 
			
		||||
		elements = &menu_strings,
 | 
			
		||||
		menu_pressed = menu_button_pressed
 | 
			
		||||
	}
 | 
			
		||||
	state.update = menu_update
 | 
			
		||||
	state.draw = menu_draw 
 | 
			
		||||
	state.free = menu_free
 | 
			
		||||
@ -45,31 +47,11 @@ menu_init :: proc(prev: ^GameState = nil) -> ^GameState {
 | 
			
		||||
menu_update :: proc(state: ^GameState, delta: f32) {
 | 
			
		||||
	menu := transmute(^Menu)state
 | 
			
		||||
	
 | 
			
		||||
	prev_element := cast(i8)menu.active_element
 | 
			
		||||
	cur_element := prev_element
 | 
			
		||||
	menu_list_update(&menu.list)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.DOWN) {
 | 
			
		||||
		cur_element += 1
 | 
			
		||||
	}
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.UP) {
 | 
			
		||||
		cur_element -= 1
 | 
			
		||||
	}
 | 
			
		||||
	if prev_element != cur_element {
 | 
			
		||||
		if cur_element < 0 { cur_element = len(Menu_Buttons) -1 }
 | 
			
		||||
		if cur_element == len(Menu_Buttons) { cur_element = 0 }
 | 
			
		||||
		menu.active_element = cast(Menu_Buttons)cur_element
 | 
			
		||||
		if menu.marker_tween != nil {
 | 
			
		||||
			tween_cancel(menu.marker_tween)
 | 
			
		||||
		}
 | 
			
		||||
		menu.marker_tween = tween_to(
 | 
			
		||||
			&menu.active_marker.y,
 | 
			
		||||
			menu.menu_pos.y + f32(menu.active_element) * menu.menu_element_offset,
 | 
			
		||||
			0.5,
 | 
			
		||||
			ease.Ease.Back_Out,
 | 
			
		||||
		)
 | 
			
		||||
	}
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.ENTER) || rl.IsKeyPressed(rl.KeyboardKey.SPACE) {
 | 
			
		||||
		switch menu.active_element {
 | 
			
		||||
menu_button_pressed :: proc(state: ^GameState, el: Menu_Buttons) {
 | 
			
		||||
	switch el  {
 | 
			
		||||
		case .START:
 | 
			
		||||
			game := game_init(state)
 | 
			
		||||
			stack_push(game)
 | 
			
		||||
@ -80,7 +62,6 @@ menu_update :: proc(state: ^GameState, delta: f32) {
 | 
			
		||||
			return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
menu_draw :: proc(state: ^GameState) {
 | 
			
		||||
	menu := transmute(^Menu)state
 | 
			
		||||
@ -91,11 +72,8 @@ menu_draw :: proc(state: ^GameState) {
 | 
			
		||||
	TitleSize := rl.MeasureTextEx(FontTitle, TitleText, TitleFontSize, TitleSpacing)
 | 
			
		||||
	rl.DrawTextPro(FontTitle, "ARKADODGE", {WINDOWF.x - 50, 50}, {TitleSize.x, 0}, 0, 96, 3, rl.WHITE)
 | 
			
		||||
 | 
			
		||||
	rl.DrawTextEx(FontUI, ">", menu.active_marker + {-30, 0}, 48, 2, rl.WHITE)
 | 
			
		||||
	for el, i in menu_strings {
 | 
			
		||||
		pos := menu.menu_pos + {0, f32(i) * menu.menu_element_offset}
 | 
			
		||||
		rl.DrawTextEx(FontUI, el, pos, 48, 2, rl.WHITE)
 | 
			
		||||
	}
 | 
			
		||||
	menu_list_draw(&menu.list)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
menu_free :: proc(state: ^GameState) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								menu_list.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								menu_list.odin
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import rl "vendor:raylib"
 | 
			
		||||
import "core:math/ease"
 | 
			
		||||
 | 
			
		||||
MenuList :: struct($T: typeid) {
 | 
			
		||||
	state: ^GameState,
 | 
			
		||||
	position: Vec2,
 | 
			
		||||
	line_size: f32,
 | 
			
		||||
	font_size: f32,
 | 
			
		||||
	active_element: T,
 | 
			
		||||
	active_marker: Vec2,
 | 
			
		||||
	tween: ^Tween,
 | 
			
		||||
	elements: ^[T]cstring,
 | 
			
		||||
	menu_pressed: proc(state: ^GameState, element: T),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
menu_list_update :: proc(list: ^MenuList($T)) {
 | 
			
		||||
	prev_element := cast(i8)list.active_element
 | 
			
		||||
	cur_element := prev_element
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.DOWN) {
 | 
			
		||||
		cur_element += 1
 | 
			
		||||
	}
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.UP) {
 | 
			
		||||
		cur_element -= 1
 | 
			
		||||
	}
 | 
			
		||||
	if prev_element != cur_element {
 | 
			
		||||
		if cur_element < 0 { cur_element = len(T) -1 }
 | 
			
		||||
		if cur_element == len(T) { cur_element = 0 }
 | 
			
		||||
		list.active_element = cast(T)cur_element
 | 
			
		||||
		if list.tween != nil {
 | 
			
		||||
			tween_cancel(list.tween)
 | 
			
		||||
		}
 | 
			
		||||
		list.tween = tween_to(
 | 
			
		||||
			&list.active_marker.y,
 | 
			
		||||
			f32(list.active_element) * list.line_size,
 | 
			
		||||
			0.5,
 | 
			
		||||
			ease.Ease.Back_Out,
 | 
			
		||||
		)
 | 
			
		||||
	}
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.ENTER) || rl.IsKeyPressed(rl.KeyboardKey.SPACE) {
 | 
			
		||||
		list.menu_pressed(list.state, list.active_element)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
menu_list_draw :: proc(list: ^MenuList($T)) {
 | 
			
		||||
	rl.DrawTextEx(FontUI, ">", list.position + list.active_marker + {-30, 0}, 48, 2, rl.WHITE)
 | 
			
		||||
	for el, i in list.elements {
 | 
			
		||||
		pos := list.position + {0, f32(i) * list.line_size}
 | 
			
		||||
		rl.DrawTextEx(FontUI, el, pos, 48, 2, rl.WHITE)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								pause.odin
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								pause.odin
									
									
									
									
									
								
							@ -11,7 +11,7 @@ Pause_Buttons :: enum {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pause_strings := [Pause_Buttons]cstring {
 | 
			
		||||
	.RESUME = "Старт",
 | 
			
		||||
	.RESUME = "Продолжить",
 | 
			
		||||
	.FULLSCREEN = "Полный экран",
 | 
			
		||||
	.EXIT = "Выход"
 | 
			
		||||
}
 | 
			
		||||
@ -19,23 +19,24 @@ pause_strings := [Pause_Buttons]cstring {
 | 
			
		||||
Pause :: struct {
 | 
			
		||||
	using state: GameState,
 | 
			
		||||
 | 
			
		||||
	menu_pos: Vec2,
 | 
			
		||||
	menu_element_offset: f32,
 | 
			
		||||
	active_element: Pause_Buttons,
 | 
			
		||||
	active_marker: Vec2,
 | 
			
		||||
	marker_tween: ^Tween,
 | 
			
		||||
	list: MenuList(Pause_Buttons)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pause_init :: proc(prev: ^GameState = nil) -> ^GameState {
 | 
			
		||||
	state := new(Pause)
 | 
			
		||||
	state.variant = state
 | 
			
		||||
	state.menu_pos = {300, 300}
 | 
			
		||||
	state.menu_element_offset = 60
 | 
			
		||||
	state.active_marker = state.menu_pos + Vec2{0, f32(state.active_element) * state.menu_element_offset}
 | 
			
		||||
	state.update = menu_update
 | 
			
		||||
	state.draw = menu_draw 
 | 
			
		||||
	state.free = menu_free
 | 
			
		||||
	state.list = MenuList(Pause_Buttons){
 | 
			
		||||
		position = {-300, 300},
 | 
			
		||||
		line_size = 60,
 | 
			
		||||
		font_size = 42,
 | 
			
		||||
		elements = &pause_strings,
 | 
			
		||||
		menu_pressed = pause_button_pressed
 | 
			
		||||
	}
 | 
			
		||||
	state.update = pause_update
 | 
			
		||||
	state.draw = pause_draw
 | 
			
		||||
	state.free = pause_free
 | 
			
		||||
	state.previous = prev
 | 
			
		||||
	tween_to(&state.list.position.x, 300, 1, ease.Ease.Back_Out)
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	return state
 | 
			
		||||
@ -44,31 +45,11 @@ pause_init :: proc(prev: ^GameState = nil) -> ^GameState {
 | 
			
		||||
pause_update :: proc(state: ^GameState, delta: f32) {
 | 
			
		||||
	menu := transmute(^Pause)state
 | 
			
		||||
	
 | 
			
		||||
	prev_element := cast(i8)menu.active_element
 | 
			
		||||
	cur_element := prev_element
 | 
			
		||||
	menu_list_update(&menu.list)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.DOWN) {
 | 
			
		||||
		cur_element += 1
 | 
			
		||||
	}
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.UP) {
 | 
			
		||||
		cur_element -= 1
 | 
			
		||||
	}
 | 
			
		||||
	if prev_element != cur_element {
 | 
			
		||||
		if cur_element < 0 { cur_element = len(Pause_Buttons) -1 }
 | 
			
		||||
		if cur_element == len(Pause_Buttons) { cur_element = 0 }
 | 
			
		||||
		menu.active_element = cast(Pause_Buttons)cur_element
 | 
			
		||||
		if menu.marker_tween != nil {
 | 
			
		||||
			tween_cancel(menu.marker_tween)
 | 
			
		||||
		}
 | 
			
		||||
		menu.marker_tween = tween_to(
 | 
			
		||||
			&menu.active_marker.y,
 | 
			
		||||
			menu.menu_pos.y + f32(menu.active_element) * menu.menu_element_offset,
 | 
			
		||||
			0.5,
 | 
			
		||||
			ease.Ease.Back_Out,
 | 
			
		||||
		)
 | 
			
		||||
	}
 | 
			
		||||
	if rl.IsKeyPressed(rl.KeyboardKey.ENTER) || rl.IsKeyPressed(rl.KeyboardKey.SPACE) {
 | 
			
		||||
		switch menu.active_element {
 | 
			
		||||
pause_button_pressed :: proc(state: ^GameState, el: Pause_Buttons) {
 | 
			
		||||
	switch el {
 | 
			
		||||
		case .RESUME:
 | 
			
		||||
			stack_pop()
 | 
			
		||||
		case .FULLSCREEN:
 | 
			
		||||
@ -77,22 +58,21 @@ pause_update :: proc(state: ^GameState, delta: f32) {
 | 
			
		||||
			stack_pop()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pause_draw :: proc(state: ^GameState) {
 | 
			
		||||
	menu := transmute(^Pause)state
 | 
			
		||||
 | 
			
		||||
	if state.previous != nil {
 | 
			
		||||
		state.previous->draw()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	TitleFontSize :: 96
 | 
			
		||||
	TitleSpacing :: 3
 | 
			
		||||
	TitleText :: "ПАУЗА"
 | 
			
		||||
	TitleSize := rl.MeasureTextEx(FontTitle, TitleText, TitleFontSize, TitleSpacing)
 | 
			
		||||
	rl.DrawTextPro(FontTitle, "ARKADODGE", {WINDOWF.x - 50, 50}, {TitleSize.x, 0}, 0, 96, 3, rl.WHITE)
 | 
			
		||||
	rl.DrawTextPro(FontTitle, "ПАУЗА", {WINDOWF.x - 50, 50}, {TitleSize.x, 0}, 0, 96, 3, rl.WHITE)
 | 
			
		||||
 | 
			
		||||
	rl.DrawTextEx(FontUI, ">", menu.active_marker + {-30, 0}, 48, 2, rl.WHITE)
 | 
			
		||||
	for el, i in menu_strings {
 | 
			
		||||
		pos := menu.menu_pos + {0, f32(i) * menu.menu_element_offset}
 | 
			
		||||
		rl.DrawTextEx(FontUI, el, pos, 48, 2, rl.WHITE)
 | 
			
		||||
	}
 | 
			
		||||
	menu_list_draw(&menu.list)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pause_free :: proc(state: ^GameState) {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user