everything I got
This commit is contained in:
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Package",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "auto",
|
||||||
|
"program": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
assets/.DS_Store
vendored
Normal file
BIN
assets/.DS_Store
vendored
Normal file
Binary file not shown.
71
assets/audio.go
Normal file
71
assets/audio.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package assets
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"embed"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/audio"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/audio/wav"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed *
|
||||||
|
//go:embed */*
|
||||||
|
var embeddedFiles embed.FS
|
||||||
|
var sampleRate = 44100
|
||||||
|
var audioContext = audio.NewContext(sampleRate)
|
||||||
|
var songChoice = 2
|
||||||
|
var SongTracks = loadTracksForSong(songChoice)
|
||||||
|
|
||||||
|
func loadTracksForSong(sng int) map[int]*audio.Player {
|
||||||
|
tempMap := make(map[int]*audio.Player)
|
||||||
|
for i := 1; i <= 10; i++ {
|
||||||
|
tempMap[i] = LoadWavAudioFile(fmt.Sprintf("audio/song0%d/track%02d.wav", sng, i), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tempMap
|
||||||
|
}
|
||||||
|
|
||||||
|
var SFXLibrary = map[string]*audio.Player{
|
||||||
|
"newLevel": LoadWavAudioFile("audio/portal2.wav", false),
|
||||||
|
"colourMatch": LoadWavAudioFile("audio/portal.wav", false),
|
||||||
|
"gameOver": LoadWavAudioFile("audio/gameOver.wav", false),
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadWavAudioFile(filePath string, loop bool) *audio.Player {
|
||||||
|
|
||||||
|
audioData, err := fs.ReadFile(embeddedFiles, filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stream, err := wav.DecodeWithSampleRate(sampleRate, bytes.NewReader(audioData))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to decode audio: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var player *audio.Player
|
||||||
|
|
||||||
|
if loop {
|
||||||
|
lengthOfAudioData := int64(len(audioData))
|
||||||
|
loopingStream := audio.NewInfiniteLoop(stream, lengthOfAudioData)
|
||||||
|
player, err = audioContext.NewPlayer(loopingStream)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
player, err = audioContext.NewPlayer(stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return player
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func SilenceSongTracks() {
|
||||||
|
for _, song := range SongTracks {
|
||||||
|
song.SetVolume(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
assets/audio/.DS_Store
vendored
Normal file
BIN
assets/audio/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
assets/audio/gameOver.wav
Normal file
BIN
assets/audio/gameOver.wav
Normal file
Binary file not shown.
BIN
assets/audio/portal.wav
Normal file
BIN
assets/audio/portal.wav
Normal file
Binary file not shown.
BIN
assets/audio/portal2.wav
Normal file
BIN
assets/audio/portal2.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track01.wav
Normal file
BIN
assets/audio/song01/track01.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track02.wav
Normal file
BIN
assets/audio/song01/track02.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track03.wav
Normal file
BIN
assets/audio/song01/track03.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track04.wav
Normal file
BIN
assets/audio/song01/track04.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track05.wav
Normal file
BIN
assets/audio/song01/track05.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track06.wav
Normal file
BIN
assets/audio/song01/track06.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track07.wav
Normal file
BIN
assets/audio/song01/track07.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track08.wav
Normal file
BIN
assets/audio/song01/track08.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track09.wav
Normal file
BIN
assets/audio/song01/track09.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track10.wav
Normal file
BIN
assets/audio/song01/track10.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track11.wav
Normal file
BIN
assets/audio/song01/track11.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track12.wav
Normal file
BIN
assets/audio/song01/track12.wav
Normal file
Binary file not shown.
BIN
assets/audio/song01/track13.wav
Normal file
BIN
assets/audio/song01/track13.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/.DS_Store
vendored
Normal file
BIN
assets/audio/song02/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
assets/audio/song02/track01.wav
Normal file
BIN
assets/audio/song02/track01.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/track02.wav
Normal file
BIN
assets/audio/song02/track02.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/track03.wav
Normal file
BIN
assets/audio/song02/track03.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/track04.wav
Normal file
BIN
assets/audio/song02/track04.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/track05.wav
Normal file
BIN
assets/audio/song02/track05.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/track06.wav
Normal file
BIN
assets/audio/song02/track06.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/track07.wav
Normal file
BIN
assets/audio/song02/track07.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/track08.wav
Normal file
BIN
assets/audio/song02/track08.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/track09.wav
Normal file
BIN
assets/audio/song02/track09.wav
Normal file
Binary file not shown.
BIN
assets/audio/song02/track10.wav
Normal file
BIN
assets/audio/song02/track10.wav
Normal file
Binary file not shown.
37
assets/fonts.go
Normal file
37
assets/fonts.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package assets
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
"golang.org/x/image/font/opentype"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed *
|
||||||
|
var FontFiles embed.FS
|
||||||
|
var fontFace font.Face
|
||||||
|
|
||||||
|
func LoadFontFace(fileName string, size float64) font.Face {
|
||||||
|
fontBytes, err := FontFiles.ReadFile(fileName)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tt, err := opentype.Parse(fontBytes)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const dpi = 144
|
||||||
|
fontFace, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||||
|
Size: size,
|
||||||
|
DPI: dpi,
|
||||||
|
Hinting: font.HintingNone,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fontFace
|
||||||
|
}
|
||||||
BIN
assets/fonts/mechanical.otf
Normal file
BIN
assets/fonts/mechanical.otf
Normal file
Binary file not shown.
BIN
assets/fonts/robot.otf
Normal file
BIN
assets/fonts/robot.otf
Normal file
Binary file not shown.
182
geometry/grid.go
Normal file
182
geometry/grid.go
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
package geom
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"fmt"
|
||||||
|
"image/color"
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var defaultSquareSpacing = 5
|
||||||
|
var minBorder = 20
|
||||||
|
var ScoreOffset = 50
|
||||||
|
var HighScoreOffset = 10
|
||||||
|
var GameGrid Grid
|
||||||
|
var MaxGridDimension = 20
|
||||||
|
|
||||||
|
type Grid struct {
|
||||||
|
squareSpacing int
|
||||||
|
squares [][]Square
|
||||||
|
startX int
|
||||||
|
startY int
|
||||||
|
squareSize int
|
||||||
|
coloredSquaresRemaining int
|
||||||
|
}
|
||||||
|
|
||||||
|
// used for comparing two squares positions
|
||||||
|
type Pair struct {
|
||||||
|
rowNum int
|
||||||
|
colNum int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr Pair) equal(pr2 Pair) bool {
|
||||||
|
return pr.rowNum == pr2.rowNum && pr.colNum == pr2.colNum
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func pairAlreadyExists(pr Pair, pairs []Pair) bool {
|
||||||
|
result := false
|
||||||
|
for _, nextPair := range pairs {
|
||||||
|
if pr.equal(nextPair) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (grd *Grid) NumSquares() int {
|
||||||
|
size := -1
|
||||||
|
if len(grd.squares[0]) != 0 {
|
||||||
|
size = len(grd.squares) * len(grd.squares[0])
|
||||||
|
}
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns num rows by num columns
|
||||||
|
func (grd *Grid) Size() (int, int) {
|
||||||
|
if len(grd.squares[0]) != 0 {
|
||||||
|
return len(grd.squares), len(grd.squares[0])
|
||||||
|
}
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildGrid(numRows int, numColumns int) {
|
||||||
|
grd := Grid{squareSpacing: defaultSquareSpacing}
|
||||||
|
|
||||||
|
winWidth, winHeight := ebiten.WindowSize()
|
||||||
|
sqSize := min((winWidth-2*minBorder-defaultSquareSpacing*numColumns)/numColumns, (winHeight-2*minBorder-ScoreOffset-3*HighScoreOffset-defaultSquareSpacing*numRows)/numRows)
|
||||||
|
sqSize = max(sqSize, 1) //ensure a nonzero, nonnegative square size
|
||||||
|
gridWidth := numColumns*(sqSize+grd.squareSpacing) - grd.squareSpacing
|
||||||
|
gridHeight := numRows*(sqSize+grd.squareSpacing) - grd.squareSpacing
|
||||||
|
|
||||||
|
currentX := (winWidth - gridWidth) / 2
|
||||||
|
currentY := ScoreOffset + (winHeight-gridHeight-ScoreOffset-HighScoreOffset)/2
|
||||||
|
grd.startX = currentX
|
||||||
|
grd.startY = currentY
|
||||||
|
grd.squareSize = sqSize
|
||||||
|
|
||||||
|
table := make([][]Square, numRows)
|
||||||
|
|
||||||
|
for i := 0; i < numRows; i++ {
|
||||||
|
row := make([]Square, numColumns)
|
||||||
|
for j := 0; j < numColumns; j++ {
|
||||||
|
sq := MakeSquare(sqSize)
|
||||||
|
sq.SetPosition(currentX, currentY)
|
||||||
|
row[j] = sq
|
||||||
|
currentX += sqSize + grd.squareSpacing
|
||||||
|
}
|
||||||
|
table[i] = row
|
||||||
|
currentY += sqSize + grd.squareSpacing
|
||||||
|
currentX = grd.startX
|
||||||
|
}
|
||||||
|
|
||||||
|
grd.squares = table
|
||||||
|
|
||||||
|
//assign random colours to a subset of all squares
|
||||||
|
squaresToColour := min(numColumns, numRows)
|
||||||
|
|
||||||
|
usedPositions := make([]Pair, squaresToColour)
|
||||||
|
coloredSoFar := 0
|
||||||
|
for i := 0; i < squaresToColour; i++ {
|
||||||
|
colourIndex := rand.Intn(len(LightRGBMap))
|
||||||
|
row := rand.Intn(numRows) + 1
|
||||||
|
col := rand.Intn(numColumns) + 1
|
||||||
|
//prevent a colour on the starting square
|
||||||
|
if row == numRows && col == 1 {
|
||||||
|
col = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
//make sure we don't colour the same square twice
|
||||||
|
nextPair := Pair{rowNum: row, colNum: col}
|
||||||
|
if coloredSoFar == 0 {
|
||||||
|
usedPositions[0] = nextPair
|
||||||
|
coloredSoFar = 1
|
||||||
|
} else {
|
||||||
|
for pairAlreadyExists(nextPair, usedPositions) {
|
||||||
|
row = rand.Intn(numRows) + 1
|
||||||
|
col = rand.Intn(numColumns) + 1
|
||||||
|
//prevent a colour on the starting square
|
||||||
|
if row == numRows && col == 1 {
|
||||||
|
col = 2
|
||||||
|
}
|
||||||
|
nextPair = Pair{rowNum: row, colNum: col}
|
||||||
|
}
|
||||||
|
usedPositions[coloredSoFar] = nextPair
|
||||||
|
coloredSoFar += 1
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
grd.ChangeColour(row, col, LightRGBMap[colourIndex])
|
||||||
|
grd.GetSquareAt(row, col).RGBColourIndex = colourIndex
|
||||||
|
}
|
||||||
|
grd.coloredSquaresRemaining = squaresToColour
|
||||||
|
|
||||||
|
GameGrid = grd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (grd *Grid) Draw(screen *ebiten.Image) {
|
||||||
|
opts := &ebiten.DrawImageOptions{}
|
||||||
|
|
||||||
|
for _, rowOfSquares := range grd.squares {
|
||||||
|
for _, sq := range rowOfSquares {
|
||||||
|
xPos := float64(sq.X())
|
||||||
|
yPos := float64(sq.Y())
|
||||||
|
opts.GeoM.Translate(xPos, yPos)
|
||||||
|
screen.DrawImage(sq.Img, opts)
|
||||||
|
opts.GeoM.Reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (grd *Grid) DrawUpTo(finalSquareCount int, screen *ebiten.Image) {
|
||||||
|
opts := &ebiten.DrawImageOptions{}
|
||||||
|
curr := 1
|
||||||
|
for _, rowOfSquares := range grd.squares {
|
||||||
|
for _, sq := range rowOfSquares {
|
||||||
|
xPos := float64(sq.X())
|
||||||
|
yPos := float64(sq.Y())
|
||||||
|
opts.GeoM.Translate(xPos, yPos)
|
||||||
|
screen.DrawImage(sq.Img, opts)
|
||||||
|
opts.GeoM.Reset()
|
||||||
|
if curr == finalSquareCount {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
curr++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (grd *Grid) ChangeColour(row int, column int, clr color.Color) {
|
||||||
|
sq := grd.squares[row-1][column-1]
|
||||||
|
sq.ChangeColour(clr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (grd *Grid) GetSquareAt(row int, column int) *Square {
|
||||||
|
return &grd.squares[row-1][column-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (grd *Grid) ColouredSquaresRemaining() int {
|
||||||
|
return grd.coloredSquaresRemaining
|
||||||
|
}
|
||||||
131
geometry/player.go
Normal file
131
geometry/player.go
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
package geom
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
|
"src.robn.tv/MrDonuts/RGB/assets"
|
||||||
|
)
|
||||||
|
|
||||||
|
var MainPlayer *Player
|
||||||
|
var totalColors = 3
|
||||||
|
var colorMap = map[int]color.Color{
|
||||||
|
0: RedFill,
|
||||||
|
1: GreenFill,
|
||||||
|
2: BlueFill,
|
||||||
|
}
|
||||||
|
var defaultStartingEnergy = 50
|
||||||
|
var nextLevelEnergyJump = 30
|
||||||
|
var CurrentEnergy = defaultStartingEnergy
|
||||||
|
var CurrentLevel = 1
|
||||||
|
|
||||||
|
type Player struct {
|
||||||
|
square Square
|
||||||
|
row int
|
||||||
|
col int
|
||||||
|
currColorIndex int
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetupPlayer() {
|
||||||
|
rows, _ := GameGrid.Size()
|
||||||
|
|
||||||
|
//build default square
|
||||||
|
sq := MakeSquare(GameGrid.squareSize)
|
||||||
|
|
||||||
|
//adjust to red as starting value
|
||||||
|
sq.ChangeColour(RedFill)
|
||||||
|
|
||||||
|
//position on bottom left
|
||||||
|
gridSq := GameGrid.GetSquareAt(rows, 1)
|
||||||
|
sq.SetPosition(gridSq.x, gridSq.y)
|
||||||
|
|
||||||
|
//setup struct for passing around
|
||||||
|
ply := Player{square: sq, row: rows, col: 1, currColorIndex: 0}
|
||||||
|
MainPlayer = &ply
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) Update() {
|
||||||
|
|
||||||
|
moveOccurs := false
|
||||||
|
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyArrowDown) {
|
||||||
|
rows, _ := GameGrid.Size()
|
||||||
|
if p.row < rows {
|
||||||
|
p.row += 1
|
||||||
|
p.square.moveDownOnGrid()
|
||||||
|
moveOccurs = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyArrowRight) {
|
||||||
|
_, cols := GameGrid.Size()
|
||||||
|
if p.col < cols {
|
||||||
|
p.col += 1
|
||||||
|
p.square.moveRightOnGrid()
|
||||||
|
moveOccurs = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyArrowLeft) {
|
||||||
|
if p.col > 1 {
|
||||||
|
p.col -= 1
|
||||||
|
p.square.moveLeftOnGrid()
|
||||||
|
moveOccurs = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyArrowUp) {
|
||||||
|
if p.row > 1 {
|
||||||
|
p.row -= 1
|
||||||
|
p.square.moveUpOnGrid()
|
||||||
|
moveOccurs = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if moveOccurs {
|
||||||
|
moveOccurs = false
|
||||||
|
|
||||||
|
p.NextColor()
|
||||||
|
|
||||||
|
// check if player is on same colour square
|
||||||
|
gridSquare := GameGrid.GetSquareAt(p.row, p.col)
|
||||||
|
if p.currColorIndex == gridSquare.RGBColourIndex {
|
||||||
|
GameGrid.coloredSquaresRemaining -= 1
|
||||||
|
gridSquare.RGBColourIndex = -1
|
||||||
|
gridSquare.ChangeColour(GrayFill)
|
||||||
|
if GameGrid.coloredSquaresRemaining != 0 {
|
||||||
|
assets.SFXLibrary["colourMatch"].Rewind()
|
||||||
|
assets.SFXLibrary["colourMatch"].Play()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// reduce energy
|
||||||
|
CurrentEnergy -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) Draw(screen *ebiten.Image) {
|
||||||
|
opts := &ebiten.DrawImageOptions{}
|
||||||
|
opts.GeoM.Translate(float64(p.square.x), float64(p.square.y))
|
||||||
|
screen.DrawImage(p.square.Img, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) NextColor() {
|
||||||
|
p.currColorIndex = (p.currColorIndex + 1) % totalColors
|
||||||
|
p.square.ChangeColour(colorMap[p.currColorIndex])
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResetPlayerValues() {
|
||||||
|
CurrentEnergy = defaultStartingEnergy
|
||||||
|
CurrentLevel = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func PrepareForNextLevel() {
|
||||||
|
CurrentEnergy += nextLevelEnergyJump
|
||||||
|
CurrentLevel += 1
|
||||||
|
}
|
||||||
93
geometry/square.go
Normal file
93
geometry/square.go
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package geom
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var GrayFill = color.RGBA{R: 128, G: 128, B: 128, A: 255}
|
||||||
|
var RedFill = color.RGBA{R: 200, G: 0, B: 0, A: 255}
|
||||||
|
var GreenFill = color.RGBA{R: 0, G: 200, B: 0, A: 255}
|
||||||
|
var BlueFill = color.RGBA{R: 0, G: 0, B: 200, A: 255}
|
||||||
|
var LightRedFill = color.RGBA{R: 255, G: 104, B: 103, A: 255}
|
||||||
|
var LightGreenFill = color.RGBA{R: 144, G: 255, B: 143, A: 255}
|
||||||
|
var LightBlueFill = color.RGBA{R: 150, G: 150, B: 255, A: 255}
|
||||||
|
|
||||||
|
var RGBColourMap = map[int]color.Color{
|
||||||
|
0: RedFill,
|
||||||
|
1: GreenFill,
|
||||||
|
2: BlueFill,
|
||||||
|
}
|
||||||
|
|
||||||
|
var AllColourMap = map[int]color.Color{
|
||||||
|
0: GrayFill,
|
||||||
|
1: RedFill,
|
||||||
|
2: GreenFill,
|
||||||
|
3: BlueFill,
|
||||||
|
4: LightRedFill,
|
||||||
|
5: LightBlueFill,
|
||||||
|
6: LightGreenFill,
|
||||||
|
}
|
||||||
|
|
||||||
|
var LightRGBMap = map[int]color.Color{
|
||||||
|
0: LightRedFill,
|
||||||
|
1: LightGreenFill,
|
||||||
|
2: LightBlueFill,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Square struct {
|
||||||
|
x int
|
||||||
|
y int
|
||||||
|
clr color.Color
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
Img *ebiten.Image
|
||||||
|
RGBColourIndex int
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeSquare(size int) Square {
|
||||||
|
image := ebiten.NewImage(size, size)
|
||||||
|
defaultColor := color.RGBA{R: 128, G: 128, B: 128, A: 255}
|
||||||
|
image.Fill(defaultColor)
|
||||||
|
sq := Square{clr: defaultColor, Img: image, width: size, height: size, x: 0, y: 0, RGBColourIndex: -1}
|
||||||
|
return sq
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *Square) ChangeColour(newColor color.Color) {
|
||||||
|
sq.clr = newColor
|
||||||
|
sq.Img.Fill(newColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *Square) SetPosition(x int, y int) {
|
||||||
|
sq.x = x
|
||||||
|
sq.y = y
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *Square) X() int {
|
||||||
|
return sq.x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *Square) Y() int {
|
||||||
|
return sq.y
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *Square) moveRightOnGrid() {
|
||||||
|
newX := sq.x + GameGrid.squareSize + GameGrid.squareSpacing
|
||||||
|
sq.x = newX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *Square) moveLeftOnGrid() {
|
||||||
|
newX := sq.x - GameGrid.squareSize - GameGrid.squareSpacing
|
||||||
|
sq.x = newX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *Square) moveDownOnGrid() {
|
||||||
|
newY := sq.y + GameGrid.squareSize + GameGrid.squareSpacing
|
||||||
|
sq.y = newY
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *Square) moveUpOnGrid() {
|
||||||
|
newY := sq.y - GameGrid.squareSize - GameGrid.squareSpacing
|
||||||
|
sq.y = newY
|
||||||
|
}
|
||||||
17
go.mod
Normal file
17
go.mod
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
module src.robn.tv/MrDonuts/RGB
|
||||||
|
|
||||||
|
go 1.21.3
|
||||||
|
|
||||||
|
require github.com/hajimehoshi/ebiten/v2 v2.6.2
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/ebitengine/oto/v3 v3.1.0 // indirect
|
||||||
|
github.com/ebitengine/purego v0.5.0 // indirect
|
||||||
|
github.com/jezek/xgb v1.1.0 // indirect
|
||||||
|
golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63 // indirect
|
||||||
|
golang.org/x/image v0.14.0
|
||||||
|
golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57 // indirect
|
||||||
|
golang.org/x/sync v0.3.0 // indirect
|
||||||
|
golang.org/x/sys v0.12.0 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
)
|
||||||
22
go.sum
Normal file
22
go.sum
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
github.com/ebitengine/oto/v3 v3.1.0 h1:9tChG6rizyeR2w3vsygTTTVVJ9QMMyu00m2yBOCch6U=
|
||||||
|
github.com/ebitengine/oto/v3 v3.1.0/go.mod h1:IK1QTnlfZK2GIB6ziyECm433hAdTaPpOsGMLhEyEGTg=
|
||||||
|
github.com/ebitengine/purego v0.5.0 h1:JrMGKfRIAM4/QVKaesIIT7m/UVjTj5GYhRSQYwfVdpo=
|
||||||
|
github.com/ebitengine/purego v0.5.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
||||||
|
github.com/hajimehoshi/bitmapfont/v3 v3.0.0 h1:r2+6gYK38nfztS/et50gHAswb9hXgxXECYgE8Nczmi4=
|
||||||
|
github.com/hajimehoshi/bitmapfont/v3 v3.0.0/go.mod h1:+CxxG+uMmgU4mI2poq944i3uZ6UYFfAkj9V6WqmuvZA=
|
||||||
|
github.com/hajimehoshi/ebiten/v2 v2.6.2 h1:tVa3ZJbp4Uz/VSjmpgtQIOvwd7aQH290XehHBLr2iWk=
|
||||||
|
github.com/hajimehoshi/ebiten/v2 v2.6.2/go.mod h1:TZtorL713an00UW4LyvMeKD8uXWnuIuCPtlH11b0pgI=
|
||||||
|
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
|
||||||
|
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
||||||
|
golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63 h1:3AGKexOYqL+ztdWdkB1bDwXgPBuTS/S8A4WzuTvJ8Cg=
|
||||||
|
golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63/go.mod h1:UH99kUObWAZkDnWqppdQe5ZhPYESUw8I0zVV1uWBR+0=
|
||||||
|
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
|
||||||
|
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
|
||||||
|
golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57 h1:Q6NT8ckDYNcwmi/bmxe+XbiDMXqMRW1xFBtJ+bIpie4=
|
||||||
|
golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57/go.mod h1:wEyOn6VvNW7tcf+bW/wBz1sehi2s2BZ4TimyR7qZen4=
|
||||||
|
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||||
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
|
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||||
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
60
main.go
Normal file
60
main.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
|
||||||
|
"src.robn.tv/MrDonuts/RGB/assets"
|
||||||
|
geom "src.robn.tv/MrDonuts/RGB/geometry"
|
||||||
|
"src.robn.tv/MrDonuts/RGB/states"
|
||||||
|
score "src.robn.tv/MrDonuts/RGB/tools"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
numRows := 3
|
||||||
|
numColumns := 6
|
||||||
|
geom.BuildGrid(numRows, numColumns)
|
||||||
|
|
||||||
|
states.SetupStateMachine()
|
||||||
|
|
||||||
|
//some audio testing
|
||||||
|
for i, song := range assets.SongTracks {
|
||||||
|
song.Play()
|
||||||
|
if i != 1 {
|
||||||
|
song.SetVolume(0)
|
||||||
|
} else {
|
||||||
|
song.SetVolume(0.7)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type Game struct{}
|
||||||
|
|
||||||
|
func (g *Game) Update() error {
|
||||||
|
|
||||||
|
states.SM.Update()
|
||||||
|
score.ScoreMngr.Update()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) Draw(screen *ebiten.Image) {
|
||||||
|
|
||||||
|
states.SM.Draw(screen)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
|
||||||
|
return 640, 480
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ebiten.SetWindowSize(640, 480)
|
||||||
|
ebiten.SetWindowTitle("RGB")
|
||||||
|
if err := ebiten.RunGame(&Game{}); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
57
states/gameOverState.go
Normal file
57
states/gameOverState.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package states
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/text"
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
"src.robn.tv/MrDonuts/RGB/assets"
|
||||||
|
geom "src.robn.tv/MrDonuts/RGB/geometry"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GameOverState struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *GameOverState) Enter() {
|
||||||
|
fmt.Println("Entering Game Over State")
|
||||||
|
assets.SilenceSongTracks()
|
||||||
|
assets.SFXLibrary["gameOver"].Rewind()
|
||||||
|
assets.SFXLibrary["gameOver"].Play()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *GameOverState) Exit() {
|
||||||
|
fmt.Println("Exiting Game OverState")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *GameOverState) Update() {
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyN) {
|
||||||
|
geom.ResetPlayerValues()
|
||||||
|
geom.BuildGrid(rand.Intn(5+geom.CurrentLevel)+2, rand.Intn(5+geom.CurrentLevel)+2)
|
||||||
|
CurrTrack = 1
|
||||||
|
assets.SongTracks[CurrTrack].SetVolume(0.7) //turn up track 1
|
||||||
|
SM.Transition("load")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *GameOverState) Draw(screen *ebiten.Image) {
|
||||||
|
w, h := ebiten.WindowSize()
|
||||||
|
|
||||||
|
gameOverStr := "Game Over"
|
||||||
|
face := assets.LoadFontFace("fonts/robot.otf", 30)
|
||||||
|
stringWidth := font.MeasureString(face, gameOverStr).Ceil()
|
||||||
|
text.Draw(screen, gameOverStr, face, w/2-stringWidth/2, h/2, color.White)
|
||||||
|
|
||||||
|
newGameStr := "(press N for new game)"
|
||||||
|
face = assets.LoadFontFace("fonts/robot.otf", 12)
|
||||||
|
stringWidth = font.MeasureString(face, newGameStr).Ceil()
|
||||||
|
text.Draw(screen, newGameStr, face, w/2-stringWidth/2, h-int(0.1*float64(h)), color.White)
|
||||||
|
|
||||||
|
}
|
||||||
52
states/loadLevelState.go
Normal file
52
states/loadLevelState.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package states
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
geom "src.robn.tv/MrDonuts/RGB/geometry"
|
||||||
|
score "src.robn.tv/MrDonuts/RGB/tools"
|
||||||
|
)
|
||||||
|
|
||||||
|
var currentEnd = 1 //used for animating squares
|
||||||
|
var secondsPerUpdate = 0.02
|
||||||
|
var ticksPerSecond = 60.0
|
||||||
|
var deltaSeconds = 1.0 / ticksPerSecond
|
||||||
|
var secondsCounter = 0.0
|
||||||
|
|
||||||
|
type LoadLevelState struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LoadLevelState) Enter() {
|
||||||
|
fmt.Println("Entering Loading State")
|
||||||
|
currentEnd = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LoadLevelState) Exit() {
|
||||||
|
fmt.Println("Exiting Loading State")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LoadLevelState) Update() {
|
||||||
|
secondsCounter += deltaSeconds
|
||||||
|
|
||||||
|
//determine how much to jump by on each draw
|
||||||
|
totalSquares := geom.GameGrid.NumSquares()
|
||||||
|
jumpAmount := math.Ceil(float64(totalSquares) / ticksPerSecond)
|
||||||
|
if secondsCounter >= float64(secondsPerUpdate) {
|
||||||
|
secondsCounter = 0
|
||||||
|
currentEnd += int(jumpAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentEnd > geom.GameGrid.NumSquares() {
|
||||||
|
SM.Transition("play")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LoadLevelState) Draw(screen *ebiten.Image) {
|
||||||
|
|
||||||
|
geom.GameGrid.DrawUpTo(currentEnd, screen)
|
||||||
|
score.ScoreMngr.Draw(screen)
|
||||||
|
}
|
||||||
71
states/playLevelState.go
Normal file
71
states/playLevelState.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package states
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
|
"src.robn.tv/MrDonuts/RGB/assets"
|
||||||
|
geom "src.robn.tv/MrDonuts/RGB/geometry"
|
||||||
|
score "src.robn.tv/MrDonuts/RGB/tools"
|
||||||
|
)
|
||||||
|
|
||||||
|
var CurrTrack = 1
|
||||||
|
|
||||||
|
type PlayLevelState struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PlayLevelState) Enter() {
|
||||||
|
fmt.Println("Entering Play State")
|
||||||
|
geom.SetupPlayer()
|
||||||
|
fmt.Println(geom.GameGrid.ColouredSquaresRemaining())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PlayLevelState) Exit() {
|
||||||
|
fmt.Println("Exiting Play State")
|
||||||
|
|
||||||
|
geom.PrepareForNextLevel()
|
||||||
|
|
||||||
|
if CurrTrack < len(assets.SongTracks) {
|
||||||
|
if geom.CurrentLevel%3 == 0 {
|
||||||
|
CurrTrack++
|
||||||
|
assets.SongTracks[CurrTrack].SetVolume(0.7)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PlayLevelState) Update() {
|
||||||
|
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyN) {
|
||||||
|
newRowSize := min(rand.Intn(5+geom.CurrentLevel)+2, geom.MaxGridDimension)
|
||||||
|
newColSize := min(rand.Intn(5+geom.CurrentLevel)+2, geom.MaxGridDimension)
|
||||||
|
geom.BuildGrid(newRowSize, newColSize)
|
||||||
|
SM.Transition("load")
|
||||||
|
assets.SFXLibrary["newLevel"].Rewind()
|
||||||
|
assets.SFXLibrary["newLevel"].Play()
|
||||||
|
}
|
||||||
|
|
||||||
|
geom.MainPlayer.Update()
|
||||||
|
if geom.CurrentEnergy == 0 {
|
||||||
|
SM.Transition("game over")
|
||||||
|
}
|
||||||
|
if geom.GameGrid.ColouredSquaresRemaining() == 0 {
|
||||||
|
//go to next level
|
||||||
|
newRowSize := min(rand.Intn(5+geom.CurrentLevel)+2, geom.MaxGridDimension)
|
||||||
|
newColSize := min(rand.Intn(5+geom.CurrentLevel)+2, geom.MaxGridDimension)
|
||||||
|
geom.BuildGrid(newRowSize, newColSize)
|
||||||
|
SM.Transition("load")
|
||||||
|
assets.SFXLibrary["newLevel"].Rewind()
|
||||||
|
assets.SFXLibrary["newLevel"].Play()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PlayLevelState) Draw(screen *ebiten.Image) {
|
||||||
|
geom.GameGrid.Draw(screen)
|
||||||
|
geom.MainPlayer.Draw(screen)
|
||||||
|
score.ScoreMngr.Draw(screen)
|
||||||
|
}
|
||||||
54
states/statemachine.go
Normal file
54
states/statemachine.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package states
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var SM StateMachine
|
||||||
|
var StateMap map[string]State
|
||||||
|
|
||||||
|
type State interface {
|
||||||
|
Enter()
|
||||||
|
Exit()
|
||||||
|
Update()
|
||||||
|
Draw(screen *ebiten.Image)
|
||||||
|
}
|
||||||
|
|
||||||
|
type StateMachine struct {
|
||||||
|
CurrentState State
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStateMachine(initialState State) *StateMachine {
|
||||||
|
sm := &StateMachine{CurrentState: initialState}
|
||||||
|
sm.CurrentState.Enter()
|
||||||
|
return sm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *StateMachine) Transition(newState string) {
|
||||||
|
sm.CurrentState.Exit()
|
||||||
|
sm.CurrentState = StateMap[newState]
|
||||||
|
sm.CurrentState.Enter()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *StateMachine) Update() {
|
||||||
|
sm.CurrentState.Update()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *StateMachine) Draw(screen *ebiten.Image) {
|
||||||
|
sm.CurrentState.Draw(screen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetupStateMachine() {
|
||||||
|
|
||||||
|
loadState := &LoadLevelState{}
|
||||||
|
playState := &PlayLevelState{}
|
||||||
|
gameOverState := &GameOverState{}
|
||||||
|
|
||||||
|
StateMap = make(map[string]State)
|
||||||
|
StateMap["load"] = loadState
|
||||||
|
StateMap["play"] = playState
|
||||||
|
StateMap["game over"] = gameOverState
|
||||||
|
|
||||||
|
SM = *NewStateMachine(loadState)
|
||||||
|
|
||||||
|
}
|
||||||
45
tools/scoreManager.go
Normal file
45
tools/scoreManager.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package score
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/text"
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
|
||||||
|
//"golang.org/x/image/font/gofont/gobold"
|
||||||
|
"src.robn.tv/MrDonuts/RGB/assets"
|
||||||
|
geom "src.robn.tv/MrDonuts/RGB/geometry"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ScoreMngr ScoreManager
|
||||||
|
|
||||||
|
type ScoreManager struct{}
|
||||||
|
|
||||||
|
func (sm *ScoreManager) Update() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *ScoreManager) Draw(screen *ebiten.Image) {
|
||||||
|
|
||||||
|
w, h := ebiten.WindowSize()
|
||||||
|
|
||||||
|
//highScoreStr := fmt.Sprintf("High Score: %v", highScore)
|
||||||
|
levelStr := fmt.Sprintf("Level: %v", geom.CurrentLevel)
|
||||||
|
face := assets.LoadFontFace("fonts/robot.otf", 12)
|
||||||
|
|
||||||
|
//draw high score (i.e. best level)
|
||||||
|
//stringWidth := font.MeasureString(face, highScoreStr).Ceil()
|
||||||
|
//text.Draw(screen, highScoreStr, face, w-stringWidth-geom.HighScoreOffset, h-geom.HighScoreOffset, color.White)
|
||||||
|
|
||||||
|
//draw current level
|
||||||
|
//stringWidth = font.MeasureString(face, levelStr).Ceil()
|
||||||
|
text.Draw(screen, levelStr, face, geom.HighScoreOffset, h-geom.HighScoreOffset, color.White)
|
||||||
|
|
||||||
|
//draw energy at the top
|
||||||
|
energyStr := fmt.Sprintf("Energy: %v", geom.CurrentEnergy)
|
||||||
|
face = assets.LoadFontFace("fonts/robot.otf", 20)
|
||||||
|
stringWidth := font.MeasureString(face, energyStr).Ceil()
|
||||||
|
text.Draw(screen, energyStr, face, w/2-stringWidth/2, geom.ScoreOffset, color.White)
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user