-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
krylovia
committed
Aug 13, 2020
0 parents
commit 99154f8
Showing
7 changed files
with
279 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/.* | ||
!/.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Go snake | ||
|
||
![Game screenshot](./screenshot.png 'Game screenshot') | ||
|
||
## Run game | ||
|
||
``` | ||
$ cd cmd/game | ||
$ go run *go | ||
``` | ||
|
||
## Sprites | ||
|
||
[DungeonTilesetII](https://0x72.itch.io/dungeontileset-ii) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
package main | ||
|
||
import ( | ||
"image" | ||
_ "image/png" | ||
"log" | ||
"math/rand" | ||
"time" | ||
|
||
"github.com/hajimehoshi/ebiten" | ||
"github.com/hajimehoshi/ebiten/ebitenutil" | ||
"github.com/hajimehoshi/ebiten/inpututil" | ||
) | ||
|
||
const ( | ||
screenWidth = 240 | ||
screenHeight = 240 | ||
|
||
tileSize = 16 | ||
tileXNum = 32 | ||
|
||
// SpriteBack - sprite for background | ||
SpriteBack = 129 | ||
|
||
// SpriteSnake - sprite for snake piece | ||
SpriteSnake = 126 | ||
) | ||
|
||
var ( | ||
tilesImage *ebiten.Image | ||
snakePosition [][]int | ||
currentDirection = ebiten.KeyRight | ||
isFinished = true | ||
pieceToPick = [2]int{-1, -1} | ||
) | ||
|
||
func init() { | ||
var err error | ||
tilesImage, _, err = ebitenutil.NewImageFromFile("assets/sprites.png", ebiten.FilterDefault) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
rand.Seed(time.Now().UnixNano()) | ||
} | ||
|
||
// Game ... | ||
type Game struct { | ||
counter int | ||
} | ||
|
||
// Update state | ||
func (g *Game) Update(screen *ebiten.Image) error { | ||
if isFinished { | ||
if inpututil.IsKeyJustPressed(ebiten.KeyR) { | ||
initNewGame() | ||
} else { | ||
return nil | ||
} | ||
} | ||
g.counter++ | ||
doStep := g.counter%10 == 1 | ||
if doStep { | ||
const xNum = screenWidth / tileSize | ||
const yNum = screenHeight / tileSize | ||
oldFirstSnakePiece := snakePosition[len(snakePosition)-1] | ||
newFirstSnakePiece := []int{oldFirstSnakePiece[0], oldFirstSnakePiece[1]} | ||
isFinished = true | ||
if currentDirection == ebiten.KeyUp { | ||
if newFirstSnakePiece[1] > 0 { | ||
newFirstSnakePiece[1]-- | ||
isFinished = false | ||
} | ||
} else if currentDirection == ebiten.KeyDown { | ||
if newFirstSnakePiece[1] < (yNum - 1) { | ||
newFirstSnakePiece[1]++ | ||
isFinished = false | ||
} | ||
} else if currentDirection == ebiten.KeyLeft { | ||
if newFirstSnakePiece[0] > 0 { | ||
newFirstSnakePiece[0]-- | ||
isFinished = false | ||
} | ||
} else if currentDirection == ebiten.KeyRight { | ||
if newFirstSnakePiece[0] < (xNum - 1) { | ||
newFirstSnakePiece[0]++ | ||
isFinished = false | ||
} | ||
} | ||
if !isFinished { | ||
// Check self-crossing | ||
for i, piece := range snakePosition { | ||
if i == 0 { | ||
continue // Skip first item (it is last snake piece and will be deleted anyway) | ||
} | ||
if piece[0] == newFirstSnakePiece[0] && piece[1] == newFirstSnakePiece[1] { | ||
isFinished = true | ||
break | ||
} | ||
} | ||
} | ||
if isFinished { | ||
return nil | ||
} | ||
startIndex := 1 | ||
if newFirstSnakePiece[0] == pieceToPick[0] && newFirstSnakePiece[1] == pieceToPick[1] { | ||
startIndex = 0 | ||
pieceToPick = getPieceToPick() | ||
} | ||
snakePosition = append(snakePosition[startIndex:len(snakePosition)], newFirstSnakePiece) | ||
} | ||
if inpututil.IsKeyJustPressed(ebiten.KeyUp) && currentDirection != ebiten.KeyDown { | ||
currentDirection = ebiten.KeyUp | ||
} else if inpututil.IsKeyJustPressed(ebiten.KeyDown) && currentDirection != ebiten.KeyUp { | ||
currentDirection = ebiten.KeyDown | ||
} else if inpututil.IsKeyJustPressed(ebiten.KeyLeft) && currentDirection != ebiten.KeyRight { | ||
currentDirection = ebiten.KeyLeft | ||
} else if inpututil.IsKeyJustPressed(ebiten.KeyRight) && currentDirection != ebiten.KeyLeft { | ||
currentDirection = ebiten.KeyRight | ||
} | ||
return nil | ||
} | ||
|
||
func initNewGame() { | ||
snakePosition = [][]int{ | ||
{0, 0}, | ||
{1, 0}, | ||
{2, 0}, | ||
{3, 0}, | ||
{4, 0}, | ||
} | ||
currentDirection = ebiten.KeyRight | ||
pieceToPick = getPieceToPick() | ||
isFinished = false | ||
} | ||
|
||
func getPieceToPick() [2]int { | ||
const xMax = screenWidth / tileSize | ||
const yMax = screenHeight / tileSize | ||
var newPieceX, newPieceY int | ||
for { | ||
newPieceIndex := rand.Intn(xMax * yMax) | ||
newPieceX = newPieceIndex % xMax | ||
newPieceY = newPieceIndex / xMax | ||
isEmptyCell := true | ||
for _, piece := range snakePosition { | ||
if piece[0] == newPieceX && piece[1] == newPieceY { | ||
isEmptyCell = false | ||
break | ||
} | ||
} | ||
if isEmptyCell { | ||
break | ||
} | ||
} | ||
return [2]int{newPieceX, newPieceY} | ||
} | ||
|
||
// Draw scene | ||
func (g *Game) Draw(screen *ebiten.Image) { | ||
const xNum = screenWidth / tileSize | ||
const yNum = screenHeight / tileSize | ||
// Draw background | ||
sx := (SpriteBack % tileXNum) * tileSize | ||
sy := (SpriteBack / tileXNum) * tileSize | ||
for x := 0; x < xNum; x++ { | ||
for y := 0; y < yNum; y++ { | ||
op := &ebiten.DrawImageOptions{} | ||
op.GeoM.Translate(float64(x*tileSize), float64(y*tileSize)) | ||
screen.DrawImage(tilesImage.SubImage(image.Rect(sx, sy, sx+tileSize, sy+tileSize)).(*ebiten.Image), op) | ||
} | ||
} | ||
// Draw snake | ||
sx = (SpriteSnake % tileXNum) * tileSize | ||
sy = (SpriteSnake / tileXNum) * tileSize | ||
for _, p := range snakePosition { | ||
op := &ebiten.DrawImageOptions{} | ||
op.GeoM.Translate(float64(p[0]*tileSize), float64(p[1]*tileSize)) | ||
screen.DrawImage(tilesImage.SubImage(image.Rect(sx, sy, sx+tileSize, sy+tileSize)).(*ebiten.Image), op) | ||
} | ||
// Draw piece to pick | ||
if pieceToPick[0] != -1 { | ||
sx = (SpriteSnake % tileXNum) * tileSize | ||
sy = (SpriteSnake / tileXNum) * tileSize | ||
op := &ebiten.DrawImageOptions{} | ||
op.GeoM.Translate(float64(pieceToPick[0]*tileSize), float64(pieceToPick[1]*tileSize)) | ||
screen.DrawImage(tilesImage.SubImage(image.Rect(sx, sy, sx+tileSize, sy+tileSize)).(*ebiten.Image), op) | ||
} | ||
// Draw finish text | ||
if isFinished { | ||
ebitenutil.DebugPrint(screen, "You've lost :( Press R to restart") | ||
} | ||
} | ||
|
||
// Layout ... | ||
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) { | ||
return screenWidth, screenHeight | ||
} | ||
|
||
func main() { | ||
g := &Game{} | ||
ebiten.SetWindowSize(screenWidth*2, screenHeight*2) | ||
ebiten.SetWindowTitle("Go Snake") | ||
initNewGame() | ||
if err := ebiten.RunGame(g); err != nil { | ||
log.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/kiaplayer/go_snake | ||
|
||
go 1.14 | ||
|
||
require github.com/hajimehoshi/ebiten v1.11.7 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= | ||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= | ||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= | ||
github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc= | ||
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= | ||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= | ||
github.com/hajimehoshi/bitmapfont v1.2.0/go.mod h1:h9QrPk6Ktb2neObTlAbma6Ini1xgMjbJ3w7ysmD7IOU= | ||
github.com/hajimehoshi/ebiten v1.11.7 h1:kxfhTXvKsS8y4XYJUhmjBUYf+V7H9GQrmq0SnKO6duo= | ||
github.com/hajimehoshi/ebiten v1.11.7/go.mod h1:/cgFsE6vG9LItlxHpVqb33Pcw7DrJFOzGnl/uNifIcE= | ||
github.com/hajimehoshi/go-mp3 v0.2.1/go.mod h1:Rr+2P46iH6PwTPVgSsEwBkon0CK5DxCAeX/Rp65DCTE= | ||
github.com/hajimehoshi/oto v0.3.4/go.mod h1:PgjqsBJff0efqL2nlMJidJgVJywLn6M4y8PI4TfeWfA= | ||
github.com/hajimehoshi/oto v0.6.3/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI= | ||
github.com/jakecoffman/cp v0.1.0/go.mod h1:a3xPx9N8RyFAACD644t2dj/nK4SuLg1v+jL61m2yVo4= | ||
github.com/jfreymuth/oggvorbis v1.0.0/go.mod h1:abe6F9QRjuU9l+2jek3gj46lu40N4qlYxh2grqkLEDM= | ||
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0= | ||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= | ||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= | ||
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | ||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | ||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | ||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= | ||
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= | ||
golang.org/x/mobile v0.0.0-20200222142934-3c8601c510d0/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= | ||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= | ||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= | ||
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= | ||
golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= | ||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.