GOingTunneling/player.go

723 lines
19 KiB
Go
Raw Normal View History

2024-08-29 00:05:28 +02:00
package main
import (
"github.com/veandco/go-sdl2/sdl"
"image/color"
"math/rand"
)
type Player struct {
2024-08-29 18:48:27 +02:00
local bool
playerColors PlayerColors
keyMap KeyMap
joyMap JoyMap
joyStick *sdl.Joystick
camera *sdl.Rect
2024-08-29 00:05:28 +02:00
energy uint16
2024-08-29 18:48:27 +02:00
ammunition uint16
shields uint16
2024-08-29 00:05:28 +02:00
digCooldown uint8
shootCooldown uint8
repairCooldown uint8
rechargeCooldown uint8
movementCooldown uint8
2024-08-29 18:48:27 +02:00
reloadCooldown uint8
gameObject *GameObject
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
window *sdl.Window
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
logicalSurface *sdl.Surface
playSurface *sdl.Surface
HUDSurface *sdl.Surface
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
playSurfaceRect *sdl.Rect
HUDSurfaceRect *sdl.Rect
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
playSurfaceTargetRect *sdl.Rect
HUDSurfaceTargetRect *sdl.Rect
2024-08-29 21:12:18 +02:00
totalHandleEventsTime uint64
totalRenderTime uint64
totalFrameTime uint64
totalScalingTime uint64
frameCount uint64
2024-08-29 18:48:27 +02:00
}
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
func (player *Player) track(camera *sdl.Rect) {
camera.X = player.gameObject.baseRect.X - 37
camera.Y = player.gameObject.baseRect.Y - 38
}
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
func (player *Player) render(camera *sdl.Rect, surface *sdl.Surface) {
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
// Common part: Rendering player
player.gameObject.baseRect = sdl.Rect{X: player.gameObject.baseRect.X, Y: player.gameObject.baseRect.Y, W: 7, H: 7}
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
if player.shields > 0 && player.shields <= MaxShields {
player.gameObject.render(camera, surface)
2024-08-29 00:05:28 +02:00
}
}
func (player *Player) digBlock(posX, posY int32, gameMap *GameMap, isShooting bool) uint8 {
collisionAtDigSite := gameMap.checkCollision(posX, posY)
if collisionAtDigSite == 0 {
return 0
} else if collisionAtDigSite == 1 && (player.digCooldown == 0 || isShooting) {
gameMap.tiles[posX][posY] = 0
player.digCooldown = DiggingCooldown
return 1
}
return 2
}
2024-08-29 18:48:27 +02:00
func (player *Player) tick(isShooting bool, bullets *[]*Bullet, format *sdl.PixelFormat) {
2024-08-29 00:05:28 +02:00
if player.digCooldown > 0 {
player.digCooldown--
}
if player.shootCooldown > 0 {
player.shootCooldown--
}
if player.repairCooldown > 0 {
player.repairCooldown--
}
if player.rechargeCooldown > 0 {
player.rechargeCooldown--
}
if player.movementCooldown > 0 {
player.movementCooldown--
}
2024-08-29 18:48:27 +02:00
if player.reloadCooldown > 0 {
player.reloadCooldown--
} else if player.ammunition < MaxAmmunition && !isShooting && player.energy > ReloadCost {
player.ammunition++
player.reloadCooldown = ReloadCooldown
player.energy -= ReloadCost
}
if player.shields <= 0 {
player.shields = MaxShields + 1
player.explode(bullets)
}
2024-08-29 00:05:28 +02:00
}
func (player *Player) tryMove(gameMap *GameMap, isShooting bool, players *[]*Player) (moved bool) {
if player.movementCooldown > 0 {
return false
}
ranOutOfEnergy := (isShooting && player.energy <= DiggingCost+ShootDiggingCostBonus) || player.energy <= DiggingCost
if ranOutOfEnergy {
isShooting = false
}
shouldPenalizeDigging := false
stopped := false
2024-08-29 18:48:27 +02:00
switch player.gameObject.orientation {
2024-08-29 00:05:28 +02:00
case 0: // Up
collisionRect := sdl.Rect{
2024-08-29 18:48:27 +02:00
X: player.gameObject.baseRect.X,
Y: player.gameObject.baseRect.Y - 1,
2024-08-29 00:05:28 +02:00
W: 5,
H: 7,
}
for _, opponent := range *players {
2024-08-29 18:48:27 +02:00
if opponent != player && opponent.gameObject.baseRect.HasIntersection(&collisionRect) {
2024-08-29 00:05:28 +02:00
return false
}
}
2024-08-29 18:48:27 +02:00
for x := player.gameObject.baseRect.X; x < player.gameObject.baseRect.X+5 && !stopped; x++ {
for y := player.gameObject.baseRect.Y - 1; y < player.gameObject.baseRect.Y+7; y++ {
2024-08-29 00:05:28 +02:00
digResult := player.digBlock(x, y, gameMap, isShooting)
if digResult == 1 {
shouldPenalizeDigging = true
if !isShooting {
stopped = true
break
}
} else if digResult != 0 {
stopped = true
break
}
}
}
if !stopped {
moved = true
2024-08-29 18:48:27 +02:00
player.gameObject.baseRect.Y--
2024-08-29 00:05:28 +02:00
}
case 1: // Right
collisionRect := sdl.Rect{
2024-08-29 18:48:27 +02:00
X: player.gameObject.baseRect.X + 1,
Y: player.gameObject.baseRect.Y,
2024-08-29 00:05:28 +02:00
W: 7,
H: 5,
}
for _, opponent := range *players {
2024-08-29 18:48:27 +02:00
if opponent != player && opponent.gameObject.baseRect.HasIntersection(&collisionRect) {
2024-08-29 00:05:28 +02:00
return false
}
}
2024-08-29 18:48:27 +02:00
for y := player.gameObject.baseRect.Y + 1; y < player.gameObject.baseRect.Y+6 && !stopped; y++ {
for x := player.gameObject.baseRect.X + 1; x < player.gameObject.baseRect.X+8; x++ {
2024-08-29 00:05:28 +02:00
digResult := player.digBlock(x, y, gameMap, isShooting)
if digResult == 1 {
shouldPenalizeDigging = true
if !isShooting {
stopped = true
break
}
} else if digResult != 0 {
stopped = true
break
}
}
}
if !stopped {
moved = true
2024-08-29 18:48:27 +02:00
player.gameObject.baseRect.X++
2024-08-29 00:05:28 +02:00
}
case 2: // Down
collisionRect := sdl.Rect{
2024-08-29 18:48:27 +02:00
X: player.gameObject.baseRect.X,
Y: player.gameObject.baseRect.Y + 1,
2024-08-29 00:05:28 +02:00
W: 5,
H: 7,
}
for _, opponent := range *players {
2024-08-29 18:48:27 +02:00
if opponent != player && opponent.gameObject.baseRect.HasIntersection(&collisionRect) {
2024-08-29 00:05:28 +02:00
return false
}
}
2024-08-29 18:48:27 +02:00
for x := player.gameObject.baseRect.X; x < player.gameObject.baseRect.X+5 && !stopped; x++ {
for y := player.gameObject.baseRect.Y + 1; y < player.gameObject.baseRect.Y+8; y++ {
2024-08-29 00:05:28 +02:00
digResult := player.digBlock(x, y, gameMap, isShooting)
if digResult == 1 {
shouldPenalizeDigging = true
if !isShooting {
stopped = true
break
}
} else if digResult != 0 {
stopped = true
break
}
}
}
if !stopped {
moved = true
2024-08-29 18:48:27 +02:00
player.gameObject.baseRect.Y++
2024-08-29 00:05:28 +02:00
}
case 3: // Left
collisionRect := sdl.Rect{
2024-08-29 18:48:27 +02:00
X: player.gameObject.baseRect.X - 1,
Y: player.gameObject.baseRect.Y,
2024-08-29 00:05:28 +02:00
W: 7,
H: 5,
}
for _, opponent := range *players {
2024-08-29 18:48:27 +02:00
if opponent != player && opponent.gameObject.baseRect.HasIntersection(&collisionRect) {
2024-08-29 00:05:28 +02:00
return false
}
}
2024-08-29 18:48:27 +02:00
for y := player.gameObject.baseRect.Y + 1; y < player.gameObject.baseRect.Y+6 && !stopped; y++ {
for x := player.gameObject.baseRect.X - 1; x < player.gameObject.baseRect.X+6; x++ {
2024-08-29 00:05:28 +02:00
digResult := player.digBlock(x, y, gameMap, isShooting)
if digResult == 1 {
shouldPenalizeDigging = true
if !isShooting {
stopped = true
break
}
} else if digResult != 0 {
stopped = true
break
}
}
}
if !stopped {
moved = true
2024-08-29 18:48:27 +02:00
player.gameObject.baseRect.X--
2024-08-29 00:05:28 +02:00
}
case 4: // Up-Right
collisionRect := sdl.Rect{
2024-08-29 18:48:27 +02:00
X: player.gameObject.baseRect.X + 1,
Y: player.gameObject.baseRect.Y - 1,
2024-08-29 00:05:28 +02:00
W: 7,
H: 7,
}
for _, opponent := range *players {
2024-08-29 18:48:27 +02:00
if opponent != player && opponent.gameObject.baseRect.HasIntersection(&collisionRect) {
2024-08-29 00:05:28 +02:00
return false
}
}
2024-08-29 18:48:27 +02:00
for x := player.gameObject.baseRect.X + 1; x < player.gameObject.baseRect.X+8 && !stopped; x++ {
for y := player.gameObject.baseRect.Y - 1; y < player.gameObject.baseRect.Y+6; y++ {
2024-08-29 00:05:28 +02:00
digResult := player.digBlock(x, y, gameMap, isShooting)
if digResult == 1 {
shouldPenalizeDigging = true
if !isShooting {
stopped = true
break
}
} else if digResult != 0 {
stopped = true
break
}
}
}
if !stopped {
moved = true
2024-08-29 18:48:27 +02:00
player.gameObject.baseRect.X++
player.gameObject.baseRect.Y--
2024-08-29 00:05:28 +02:00
}
case 5: // Up-Left
collisionRect := sdl.Rect{
2024-08-29 18:48:27 +02:00
X: player.gameObject.baseRect.X - 1,
Y: player.gameObject.baseRect.Y - 1,
2024-08-29 00:05:28 +02:00
W: 7,
H: 7,
}
for _, opponent := range *players {
2024-08-29 18:48:27 +02:00
if opponent != player && opponent.gameObject.baseRect.HasIntersection(&collisionRect) {
2024-08-29 00:05:28 +02:00
return false
}
}
2024-08-29 18:48:27 +02:00
for x := player.gameObject.baseRect.X - 1; x < player.gameObject.baseRect.X+6 && !stopped; x++ {
for y := player.gameObject.baseRect.Y - 1; y < player.gameObject.baseRect.Y+6; y++ {
2024-08-29 00:05:28 +02:00
digResult := player.digBlock(x, y, gameMap, isShooting)
if digResult == 1 {
shouldPenalizeDigging = true
if !isShooting {
stopped = true
break
}
} else if digResult != 0 {
stopped = true
break
}
}
}
if !stopped {
moved = true
2024-08-29 18:48:27 +02:00
player.gameObject.baseRect.X--
player.gameObject.baseRect.Y--
2024-08-29 00:05:28 +02:00
}
case 6: // Down-Right
collisionRect := sdl.Rect{
2024-08-29 18:48:27 +02:00
X: player.gameObject.baseRect.X + 1,
Y: player.gameObject.baseRect.Y + 1,
2024-08-29 00:05:28 +02:00
W: 7,
H: 7,
}
for _, opponent := range *players {
2024-08-29 18:48:27 +02:00
if opponent != player && opponent.gameObject.baseRect.HasIntersection(&collisionRect) {
2024-08-29 00:05:28 +02:00
return false
}
}
2024-08-29 18:48:27 +02:00
for x := player.gameObject.baseRect.X + 1; x < player.gameObject.baseRect.X+8 && !stopped; x++ {
for y := player.gameObject.baseRect.Y + 1; y < player.gameObject.baseRect.Y+8; y++ {
2024-08-29 00:05:28 +02:00
digResult := player.digBlock(x, y, gameMap, isShooting)
if digResult == 1 {
shouldPenalizeDigging = true
if !isShooting {
stopped = true
break
}
} else if digResult != 0 {
stopped = true
break
}
}
}
if !stopped {
moved = true
2024-08-29 18:48:27 +02:00
player.gameObject.baseRect.X++
player.gameObject.baseRect.Y++
2024-08-29 00:05:28 +02:00
}
case 7: // Down-Left
collisionRect := sdl.Rect{
2024-08-29 18:48:27 +02:00
X: player.gameObject.baseRect.X - 1,
Y: player.gameObject.baseRect.Y + 1,
2024-08-29 00:05:28 +02:00
W: 7,
H: 7,
}
for _, opponent := range *players {
2024-08-29 18:48:27 +02:00
if opponent != player && opponent.gameObject.baseRect.HasIntersection(&collisionRect) {
2024-08-29 00:05:28 +02:00
return false
}
}
2024-08-29 18:48:27 +02:00
for x := player.gameObject.baseRect.X - 1; x < player.gameObject.baseRect.X+6 && !stopped; x++ {
for y := player.gameObject.baseRect.Y + 1; y < player.gameObject.baseRect.Y+8; y++ {
2024-08-29 00:05:28 +02:00
digResult := player.digBlock(x, y, gameMap, isShooting)
if digResult == 1 {
shouldPenalizeDigging = true
if !isShooting {
stopped = true
break
}
} else if digResult != 0 {
stopped = true
break
}
}
}
if !stopped {
moved = true
2024-08-29 18:48:27 +02:00
player.gameObject.baseRect.X--
player.gameObject.baseRect.Y++
2024-08-29 00:05:28 +02:00
}
}
// Penalties and cooldown handling
if shouldPenalizeDigging {
2024-08-29 18:48:27 +02:00
if isShooting && player.ammunition < MaxAmmunition && rand.Intn(2) == 0 {
player.ammunition++
}
2024-08-29 00:05:28 +02:00
if ranOutOfEnergy {
player.digCooldown = DiggingCooldownNoEnergy
}
player.energy -= DiggingCost
if isShooting {
player.energy -= ShootDiggingCostBonus
}
}
if moved {
if ranOutOfEnergy {
player.movementCooldown = MovementCooldownNoEnergy
} else {
player.movementCooldown = MovementCooldown
}
}
return
}
2024-08-29 18:48:27 +02:00
func (player *Player) getRGBAColor(colorIndex uint8, format *sdl.PixelFormat) uint32 {
var selectedColor color.Color
switch colorIndex {
case 0:
selectedColor = player.playerColors.tracks
case 1:
selectedColor = player.playerColors.body
case 2:
selectedColor = player.playerColors.cannon
}
var r, g, b, a uint8
if selectedColor != nil {
rt, gt, bt, at := selectedColor.RGBA()
r, g, b, a = uint8(rt), uint8(gt), uint8(bt), uint8(at)
}
return sdl.MapRGBA(format, r, g, b, a)
}
func (player *Player) shoot(super bool, bullets *[]*Bullet) {
if (super && (player.energy <= SuperShotCost || player.ammunition < MaxAmmunition)) || (!super && (player.energy <= NormalShotCost || player.ammunition < 1)) {
2024-08-29 00:05:28 +02:00
return
}
if player.shootCooldown == 0 {
var shootX, shootY int32
2024-08-29 18:48:27 +02:00
switch player.gameObject.orientation {
2024-08-29 00:05:28 +02:00
case 0: // Up
2024-08-29 18:48:27 +02:00
shootY = player.gameObject.baseRect.Y - 1
shootX = player.gameObject.baseRect.X + 2
2024-08-29 00:05:28 +02:00
break
case 1: // Right
2024-08-29 18:48:27 +02:00
shootY = player.gameObject.baseRect.Y + 3
shootX = player.gameObject.baseRect.X + 8
2024-08-29 00:05:28 +02:00
break
case 2: // Down
2024-08-29 18:48:27 +02:00
shootX = player.gameObject.baseRect.X + 2
shootY = player.gameObject.baseRect.Y + 8
2024-08-29 00:05:28 +02:00
break
case 3: // Left
2024-08-29 18:48:27 +02:00
shootY = player.gameObject.baseRect.Y + 3
shootX = player.gameObject.baseRect.X - 2
2024-08-29 00:05:28 +02:00
break
case 4: // Up-Right
2024-08-29 18:48:27 +02:00
shootY = player.gameObject.baseRect.Y
shootX = player.gameObject.baseRect.X + 5
2024-08-29 00:05:28 +02:00
break
case 5: // Up-Left
2024-08-29 18:48:27 +02:00
shootY = player.gameObject.baseRect.Y
shootX = player.gameObject.baseRect.X - 1
2024-08-29 00:05:28 +02:00
break
case 6: // Down-Right
2024-08-29 18:48:27 +02:00
shootY = player.gameObject.baseRect.Y + 5
shootX = player.gameObject.baseRect.X + 5
2024-08-29 00:05:28 +02:00
break
case 7: // Down-Left
2024-08-29 18:48:27 +02:00
shootY = player.gameObject.baseRect.Y + 5
shootX = player.gameObject.baseRect.X - 1
2024-08-29 00:05:28 +02:00
break
}
// Set bullet color
2024-08-29 18:48:27 +02:00
bulletColor := player.playerColors.body
2024-08-29 00:05:28 +02:00
// Create and add the bullet
*bullets = append(*bullets, &Bullet{
posX: shootX,
posY: shootY,
2024-08-29 18:48:27 +02:00
direction: player.gameObject.orientation,
2024-08-29 00:05:28 +02:00
color: bulletColor,
super: super,
})
// Set cooldown and decrease energy
player.shootCooldown = ShootCooldown
if super {
player.energy -= SuperShotCost
2024-08-29 18:48:27 +02:00
player.ammunition = 0
2024-08-29 00:05:28 +02:00
} else {
player.energy -= NormalShotCost
2024-08-29 18:48:27 +02:00
player.ammunition--
}
}
}
func (player *Player) explode(bullets *[]*Bullet) {
// Set bullet color
bulletColor := player.playerColors.body
for x := player.gameObject.baseRect.X - BlastRadius; x < BlastRadius*2+1; x++ {
for y := player.gameObject.baseRect.Y - BlastRadius; y < BlastRadius*2+1; y++ {
// Create and add the bullet
*bullets = append(*bullets, &Bullet{
posX: x,
posY: y,
direction: uint8(rand.Intn(8)),
color: bulletColor,
super: true,
})
2024-08-29 00:05:28 +02:00
}
}
}
2024-08-29 18:48:27 +02:00
func createPlayers(amount uint8, playerColors []PlayerColors, keyMaps []KeyMap, joyMaps []JoyMap, gameMap *GameMap, players *[]*Player) {
joyStickCount := sdl.NumJoysticks()
if amount > uint8(len(keyMaps)+len(joyMaps)) || amount > uint8(len(keyMaps)+joyStickCount) {
panic("Too many players, not enough inputs")
}
if amount >= uint8(len(playerColors)) {
panic("Too many players, not enough colors")
}
addedKeyboardPlayers := 0
for i := uint8(0); i < amount; i++ {
var keyMap KeyMap
var joyMap JoyMap
var joyStick *sdl.Joystick
if (DoAllKeymapsPlayers && i <= uint8(len(keyMaps))) || (DoKeymapPlayer && i == 0) || (uint8(joyStickCount) <= i) {
keyMap = keyMaps[addedKeyboardPlayers]
addedKeyboardPlayers++
} else {
joyStickIndex := i - uint8(addedKeyboardPlayers)
joyMap = joyMaps[joyStickIndex]
joyStick = sdl.JoystickOpen(int(joyStickIndex))
}
createPlayer(
playerColors[i],
keyMap,
joyMap,
joyStick,
gameMap,
players,
)
}
}
func closeThings(players *[]*Player) {
for _, player := range *players {
if player.joyStick != nil {
player.joyStick.Close()
}
if player.window != nil {
player.window.Destroy()
}
if player.logicalSurface != nil {
player.logicalSurface.Free()
}
if player.playSurface != nil {
player.playSurface.Free()
}
if player.HUDSurface != nil {
player.HUDSurface.Free()
}
}
}
func createPlayer(playerColors PlayerColors, keyMap KeyMap, joyMap JoyMap, joyStick *sdl.Joystick, gameMap *GameMap, players *[]*Player) {
2024-08-29 00:05:28 +02:00
coordsAreValid := false
var posX, posY int32
2024-08-29 18:48:27 +02:00
maxTries := 1000
for !coordsAreValid && maxTries >= 0 {
maxTries--
posX = int32(16 + rand.Intn(int(gameMap.width-43)))
posY = int32(16 + rand.Intn(int(gameMap.height-43)))
2024-08-29 00:05:28 +02:00
coordsAreValid = true
for _, player := range *players {
2024-08-29 18:48:27 +02:00
distance := (player.gameObject.baseRect.X-posX)*(player.gameObject.baseRect.X-posX) +
(player.gameObject.baseRect.Y-posY)*(player.gameObject.baseRect.Y-posY)
2024-08-29 00:05:28 +02:00
if distance < 300*300 { // Check if distance is less than 300 units
coordsAreValid = false
break
}
}
2024-08-29 18:48:27 +02:00
if posX < 16 || posX > gameMap.width-36-7 || posY < 16 || posY > gameMap.height-36-7 {
coordsAreValid = false
break
}
2024-08-29 00:05:28 +02:00
}
2024-08-29 18:48:27 +02:00
if maxTries < 0 {
panic("Could not place all players, increase map size")
}
gameObject := &GameObject{}
gameObject.baseRect = sdl.Rect{
X: posX,
Y: posY,
W: 7,
H: 7,
}
gameObject.addColor(playerColors.tracks)
gameObject.addColor(playerColors.body)
gameObject.addColor(playerColors.cannon)
gameObject.orientation = 0 // Up
gameObject.addColoredRect(0, 1, 1, 6, 0)
gameObject.addColoredRect(4, 1, 1, 6, 0)
gameObject.addColoredRect(1, 2, 3, 4, 1)
gameObject.addColoredRect(2, 0, 1, 4, 2)
gameObject.orientation = 1 // Right
gameObject.addColoredRect(1, 1, 6, 1, 0)
gameObject.addColoredRect(1, 5, 6, 1, 0)
gameObject.addColoredRect(2, 2, 4, 3, 1)
gameObject.addColoredRect(4, 3, 4, 1, 2)
gameObject.orientation = 2 // Down
gameObject.addColoredRect(0, 1, 1, 6, 0)
gameObject.addColoredRect(4, 1, 1, 6, 0)
gameObject.addColoredRect(1, 2, 3, 4, 1)
gameObject.addColoredRect(2, 4, 1, 4, 2)
gameObject.orientation = 3 // Left
gameObject.addColoredRect(1, 1, 6, 1, 0)
gameObject.addColoredRect(1, 5, 6, 1, 0)
gameObject.addColoredRect(2, 2, 4, 3, 1)
gameObject.addColoredRect(0, 3, 4, 1, 2)
gameObject.orientation = 4 // Up-Right
gameObject.addColoredRect(3, 0, 1, 1, 0)
gameObject.addColoredRect(2, 1, 1, 1, 0)
gameObject.addColoredRect(1, 2, 1, 1, 0)
gameObject.addColoredRect(0, 3, 1, 1, 0)
gameObject.addColoredRect(6, 3, 1, 1, 0)
gameObject.addColoredRect(5, 4, 1, 1, 0)
gameObject.addColoredRect(4, 5, 1, 1, 0)
gameObject.addColoredRect(3, 6, 1, 1, 0)
gameObject.addColoredRect(3, 1, 1, 1, 1)
gameObject.addColoredRect(2, 2, 2, 1, 1)
gameObject.addColoredRect(1, 3, 2, 1, 1)
gameObject.addColoredRect(4, 3, 2, 1, 1)
gameObject.addColoredRect(2, 4, 3, 1, 1)
gameObject.addColoredRect(3, 5, 1, 1, 1)
gameObject.addColoredRect(5, 1, 1, 1, 2)
gameObject.addColoredRect(4, 2, 1, 1, 2)
gameObject.addColoredRect(3, 3, 1, 1, 2)
// Up-Left orientation (Y-axis reflection)
gameObject.orientation = 5 // Up-Left
gameObject.addColoredRect(3, 0, 1, 1, 0)
gameObject.addColoredRect(4, 1, 1, 1, 0)
gameObject.addColoredRect(5, 2, 1, 1, 0)
gameObject.addColoredRect(6, 3, 1, 1, 0)
gameObject.addColoredRect(0, 3, 1, 1, 0)
gameObject.addColoredRect(1, 4, 1, 1, 0)
gameObject.addColoredRect(2, 5, 1, 1, 0)
gameObject.addColoredRect(3, 6, 1, 1, 0)
gameObject.addColoredRect(3, 1, 1, 1, 1)
gameObject.addColoredRect(3, 2, 2, 1, 1)
gameObject.addColoredRect(4, 3, 2, 1, 1)
gameObject.addColoredRect(1, 3, 2, 1, 1)
gameObject.addColoredRect(2, 4, 3, 1, 1)
gameObject.addColoredRect(3, 5, 1, 1, 1)
gameObject.addColoredRect(1, 1, 1, 1, 2)
gameObject.addColoredRect(2, 2, 1, 1, 2)
gameObject.addColoredRect(3, 3, 1, 1, 2)
// Down-Right orientation (X-axis reflection)
gameObject.orientation = 6 // Down-Right
gameObject.addColoredRect(3, 6, 1, 1, 0)
gameObject.addColoredRect(2, 5, 1, 1, 0)
gameObject.addColoredRect(1, 4, 1, 1, 0)
gameObject.addColoredRect(0, 3, 1, 1, 0)
gameObject.addColoredRect(6, 3, 1, 1, 0)
gameObject.addColoredRect(5, 2, 1, 1, 0)
gameObject.addColoredRect(4, 1, 1, 1, 0)
gameObject.addColoredRect(3, 0, 1, 1, 0)
gameObject.addColoredRect(3, 5, 1, 1, 1)
gameObject.addColoredRect(2, 4, 2, 1, 1)
gameObject.addColoredRect(1, 3, 2, 1, 1)
gameObject.addColoredRect(4, 3, 2, 1, 1)
gameObject.addColoredRect(2, 2, 3, 1, 1)
gameObject.addColoredRect(3, 1, 1, 1, 1)
gameObject.addColoredRect(5, 5, 1, 1, 2)
gameObject.addColoredRect(4, 4, 1, 1, 2)
gameObject.addColoredRect(3, 3, 1, 1, 2)
// Down-Left orientation (XY reflection)
gameObject.orientation = 7 // Down-Left
gameObject.addColoredRect(3, 6, 1, 1, 0)
gameObject.addColoredRect(4, 5, 1, 1, 0)
gameObject.addColoredRect(5, 4, 1, 1, 0)
gameObject.addColoredRect(6, 3, 1, 1, 0)
gameObject.addColoredRect(0, 3, 1, 1, 0)
gameObject.addColoredRect(1, 2, 1, 1, 0)
gameObject.addColoredRect(2, 1, 1, 1, 0)
gameObject.addColoredRect(3, 0, 1, 1, 0)
gameObject.addColoredRect(3, 1, 1, 1, 1)
gameObject.addColoredRect(2, 2, 3, 1, 1)
gameObject.addColoredRect(1, 3, 2, 1, 1)
gameObject.addColoredRect(4, 3, 2, 1, 1)
gameObject.addColoredRect(3, 4, 2, 1, 1)
gameObject.addColoredRect(3, 5, 1, 1, 1)
gameObject.addColoredRect(1, 5, 1, 1, 2)
gameObject.addColoredRect(2, 4, 1, 1, 2)
gameObject.addColoredRect(3, 3, 1, 1, 2)
gameObject.orientation = 0
2024-08-29 00:05:28 +02:00
*players = append(*players, &Player{
2024-08-29 18:48:27 +02:00
playerColors: playerColors,
keyMap: keyMap,
joyMap: joyMap,
joyStick: joyStick,
shields: MaxShields,
energy: MaxEnergy,
gameObject: gameObject,
local: true,
2024-08-29 00:05:28 +02:00
})
}