package main import ( "image/color" "tetris/assets" "tetris/engine/core" "tetris/engine/graphics" "tetris/engine/render" "tetris/game" "tetris/game/draw" rl "github.com/gen2brain/raylib-go/raylib" ) var ( shape game.Shape shape_pos core.Vec2i8 dropTimer = core.NewIntervalTimer(0.3) moveTimer = core.NewIntervalTimer(0.1) grid = game.Grid{} nextShape game.ShapeType r = draw.Renderer{ Theme: &draw.Theme{ FrameBG: color.RGBA{R: 30, G: 30, B: 46, A: 255}, FrameBorder: color.RGBA{R: 242, G: 205, B: 205, A: 255}, TextHeader: color.RGBA{R: 242, G: 205, B: 205, A: 255}, Text: color.RGBA{R: 205, G: 214, B: 244, A: 255}, GridBackground: color.RGBA{R: 17, G: 17, B: 27, A: 255}, }, } ) func SpawnShape() { shape = game.NewShape(nextShape) shape_pos = core.Vec2i8{X: 4, Y: 0} nextShape = (nextShape + 1) % 7 } func LockShape() { for _, block := range shape.Coordinates() { block = shape_pos.Add(block) // Check bounds if block.X < 0 || block.X > int8(grid.Width()) || block.Y < 0 || block.Y > int8(grid.Height()) { continue } grid.Set(byte(block.X), byte(block.Y), shape.GetBlock()) } } func Update(delta float32) { if rl.IsKeyPressed(rl.KeyDown) { dropTimer.SetInterval(0.05) } else if rl.IsKeyReleased(rl.KeyDown) { dropTimer.SetInterval(0.3) } if rl.IsKeyPressed(rl.KeyUp) { rotated := shape.RotateCW() if !game.CheckShapeCollision(shape_pos, &rotated, &grid) { shape = rotated } } if moveTimer.UpdateReset(delta) && (rl.IsKeyDown(rl.KeyLeft) || rl.IsKeyDown(rl.KeyRight)) { new_pos := shape_pos if rl.IsKeyDown(rl.KeyLeft) { new_pos.X -= 1 } else { new_pos.X += 1 } if !game.CheckShapeCollision(new_pos, &shape, &grid) { shape_pos.X = new_pos.X } } if dropTimer.UpdateReset(delta) { new_pos := shape_pos new_pos.Y += 1 // Update position if it does not collide if game.CheckShapeCollision(new_pos, &shape, &grid) { LockShape() SpawnShape() } else { shape_pos = new_pos } } } func Render() { render.Begin(r.Theme.GridBackground) r.DrawGrid(rl.NewVector2(25, 25), grid) draw.DrawShape(rl.NewVector2(25, 25), shape_pos, shape) r.DrawFrame(rl.RectangleInt32{X: 400, Y: 25, Width: 250, Height: 100}) r.DrawHeaderText(410, 30, "Score") r.DrawText(410, 65, "999999") r.DrawFrame(rl.RectangleInt32{X: 400, Y: 150, Width: 250, Height: 200}) render.End() } func main() { // Set random blocks to test render.Init(render.Config{ Title: "Tetris", WindowWidth: 685, WindowHeight: 600, RenderWidth: 685, RenderHeight: 600, ScaleFlags: render.SCALE_INTEGER, }) defer render.Exit() // Load texture texture := graphics.LoadTextureFromMemory(".png", assets.Sprite) defer rl.UnloadTexture(texture) render.SetTexture(texture) render.SetFont(&assets.Font) SpawnShape() for !rl.WindowShouldClose() { Update(rl.GetFrameTime()) Render() } }