polish some things
This commit is contained in:
@@ -5,6 +5,8 @@ import "image/color"
|
|||||||
var (
|
var (
|
||||||
Black = color.RGBA{0, 0, 0, 1}
|
Black = color.RGBA{0, 0, 0, 1}
|
||||||
LightGray = color.RGBA{24, 24, 24, 1}
|
LightGray = color.RGBA{24, 24, 24, 1}
|
||||||
|
Gray = color.RGBA{80, 80, 80, 1}
|
||||||
Red = color.RGBA{186, 46, 46, 1}
|
Red = color.RGBA{186, 46, 46, 1}
|
||||||
|
Green = color.RGBA{46, 186, 46, 1}
|
||||||
DarkYellow = color.RGBA{184, 178, 94, 1}
|
DarkYellow = color.RGBA{184, 178, 94, 1}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ func (b *MenuButton) GetMenuButtonImg(
|
|||||||
|
|
||||||
fontOptions := &text.DrawOptions{}
|
fontOptions := &text.DrawOptions{}
|
||||||
if isFocused {
|
if isFocused {
|
||||||
fontOptions.ColorScale.ScaleWithColor(colors.Red)
|
|
||||||
} else {
|
|
||||||
fontOptions.ColorScale.ScaleWithColor(color.White)
|
fontOptions.ColorScale.ScaleWithColor(color.White)
|
||||||
|
} else {
|
||||||
|
fontOptions.ColorScale.ScaleWithColor(colors.Gray)
|
||||||
}
|
}
|
||||||
|
|
||||||
text.Draw(
|
text.Draw(
|
||||||
|
|||||||
+28
-12
@@ -9,8 +9,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
WINDOW_WIDTH int = 1200
|
WindowWidth int = 500
|
||||||
WINDOW_HEIGHT int = 800
|
WindowHeight int = 500
|
||||||
)
|
)
|
||||||
|
|
||||||
type GameState int
|
type GameState int
|
||||||
@@ -19,6 +19,7 @@ const (
|
|||||||
MainMenu GameState = iota
|
MainMenu GameState = iota
|
||||||
Playing
|
Playing
|
||||||
Dead
|
Dead
|
||||||
|
Won
|
||||||
)
|
)
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
@@ -32,7 +33,7 @@ type Game struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func InitGame() *Game {
|
func InitGame() *Game {
|
||||||
ebiten.SetWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT)
|
ebiten.SetWindowSize(WindowWidth, WindowHeight)
|
||||||
ebiten.SetWindowTitle("Snake")
|
ebiten.SetWindowTitle("Snake")
|
||||||
|
|
||||||
fontFile, err := os.Open("fonts/rockers_garage.ttf")
|
fontFile, err := os.Open("fonts/rockers_garage.ttf")
|
||||||
@@ -49,7 +50,7 @@ func InitGame() *Game {
|
|||||||
font: font,
|
font: font,
|
||||||
titleImg: initTitle(font),
|
titleImg: initTitle(font),
|
||||||
state: MainMenu,
|
state: MainMenu,
|
||||||
snake: InitSnake(WINDOW_WIDTH, WINDOW_HEIGHT),
|
snake: InitSnake(WindowWidth, WindowHeight),
|
||||||
menu: InitMenu(),
|
menu: InitMenu(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,12 +68,21 @@ func (g *Game) Update() error {
|
|||||||
g.snake.Move()
|
g.snake.Move()
|
||||||
|
|
||||||
if g.snake.HasCollided() {
|
if g.snake.HasCollided() {
|
||||||
g.snake.isDead = true
|
g.state = Dead
|
||||||
|
// g.snake.isDead = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if g.snake.isDead {
|
if g.snake.score == g.snake.total {
|
||||||
g.snake.Click(g)
|
g.state = Won
|
||||||
|
// g.snake.hasWon = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if g.snake.isDead || g.snake.hasWon {
|
||||||
|
// g.snake.Click(g)
|
||||||
|
// }
|
||||||
|
|
||||||
|
case Dead, Won:
|
||||||
|
g.snake.Click(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -87,28 +97,34 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
|||||||
|
|
||||||
case Playing:
|
case Playing:
|
||||||
g.snake.Render(screen, g.font)
|
g.snake.Render(screen, g.font)
|
||||||
|
|
||||||
|
case Won:
|
||||||
|
g.snake.renderWinScreen(screen, g.font)
|
||||||
|
|
||||||
|
case Dead:
|
||||||
|
g.snake.renderDeadScreen(screen, g.font)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Layout(outsideWith, outsideHeight int) (screenWidth, screenHeight int) {
|
func (g *Game) Layout(outsideWith, outsideHeight int) (screenWidth, screenHeight int) {
|
||||||
return WINDOW_WIDTH, WINDOW_HEIGHT
|
return WindowWidth, WindowHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
func initTitle(font *text.GoTextFaceSource) *ebiten.Image {
|
func initTitle(font *text.GoTextFaceSource) *ebiten.Image {
|
||||||
face := &text.GoTextFace{
|
face := &text.GoTextFace{
|
||||||
Source: font,
|
Source: font,
|
||||||
Size: 60,
|
Size: 30,
|
||||||
}
|
}
|
||||||
|
|
||||||
titleW, _ := text.Measure("snake", face, 0)
|
titleW, _ := text.Measure("snake", face, 0)
|
||||||
|
|
||||||
fontOptions := &text.DrawOptions{}
|
fontOptions := &text.DrawOptions{}
|
||||||
fontOptions.GeoM.Translate(float64(WINDOW_WIDTH)/2-titleW/2, 10)
|
fontOptions.GeoM.Translate(float64(WindowWidth)/2-titleW/2, 10)
|
||||||
fontOptions.ColorScale.ScaleWithColor(color.RGBA{194, 169, 60, 1})
|
fontOptions.ColorScale.ScaleWithColor(color.RGBA{194, 169, 60, 1})
|
||||||
|
|
||||||
h := float64(WINDOW_HEIGHT) * 0.1
|
h := float64(WindowHeight) * 0.1
|
||||||
|
|
||||||
titleImg := ebiten.NewImage(WINDOW_WIDTH, int(h))
|
titleImg := ebiten.NewImage(WindowWidth, int(h))
|
||||||
|
|
||||||
text.Draw(titleImg, "snake", face, fontOptions)
|
text.Draw(titleImg, "snake", face, fontOptions)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -43,7 +43,7 @@ func (m *Menu) Click(game *Game) {
|
|||||||
func (m *Menu) executeAction(game *Game, action buttons.MenuAction) {
|
func (m *Menu) executeAction(game *Game, action buttons.MenuAction) {
|
||||||
switch action {
|
switch action {
|
||||||
case buttons.StartGame:
|
case buttons.StartGame:
|
||||||
game.snake = InitSnake(WINDOW_WIDTH, WINDOW_HEIGHT)
|
game.snake = InitSnake(WindowWidth, WindowHeight)
|
||||||
game.state = Playing
|
game.state = Playing
|
||||||
|
|
||||||
case buttons.ExitGame:
|
case buttons.ExitGame:
|
||||||
@@ -80,7 +80,7 @@ func (m *Menu) Render(screen *ebiten.Image, font *text.GoTextFaceSource) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
imgOp := &ebiten.DrawImageOptions{}
|
imgOp := &ebiten.DrawImageOptions{}
|
||||||
imgOp.GeoM.Translate(150, 200)
|
imgOp.GeoM.Translate(50, 100)
|
||||||
screen.DrawImage(m.img, imgOp)
|
screen.DrawImage(m.img, imgOp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+76
-46
@@ -40,17 +40,19 @@ type Snake struct {
|
|||||||
diff time.Duration
|
diff time.Duration
|
||||||
|
|
||||||
isDead bool
|
isDead bool
|
||||||
|
hasWon bool
|
||||||
|
|
||||||
total int
|
total int
|
||||||
score int
|
score int
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
START_LENGTH = 20
|
StartLength = 20
|
||||||
THICKNESS = 8
|
Thickness = 10
|
||||||
MIN_SPEED int64 = 500
|
MinSpeed int64 = 400
|
||||||
MAX_SPEED int64 = 50
|
MaxSpeed int64 = 50
|
||||||
MAX_SPRINT int64 = 20
|
MaxSprint int64 = 20
|
||||||
|
EnnemiesCount = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitSnake(width, height int) *Snake {
|
func InitSnake(width, height int) *Snake {
|
||||||
@@ -60,11 +62,13 @@ func InitSnake(width, height int) *Snake {
|
|||||||
|
|
||||||
return &Snake{
|
return &Snake{
|
||||||
img: img,
|
img: img,
|
||||||
speed: MIN_SPEED,
|
speed: MinSpeed,
|
||||||
direction: Right,
|
direction: Right,
|
||||||
positions: getInitPositions(utils.GetCenter(width, height)),
|
positions: getInitPositions(utils.GetCenter(width, height)),
|
||||||
ennemies: randomEnnemies(width, h, 10),
|
ennemies: randomEnnemies(width, h, EnnemiesCount),
|
||||||
isDead: false,
|
isDead: false,
|
||||||
|
total: EnnemiesCount,
|
||||||
|
score: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,11 +81,6 @@ func (snake *Snake) Render(screen *ebiten.Image, font *text.GoTextFaceSource) {
|
|||||||
|
|
||||||
renderScoreScreen(screen, snake, font)
|
renderScoreScreen(screen, snake, font)
|
||||||
|
|
||||||
if snake.isDead {
|
|
||||||
renderDeadScreen(screen, snake, font)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
snake.img.Fill(colors.LightGray)
|
snake.img.Fill(colors.LightGray)
|
||||||
|
|
||||||
for _, ennemy := range snake.ennemies {
|
for _, ennemy := range snake.ennemies {
|
||||||
@@ -89,8 +88,8 @@ func (snake *Snake) Render(screen *ebiten.Image, font *text.GoTextFaceSource) {
|
|||||||
snake.img,
|
snake.img,
|
||||||
float32(ennemy.X),
|
float32(ennemy.X),
|
||||||
float32(ennemy.Y),
|
float32(ennemy.Y),
|
||||||
THICKNESS,
|
Thickness,
|
||||||
THICKNESS,
|
Thickness,
|
||||||
colors.DarkYellow,
|
colors.DarkYellow,
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
@@ -101,8 +100,8 @@ func (snake *Snake) Render(screen *ebiten.Image, font *text.GoTextFaceSource) {
|
|||||||
snake.img,
|
snake.img,
|
||||||
float32(point.X),
|
float32(point.X),
|
||||||
float32(point.Y),
|
float32(point.Y),
|
||||||
THICKNESS,
|
Thickness,
|
||||||
THICKNESS,
|
Thickness,
|
||||||
color.White,
|
color.White,
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
@@ -168,9 +167,11 @@ func (snake *Snake) Eat() {
|
|||||||
snake.positions...,
|
snake.positions...,
|
||||||
)
|
)
|
||||||
|
|
||||||
if snake.speed > MAX_SPEED {
|
if snake.speed > MaxSpeed {
|
||||||
snake.speed -= 50
|
snake.speed -= 50
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snake.score += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (snake *Snake) Move() {
|
func (snake *Snake) Move() {
|
||||||
@@ -180,7 +181,7 @@ func (snake *Snake) Move() {
|
|||||||
|
|
||||||
var speed int64
|
var speed int64
|
||||||
if snake.sprint {
|
if snake.sprint {
|
||||||
speed = MAX_SPRINT
|
speed = MaxSprint
|
||||||
} else {
|
} else {
|
||||||
speed = snake.speed
|
speed = snake.speed
|
||||||
}
|
}
|
||||||
@@ -215,13 +216,13 @@ func (snake *Snake) getNextPosition() image.Point {
|
|||||||
|
|
||||||
switch snake.direction {
|
switch snake.direction {
|
||||||
case Up:
|
case Up:
|
||||||
nextHead.Y = nextHead.Y - THICKNESS
|
nextHead.Y = nextHead.Y - Thickness
|
||||||
case Right:
|
case Right:
|
||||||
nextHead.X = nextHead.X + THICKNESS
|
nextHead.X = nextHead.X + Thickness
|
||||||
case Down:
|
case Down:
|
||||||
nextHead.Y = nextHead.Y + THICKNESS
|
nextHead.Y = nextHead.Y + Thickness
|
||||||
case Left:
|
case Left:
|
||||||
nextHead.X = nextHead.X - THICKNESS
|
nextHead.X = nextHead.X - Thickness
|
||||||
}
|
}
|
||||||
|
|
||||||
return nextHead
|
return nextHead
|
||||||
@@ -237,8 +238,8 @@ func (snake *Snake) Click(game *Game) {
|
|||||||
func getInitPositions(center image.Point) []image.Point {
|
func getInitPositions(center image.Point) []image.Point {
|
||||||
points := []image.Point{}
|
points := []image.Point{}
|
||||||
|
|
||||||
for i := range START_LENGTH {
|
for i := range StartLength {
|
||||||
points = append(points, image.Point{X: center.X - i*THICKNESS, Y: center.Y})
|
points = append(points, image.Point{X: center.X - i*Thickness, Y: center.Y})
|
||||||
}
|
}
|
||||||
|
|
||||||
return points
|
return points
|
||||||
@@ -247,12 +248,12 @@ func getInitPositions(center image.Point) []image.Point {
|
|||||||
func randomEnnemies(width int, height int, count int) []image.Point {
|
func randomEnnemies(width int, height int, count int) []image.Point {
|
||||||
ennemies := []image.Point{}
|
ennemies := []image.Point{}
|
||||||
|
|
||||||
w := width / THICKNESS
|
w := width / Thickness
|
||||||
h := height / THICKNESS
|
h := height / Thickness
|
||||||
|
|
||||||
for range count {
|
for range count {
|
||||||
x := rand.Intn(w) * THICKNESS
|
x := rand.Intn(w) * Thickness
|
||||||
y := rand.Intn(h) * THICKNESS
|
y := rand.Intn(h) * Thickness
|
||||||
|
|
||||||
ennemies = append(ennemies, image.Point{X: x, Y: y})
|
ennemies = append(ennemies, image.Point{X: x, Y: y})
|
||||||
}
|
}
|
||||||
@@ -261,31 +262,18 @@ func randomEnnemies(width int, height int, count int) []image.Point {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func renderScoreScreen(screen *ebiten.Image, snake *Snake, font *text.GoTextFaceSource) {
|
func renderScoreScreen(screen *ebiten.Image, snake *Snake, font *text.GoTextFaceSource) {
|
||||||
scoreImg := ebiten.NewImage(WINDOW_WIDTH, 100)
|
scoreImg := ebiten.NewImage(WindowWidth, 50)
|
||||||
scoreImg.Fill(colors.Red)
|
scoreImg.Fill(colors.Black)
|
||||||
|
|
||||||
levelOptions := &text.DrawOptions{}
|
|
||||||
levelOptions.ColorScale.ScaleWithColor(color.White)
|
|
||||||
levelOptions.GeoM.Translate(10, 10)
|
|
||||||
text.Draw(
|
|
||||||
scoreImg,
|
|
||||||
"Level 1",
|
|
||||||
&text.GoTextFace{
|
|
||||||
Source: font,
|
|
||||||
Size: 25,
|
|
||||||
},
|
|
||||||
levelOptions,
|
|
||||||
)
|
|
||||||
|
|
||||||
scoreOptions := &text.DrawOptions{}
|
scoreOptions := &text.DrawOptions{}
|
||||||
scoreOptions.ColorScale.ScaleWithColor(color.White)
|
scoreOptions.ColorScale.ScaleWithColor(color.White)
|
||||||
scoreOptions.GeoM.Translate(100, 10)
|
scoreOptions.GeoM.Translate(float64(WindowWidth)-100, 15)
|
||||||
text.Draw(
|
text.Draw(
|
||||||
scoreImg,
|
scoreImg,
|
||||||
fmt.Sprintf("Score: %d/%d", snake.score, snake.total),
|
fmt.Sprintf("Score: %d/%d", snake.score, snake.total),
|
||||||
&text.GoTextFace{
|
&text.GoTextFace{
|
||||||
Source: font,
|
Source: font,
|
||||||
Size: 25,
|
Size: 20,
|
||||||
},
|
},
|
||||||
scoreOptions,
|
scoreOptions,
|
||||||
)
|
)
|
||||||
@@ -295,7 +283,49 @@ func renderScoreScreen(screen *ebiten.Image, snake *Snake, font *text.GoTextFace
|
|||||||
screen.DrawImage(snake.img, &ebiten.DrawImageOptions{})
|
screen.DrawImage(snake.img, &ebiten.DrawImageOptions{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderDeadScreen(screen *ebiten.Image, snake *Snake, font *text.GoTextFaceSource) {
|
func (snake *Snake) renderWinScreen(screen *ebiten.Image, font *text.GoTextFaceSource) {
|
||||||
|
snake.img.Fill(colors.Black)
|
||||||
|
|
||||||
|
fontOptions := &text.DrawOptions{}
|
||||||
|
fontOptions.ColorScale.ScaleWithColor(colors.Green)
|
||||||
|
|
||||||
|
winImg := ebiten.NewImage(450, 90)
|
||||||
|
|
||||||
|
text.Draw(
|
||||||
|
winImg,
|
||||||
|
"You won !",
|
||||||
|
&text.GoTextFace{
|
||||||
|
Source: font,
|
||||||
|
Size: 80,
|
||||||
|
},
|
||||||
|
fontOptions,
|
||||||
|
)
|
||||||
|
|
||||||
|
deadImgW := winImg.Bounds().Dx()
|
||||||
|
deadImgH := winImg.Bounds().Dy()
|
||||||
|
x := float64(screen.Bounds().Dx()/2 - deadImgW/2)
|
||||||
|
y := float64(screen.Bounds().Dy()/2 - deadImgH/2)
|
||||||
|
op := &ebiten.DrawImageOptions{}
|
||||||
|
op.GeoM.Translate(x, y)
|
||||||
|
snake.img.DrawImage(winImg, op)
|
||||||
|
|
||||||
|
// ---- return to menu button
|
||||||
|
|
||||||
|
returnToMenuButton := buttons.MenuButton{
|
||||||
|
Value: "return to menu",
|
||||||
|
Action: buttons.ReturnToMenu,
|
||||||
|
}
|
||||||
|
|
||||||
|
rtmbImg := returnToMenuButton.GetMenuButtonImg(font, 24, true)
|
||||||
|
|
||||||
|
rtmOp := &ebiten.DrawImageOptions{}
|
||||||
|
rtmOp.GeoM.Translate(x, y+100)
|
||||||
|
snake.img.DrawImage(rtmbImg, rtmOp)
|
||||||
|
|
||||||
|
screen.DrawImage(snake.img, &ebiten.DrawImageOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (snake *Snake) renderDeadScreen(screen *ebiten.Image, font *text.GoTextFaceSource) {
|
||||||
snake.img.Fill(colors.Black)
|
snake.img.Fill(colors.Black)
|
||||||
|
|
||||||
fontOptions := &text.DrawOptions{}
|
fontOptions := &text.DrawOptions{}
|
||||||
|
|||||||
Reference in New Issue
Block a user