everything I got

This commit is contained in:
MrDonuts
2023-11-19 20:53:35 -05:00
commit a875a4ed57
45 changed files with 903 additions and 0 deletions

182
geometry/grid.go Normal file
View 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
View 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
View 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
}