Compare commits

...

1 Commits

Author SHA1 Message Date
Nefrace 45153ae418 Moved tweens to NTween 2024-11-04 22:26:42 +03:00
8 changed files with 172 additions and 165 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "ntween"]
path = ntween
url = https://git.nefrace.ru/nefrace/ntween.git

View File

@ -1,13 +1,14 @@
package main package main
import rl "vendor:raylib"
import "core:math/ease" import "core:math/ease"
import "ntween"
import rl "vendor:raylib"
GameOver :: struct { GameOver :: struct {
using state: GameState, using state: GameState,
position: Vec2, position: Vec2,
size: Vec2, size: Vec2,
ready_to_go: bool, ready_to_go: bool,
} }
@ -21,8 +22,16 @@ gameover_init :: proc(prev: ^GameState = nil) -> ^GameState {
state.free = gameover_free state.free = gameover_free
state.previous = prev state.previous = prev
tween_to(&state.position.y, WINDOWF.y / 2, 1, ease.Ease.Back_Out, state, gameover_ready) ntween.animate(
&v2tween,
&state.position,
WINDOWF.y,
1,
ease.Ease.Back_Out,
state,
gameover_ready,
)
return state return state
} }
@ -32,7 +41,7 @@ gameover_update :: proc(state: ^GameState, delta: f32) {
if rl.IsKeyPressed(rl.KeyboardKey.ESCAPE) { if rl.IsKeyPressed(rl.KeyboardKey.ESCAPE) {
stack_pop() stack_pop()
stack_pop() stack_pop()
return return
} }
if rl.IsKeyPressed(rl.KeyboardKey.ENTER) { if rl.IsKeyPressed(rl.KeyboardKey.ENTER) {
stack_pop() stack_pop()
@ -45,7 +54,7 @@ gameover_update :: proc(state: ^GameState, delta: f32) {
gameover_draw :: proc(state: ^GameState) { gameover_draw :: proc(state: ^GameState) {
gameover := transmute(^GameOver)state gameover := transmute(^GameOver)state
if state.previous != nil { if state.previous != nil {
state.previous->draw() state.previous->draw()
} }
@ -55,7 +64,11 @@ gameover_draw :: proc(state: ^GameState) {
TitleText :: "ИГРА ОКОНЧЕНА" TitleText :: "ИГРА ОКОНЧЕНА"
TitleSize := rl.MeasureTextEx(FontTitle, TitleText, TitleFontSize, TitleSpacing) TitleSize := rl.MeasureTextEx(FontTitle, TitleText, TitleFontSize, TitleSpacing)
SubtitleText := [3]cstring{"Нажмите Enter", "чтобы начать сначала", "Или Escape для выхода"} SubtitleText := [3]cstring {
"Нажмите Enter",
"чтобы начать сначала",
"Или Escape для выхода",
}
SubtitleFontSize :: 48 SubtitleFontSize :: 48
SubtitleSpacing :: 2 SubtitleSpacing :: 2
SubtitleSizes := [3]Vec2{} SubtitleSizes := [3]Vec2{}
@ -63,12 +76,34 @@ gameover_draw :: proc(state: ^GameState) {
SubtitleSizes = rl.MeasureTextEx(FontUI, c, SubtitleFontSize, SubtitleSpacing) SubtitleSizes = rl.MeasureTextEx(FontUI, c, SubtitleFontSize, SubtitleSpacing)
} }
rl.DrawRectangleV(gameover.position - gameover.size / 2, gameover.size, rl.Color{90, 30, 150, 255})
rl.DrawTextPro(FontTitle, TitleText, gameover.position - {0, 100}, TitleSize / 2, 0, TitleFontSize, TitleSpacing, rl.WHITE) rl.DrawRectangleV(
gameover.position - gameover.size / 2,
gameover.size,
rl.Color{90, 30, 150, 255},
)
rl.DrawTextPro(
FontTitle,
TitleText,
gameover.position - {0, 100},
TitleSize / 2,
0,
TitleFontSize,
TitleSpacing,
rl.WHITE,
)
for c, i in SubtitleText { for c, i in SubtitleText {
rl.DrawTextPro(FontUI, c, gameover.position - {0, f32(10 - i * 50)}, SubtitleSizes[i] / 2, 0, SubtitleFontSize, SubtitleSpacing, rl.WHITE) rl.DrawTextPro(
FontUI,
c,
gameover.position - {0, f32(10 - i * 50)},
SubtitleSizes[i] / 2,
0,
SubtitleFontSize,
SubtitleSpacing,
rl.WHITE,
)
} }
@ -82,3 +117,4 @@ gameover_ready :: proc(state: rawptr) {
gameover := transmute(^GameOver)state gameover := transmute(^GameOver)state
gameover.ready_to_go = true gameover.ready_to_go = true
} }

View File

@ -1,13 +1,14 @@
package main package main
import rl "vendor:raylib"
import "core:math/ease" import "core:math/ease"
import "ntween"
import rl "vendor:raylib"
LevelDone :: struct { LevelDone :: struct {
using state: GameState, using state: GameState,
position: Vec2, position: Vec2,
size: Vec2, size: Vec2,
ready_to_go: bool, ready_to_go: bool,
} }
@ -21,8 +22,16 @@ leveldone_init :: proc(prev: ^GameState = nil) -> ^GameState {
state.free = leveldone_free state.free = leveldone_free
state.previous = prev state.previous = prev
tween_to(&state.position.y, WINDOWF.y / 2, 1, ease.Ease.Back_Out, state, leveldone_ready) ntween.animate(
&v2tween,
&state.position,
WINDOWF / 2,
1,
ease.Ease.Back_Out,
state,
leveldone_ready,
)
return state return state
} }
@ -61,11 +70,33 @@ leveldone_draw :: proc(state: ^GameState) {
SubtitleSpacing :: 2 SubtitleSpacing :: 2
SubtitleSize := rl.MeasureTextEx(FontUI, SubtitleText, SubtitleFontSize, SubtitleSpacing) SubtitleSize := rl.MeasureTextEx(FontUI, SubtitleText, SubtitleFontSize, SubtitleSpacing)
rl.DrawRectangleV(leveldone.position - leveldone.size / 2, leveldone.size, rl.Color{90, 30, 150, 255})
rl.DrawTextPro(FontTitle, TitleText, leveldone.position - {0, 50}, TitleSize / 2, 0, TitleFontSize, TitleSpacing, rl.WHITE) rl.DrawRectangleV(
rl.DrawTextPro(FontUI, SubtitleText, leveldone.position + {0, 20}, SubtitleSize / 2, 0, SubtitleFontSize, SubtitleSpacing, rl.WHITE) leveldone.position - leveldone.size / 2,
leveldone.size,
rl.Color{90, 30, 150, 255},
)
rl.DrawTextPro(
FontTitle,
TitleText,
leveldone.position - {0, 50},
TitleSize / 2,
0,
TitleFontSize,
TitleSpacing,
rl.WHITE,
)
rl.DrawTextPro(
FontUI,
SubtitleText,
leveldone.position + {0, 20},
SubtitleSize / 2,
0,
SubtitleFontSize,
SubtitleSpacing,
rl.WHITE,
)
} }
@ -77,3 +108,4 @@ leveldone_ready :: proc(state: rawptr) {
leveldone := transmute(^LevelDone)state leveldone := transmute(^LevelDone)state
leveldone.ready_to_go = true leveldone.ready_to_go = true
} }

View File

@ -1,36 +1,45 @@
package main package main
import "core:fmt"
import "core:slice"
import "ntween"
import rl "vendor:raylib" import rl "vendor:raylib"
import rlgl "vendor:raylib/rlgl" import rlgl "vendor:raylib/rlgl"
import "core:slice"
import "core:fmt"
import "core:math/ease" import "core:math/ease"
Vec2 :: [2]f32 Vec2 :: [2]f32
Vec2i :: [2]i32 Vec2i :: [2]i32
WINDOW : Vec2i WINDOW: Vec2i
WINDOWF : Vec2 WINDOWF: Vec2
FontTitle : rl.Font FontTitle: rl.Font
FontUI: rl.Font FontUI: rl.Font
WindowShouldExit := false WindowShouldExit := false
f32tween: ntween.Tween_Map(f32)
v2tween: ntween.Tween_Map(Vec2)
main :: proc() { main :: proc() {
rl.SetConfigFlags(rl.ConfigFlags{.FULLSCREEN_MODE, .VSYNC_HINT, }) rl.SetConfigFlags(rl.ConfigFlags{.FULLSCREEN_MODE, .VSYNC_HINT})
monitor := rl.GetCurrentMonitor() monitor := rl.GetCurrentMonitor()
rl.InitWindow(0, 0, "SinePong") rl.InitWindow(0, 0, "SinePong")
rl.SetTargetFPS(9999) rl.SetTargetFPS(9999)
tween_init() f32tween = ntween.init(f32)
defer tween_clean() v2tween = ntween.init(Vec2)
defer {
ntween.destroy_tweens(&f32tween)
ntween.destroy_tweens(&v2tween)
}
FontUI = rl.LoadFontEx("assets/monogram-extended.ttf", 96, nil, 2048) FontUI = rl.LoadFontEx("assets/monogram-extended.ttf", 96, nil, 2048)
// FontUI = rl.LoadFont("assets/monogram-extended.ttf") // FontUI = rl.LoadFont("assets/monogram-extended.ttf")
FontTitle = rl.LoadFontEx("assets/monogram-extended.ttf", 96*2, nil, 2048) FontTitle = rl.LoadFontEx("assets/monogram-extended.ttf", 96 * 2, nil, 2048)
defer rl.UnloadFont(FontTitle) defer rl.UnloadFont(FontTitle)
defer rl.UnloadFont(FontUI) defer rl.UnloadFont(FontUI)
rl.SetTextureFilter(FontUI.texture, rl.TextureFilter.POINT) rl.SetTextureFilter(FontUI.texture, rl.TextureFilter.POINT)
@ -47,7 +56,7 @@ main :: proc() {
state->free() state->free()
} }
} }
game := game_init() game := game_init()
menu := menu_init() menu := menu_init()
append(&state_stack, menu) append(&state_stack, menu)
@ -59,10 +68,11 @@ main :: proc() {
WINDOWF = Vec2{f32(WINDOW.x), f32(WINDOW.y)} WINDOWF = Vec2{f32(WINDOW.x), f32(WINDOW.y)}
} }
current_state := state_stack[len(state_stack)-1] current_state := state_stack[len(state_stack) - 1]
delta := rl.GetFrameTime() delta := rl.GetFrameTime()
tweens_process(delta) ntween.process(&f32tween, delta)
ntween.process(&v2tween, delta)
current_state->update(delta) current_state->update(delta)
{ {
@ -76,7 +86,6 @@ main :: proc() {
} }
/* /*
TODO: TODO:
@ -92,3 +101,4 @@ main :: proc() {
[ ] Звуки [ ] Звуки
*/ */

View File

@ -1,21 +1,22 @@
package main package main
import rl "vendor:raylib"
import "core:math/ease"
import "core:fmt" import "core:fmt"
import "core:math/ease"
import "ntween"
import rl "vendor:raylib"
MenuList :: struct($T: typeid) { MenuList :: struct($T: typeid) {
state: ^GameState, state: ^GameState,
position: Vec2, position: Vec2,
line_size: f32, line_size: f32,
font_size: f32, font_size: f32,
active_element: T, active_element: T,
active_marker: Vec2, active_marker: Vec2,
tween: ^Tween, tween: ^ntween.Tween(f32),
elements: ^[T]cstring, elements: ^[T]cstring,
menu_pressed: proc(state: ^GameState, element: T), menu_pressed: proc(state: ^GameState, element: T),
background: rl.Color, background: rl.Color,
mouse_pos: Vec2, mouse_pos: Vec2,
} }
@ -29,14 +30,12 @@ menu_list_update :: proc(list: ^MenuList($T)) {
list.mouse_pos = rl.GetMousePosition() list.mouse_pos = rl.GetMousePosition()
size := menu_list_get_size(list) size := menu_list_get_size(list)
if rl.CheckCollisionPointRec(list.mouse_pos, rl.Rectangle{ if rl.CheckCollisionPointRec(
x = list.position.x, list.mouse_pos,
y = list.position.y, rl.Rectangle{x = list.position.x, y = list.position.y, width = size.x, height = size.y},
width = size.x, ) {
height = size.y,
}) {
if last_mouse_pos != list.mouse_pos { if last_mouse_pos != list.mouse_pos {
mouse_relative := list.mouse_pos - list.position mouse_relative := list.mouse_pos - list.position
cur_element = i8(mouse_relative.y / list.line_size) cur_element = i8(mouse_relative.y / list.line_size)
fmt.println(cur_element) fmt.println(cur_element)
} }
@ -47,7 +46,6 @@ menu_list_update :: proc(list: ^MenuList($T)) {
last_mouse_pos = list.mouse_pos last_mouse_pos = list.mouse_pos
if rl.IsKeyPressed(rl.KeyboardKey.DOWN) { if rl.IsKeyPressed(rl.KeyboardKey.DOWN) {
cur_element += 1 cur_element += 1
} }
@ -55,13 +53,14 @@ menu_list_update :: proc(list: ^MenuList($T)) {
cur_element -= 1 cur_element -= 1
} }
if prev_element != cur_element { if prev_element != cur_element {
if cur_element < 0 { cur_element = len(T) -1 } if cur_element < 0 {cur_element = len(T) - 1}
if cur_element == len(T) { cur_element = 0 } if cur_element == len(T) {cur_element = 0}
list.active_element = cast(T)cur_element list.active_element = cast(T)cur_element
if list.tween != nil { if list.tween != nil {
tween_cancel(list.tween) ntween.cancel(list.tween)
} }
list.tween = tween_to( list.tween = ntween.animate(
&f32tween,
&list.active_marker.y, &list.active_marker.y,
f32(list.active_element) * list.line_size, f32(list.active_element) * list.line_size,
0.25, 0.25,
@ -97,3 +96,4 @@ menu_list_get_size :: proc(list: ^MenuList($T)) -> Vec2 {
} }
return size return size
} }

1
ntween Submodule

@ -0,0 +1 @@
Subproject commit 7136c68f3e63470b9b1c80109dd0904151e08070

View File

@ -1,49 +1,49 @@
package main package main
import rl "vendor:raylib"
import "core:math/ease" import "core:math/ease"
import "ntween"
import rl "vendor:raylib"
Pause_Buttons :: enum { Pause_Buttons :: enum {
RESUME, RESUME,
EXIT EXIT,
} }
pause_strings := [Pause_Buttons]cstring { pause_strings := [Pause_Buttons]cstring {
.RESUME = "Продолжить", .RESUME = "Продолжить",
.EXIT = "Выход" .EXIT = "Выход",
} }
Pause :: struct { Pause :: struct {
using state: GameState, using state: GameState,
list: MenuList(Pause_Buttons),
list: MenuList(Pause_Buttons)
} }
pause_init :: proc(prev: ^GameState = nil) -> ^GameState { pause_init :: proc(prev: ^GameState = nil) -> ^GameState {
state := new(Pause) state := new(Pause)
state.variant = state state.variant = state
state.list = MenuList(Pause_Buttons){ state.list = MenuList(Pause_Buttons) {
position = {-300, 300}, position = {-300, 300},
line_size = 60, line_size = 60,
font_size = 42, font_size = 42,
elements = &pause_strings, elements = &pause_strings,
menu_pressed = pause_button_pressed, menu_pressed = pause_button_pressed,
background = rl.Color{50, 10, 110, 180}, background = rl.Color{50, 10, 110, 180},
} }
state.update = pause_update state.update = pause_update
state.draw = pause_draw state.draw = pause_draw
state.free = pause_free state.free = pause_free
state.previous = prev state.previous = prev
tween_to(&state.list.position.x, 300, 1, ease.Ease.Back_Out) ntween.animate(&f32tween, &state.list.position.x, 300, 1, ease.Ease.Back_Out)
return state return state
} }
pause_update :: proc(state: ^GameState, delta: f32) { pause_update :: proc(state: ^GameState, delta: f32) {
menu := transmute(^Pause)state menu := transmute(^Pause)state
if rl.IsKeyPressed(rl.KeyboardKey.ESCAPE) { if rl.IsKeyPressed(rl.KeyboardKey.ESCAPE) {
stack_pop() stack_pop()
return return
@ -53,11 +53,11 @@ pause_update :: proc(state: ^GameState, delta: f32) {
pause_button_pressed :: proc(state: ^GameState, el: Pause_Buttons) { pause_button_pressed :: proc(state: ^GameState, el: Pause_Buttons) {
switch el { switch el {
case .RESUME: case .RESUME:
stack_pop() stack_pop()
case .EXIT: case .EXIT:
stack_pop() stack_pop()
stack_pop() stack_pop()
} }
} }
@ -72,7 +72,16 @@ pause_draw :: proc(state: ^GameState) {
TitleSpacing :: 3 TitleSpacing :: 3
TitleText :: "ПАУЗА" TitleText :: "ПАУЗА"
TitleSize := rl.MeasureTextEx(FontTitle, TitleText, TitleFontSize, TitleSpacing) TitleSize := rl.MeasureTextEx(FontTitle, TitleText, TitleFontSize, TitleSpacing)
rl.DrawTextPro(FontTitle, "ПАУЗА", {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,
)
menu_list_draw(&menu.list) menu_list_draw(&menu.list)
} }
@ -81,3 +90,4 @@ pause_free :: proc(state: ^GameState) {
pause := transmute(^Pause)state pause := transmute(^Pause)state
free(state) free(state)
} }

View File

@ -1,85 +0,0 @@
package main
import "core:math"
import "core:math/ease"
import "core:math/linalg"
import "core:slice"
Tween :: struct {
ptr: ^f32,
from: f32,
to: f32,
time: f32,
duration: f32,
ease_type: ease.Ease,
active: bool,
finished: proc(data: rawptr),
data: rawptr
}
TWEEN_SIZE :: 128
tweens_buf: [TWEEN_SIZE]^Tween
tweens : [dynamic]^Tween
tween_init :: proc() {
tweens = slice.into_dynamic(tweens_buf[:])
}
tween_clean :: proc() {
for tween, i in tweens {
free(tween)
}
}
tween_to :: proc(
value: ^f32, to: f32, duration: f32,
ease: ease.Ease = ease.Ease.Quartic_In_Out,
data: rawptr = nil,
callback: proc(data: rawptr) = nil
) -> ^Tween {
tween := new(Tween)
tween.ptr = value
tween.from = value^
tween.to = to
tween.duration = duration
tween.ease_type = ease
tween.active = true
tween.data = data
tween.finished = callback
append(&tweens, tween)
return tween
}
tween_cancel :: proc(t: ^Tween) {
t.active = false
}
tweens_process :: proc(delta: f32) {
#reverse for tween, i in tweens {
tween.time += delta
p := clamp(tween.time / tween.duration, 0, 1)
val := ease.ease(tween.ease_type, p)
if tween.ptr != nil {
tween.ptr^ = math.lerp(tween.from, tween.to, val)
} else {
tween.active = false
}
if tween.time >= tween.duration {
tween.active = false
if tween.finished != nil {
tween.finished(tween.data)
}
}
if !tween.active {
free(tween)
unordered_remove(&tweens, i)
}
}
}