step
This commit is contained in:
parent
0bec81c656
commit
fe6d2c0ed3
190 changed files with 104835 additions and 5 deletions
277
examples/games/arkanoid/main.go
Normal file
277
examples/games/arkanoid/main.go
Normal file
|
@ -0,0 +1,277 @@
|
|||
package main
|
||||
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - sample game: arkanoid
|
||||
*
|
||||
* Sample game Marc Palau and Ramon Santamaria
|
||||
*
|
||||
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Ported to raylib-go by Nehpe (@nehpe), July 2019
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
PLAYER_MAX_LIFE = 5
|
||||
LINES_OF_BRICKS = 5
|
||||
BRICKS_PER_LINE = 20
|
||||
)
|
||||
|
||||
type Player struct {
|
||||
position rl.Vector2
|
||||
size rl.Vector2
|
||||
life int
|
||||
}
|
||||
|
||||
type Ball struct {
|
||||
position rl.Vector2
|
||||
speed rl.Vector2
|
||||
radius float32
|
||||
active bool
|
||||
}
|
||||
|
||||
type Brick struct {
|
||||
position rl.Vector2
|
||||
active bool
|
||||
}
|
||||
|
||||
const (
|
||||
screenWidth = 800
|
||||
screenHeight = 450
|
||||
)
|
||||
|
||||
type Game struct {
|
||||
gameOver bool
|
||||
pause bool
|
||||
player Player
|
||||
ball Ball
|
||||
brick [LINES_OF_BRICKS][BRICKS_PER_LINE]Brick
|
||||
brickSize rl.Vector2
|
||||
}
|
||||
|
||||
func main() {
|
||||
rl.InitWindow(screenWidth, screenHeight, "sample game: arkanoid")
|
||||
|
||||
// Init game
|
||||
game := NewGame()
|
||||
game.gameOver = true
|
||||
|
||||
rl.SetTargetFPS(60)
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
game.Update()
|
||||
|
||||
game.Draw()
|
||||
|
||||
}
|
||||
|
||||
rl.CloseWindow()
|
||||
|
||||
}
|
||||
|
||||
// For android
|
||||
func init() {
|
||||
rl.SetCallbackFunc(main)
|
||||
}
|
||||
|
||||
// NewGame - Create a new game instance
|
||||
func NewGame() (g Game) {
|
||||
g.Init()
|
||||
return
|
||||
}
|
||||
|
||||
// Init - initialize game
|
||||
func (g *Game) Init() {
|
||||
g.brickSize = rl.Vector2{float32(rl.GetScreenWidth() / BRICKS_PER_LINE), 40}
|
||||
|
||||
// Initialize player
|
||||
g.player.position = rl.Vector2{float32(screenWidth / 2), float32(screenHeight * 7 / 8)}
|
||||
g.player.size = rl.Vector2{float32(screenWidth / 10), 20}
|
||||
g.player.life = PLAYER_MAX_LIFE
|
||||
|
||||
// Initialize ball
|
||||
g.ball.position = rl.Vector2{float32(screenWidth / 2), float32(screenHeight*7/8 - 30)}
|
||||
g.ball.speed = rl.Vector2{0, 0}
|
||||
g.ball.radius = 7
|
||||
g.ball.active = false
|
||||
|
||||
initialDownPosition := int(50)
|
||||
|
||||
for i := 0; i < LINES_OF_BRICKS; i++ {
|
||||
for j := 0; j < BRICKS_PER_LINE; j++ {
|
||||
g.brick[i][j].position = rl.Vector2{float32(j)*g.brickSize.X + g.brickSize.X/2, float32(i)*g.brickSize.Y + float32(initialDownPosition)}
|
||||
g.brick[i][j].active = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update - update game state
|
||||
func (g *Game) Update() {
|
||||
if !g.gameOver {
|
||||
|
||||
if rl.IsKeyPressed(rl.KeyP) {
|
||||
g.pause = !g.pause
|
||||
}
|
||||
|
||||
if !g.pause {
|
||||
|
||||
if rl.IsKeyDown(rl.KeyLeft) || rl.IsKeyDown(rl.KeyA) {
|
||||
g.player.position.X -= 5
|
||||
}
|
||||
if (g.player.position.X - g.player.size.X/2) <= 0 {
|
||||
g.player.position.X = g.player.size.X / 2
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeyRight) || rl.IsKeyDown(rl.KeyD) {
|
||||
g.player.position.X += 5
|
||||
}
|
||||
if (g.player.position.X + g.player.size.X/2) >= screenWidth {
|
||||
g.player.position.X = screenWidth - g.player.size.X/2
|
||||
}
|
||||
|
||||
if !g.ball.active {
|
||||
if rl.IsKeyPressed(rl.KeySpace) {
|
||||
g.ball.active = true
|
||||
g.ball.speed = rl.Vector2{0, -5}
|
||||
}
|
||||
}
|
||||
|
||||
if g.ball.active {
|
||||
g.ball.position.X += g.ball.speed.X
|
||||
g.ball.position.Y += g.ball.speed.Y
|
||||
} else {
|
||||
g.ball.position = rl.Vector2{g.player.position.X, screenHeight*7/8 - 30}
|
||||
}
|
||||
|
||||
// Collision logic: ball vs walls
|
||||
if ((g.ball.position.X + g.ball.radius) >= screenWidth) || ((g.ball.position.X - g.ball.radius) <= 0) {
|
||||
g.ball.speed.X *= -1
|
||||
}
|
||||
if (g.ball.position.Y - g.ball.radius) <= 0 {
|
||||
g.ball.speed.Y *= -1
|
||||
}
|
||||
if (g.ball.position.Y + g.ball.radius) >= screenHeight {
|
||||
g.ball.speed = rl.Vector2{0, 0}
|
||||
g.ball.active = false
|
||||
|
||||
g.player.life--
|
||||
}
|
||||
if (rl.CheckCollisionCircleRec(g.ball.position, g.ball.radius,
|
||||
rl.Rectangle{g.player.position.X - g.player.size.X/2, g.player.position.Y - g.player.size.Y/2, g.player.size.X, g.player.size.Y})) {
|
||||
if g.ball.speed.Y > 0 {
|
||||
g.ball.speed.Y *= -1
|
||||
g.ball.speed.X = (g.ball.position.X - g.player.position.X) / (g.player.size.X / 2) * 5
|
||||
}
|
||||
}
|
||||
// Collision logic: ball vs bricks
|
||||
for i := 0; i < LINES_OF_BRICKS; i++ {
|
||||
for j := 0; j < BRICKS_PER_LINE; j++ {
|
||||
if g.brick[i][j].active {
|
||||
if ((g.ball.position.Y - g.ball.radius) <= (g.brick[i][j].position.Y + g.brickSize.Y/2)) &&
|
||||
((g.ball.position.Y - g.ball.radius) > (g.brick[i][j].position.Y + g.brickSize.Y/2 + g.ball.speed.Y)) &&
|
||||
((float32(math.Abs(float64(g.ball.position.X - g.brick[i][j].position.X)))) < (g.brickSize.X/2 + g.ball.radius*2/3)) &&
|
||||
(g.ball.speed.Y < 0) {
|
||||
// Hit below
|
||||
g.brick[i][j].active = false
|
||||
g.ball.speed.Y *= -1
|
||||
} else if ((g.ball.position.Y + g.ball.radius) >= (g.brick[i][j].position.Y - g.brickSize.Y/2)) &&
|
||||
((g.ball.position.Y + g.ball.radius) < (g.brick[i][j].position.Y - g.brickSize.Y/2 + g.ball.speed.Y)) &&
|
||||
((float32(math.Abs(float64(g.ball.position.X - g.brick[i][j].position.X)))) < (g.brickSize.X/2 + g.ball.radius*2/3)) &&
|
||||
(g.ball.speed.Y > 0) {
|
||||
// Hit above
|
||||
g.brick[i][j].active = false
|
||||
g.ball.speed.Y *= -1
|
||||
} else if ((g.ball.position.X + g.ball.radius) >= (g.brick[i][j].position.X - g.brickSize.X/2)) &&
|
||||
((g.ball.position.X + g.ball.radius) < (g.brick[i][j].position.X - g.brickSize.X/2 + g.ball.speed.X)) &&
|
||||
((float32(math.Abs(float64(g.ball.position.Y - g.brick[i][j].position.Y)))) < (g.brickSize.Y/2 + g.ball.radius*2/3)) &&
|
||||
(g.ball.speed.X > 0) {
|
||||
// Hit left
|
||||
g.brick[i][j].active = false
|
||||
g.ball.speed.X *= -1
|
||||
} else if ((g.ball.position.X - g.ball.radius) <= (g.brick[i][j].position.X + g.brickSize.X/2)) &&
|
||||
((g.ball.position.X - g.ball.radius) > (g.brick[i][j].position.X + g.brickSize.X/2 + g.ball.speed.X)) &&
|
||||
((float32(math.Abs(float64(g.ball.position.Y - g.brick[i][j].position.Y)))) < (g.brickSize.Y/2 + g.ball.radius*2/3)) &&
|
||||
(g.ball.speed.X < 0) {
|
||||
// Hit right
|
||||
g.brick[i][j].active = false
|
||||
g.ball.speed.X *= -1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Game over logic
|
||||
if g.player.life <= 0 {
|
||||
g.gameOver = true
|
||||
} else {
|
||||
g.gameOver = true
|
||||
|
||||
for i := 0; i < LINES_OF_BRICKS; i++ {
|
||||
for j := 0; j < BRICKS_PER_LINE; j++ {
|
||||
if g.brick[i][j].active {
|
||||
g.gameOver = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if rl.IsKeyPressed(rl.KeyEnter) {
|
||||
g.Init()
|
||||
g.gameOver = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw - draw game
|
||||
func (g *Game) Draw() {
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.White)
|
||||
|
||||
if !g.gameOver {
|
||||
// Draw player bar
|
||||
rl.DrawRectangle(int32(g.player.position.X-g.player.size.X/2), int32(g.player.position.Y-g.player.size.Y/2), int32(g.player.size.X), int32(g.player.size.Y), rl.Black)
|
||||
|
||||
// Draw player lives
|
||||
for i := 0; i < g.player.life; i++ {
|
||||
rl.DrawRectangle(int32(20+40*i), screenHeight-30, 35, 10, rl.LightGray)
|
||||
}
|
||||
|
||||
// Draw Ball
|
||||
rl.DrawCircleV(g.ball.position, g.ball.radius, rl.Maroon)
|
||||
|
||||
for i := 0; i < LINES_OF_BRICKS; i++ {
|
||||
for j := 0; j < BRICKS_PER_LINE; j++ {
|
||||
if g.brick[i][j].active {
|
||||
if (i+j)%2 == 0 {
|
||||
rl.DrawRectangle(int32(g.brick[i][j].position.X-g.brickSize.X/2), int32(g.brick[i][j].position.Y-g.brickSize.Y/2), int32(g.brickSize.X), int32(g.brickSize.Y), rl.Gray)
|
||||
} else {
|
||||
rl.DrawRectangle(int32(g.brick[i][j].position.X-g.brickSize.X/2), int32(g.brick[i][j].position.Y-g.brickSize.Y/2), int32(g.brickSize.X), int32(g.brickSize.Y), rl.DarkGray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if g.pause {
|
||||
rl.DrawText("GAME PAUSED", screenWidth/2-rl.MeasureText("GAME PAUSED", 40)/2, screenHeight/2+screenHeight/4-40, 40, rl.Gray)
|
||||
}
|
||||
|
||||
} else {
|
||||
str := "PRESS [ENTER] TO PLAY AGAIN"
|
||||
x := int(rl.GetScreenWidth()/2) - int(rl.MeasureText(str, 20)/2)
|
||||
y := rl.GetScreenHeight()/2 - 50
|
||||
rl.DrawText(str, int32(x), int32(y), 20, rl.Gray)
|
||||
}
|
||||
|
||||
rl.EndDrawing()
|
||||
}
|
5
examples/games/floppy/README.md
Normal file
5
examples/games/floppy/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
## Floppy Gopher
|
||||
|
||||

|
||||
|
||||
[Android APK](https://gist.github.com/gen2brain/ae96bc92d2c2e307af35f5583f30ea25)
|
2
examples/games/floppy/images/README
Normal file
2
examples/games/floppy/images/README
Normal file
|
@ -0,0 +1,2 @@
|
|||
The Gopher sprites were created by Renee French and are distributed
|
||||
under the Creative Commons Attributions 3.0 license.
|
BIN
examples/games/floppy/images/clouds.png
Normal file
BIN
examples/games/floppy/images/clouds.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
BIN
examples/games/floppy/images/smoke.png
Normal file
BIN
examples/games/floppy/images/smoke.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.8 KiB |
BIN
examples/games/floppy/images/sprite.png
Normal file
BIN
examples/games/floppy/images/sprite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
452
examples/games/floppy/main.go
Normal file
452
examples/games/floppy/main.go
Normal file
|
@ -0,0 +1,452 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
// Screen width
|
||||
screenWidth = 504
|
||||
// Screen height
|
||||
screenHeight = 896
|
||||
|
||||
// Maximum number of pipes
|
||||
maxPipes = 100
|
||||
// Maximum number of particles
|
||||
maxParticles = 50
|
||||
|
||||
// Pipes width
|
||||
pipesWidth = 60
|
||||
// Sprite size
|
||||
spriteSize = 48
|
||||
|
||||
// Pipes speed
|
||||
pipesSpeedX = 2.5
|
||||
// Clouds speed
|
||||
cloudsSpeedX = 1
|
||||
|
||||
// Gravity
|
||||
gravity = 1.2
|
||||
)
|
||||
|
||||
// Floppy type
|
||||
type Floppy struct {
|
||||
Position rl.Vector2
|
||||
}
|
||||
|
||||
// Pipe type
|
||||
type Pipe struct {
|
||||
Rec rl.Rectangle
|
||||
Color rl.Color
|
||||
Active bool
|
||||
}
|
||||
|
||||
// Particle type
|
||||
type Particle struct {
|
||||
Position rl.Vector2
|
||||
Color rl.Color
|
||||
Alpha float32
|
||||
Size float32
|
||||
Rotation float32
|
||||
Active bool
|
||||
}
|
||||
|
||||
// Game type
|
||||
type Game struct {
|
||||
FxFlap rl.Sound
|
||||
FxSlap rl.Sound
|
||||
FxPoint rl.Sound
|
||||
FxClick rl.Sound
|
||||
|
||||
TxSprites rl.Texture2D
|
||||
TxSmoke rl.Texture2D
|
||||
TxClouds rl.Texture2D
|
||||
|
||||
CloudRec rl.Rectangle
|
||||
FrameRec rl.Rectangle
|
||||
|
||||
GameOver bool
|
||||
Dead bool
|
||||
Pause bool
|
||||
SuperFX bool
|
||||
|
||||
Score int
|
||||
HiScore int
|
||||
FramesCounter int32
|
||||
|
||||
WindowShouldClose bool
|
||||
|
||||
Floppy Floppy
|
||||
Particles []Particle
|
||||
|
||||
Pipes []Pipe
|
||||
PipesPos []rl.Vector2
|
||||
}
|
||||
|
||||
// NewGame - Start new game
|
||||
func NewGame() (g Game) {
|
||||
g.Init()
|
||||
return
|
||||
}
|
||||
|
||||
// On Android this sets callback function to be used for android_main
|
||||
func init() {
|
||||
rl.SetCallbackFunc(main)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Initialize game
|
||||
game := NewGame()
|
||||
game.GameOver = true
|
||||
|
||||
// Initialize window
|
||||
rl.InitWindow(screenWidth, screenHeight, "Floppy Gopher")
|
||||
|
||||
// Initialize audio
|
||||
rl.InitAudioDevice()
|
||||
|
||||
// NOTE: Textures and Sounds MUST be loaded after Window/Audio initialization
|
||||
game.Load()
|
||||
|
||||
// Limit FPS
|
||||
rl.SetTargetFPS(60)
|
||||
|
||||
// Main loop
|
||||
for !game.WindowShouldClose {
|
||||
// Update game
|
||||
game.Update()
|
||||
|
||||
// Draw game
|
||||
game.Draw()
|
||||
}
|
||||
|
||||
// Free resources
|
||||
game.Unload()
|
||||
|
||||
// Close audio
|
||||
rl.CloseAudioDevice()
|
||||
|
||||
// Close window
|
||||
rl.CloseWindow()
|
||||
|
||||
// Exit
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Init - Initialize game
|
||||
func (g *Game) Init() {
|
||||
|
||||
// Gopher
|
||||
g.Floppy = Floppy{rl.NewVector2(80, float32(screenHeight)/2-spriteSize/2)}
|
||||
|
||||
// Sprite rectangle
|
||||
g.FrameRec = rl.NewRectangle(0, 0, spriteSize, spriteSize)
|
||||
|
||||
// Cloud rectangle
|
||||
g.CloudRec = rl.NewRectangle(0, 0, float32(screenWidth), float32(g.TxClouds.Height))
|
||||
|
||||
// Initialize particles
|
||||
g.Particles = make([]Particle, maxParticles)
|
||||
for i := 0; i < maxParticles; i++ {
|
||||
g.Particles[i].Position = rl.NewVector2(0, 0)
|
||||
g.Particles[i].Color = rl.RayWhite
|
||||
g.Particles[i].Alpha = 1.0
|
||||
g.Particles[i].Size = float32(rl.GetRandomValue(1, 30)) / 20.0
|
||||
g.Particles[i].Rotation = float32(rl.GetRandomValue(0, 360))
|
||||
g.Particles[i].Active = false
|
||||
}
|
||||
|
||||
// Pipes positions
|
||||
g.PipesPos = make([]rl.Vector2, maxPipes)
|
||||
for i := 0; i < maxPipes; i++ {
|
||||
g.PipesPos[i].X = float32(480 + 360*i)
|
||||
g.PipesPos[i].Y = -float32(rl.GetRandomValue(0, 240))
|
||||
}
|
||||
|
||||
// Pipes colors
|
||||
colors := []rl.Color{
|
||||
rl.Orange, rl.Red, rl.Gold, rl.Lime,
|
||||
rl.Violet, rl.Brown, rl.LightGray, rl.Blue,
|
||||
rl.Yellow, rl.Green, rl.Purple, rl.Beige,
|
||||
}
|
||||
|
||||
// Pipes
|
||||
g.Pipes = make([]Pipe, maxPipes*2)
|
||||
for i := 0; i < maxPipes*2; i += 2 {
|
||||
g.Pipes[i].Rec.X = g.PipesPos[i/2].X
|
||||
g.Pipes[i].Rec.Y = g.PipesPos[i/2].Y
|
||||
g.Pipes[i].Rec.Width = pipesWidth
|
||||
g.Pipes[i].Rec.Height = 550
|
||||
g.Pipes[i].Color = colors[rl.GetRandomValue(0, int32(len(colors)-1))]
|
||||
|
||||
g.Pipes[i+1].Rec.X = g.PipesPos[i/2].X
|
||||
g.Pipes[i+1].Rec.Y = 1200 + g.PipesPos[i/2].Y - 550
|
||||
g.Pipes[i+1].Rec.Width = pipesWidth
|
||||
g.Pipes[i+1].Rec.Height = 550
|
||||
|
||||
g.Pipes[i/2].Active = true
|
||||
}
|
||||
|
||||
g.Score = 0
|
||||
g.FramesCounter = 0
|
||||
g.WindowShouldClose = false
|
||||
|
||||
g.GameOver = false
|
||||
g.Dead = false
|
||||
g.SuperFX = false
|
||||
g.Pause = false
|
||||
}
|
||||
|
||||
// Load - Load resources
|
||||
func (g *Game) Load() {
|
||||
g.FxFlap = rl.LoadSound("sounds/flap.wav")
|
||||
g.FxSlap = rl.LoadSound("sounds/slap.wav")
|
||||
g.FxPoint = rl.LoadSound("sounds/point.wav")
|
||||
g.FxClick = rl.LoadSound("sounds/click.wav")
|
||||
g.TxSprites = rl.LoadTexture("images/sprite.png")
|
||||
g.TxSmoke = rl.LoadTexture("images/smoke.png")
|
||||
g.TxClouds = rl.LoadTexture("images/clouds.png")
|
||||
}
|
||||
|
||||
// Unload - Unload resources
|
||||
func (g *Game) Unload() {
|
||||
rl.UnloadSound(g.FxFlap)
|
||||
rl.UnloadSound(g.FxSlap)
|
||||
rl.UnloadSound(g.FxPoint)
|
||||
rl.UnloadSound(g.FxClick)
|
||||
rl.UnloadTexture(g.TxSprites)
|
||||
rl.UnloadTexture(g.TxSmoke)
|
||||
rl.UnloadTexture(g.TxClouds)
|
||||
}
|
||||
|
||||
// Update - Update game
|
||||
func (g *Game) Update() {
|
||||
if rl.WindowShouldClose() {
|
||||
g.WindowShouldClose = true
|
||||
}
|
||||
|
||||
if !g.GameOver {
|
||||
if rl.IsKeyPressed(rl.KeyP) || rl.IsKeyPressed(rl.KeyBack) {
|
||||
rl.PlaySound(g.FxClick)
|
||||
|
||||
if runtime.GOOS == "android" && g.Pause {
|
||||
g.WindowShouldClose = true
|
||||
}
|
||||
|
||||
g.Pause = !g.Pause
|
||||
}
|
||||
|
||||
if !g.Pause {
|
||||
if !g.Dead {
|
||||
// Scroll pipes
|
||||
for i := 0; i < maxPipes; i++ {
|
||||
g.PipesPos[i].X -= float32(pipesSpeedX)
|
||||
}
|
||||
|
||||
for i := 0; i < maxPipes*2; i += 2 {
|
||||
g.Pipes[i].Rec.X = g.PipesPos[i/2].X
|
||||
g.Pipes[i+1].Rec.X = g.PipesPos[i/2].X
|
||||
}
|
||||
|
||||
// Scroll clouds
|
||||
g.CloudRec.X += cloudsSpeedX
|
||||
if g.CloudRec.X > float32(g.TxClouds.Width) {
|
||||
g.CloudRec.X = 0
|
||||
}
|
||||
|
||||
// Movement/Controls
|
||||
if rl.IsKeyDown(rl.KeySpace) || rl.IsMouseButtonDown(rl.MouseLeftButton) {
|
||||
rl.PlaySound(g.FxFlap)
|
||||
|
||||
// Activate one particle every frame
|
||||
for i := 0; i < maxParticles; i++ {
|
||||
if !g.Particles[i].Active {
|
||||
g.Particles[i].Active = true
|
||||
g.Particles[i].Alpha = 1.0
|
||||
g.Particles[i].Position = g.Floppy.Position
|
||||
g.Particles[i].Position.X += spriteSize / 2
|
||||
g.Particles[i].Position.Y += spriteSize / 2
|
||||
i = maxParticles
|
||||
}
|
||||
}
|
||||
|
||||
// Switch flap sprites every 8 frames
|
||||
g.FramesCounter++
|
||||
if g.FramesCounter >= 8 {
|
||||
g.FramesCounter = 0
|
||||
g.FrameRec.X = spriteSize * 3
|
||||
} else {
|
||||
g.FrameRec.X = spriteSize * 2
|
||||
}
|
||||
|
||||
// Floppy go up
|
||||
g.Floppy.Position.Y -= 3
|
||||
} else {
|
||||
// Switch run sprites every 8 frames
|
||||
g.FramesCounter++
|
||||
if g.FramesCounter >= 8 {
|
||||
g.FramesCounter = 0
|
||||
g.FrameRec.X = spriteSize
|
||||
} else {
|
||||
g.FrameRec.X = 0
|
||||
}
|
||||
|
||||
// Floppy fall down
|
||||
g.Floppy.Position.Y += gravity
|
||||
}
|
||||
|
||||
// Update active particles
|
||||
for i := 0; i < maxParticles; i++ {
|
||||
if g.Particles[i].Active {
|
||||
g.Particles[i].Position.X -= 1.0
|
||||
g.Particles[i].Alpha -= 0.05
|
||||
|
||||
if g.Particles[i].Alpha <= 0.0 {
|
||||
g.Particles[i].Active = false
|
||||
}
|
||||
|
||||
g.Particles[i].Rotation += 3.0
|
||||
}
|
||||
}
|
||||
|
||||
// Check Collisions
|
||||
for i := 0; i < maxPipes*2; i++ {
|
||||
if rl.CheckCollisionRecs(rl.NewRectangle(g.Floppy.Position.X, g.Floppy.Position.Y, spriteSize, spriteSize), g.Pipes[i].Rec) {
|
||||
// OMG You killed Gopher you bastard!
|
||||
g.Dead = true
|
||||
|
||||
rl.PlaySound(g.FxSlap)
|
||||
} else if (g.PipesPos[i/2].X < g.Floppy.Position.X-spriteSize) && g.Pipes[i/2].Active && !g.GameOver {
|
||||
// Score point
|
||||
g.Score += 1
|
||||
g.Pipes[i/2].Active = false
|
||||
|
||||
// Flash screen
|
||||
g.SuperFX = true
|
||||
|
||||
// Update HiScore
|
||||
if g.Score > g.HiScore {
|
||||
g.HiScore = g.Score
|
||||
}
|
||||
|
||||
rl.PlaySound(g.FxPoint)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Wait 60 frames before GameOver
|
||||
g.FramesCounter++
|
||||
if g.FramesCounter >= 60 {
|
||||
g.GameOver = true
|
||||
}
|
||||
|
||||
// Switch dead sprite
|
||||
if g.FramesCounter >= 8 {
|
||||
g.FrameRec.X = spriteSize * 5
|
||||
} else {
|
||||
g.FrameRec.X = spriteSize * 4
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if rl.IsMouseButtonDown(rl.MouseLeftButton) {
|
||||
g.Pause = !g.Pause
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if rl.IsKeyPressed(rl.KeyEnter) || rl.IsMouseButtonDown(rl.MouseLeftButton) {
|
||||
rl.PlaySound(g.FxClick)
|
||||
|
||||
// Return of the Gopher!
|
||||
g.Init()
|
||||
} else if runtime.GOOS == "android" && rl.IsKeyDown(rl.KeyBack) {
|
||||
g.WindowShouldClose = true
|
||||
}
|
||||
|
||||
// Switch flap sprites
|
||||
g.FramesCounter++
|
||||
if g.FramesCounter >= 8 {
|
||||
g.FramesCounter = 0
|
||||
g.FrameRec.X = spriteSize
|
||||
} else {
|
||||
g.FrameRec.X = 0
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Draw - Draw game
|
||||
func (g *Game) Draw() {
|
||||
rl.BeginDrawing()
|
||||
|
||||
rl.ClearBackground(rl.SkyBlue)
|
||||
|
||||
if !g.GameOver {
|
||||
// Draw clouds
|
||||
rl.DrawTextureRec(g.TxClouds, g.CloudRec, rl.NewVector2(0, float32(screenHeight-g.TxClouds.Height)), rl.RayWhite)
|
||||
|
||||
// Draw rotated clouds
|
||||
rl.DrawTexturePro(g.TxClouds, rl.NewRectangle(-g.CloudRec.X, 0, float32(g.TxClouds.Width), float32(g.TxClouds.Height)),
|
||||
rl.NewRectangle(0, 0, float32(g.TxClouds.Width), float32(g.TxClouds.Height)), rl.NewVector2(float32(g.TxClouds.Width), float32(g.TxClouds.Height)), 180, rl.White)
|
||||
|
||||
// Draw Gopher
|
||||
rl.DrawTextureRec(g.TxSprites, g.FrameRec, g.Floppy.Position, rl.RayWhite)
|
||||
|
||||
// Draw active particles
|
||||
if !g.Dead {
|
||||
for i := 0; i < maxParticles; i++ {
|
||||
if g.Particles[i].Active {
|
||||
rl.DrawTexturePro(
|
||||
g.TxSmoke,
|
||||
rl.NewRectangle(0, 0, float32(g.TxSmoke.Width), float32(g.TxSmoke.Height)),
|
||||
rl.NewRectangle(g.Particles[i].Position.X, g.Particles[i].Position.Y, float32(g.TxSmoke.Width)*g.Particles[i].Size, float32(g.TxSmoke.Height)*g.Particles[i].Size),
|
||||
rl.NewVector2(float32(g.TxSmoke.Width)*g.Particles[i].Size/2, float32(g.TxSmoke.Height)*g.Particles[i].Size/2),
|
||||
g.Particles[i].Rotation,
|
||||
rl.Fade(g.Particles[i].Color, g.Particles[i].Alpha),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw pipes
|
||||
for i := 0; i < maxPipes; i++ {
|
||||
rl.DrawRectangle(int32(g.Pipes[i*2].Rec.X), int32(g.Pipes[i*2].Rec.Y), int32(g.Pipes[i*2].Rec.Width), int32(g.Pipes[i*2].Rec.Height), g.Pipes[i*2].Color)
|
||||
rl.DrawRectangle(int32(g.Pipes[i*2+1].Rec.X), int32(g.Pipes[i*2+1].Rec.Y), int32(g.Pipes[i*2+1].Rec.Width), int32(g.Pipes[i*2+1].Rec.Height), g.Pipes[i*2].Color)
|
||||
|
||||
// Draw borders
|
||||
rl.DrawRectangleLines(int32(g.Pipes[i*2].Rec.X), int32(g.Pipes[i*2].Rec.Y), int32(g.Pipes[i*2].Rec.Width), int32(g.Pipes[i*2].Rec.Height), rl.Black)
|
||||
rl.DrawRectangleLines(int32(g.Pipes[i*2+1].Rec.X), int32(g.Pipes[i*2+1].Rec.Y), int32(g.Pipes[i*2+1].Rec.Width), int32(g.Pipes[i*2+1].Rec.Height), rl.Black)
|
||||
}
|
||||
|
||||
// Draw Super Flashing FX (one frame only)
|
||||
if g.SuperFX {
|
||||
rl.DrawRectangle(0, 0, screenWidth, screenHeight, rl.White)
|
||||
g.SuperFX = false
|
||||
}
|
||||
|
||||
// Draw HI-SCORE
|
||||
rl.DrawText(fmt.Sprintf("%02d", g.Score), 20, 20, 32, rl.Black)
|
||||
rl.DrawText(fmt.Sprintf("HI-SCORE: %02d", g.HiScore), 20, 64, 20, rl.Black)
|
||||
|
||||
if g.Pause {
|
||||
// Draw PAUSED text
|
||||
rl.DrawText("PAUSED", screenWidth/2-rl.MeasureText("PAUSED", 24)/2, screenHeight/2-50, 20, rl.Black)
|
||||
}
|
||||
} else {
|
||||
// Draw text
|
||||
rl.DrawText("Floppy Gopher", int32(rl.GetScreenWidth())/2-rl.MeasureText("Floppy Gopher", 40)/2, int32(rl.GetScreenHeight())/2-150, 40, rl.RayWhite)
|
||||
|
||||
if runtime.GOOS == "android" {
|
||||
rl.DrawText("[TAP] TO PLAY", int32(rl.GetScreenWidth())/2-rl.MeasureText("[TAP] TO PLAY", 20)/2, int32(rl.GetScreenHeight())/2-50, 20, rl.Black)
|
||||
} else {
|
||||
rl.DrawText("[ENTER] TO PLAY", int32(rl.GetScreenWidth())/2-rl.MeasureText("[ENTER] TO PLAY", 20)/2, int32(rl.GetScreenHeight())/2-50, 20, rl.Black)
|
||||
}
|
||||
|
||||
// Draw Gopher
|
||||
rl.DrawTextureRec(g.TxSprites, g.FrameRec, rl.NewVector2(float32(rl.GetScreenWidth()/2-spriteSize/2), float32(rl.GetScreenHeight()/2)), rl.RayWhite)
|
||||
}
|
||||
|
||||
rl.EndDrawing()
|
||||
}
|
BIN
examples/games/floppy/sounds/click.wav
Normal file
BIN
examples/games/floppy/sounds/click.wav
Normal file
Binary file not shown.
BIN
examples/games/floppy/sounds/flap.wav
Normal file
BIN
examples/games/floppy/sounds/flap.wav
Normal file
Binary file not shown.
BIN
examples/games/floppy/sounds/point.wav
Normal file
BIN
examples/games/floppy/sounds/point.wav
Normal file
Binary file not shown.
BIN
examples/games/floppy/sounds/slap.wav
Normal file
BIN
examples/games/floppy/sounds/slap.wav
Normal file
Binary file not shown.
200
examples/games/life/main.go
Normal file
200
examples/games/life/main.go
Normal file
|
@ -0,0 +1,200 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
squareSize = 8
|
||||
)
|
||||
|
||||
// Cell type
|
||||
type Cell struct {
|
||||
Position rl.Vector2
|
||||
Size rl.Vector2
|
||||
Alive bool
|
||||
Next bool
|
||||
Visited bool
|
||||
}
|
||||
|
||||
// Game type
|
||||
type Game struct {
|
||||
ScreenWidth int32
|
||||
ScreenHeight int32
|
||||
Cols int32
|
||||
Rows int32
|
||||
FramesCounter int32
|
||||
Playing bool
|
||||
Cells [][]*Cell
|
||||
}
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
game := Game{}
|
||||
game.Init(false)
|
||||
|
||||
rl.InitWindow(game.ScreenWidth, game.ScreenHeight, "Conway's Game of Life")
|
||||
rl.SetTargetFPS(20)
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
if game.Playing {
|
||||
game.Update()
|
||||
}
|
||||
|
||||
game.Input()
|
||||
|
||||
game.Draw()
|
||||
}
|
||||
|
||||
rl.CloseWindow()
|
||||
}
|
||||
|
||||
// Init - Initialize game
|
||||
func (g *Game) Init(clear bool) {
|
||||
g.ScreenWidth = 800
|
||||
g.ScreenHeight = 450
|
||||
g.FramesCounter = 0
|
||||
|
||||
g.Cols = g.ScreenWidth / squareSize
|
||||
g.Rows = g.ScreenHeight / squareSize
|
||||
|
||||
g.Cells = make([][]*Cell, g.Cols+1)
|
||||
for i := int32(0); i <= g.Cols; i++ {
|
||||
g.Cells[i] = make([]*Cell, g.Rows+1)
|
||||
}
|
||||
|
||||
for x := int32(0); x <= g.Cols; x++ {
|
||||
for y := int32(0); y <= g.Rows; y++ {
|
||||
g.Cells[x][y] = &Cell{}
|
||||
g.Cells[x][y].Position = rl.NewVector2((float32(x) * squareSize), (float32(y)*squareSize)+1)
|
||||
g.Cells[x][y].Size = rl.NewVector2(squareSize-1, squareSize-1)
|
||||
if rand.Float64() < 0.1 && clear == false {
|
||||
g.Cells[x][y].Alive = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Input - Game input
|
||||
func (g *Game) Input() {
|
||||
// control
|
||||
if rl.IsKeyPressed(rl.KeyR) {
|
||||
g.Init(false)
|
||||
}
|
||||
if rl.IsKeyPressed(rl.KeyC) {
|
||||
g.Init(true)
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeyRight) && !g.Playing {
|
||||
g.Update()
|
||||
}
|
||||
if rl.IsMouseButtonPressed(rl.MouseLeftButton) {
|
||||
g.Click(rl.GetMouseX(), rl.GetMouseY())
|
||||
}
|
||||
if rl.IsKeyPressed(rl.KeySpace) {
|
||||
g.Playing = !g.Playing
|
||||
}
|
||||
|
||||
g.FramesCounter++
|
||||
}
|
||||
|
||||
// Click - Toggle if a cell is alive or dead on click
|
||||
func (g *Game) Click(x, y int32) {
|
||||
for i := int32(0); i <= g.Cols; i++ {
|
||||
for j := int32(0); j <= g.Rows; j++ {
|
||||
cell := g.Cells[i][j].Position
|
||||
if int32(cell.X) < x && int32(cell.X)+squareSize > x && int32(cell.Y) < y && int32(cell.Y)+squareSize > y {
|
||||
g.Cells[i][j].Alive = !g.Cells[i][j].Alive
|
||||
g.Cells[i][j].Next = g.Cells[i][j].Alive
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update - Update game
|
||||
func (g *Game) Update() {
|
||||
for i := int32(0); i <= g.Cols; i++ {
|
||||
for j := int32(0); j <= g.Rows; j++ {
|
||||
NeighborCount := g.CountNeighbors(i, j)
|
||||
if g.Cells[i][j].Alive {
|
||||
if NeighborCount < 2 {
|
||||
g.Cells[i][j].Next = false
|
||||
} else if NeighborCount > 3 {
|
||||
g.Cells[i][j].Next = false
|
||||
} else {
|
||||
g.Cells[i][j].Next = true
|
||||
}
|
||||
} else {
|
||||
if NeighborCount == 3 {
|
||||
g.Cells[i][j].Next = true
|
||||
g.Cells[i][j].Visited = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := int32(0); i <= g.Cols; i++ {
|
||||
for j := int32(0); j < g.Rows; j++ {
|
||||
g.Cells[i][j].Alive = g.Cells[i][j].Next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CountNeighbors - Counts how many neighbous a cell has
|
||||
func (g *Game) CountNeighbors(x, y int32) int {
|
||||
count := 0
|
||||
|
||||
for i := int32(-1); i < 2; i++ {
|
||||
for j := int32(-1); j < 2; j++ {
|
||||
col := (x + i + (g.Cols)) % (g.Cols)
|
||||
row := (y + j + (g.Rows)) % (g.Rows)
|
||||
if g.Cells[col][row].Alive {
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if g.Cells[x][y].Alive {
|
||||
count--
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
// Draw - Draw game
|
||||
func (g *Game) Draw() {
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.RayWhite)
|
||||
|
||||
// Draw cells
|
||||
for x := int32(0); x <= g.Cols; x++ {
|
||||
for y := int32(0); y <= g.Rows; y++ {
|
||||
if g.Cells[x][y].Alive {
|
||||
rl.DrawRectangleV(g.Cells[x][y].Position, g.Cells[x][y].Size, rl.Blue)
|
||||
} else if g.Cells[x][y].Visited {
|
||||
rl.DrawRectangleV(g.Cells[x][y].Position, g.Cells[x][y].Size, rl.Color{R: 128, G: 177, B: 136, A: 255})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw grid lines
|
||||
for i := int32(0); i < g.Cols+1; i++ {
|
||||
rl.DrawLineV(
|
||||
rl.NewVector2(float32(squareSize*i), 0),
|
||||
rl.NewVector2(float32(squareSize*i), float32(g.ScreenHeight)),
|
||||
rl.LightGray,
|
||||
)
|
||||
}
|
||||
|
||||
for i := int32(0); i < g.Rows+1; i++ {
|
||||
rl.DrawLineV(
|
||||
rl.NewVector2(0, float32(squareSize*i)),
|
||||
rl.NewVector2(float32(g.ScreenWidth), float32(squareSize*i)),
|
||||
rl.LightGray,
|
||||
)
|
||||
}
|
||||
|
||||
rl.EndDrawing()
|
||||
}
|
238
examples/games/snake/main.go
Normal file
238
examples/games/snake/main.go
Normal file
|
@ -0,0 +1,238 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
snakeLength = 256
|
||||
squareSize = 31
|
||||
)
|
||||
|
||||
// Snake type
|
||||
type Snake struct {
|
||||
Position rl.Vector2
|
||||
Size rl.Vector2
|
||||
Speed rl.Vector2
|
||||
Color rl.Color
|
||||
}
|
||||
|
||||
// Food type
|
||||
type Food struct {
|
||||
Position rl.Vector2
|
||||
Size rl.Vector2
|
||||
Active bool
|
||||
Color rl.Color
|
||||
}
|
||||
|
||||
// Game type
|
||||
type Game struct {
|
||||
ScreenWidth int32
|
||||
ScreenHeight int32
|
||||
|
||||
FramesCounter int32
|
||||
GameOver bool
|
||||
Pause bool
|
||||
|
||||
Fruit Food
|
||||
Snake []Snake
|
||||
SnakePosition []rl.Vector2
|
||||
AllowMove bool
|
||||
Offset rl.Vector2
|
||||
CounterTail int
|
||||
}
|
||||
|
||||
func main() {
|
||||
game := Game{}
|
||||
game.Init()
|
||||
|
||||
rl.InitWindow(game.ScreenWidth, game.ScreenHeight, "sample game: snake")
|
||||
|
||||
rl.SetTargetFPS(60)
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
game.Update()
|
||||
|
||||
game.Draw()
|
||||
}
|
||||
|
||||
rl.CloseWindow()
|
||||
}
|
||||
|
||||
// Init - Initialize game
|
||||
func (g *Game) Init() {
|
||||
g.ScreenWidth = 800
|
||||
g.ScreenHeight = 450
|
||||
|
||||
g.FramesCounter = 0
|
||||
g.GameOver = false
|
||||
g.Pause = false
|
||||
|
||||
g.CounterTail = 1
|
||||
g.AllowMove = false
|
||||
|
||||
g.Offset = rl.Vector2{}
|
||||
g.Offset.X = float32(g.ScreenWidth % squareSize)
|
||||
g.Offset.Y = float32(g.ScreenHeight % squareSize)
|
||||
|
||||
g.Snake = make([]Snake, snakeLength)
|
||||
|
||||
for i := 0; i < snakeLength; i++ {
|
||||
g.Snake[i].Position = rl.NewVector2(g.Offset.X/2, g.Offset.Y/2)
|
||||
g.Snake[i].Size = rl.NewVector2(squareSize, squareSize)
|
||||
g.Snake[i].Speed = rl.NewVector2(squareSize, 0)
|
||||
|
||||
if i == 0 {
|
||||
g.Snake[i].Color = rl.DarkBlue
|
||||
} else {
|
||||
g.Snake[i].Color = rl.Blue
|
||||
}
|
||||
}
|
||||
|
||||
g.SnakePosition = make([]rl.Vector2, snakeLength)
|
||||
|
||||
for i := 0; i < snakeLength; i++ {
|
||||
g.SnakePosition[i] = rl.NewVector2(0.0, 0.0)
|
||||
}
|
||||
|
||||
g.Fruit.Size = rl.NewVector2(squareSize, squareSize)
|
||||
g.Fruit.Color = rl.SkyBlue
|
||||
g.Fruit.Active = false
|
||||
}
|
||||
|
||||
// Update - Update game
|
||||
func (g *Game) Update() {
|
||||
if !g.GameOver {
|
||||
if rl.IsKeyPressed(rl.KeyP) {
|
||||
g.Pause = !g.Pause
|
||||
}
|
||||
|
||||
if !g.Pause {
|
||||
// control
|
||||
if rl.IsKeyPressed(rl.KeyRight) && g.Snake[0].Speed.X == 0 && g.AllowMove {
|
||||
g.Snake[0].Speed = rl.NewVector2(squareSize, 0)
|
||||
g.AllowMove = false
|
||||
}
|
||||
if rl.IsKeyPressed(rl.KeyLeft) && g.Snake[0].Speed.X == 0 && g.AllowMove {
|
||||
g.Snake[0].Speed = rl.NewVector2(-squareSize, 0)
|
||||
g.AllowMove = false
|
||||
}
|
||||
if rl.IsKeyPressed(rl.KeyUp) && g.Snake[0].Speed.Y == 0 && g.AllowMove {
|
||||
g.Snake[0].Speed = rl.NewVector2(0, -squareSize)
|
||||
g.AllowMove = false
|
||||
}
|
||||
if rl.IsKeyPressed(rl.KeyDown) && g.Snake[0].Speed.Y == 0 && g.AllowMove {
|
||||
g.Snake[0].Speed = rl.NewVector2(0, squareSize)
|
||||
g.AllowMove = false
|
||||
}
|
||||
|
||||
// movement
|
||||
for i := 0; i < g.CounterTail; i++ {
|
||||
g.SnakePosition[i] = g.Snake[i].Position
|
||||
}
|
||||
|
||||
if g.FramesCounter%5 == 0 {
|
||||
for i := 0; i < g.CounterTail; i++ {
|
||||
if i == 0 {
|
||||
g.Snake[0].Position.X += g.Snake[0].Speed.X
|
||||
g.Snake[0].Position.Y += g.Snake[0].Speed.Y
|
||||
g.AllowMove = true
|
||||
} else {
|
||||
g.Snake[i].Position = g.SnakePosition[i-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wall behaviour
|
||||
if ((g.Snake[0].Position.X) > (float32(g.ScreenWidth) - g.Offset.X)) ||
|
||||
((g.Snake[0].Position.Y) > (float32(g.ScreenHeight) - g.Offset.Y)) ||
|
||||
(g.Snake[0].Position.X < 0) || (g.Snake[0].Position.Y < 0) {
|
||||
g.GameOver = true
|
||||
}
|
||||
|
||||
// collision with yourself
|
||||
for i := 1; i < g.CounterTail; i++ {
|
||||
if (g.Snake[0].Position.X == g.Snake[i].Position.X) && (g.Snake[0].Position.Y == g.Snake[i].Position.Y) {
|
||||
g.GameOver = true
|
||||
}
|
||||
}
|
||||
|
||||
if !g.Fruit.Active {
|
||||
g.Fruit.Active = true
|
||||
g.Fruit.Position = rl.NewVector2(
|
||||
float32(rl.GetRandomValue(0, (g.ScreenWidth/squareSize)-1)*squareSize+int32(g.Offset.X)/2),
|
||||
float32(rl.GetRandomValue(0, (g.ScreenHeight/squareSize)-1)*squareSize+int32(g.Offset.Y)/2),
|
||||
)
|
||||
|
||||
for i := 0; i < g.CounterTail; i++ {
|
||||
for (g.Fruit.Position.X == g.Snake[i].Position.X) && (g.Fruit.Position.Y == g.Snake[i].Position.Y) {
|
||||
g.Fruit.Position = rl.NewVector2(
|
||||
float32(rl.GetRandomValue(0, (g.ScreenWidth/squareSize)-1)*squareSize),
|
||||
float32(rl.GetRandomValue(0, (g.ScreenHeight/squareSize)-1)*squareSize),
|
||||
)
|
||||
i = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// collision
|
||||
if rl.CheckCollisionRecs(
|
||||
rl.NewRectangle(g.Snake[0].Position.X, g.Snake[0].Position.Y, g.Snake[0].Size.X, g.Snake[0].Size.Y),
|
||||
rl.NewRectangle(g.Fruit.Position.X, g.Fruit.Position.Y, g.Fruit.Size.X, g.Fruit.Size.Y),
|
||||
) {
|
||||
g.Snake[g.CounterTail].Position = g.SnakePosition[g.CounterTail-1]
|
||||
g.CounterTail += 1
|
||||
g.Fruit.Active = false
|
||||
}
|
||||
|
||||
g.FramesCounter++
|
||||
}
|
||||
} else {
|
||||
if rl.IsKeyPressed(rl.KeyEnter) {
|
||||
g.Init()
|
||||
g.GameOver = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw - Draw game
|
||||
func (g *Game) Draw() {
|
||||
rl.BeginDrawing()
|
||||
|
||||
rl.ClearBackground(rl.RayWhite)
|
||||
|
||||
if !g.GameOver {
|
||||
// Draw grid lines
|
||||
for i := int32(0); i < g.ScreenWidth/squareSize+1; i++ {
|
||||
rl.DrawLineV(
|
||||
rl.NewVector2(float32(squareSize*i)+g.Offset.X/2, g.Offset.Y/2),
|
||||
rl.NewVector2(float32(squareSize*i)+g.Offset.X/2, float32(g.ScreenHeight)-g.Offset.Y/2),
|
||||
rl.LightGray,
|
||||
)
|
||||
}
|
||||
|
||||
for i := int32(0); i < g.ScreenHeight/squareSize+1; i++ {
|
||||
rl.DrawLineV(
|
||||
rl.NewVector2(g.Offset.X/2, float32(squareSize*i)+g.Offset.Y/2),
|
||||
rl.NewVector2(float32(g.ScreenWidth)-g.Offset.X/2, float32(squareSize*i)+g.Offset.Y/2),
|
||||
rl.LightGray,
|
||||
)
|
||||
}
|
||||
|
||||
// Draw snake
|
||||
for i := 0; i < g.CounterTail; i++ {
|
||||
rl.DrawRectangleV(g.Snake[i].Position, g.Snake[i].Size, g.Snake[i].Color)
|
||||
}
|
||||
|
||||
// Draw fruit to pick
|
||||
rl.DrawRectangleV(g.Fruit.Position, g.Fruit.Size, g.Fruit.Color)
|
||||
|
||||
if g.Pause {
|
||||
rl.DrawText("GAME PAUSED", g.ScreenWidth/2-rl.MeasureText("GAME PAUSED", 40)/2, g.ScreenHeight/2-40, 40, rl.Gray)
|
||||
}
|
||||
} else {
|
||||
rl.DrawText("PRESS [ENTER] TO PLAY AGAIN", int32(rl.GetScreenWidth())/2-rl.MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, int32(rl.GetScreenHeight())/2-50, 20, rl.Gray)
|
||||
}
|
||||
|
||||
rl.EndDrawing()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue