Implement next and hold
This commit is contained in:
parent
d22fa6e189
commit
545a76109e
|
@ -8,7 +8,7 @@ type Piece struct {
|
|||
Blocks []*Block
|
||||
}
|
||||
|
||||
var Pieces = []*Piece{
|
||||
var Pieces = []Piece{
|
||||
{
|
||||
Blocks: []*Block{
|
||||
{rl.NewVector2(-1, 0), Cyan, false},
|
||||
|
@ -67,8 +67,24 @@ var Pieces = []*Piece{
|
|||
},
|
||||
}
|
||||
|
||||
func (p *Piece) Draw(pos rl.Vector2, scale rl.Vector2, offset rl.Vector2) {
|
||||
func (p Piece) Draw(pos rl.Vector2, scale rl.Vector2, offset rl.Vector2) {
|
||||
for _, block := range p.Blocks {
|
||||
block.Draw(pos, scale, offset)
|
||||
}
|
||||
}
|
||||
|
||||
func GetRandomPiece() *Piece {
|
||||
base := Pieces[rl.GetRandomValue(0, int32(len(Pieces)-1))]
|
||||
newPiece := &Piece{
|
||||
Blocks: make([]*Block, 4),
|
||||
}
|
||||
for i, block := range base.Blocks {
|
||||
newPiece.Blocks[i] = &Block{
|
||||
Position: block.Position,
|
||||
Color: block.Color,
|
||||
LongBoi: block.LongBoi,
|
||||
}
|
||||
}
|
||||
|
||||
return newPiece
|
||||
}
|
||||
|
|
100
game/board.go
100
game/board.go
|
@ -7,35 +7,30 @@ import (
|
|||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
type Board interface {
|
||||
DescendActivePiece() bool
|
||||
DropActivePiece() bool
|
||||
MoveActivePiece(direction int)
|
||||
RotateActivePiece(clockwise bool)
|
||||
ClearLines()
|
||||
Draw(offset, scale rl.Vector2)
|
||||
}
|
||||
|
||||
type board struct {
|
||||
type Board struct {
|
||||
Board [10][20]*elements.Block
|
||||
|
||||
ActivePiece *elements.Piece
|
||||
ActivePiecePos rl.Vector2
|
||||
NextPiece *elements.Piece
|
||||
HeldPiece *elements.Piece
|
||||
AlreadyHeld bool
|
||||
}
|
||||
|
||||
var _ Board = (*board)(nil)
|
||||
|
||||
func InitBoard() *board {
|
||||
board := &board{}
|
||||
board.newActivePiece()
|
||||
func InitBoard() *Board {
|
||||
board := &Board{
|
||||
NextPiece: elements.GetRandomPiece(),
|
||||
}
|
||||
board.getNextPiece()
|
||||
|
||||
return board
|
||||
}
|
||||
|
||||
func (b *board) newActivePiece() bool {
|
||||
func (b *Board) getNextPiece() bool {
|
||||
b.AlreadyHeld = false
|
||||
b.ActivePiecePos = rl.NewVector2(5, 0)
|
||||
b.ActivePiece = elements.Pieces[rl.GetRandomValue(0, int32(len(elements.Pieces)-1))]
|
||||
b.ActivePiece = b.NextPiece
|
||||
b.NextPiece = elements.GetRandomPiece()
|
||||
for _, block := range b.ActivePiece.Blocks {
|
||||
newX, newY := b.ActivePiecePos.X+block.Position.X, b.ActivePiecePos.Y+block.Position.Y
|
||||
if newY >= 0 && b.Board[int(newX)][int(newY)] != nil {
|
||||
|
@ -45,7 +40,7 @@ func (b *board) newActivePiece() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (b *board) setBlocksFromActivePiece() {
|
||||
func (b *Board) setBlocksFromActivePiece() {
|
||||
for _, block := range b.ActivePiece.Blocks {
|
||||
newX, newY := b.ActivePiecePos.X+block.Position.X, b.ActivePiecePos.Y+block.Position.Y
|
||||
b.Board[int(newX)][int(newY)] = &elements.Block{
|
||||
|
@ -55,7 +50,7 @@ func (b *board) setBlocksFromActivePiece() {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *board) checkHorizontalCollision(left bool) bool {
|
||||
func (b *Board) checkHorizontalCollision(left bool) bool {
|
||||
for _, activeBlock := range b.ActivePiece.Blocks {
|
||||
xPos := int(b.ActivePiecePos.X + activeBlock.Position.X)
|
||||
yPos := int(b.ActivePiecePos.Y + activeBlock.Position.Y)
|
||||
|
@ -78,7 +73,7 @@ func (b *board) checkHorizontalCollision(left bool) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (b *board) descendActivePiece() bool {
|
||||
func (b *Board) descendActivePiece() bool {
|
||||
b.ActivePiecePos.Y += 1
|
||||
for _, activeBlock := range b.ActivePiece.Blocks {
|
||||
if b.ActivePiecePos.Y+activeBlock.Position.Y == 20 {
|
||||
|
@ -98,23 +93,23 @@ func (b *board) descendActivePiece() bool {
|
|||
|
||||
// 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.
|
||||
func (b *board) DescendActivePiece() bool {
|
||||
func (b *Board) DescendActivePiece() bool {
|
||||
if b.descendActivePiece() {
|
||||
return b.newActivePiece()
|
||||
return b.getNextPiece()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (b *board) DropActivePiece() bool {
|
||||
func (b *Board) DropActivePiece() bool {
|
||||
for !b.descendActivePiece() {
|
||||
}
|
||||
return b.newActivePiece()
|
||||
return b.getNextPiece()
|
||||
}
|
||||
|
||||
// MoveActivePiece moves the piece left or right. If the piece cannot move in the specified direction, nothing happens.
|
||||
func (b *board) MoveActivePiece(direction int) {
|
||||
func (b *Board) MoveActivePiece(direction int) {
|
||||
if !b.checkHorizontalCollision(direction == -1) {
|
||||
b.ActivePiecePos.X += float32(direction)
|
||||
}
|
||||
|
@ -130,7 +125,7 @@ func getCollisionDepth(collisionDepth int, longBoi bool) int {
|
|||
|
||||
// RotateActivePiece rotates the piece clockwise or counter-clockwise. If the piece cannot rotate in the specified
|
||||
// direction, nothing happens.
|
||||
func (b *board) RotateActivePiece(clockwise bool) {
|
||||
func (b *Board) RotateActivePiece(clockwise bool) {
|
||||
if b.ActivePiece.Blocks[0].Color == elements.Yellow {
|
||||
return
|
||||
}
|
||||
|
@ -195,8 +190,22 @@ func (b *board) RotateActivePiece(clockwise bool) {
|
|||
b.ActivePiece = tmpPiece
|
||||
}
|
||||
|
||||
func (b *Board) HoldPiece() {
|
||||
if b.AlreadyHeld {
|
||||
return
|
||||
}
|
||||
b.AlreadyHeld = true
|
||||
if b.HeldPiece == nil {
|
||||
b.HeldPiece = b.ActivePiece
|
||||
b.getNextPiece()
|
||||
return
|
||||
}
|
||||
b.HeldPiece, b.ActivePiece = b.ActivePiece, b.HeldPiece
|
||||
b.ActivePiecePos = rl.NewVector2(5, 0)
|
||||
}
|
||||
|
||||
// ClearLines clears all lines that are completely filled.
|
||||
func (g *board) ClearLines() {
|
||||
func (g *Board) ClearLines() {
|
||||
for y := 19; y >= 0; {
|
||||
skip := false
|
||||
for x := 0; x < 10; x++ {
|
||||
|
@ -225,7 +234,7 @@ func (g *board) ClearLines() {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *board) drawGrid(offset, scale rl.Vector2) {
|
||||
func (b *Board) DrawGrid(offset, scale rl.Vector2) {
|
||||
for i := 0; i < 10; i++ {
|
||||
rl.DrawLine(
|
||||
int32(scale.X*float32(i)+offset.X),
|
||||
|
@ -246,9 +255,38 @@ func (b *board) drawGrid(offset, scale rl.Vector2) {
|
|||
}
|
||||
}
|
||||
|
||||
// Draw draws the board with placed blocks and the active piece.
|
||||
func (b *board) Draw(offset rl.Vector2, scale rl.Vector2) {
|
||||
b.drawGrid(offset, scale)
|
||||
func (b *Board) drawUIPiece(piece *elements.Piece, position, scale rl.Vector2) {
|
||||
centerOffset := rl.NewVector2(0, 0)
|
||||
for _, block := range piece.Blocks {
|
||||
centerOffset = rl.Vector2Add(
|
||||
centerOffset,
|
||||
rl.Vector2Add(block.Position, rl.NewVector2(0.5, 0.5)),
|
||||
)
|
||||
}
|
||||
centerOffset = rl.Vector2Divide(centerOffset, rl.NewVector2(4, 4))
|
||||
centerOffset = rl.Vector2Add(centerOffset, rl.NewVector2(0, 1))
|
||||
centerOffset = rl.Vector2Multiply(centerOffset, scale)
|
||||
for _, block := range piece.Blocks {
|
||||
block.Draw(rl.NewVector2(0, 1), scale, rl.Vector2Subtract(position, centerOffset))
|
||||
}
|
||||
}
|
||||
|
||||
// DrawNextPiece draws the next piece in the UI at the specified position.
|
||||
func (b *Board) DrawNextPiece(position, scale rl.Vector2) {
|
||||
b.drawUIPiece(b.NextPiece, position, scale)
|
||||
}
|
||||
|
||||
// DrawHeldPiece draws the held piece in the UI at the specified position.
|
||||
func (b *Board) DrawHeldPiece(position, scale rl.Vector2) {
|
||||
if b.HeldPiece == nil {
|
||||
return
|
||||
}
|
||||
b.drawUIPiece(b.HeldPiece, position, scale)
|
||||
}
|
||||
|
||||
// DrawBoard draws the board with placed blocks and the active piece.
|
||||
func (b *Board) DrawBoard(offset rl.Vector2, scale rl.Vector2) {
|
||||
// b.DrawGrid(offset, scale)
|
||||
for i := 0; i < 20; i++ {
|
||||
for j := 0; j < 10; j++ {
|
||||
if b.Board[j][i] == nil {
|
||||
|
|
|
@ -16,7 +16,7 @@ type Game struct {
|
|||
|
||||
Scale rl.Vector2
|
||||
|
||||
Board Board
|
||||
Board *Board
|
||||
UI *UI
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,9 @@ func (g *Game) Update() {
|
|||
return
|
||||
}
|
||||
|
||||
if rl.IsKeyPressed(rl.KeyC) {
|
||||
g.Board.HoldPiece()
|
||||
}
|
||||
if rl.IsKeyPressed(rl.KeyI) {
|
||||
g.Board.MoveActivePiece(1)
|
||||
}
|
||||
|
@ -77,7 +80,9 @@ func (g *Game) Draw() {
|
|||
g.UI.Draw(g)
|
||||
|
||||
if !g.GameOver {
|
||||
g.Board.Draw(g.UI.BoardOffset, g.Scale)
|
||||
g.Board.DrawBoard(g.UI.BoardOffset, g.Scale)
|
||||
g.Board.DrawNextPiece(g.UI.NextPiecePosition, g.Scale)
|
||||
g.Board.DrawHeldPiece(g.UI.HeldPiecePosition, g.Scale)
|
||||
} else {
|
||||
rl.DrawText(
|
||||
"PRESS [ENTER] TO PLAY AGAIN",
|
||||
|
|
35
game/ui.go
35
game/ui.go
|
@ -1,19 +1,21 @@
|
|||
package game
|
||||
|
||||
import (
|
||||
// "fmt"
|
||||
"fmt"
|
||||
|
||||
"gitea.theedgeofrage.com/theedgeofrage/yeetris/elements"
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
type UI struct {
|
||||
ScreenWidth int32
|
||||
ScreenHeight int32
|
||||
BoardWidth int32
|
||||
BoardHeight int32
|
||||
BoardOffset rl.Vector2
|
||||
UIOffsetWidth int32
|
||||
ScreenWidth int32
|
||||
ScreenHeight int32
|
||||
BoardWidth int32
|
||||
BoardHeight int32
|
||||
BoardOffset rl.Vector2
|
||||
UIOffsetWidth int32
|
||||
NextPiecePosition rl.Vector2
|
||||
HeldPiecePosition rl.Vector2
|
||||
|
||||
Score int
|
||||
}
|
||||
|
@ -26,12 +28,14 @@ func InitUI(scale rl.Vector2) *UI {
|
|||
rl.InitWindow(screenWidth, screenHeight, "Yeetris")
|
||||
|
||||
return &UI{
|
||||
ScreenWidth: screenWidth,
|
||||
ScreenHeight: screenHeight,
|
||||
BoardWidth: boardWidth,
|
||||
BoardHeight: boardHeight,
|
||||
BoardOffset: rl.NewVector2(20, 20),
|
||||
UIOffsetWidth: boardWidth + 40 + 20,
|
||||
ScreenWidth: screenWidth,
|
||||
ScreenHeight: screenHeight,
|
||||
BoardWidth: boardWidth,
|
||||
BoardHeight: boardHeight,
|
||||
BoardOffset: rl.NewVector2(20, 20),
|
||||
UIOffsetWidth: boardWidth + 40 + 20,
|
||||
NextPiecePosition: rl.NewVector2(float32(boardWidth+40+20+110), 250),
|
||||
HeldPiecePosition: rl.NewVector2(float32(boardWidth+40+20+110), 510),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,6 +47,11 @@ func drawRectangleBorder(x, y, width, height, border int32, color rl.Color) {
|
|||
func (u *UI) Draw(g *Game) {
|
||||
drawRectangleBorder(int32(u.BoardOffset.X), int32(u.BoardOffset.Y), u.BoardWidth, u.BoardHeight, 20, elements.Gray)
|
||||
rl.DrawText("Yeetris", u.UIOffsetWidth, 20, 40, rl.White)
|
||||
rl.DrawText(fmt.Sprintf("Score: %d", u.Score), u.UIOffsetWidth, 70, 20, rl.White)
|
||||
rl.DrawText("Next Piece:", u.UIOffsetWidth, 110, 20, rl.White)
|
||||
drawRectangleBorder(u.UIOffsetWidth+10, 150, 200, 200, 10, elements.Gray)
|
||||
rl.DrawText("Hold:", u.UIOffsetWidth, 370, 20, rl.White)
|
||||
drawRectangleBorder(u.UIOffsetWidth+10, 410, 200, 200, 10, elements.Gray)
|
||||
|
||||
if g.Pause {
|
||||
rl.DrawText(
|
||||
|
|
Loading…
Reference in New Issue