mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
examples/tetris: use better unique colors, implement game over/pause
This commit is contained in:
parent
49205dcce3
commit
4760fea489
Binary file not shown.
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 10 KiB |
@ -19,15 +19,16 @@ const (
|
||||
WinWidth = BlockSize * FieldWidth
|
||||
WinHeight = BlockSize * FieldHeight
|
||||
TimerPeriod = 250 // ms
|
||||
TextSize = 12
|
||||
)
|
||||
|
||||
const (
|
||||
const (
|
||||
text_cfg = gx.TextCfg{
|
||||
align:gx.ALIGN_LEFT
|
||||
size:12
|
||||
color:gx.rgb(0, 0, 170)
|
||||
size:TextSize
|
||||
color:gx.rgb(0, 0, 0)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
const (
|
||||
// Tetros' 4 possible states are encoded in binaries
|
||||
@ -68,15 +69,15 @@ const (
|
||||
]
|
||||
// Each tetro has its unique color
|
||||
Colors = [
|
||||
gx.rgb(0, 0, 0),
|
||||
gx.rgb(253, 32, 47),
|
||||
gx.rgb(0, 110, 194),
|
||||
gx.rgb(34, 169, 16),
|
||||
gx.rgb(170, 0, 170),
|
||||
gx.rgb(0, 0, 170),
|
||||
gx.rgb(0, 170, 0),
|
||||
gx.rgb(170, 85, 0),
|
||||
gx.rgb(0, 170, 170),
|
||||
gx.rgb(0, 0, 0), // unused ?
|
||||
gx.rgb(253, 32, 47), // lightred quad
|
||||
gx.rgb(0, 110, 194), // lightblue triple
|
||||
gx.rgb(170, 170, 0), // darkyellow short topright
|
||||
gx.rgb(170, 0, 170), // purple short topleft
|
||||
gx.rgb(50, 90, 110), // darkgrey long topleft
|
||||
gx.rgb(0, 170, 0), // lightgreen long topright
|
||||
gx.rgb(170, 85, 0), // brown longest
|
||||
gx.rgb(0, 170, 170), // unused ?
|
||||
]
|
||||
)
|
||||
|
||||
@ -87,10 +88,15 @@ struct Block {
|
||||
y int
|
||||
}
|
||||
|
||||
enum GameState {
|
||||
paused running gameover
|
||||
}
|
||||
struct Game {
|
||||
mut:
|
||||
// Score of the current game
|
||||
score int
|
||||
// State of the current game
|
||||
state GameState
|
||||
// Position of the current tetro
|
||||
pos_x int
|
||||
pos_y int
|
||||
@ -113,7 +119,7 @@ struct Game {
|
||||
gg *gg.GG
|
||||
// ft context for font drawing
|
||||
ft *freetype.Context
|
||||
font_loaded bool
|
||||
font_loaded bool
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@ -141,8 +147,8 @@ fn main() {
|
||||
use_ortho: true
|
||||
font_size: 18
|
||||
scale: 2
|
||||
})
|
||||
game.font_loaded = (game.ft != 0 )
|
||||
})
|
||||
game.font_loaded = (game.ft != 0 )
|
||||
for {
|
||||
gg.clear(gx.White)
|
||||
game.draw_scene()
|
||||
@ -173,6 +179,7 @@ fn (g mut Game) init_game() {
|
||||
last_row[j] = - 1
|
||||
}
|
||||
g.score = 0
|
||||
g.state = .running
|
||||
}
|
||||
|
||||
fn (g mut Game) parse_tetros() {
|
||||
@ -187,8 +194,10 @@ fn (g mut Game) parse_tetros() {
|
||||
|
||||
fn (g mut Game) run() {
|
||||
for {
|
||||
g.move_tetro()
|
||||
g.delete_completed_lines()
|
||||
if g.state == .running {
|
||||
g.move_tetro()
|
||||
g.delete_completed_lines()
|
||||
}
|
||||
glfw.post_empty_event() // force window redraw
|
||||
time.sleep_ms(TimerPeriod)
|
||||
}
|
||||
@ -206,7 +215,7 @@ fn (g mut Game) move_tetro() {
|
||||
if row[x] != 0 {
|
||||
// The new tetro has no space to drop => end of the game
|
||||
if g.pos_y < 2 {
|
||||
g.init_game()
|
||||
g.state = .gameover
|
||||
return
|
||||
}
|
||||
// Drop it and generate a new one
|
||||
@ -309,8 +318,15 @@ fn (g &Game) draw_field() {
|
||||
}
|
||||
|
||||
fn (g &Game) draw_score() {
|
||||
if g.font_loaded {
|
||||
g.ft.draw_text(1, 2, 'score: ' + g.score.str(), text_cfg)
|
||||
if g.font_loaded {
|
||||
g.ft.draw_text(1, 2, 'score: ' + g.score.str(), text_cfg)
|
||||
if g.state == .gameover {
|
||||
g.ft.draw_text(1, WinHeight / 2 + 0 * TextSize, 'Game Over', text_cfg)
|
||||
g.ft.draw_text(1, WinHeight / 2 + 2 * TextSize, 'SPACE to restart', text_cfg)
|
||||
} else if g.state == .paused {
|
||||
g.ft.draw_text(1, WinHeight / 2 + 0 * TextSize, 'Game Paused', text_cfg)
|
||||
g.ft.draw_text(1, WinHeight / 2 + 2 * TextSize, 'SPACE to resume', text_cfg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,9 +370,25 @@ fn key_down(wnd voidptr, key, code, action, mods int) {
|
||||
}
|
||||
// Fetch the game object stored in the user pointer
|
||||
mut game := &Game(glfw.get_window_user_pointer(wnd))
|
||||
// global keys
|
||||
switch key {
|
||||
case glfw.KEY_ESCAPE:
|
||||
glfw.set_should_close(wnd, true)
|
||||
case GLFW_KEY_SPACE:
|
||||
if game.state == .running {
|
||||
game.state = .paused
|
||||
} else if game.state == .paused {
|
||||
game.state = .running
|
||||
} else if game.state == .gameover {
|
||||
game.init_game()
|
||||
game.state = .running
|
||||
}
|
||||
}
|
||||
if game.state != .running {
|
||||
return
|
||||
}
|
||||
// keys while game is running
|
||||
switch key {
|
||||
case glfw.KeyUp:
|
||||
// Rotate the tetro
|
||||
old_rotation_idx := game.rotation_idx
|
||||
|
@ -35,7 +35,7 @@ import const (
|
||||
)
|
||||
|
||||
import const (
|
||||
GLFW_KEY_ENTER
|
||||
GLFW_KEY_SPACE
|
||||
GLFW_KEY_A
|
||||
GLFW_KEY_B
|
||||
GLFW_KEY_P
|
||||
@ -49,7 +49,6 @@ import const (
|
||||
GLFW_KEY_Z
|
||||
GLFW_KEY_UP
|
||||
GLFW_KEY_DOWN
|
||||
GLFW_KEY_UP
|
||||
GLFW_KEY_LEFT
|
||||
GLFW_KEY_RIGHT
|
||||
GLFW_KEY_BACKSPACE
|
||||
|
Loading…
Reference in New Issue
Block a user