Fix game over panic

This commit is contained in:
Pavle Portic 2024-01-30 20:13:51 +01:00
parent 545a76109e
commit 6f5081ab57
Signed by: TheEdgeOfRage
GPG Key ID: 66AD4BA646FBC0D2
4 changed files with 53 additions and 31 deletions

View File

@ -21,12 +21,12 @@ func InitBoard() *Board {
board := &Board{ board := &Board{
NextPiece: elements.GetRandomPiece(), NextPiece: elements.GetRandomPiece(),
} }
board.getNextPiece() _ = board.getNextPiece()
return board return board
} }
func (b *Board) getNextPiece() bool { func (b *Board) getNextPiece() error {
b.AlreadyHeld = false b.AlreadyHeld = false
b.ActivePiecePos = rl.NewVector2(5, 0) b.ActivePiecePos = rl.NewVector2(5, 0)
b.ActivePiece = b.NextPiece b.ActivePiece = b.NextPiece
@ -34,20 +34,25 @@ func (b *Board) getNextPiece() bool {
for _, block := range b.ActivePiece.Blocks { for _, block := range b.ActivePiece.Blocks {
newX, newY := b.ActivePiecePos.X+block.Position.X, b.ActivePiecePos.Y+block.Position.Y newX, newY := b.ActivePiecePos.X+block.Position.X, b.ActivePiecePos.Y+block.Position.Y
if newY >= 0 && b.Board[int(newX)][int(newY)] != nil { if newY >= 0 && b.Board[int(newX)][int(newY)] != nil {
return true return ErrGameOver
} }
} }
return false return nil
} }
func (b *Board) setBlocksFromActivePiece() { func (b *Board) setBlocksFromActivePiece() error {
for _, block := range b.ActivePiece.Blocks { for _, block := range b.ActivePiece.Blocks {
newX, newY := b.ActivePiecePos.X+block.Position.X, b.ActivePiecePos.Y+block.Position.Y newX, newY := b.ActivePiecePos.X+block.Position.X, b.ActivePiecePos.Y+block.Position.Y
if newY < 0 {
return ErrGameOver
}
b.Board[int(newX)][int(newY)] = &elements.Block{ b.Board[int(newX)][int(newY)] = &elements.Block{
Position: rl.NewVector2(newX, newY), Position: rl.NewVector2(newX, newY),
Color: b.ActivePiece.Blocks[0].Color, Color: b.ActivePiece.Blocks[0].Color,
} }
} }
return nil
} }
func (b *Board) checkHorizontalCollision(left bool) bool { func (b *Board) checkHorizontalCollision(left bool) bool {
@ -73,37 +78,43 @@ func (b *Board) checkHorizontalCollision(left bool) bool {
return false return false
} }
func (b *Board) descendActivePiece() bool { func (b *Board) descendActivePiece() (bool, error) {
b.ActivePiecePos.Y += 1 b.ActivePiecePos.Y += 1
for _, activeBlock := range b.ActivePiece.Blocks { for _, activeBlock := range b.ActivePiece.Blocks {
if b.ActivePiecePos.Y+activeBlock.Position.Y == 20 { if b.ActivePiecePos.Y+activeBlock.Position.Y == 20 ||
b.Board[int(b.ActivePiecePos.X+activeBlock.Position.X)][int(b.ActivePiecePos.Y+activeBlock.Position.Y)] != nil {
b.ActivePiecePos.Y -= 1 b.ActivePiecePos.Y -= 1
b.setBlocksFromActivePiece() return true, b.setBlocksFromActivePiece()
return true
}
if b.Board[int(b.ActivePiecePos.X+activeBlock.Position.X)][int(b.ActivePiecePos.Y+activeBlock.Position.Y)] != nil {
b.ActivePiecePos.Y -= 1
b.setBlocksFromActivePiece()
return true
} }
} }
return false return false, nil
} }
// DescendActivePiece moves the piece down by one block. If the piece cannot move down, it will be placed on the board. // DescendActivePiece moves the piece down by one block. If the piece cannot move down, it will be placed on the board.
// After that, a new piece will be generated. If the new piece cannot be placed, true is returned. // After that, a new piece will be generated. If the new piece cannot be placed, a game over error is returned.
func (b *Board) DescendActivePiece() bool { func (b *Board) DescendActivePiece() error {
if b.descendActivePiece() { placed, err := b.descendActivePiece()
if err != nil {
return err
}
if placed {
return b.getNextPiece() return b.getNextPiece()
} }
return false return nil
} }
// DropActivePiece moves the piece down until it cannot move down anymore. After that, a new piece will be generated. // DropActivePiece moves the piece down until it cannot move down anymore. After that, a new piece will be generated.
// If the new piece cannot be placed, true is returned. // If the new piece cannot be placed, a game over error is returned.
func (b *Board) DropActivePiece() bool { func (b *Board) DropActivePiece() error {
for !b.descendActivePiece() { for {
placed, err := b.descendActivePiece()
if err != nil {
return err
}
if placed {
break
}
} }
return b.getNextPiece() return b.getNextPiece()
} }
@ -197,7 +208,7 @@ func (b *Board) HoldPiece() {
b.AlreadyHeld = true b.AlreadyHeld = true
if b.HeldPiece == nil { if b.HeldPiece == nil {
b.HeldPiece = b.ActivePiece b.HeldPiece = b.ActivePiece
b.getNextPiece() _ = b.getNextPiece()
return return
} }
b.HeldPiece, b.ActivePiece = b.ActivePiece, b.HeldPiece b.HeldPiece, b.ActivePiece = b.ActivePiece, b.HeldPiece

View File

@ -1,11 +1,13 @@
package game package game
import ( import (
"gitea.theedgeofrage.com/theedgeofrage/yeetris/elements"
"github.com/gen2brain/raylib-go/raylib" "github.com/gen2brain/raylib-go/raylib"
"github.com/go-errors/errors"
"gitea.theedgeofrage.com/theedgeofrage/yeetris/elements"
) )
const DEBUG = false var ErrGameOver = errors.New("game over")
// Game type // Game type
type Game struct { type Game struct {
@ -33,6 +35,7 @@ func (g *Game) Init() {
} }
func (g *Game) Update() { func (g *Game) Update() {
var err error
defer g.Board.ClearLines() defer g.Board.ClearLines()
if g.GameOver { if g.GameOver {
if rl.IsKeyPressed(rl.KeyEnter) { if rl.IsKeyPressed(rl.KeyEnter) {
@ -62,13 +65,16 @@ func (g *Game) Update() {
g.Board.RotateActivePiece(true) g.Board.RotateActivePiece(true)
} }
if rl.IsKeyPressed(rl.KeyN) { if rl.IsKeyPressed(rl.KeyN) {
g.Board.DescendActivePiece() err = g.Board.DescendActivePiece()
} }
if rl.IsKeyPressed(rl.KeySpace) { if rl.IsKeyPressed(rl.KeySpace) {
g.Board.DropActivePiece() err = g.Board.DropActivePiece()
} }
if g.FramesCounter%g.TickRate == 0 && !DEBUG { if g.FramesCounter%g.TickRate == 0 {
g.Board.DescendActivePiece() err = g.Board.DescendActivePiece()
}
if errors.Is(err, ErrGameOver) {
g.GameOver = true
} }
g.FramesCounter++ g.FramesCounter++
} }

5
go.mod
View File

@ -2,7 +2,10 @@ module gitea.theedgeofrage.com/theedgeofrage/yeetris
go 1.21.6 go 1.21.6
require github.com/gen2brain/raylib-go/raylib v0.0.0-20240125111008-83d871a38f28 require (
github.com/gen2brain/raylib-go/raylib v0.0.0-20240125111008-83d871a38f28
github.com/go-errors/errors v1.5.1
)
require ( require (
github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa // indirect github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa // indirect

2
go.sum
View File

@ -2,5 +2,7 @@ github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa h1:Ik7
github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= github.com/ebitengine/purego v0.6.0-alpha.1.0.20231122024802-192c5e846faa/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/gen2brain/raylib-go/raylib v0.0.0-20240125111008-83d871a38f28 h1:e0HOaKlvsdC0ZtfWbEaaWAxYTSxUZoCAFS36jLfsVRA= github.com/gen2brain/raylib-go/raylib v0.0.0-20240125111008-83d871a38f28 h1:e0HOaKlvsdC0ZtfWbEaaWAxYTSxUZoCAFS36jLfsVRA=
github.com/gen2brain/raylib-go/raylib v0.0.0-20240125111008-83d871a38f28/go.mod h1:P/hDjVwz/9fhR0ww3+umzDpDA7Bf7Tce4xNChHIEFqE= github.com/gen2brain/raylib-go/raylib v0.0.0-20240125111008-83d871a38f28/go.mod h1:P/hDjVwz/9fhR0ww3+umzDpDA7Bf7Tce4xNChHIEFqE=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=