Skip to content

Commit e9a4312

Browse files
committed
examples: cleanup snek.v, by using math.vec, the builtin array support, instead of datatypes, and by removing casts that are no longer needed
1 parent 1ba8021 commit e9a4312

File tree

1 file changed

+50
-84
lines changed

1 file changed

+50
-84
lines changed

examples/snek/snek.v

+50-84
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import datatypes
21
import gg
32
import gx
43
import os
54
import rand
65
import time
6+
import math.vec { Vec2 }
77

88
// constants
9+
const font = $embed_file('../assets/fonts/RobotoMono-Regular.ttf')
910
const top_height = 100
1011
const canvas_size = 700
1112
const game_size = 17
@@ -14,20 +15,8 @@ const tick_rate_ms = 100
1415
const high_score_file_path = os.join_path(os.cache_dir(), 'v', 'examples', 'snek')
1516

1617
// types
17-
struct Vec {
18-
x int
19-
y int
20-
}
21-
22-
fn (a Vec) + (b Vec) Vec {
23-
return Vec{a.x + b.x, a.y + b.y}
24-
}
25-
26-
fn (a Vec) - (b Vec) Vec {
27-
return Vec{a.x - b.x, a.y - b.y}
28-
}
29-
3018
type HighScore = int
19+
type Vec = Vec2[int]
3120

3221
fn (mut h HighScore) save() {
3322
os.mkdir_all(os.dir(high_score_file_path)) or { return }
@@ -45,22 +34,17 @@ mut:
4534
best HighScore
4635
snake []Vec
4736
dir Vec
48-
dir_queue datatypes.Queue[Vec]
37+
dir_queue []Vec
4938
food Vec
5039
last_tick i64
5140
}
5241

5342
// utility
5443
fn (mut app App) reset_game() {
5544
app.score = 0
56-
app.snake = [
57-
Vec{3, 8},
58-
Vec{2, 8},
59-
Vec{1, 8},
60-
Vec{0, 8},
61-
]
45+
app.snake = [Vec{3, 8}, Vec{2, 8}, Vec{1, 8}, Vec{0, 8}]
6246
app.dir = Vec{1, 0}
63-
app.dir_queue = datatypes.Queue[Vec]{}
47+
app.dir_queue = []
6448
app.food = Vec{10, 8}
6549
app.last_tick = time.ticks()
6650
}
@@ -70,35 +54,12 @@ fn (mut app App) move_food() {
7054
x := rand.intn(game_size) or { 0 }
7155
y := rand.intn(game_size) or { 0 }
7256
app.food = Vec{x, y}
73-
7457
if app.food !in app.snake {
7558
return
7659
}
7760
}
7861
}
7962

80-
// events
81-
fn on_keydown(key gg.KeyCode, mod gg.Modifier, mut app App) {
82-
dir := match key {
83-
.w, .up {
84-
Vec{0, -1}
85-
}
86-
.s, .down {
87-
Vec{0, 1}
88-
}
89-
.a, .left {
90-
Vec{-1, 0}
91-
}
92-
.d, .right {
93-
Vec{1, 0}
94-
}
95-
else {
96-
return
97-
}
98-
}
99-
app.dir_queue.push(dir)
100-
}
101-
10263
fn on_frame(mut app App) {
10364
// check if snake bit itself
10465
if app.snake[0] in app.snake[1..] {
@@ -110,10 +71,10 @@ fn on_frame(mut app App) {
11071
|| app.snake[0].y >= game_size {
11172
app.reset_game()
11273
}
113-
11474
progress := f32_min(1, f32(time.ticks() - app.last_tick) / f32(tick_rate_ms))
115-
app.gg.begin()
11675

76+
// draw everything:
77+
app.gg.begin()
11778
// draw food
11879
app.gg.draw_rect_filled(tile_size * app.food.x, tile_size * app.food.y + top_height,
11980
tile_size, tile_size, gx.red)
@@ -126,16 +87,14 @@ fn on_frame(mut app App) {
12687

12788
// draw partial head
12889
head := app.snake[0]
129-
app.gg.draw_rect_filled(int(tile_size * (head.x + app.dir.x * progress)),
130-
int(tile_size * (head.y + app.dir.y * progress)) + top_height, tile_size, tile_size,
131-
gx.blue)
90+
app.gg.draw_rect_filled(tile_size * (head.x + app.dir.x * progress), tile_size * (head.y +
91+
app.dir.y * progress) + top_height, tile_size, tile_size, gx.blue)
13292

13393
// draw partial tail
13494
tail := app.snake.last()
13595
tail_dir := app.snake[app.snake.len - 2] - tail
136-
app.gg.draw_rect_filled(int(tile_size * (tail.x + tail_dir.x * progress)),
137-
int(tile_size * (tail.y + tail_dir.y * progress)) + top_height, tile_size, tile_size,
138-
gx.blue)
96+
app.gg.draw_rect_filled(tile_size * (tail.x + tail_dir.x * progress), tile_size * (tail.y +
97+
tail_dir.y * progress) + top_height, tile_size, tile_size, gx.blue)
13998

14099
// draw score bar
141100
app.gg.draw_rect_filled(0, 0, canvas_size, top_height, gx.black)
@@ -156,11 +115,8 @@ fn on_frame(mut app App) {
156115
// "snake" along
157116
mut prev := app.snake[0]
158117
app.snake[0] = app.snake[0] + app.dir
159-
160118
for i in 1 .. app.snake.len {
161-
tmp := app.snake[i]
162-
app.snake[i] = prev
163-
prev = tmp
119+
app.snake[i], prev = prev, app.snake[i]
164120
}
165121

166122
// add tail segment if food has been eaten
@@ -174,7 +130,8 @@ fn on_frame(mut app App) {
174130
app.move_food()
175131
}
176132

177-
if dir := app.dir_queue.pop() {
133+
if app.dir_queue.len > 0 {
134+
dir := app.dir_queue.pop()
178135
if dir.x != -app.dir.x || dir.y != -app.dir.y {
179136
app.dir = dir
180137
}
@@ -186,31 +143,40 @@ fn on_frame(mut app App) {
186143
app.gg.end()
187144
}
188145

189-
const font = $embed_file('../assets/fonts/RobotoMono-Regular.ttf')
190-
191-
// setup
192-
fn main() {
193-
mut app := App{}
194-
app.reset_game()
195-
app.best.load()
196-
197-
mut font_copy := font
198-
font_bytes := unsafe {
199-
font_copy.data().vbytes(font_copy.len)
146+
// events
147+
fn on_keydown(key gg.KeyCode, mod gg.Modifier, mut app App) {
148+
app.dir_queue << match key {
149+
.w, .up {
150+
Vec{0, -1}
151+
}
152+
.s, .down {
153+
Vec{0, 1}
154+
}
155+
.a, .left {
156+
Vec{-1, 0}
157+
}
158+
.d, .right {
159+
Vec{1, 0}
160+
}
161+
else {
162+
return
163+
}
200164
}
201-
202-
app.gg = gg.new_context(
203-
bg_color: gx.white
204-
frame_fn: on_frame
205-
keydown_fn: on_keydown
206-
user_data: &app
207-
width: canvas_size
208-
height: top_height + canvas_size
209-
create_window: true
210-
resizable: false
211-
window_title: 'snek'
212-
font_bytes_normal: font_bytes
213-
)
214-
215-
app.gg.run()
216165
}
166+
167+
mut app := App{}
168+
app.reset_game()
169+
app.best.load()
170+
171+
mut font_copy := font
172+
app.gg = gg.new_context(
173+
bg_color: gx.white
174+
frame_fn: on_frame
175+
keydown_fn: on_keydown
176+
user_data: &app
177+
width: canvas_size
178+
height: top_height + canvas_size
179+
window_title: 'snek'
180+
font_bytes_normal: unsafe { font_copy.data().vbytes(font_copy.len) }
181+
)
182+
app.gg.run()

0 commit comments

Comments
 (0)