everything I got
This commit is contained in:
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
|
||||
}
|
||||
Reference in New Issue
Block a user