GOingTunneling/main.go

187 lines
5.4 KiB
Go
Raw Normal View History

2024-08-29 00:05:28 +02:00
package main
import (
"github.com/veandco/go-sdl2/sdl"
)
const (
2024-08-29 18:48:27 +02:00
MapWidth = 1000 // Width of the map
MapHeight = 1000 // Height of the map
BlastRadius = 5
MaxEnergy = 3520
MaxAmmunition = 6
MaxShields = 100
NormalShotCost = 7
SuperShotCost = 80
ReloadCost = 4
MovementCost = 1
DiggingCost = 3
ShootDiggingCostBonus = 1
2024-08-29 00:05:28 +02:00
ShootCooldown = 8
RechargeCooldownOwn = 0
DiggingCooldown = 4
RechargeCooldownOpponent = 6
RepairCooldown = 4
MovementCooldown = 2
MovementCooldownNoEnergy = 4
DiggingCooldownNoEnergy = 8
2024-08-29 18:48:27 +02:00
ReloadCooldown = 16
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
Debug = false
MapWindow = true
RenderGameObjects = true
ProfilerOn = true
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
JoyStickDeadZone = 8000
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
DoAllKeymapsPlayers = true
DoJoyStickPlayers = true
DoKeymapPlayer = true
)
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
var mapWindow *sdl.Window
var mapSurface *sdl.Surface
var mapRendererRect = &sdl.Rect{X: 0, Y: 0, W: MapWidth, H: MapHeight}
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
func main() {
initializeSDL()
defer sdl.Quit()
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
gameMap := &GameMap{}
2024-08-29 00:05:28 +02:00
gameMap.createGameMap(MapWidth, MapHeight)
players := &[]*Player{}
2024-08-29 18:48:27 +02:00
initPlayerColors()
createPlayers(getNeededPlayers(), playerColors, keyMaps, joyMaps, gameMap, players)
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
defer closeThings(players)
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
bases := createBases(players, gameMap)
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
bullets := &[]*Bullet{}
bulletParticles := &[]*BulletParticle{}
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
for playerIndex, player := range *players {
initPlayer(uint8(playerIndex), player)
}
if MapWindow {
mapWindow, mapSurface = setupMapWindowAndSurface()
}
2024-08-29 00:05:28 +02:00
running := true
for running {
2024-08-29 18:48:27 +02:00
frameStart := sdl.GetTicks64()
for playerIndex, player := range *players {
// Delay to achieve roughly 60 FPS
if player.local {
running = doPlayerFrame(uint8(playerIndex), player, players, gameMap, bases, bullets, bulletParticles)
if !running {
break
}
}
}
if MapWindow {
gameMap.render(mapRendererRect, mapSurface)
for _, bullet := range *bullets {
(*bullet).render(mapRendererRect, mapSurface)
}
for _, base := range *bases {
(*base).render(mapRendererRect, mapSurface)
}
for _, playerLoop := range *players {
(*playerLoop).render(mapRendererRect, mapSurface)
}
for _, bulletParticle := range *bulletParticles {
bulletParticle.render(mapRendererRect, mapSurface)
}
adjustWindow(mapWindow, mapSurface)
}
//now tick world
for _, bullet := range *bullets {
(*bullet).tick(gameMap, bulletParticles, bullets, players)
}
for _, base := range *bases {
(*base).tick(players)
}
for _, bulletParticle := range *bulletParticles {
bulletParticle.tick(bulletParticles)
}
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
enforceFrameRate(frameStart, 60)
}
}
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
func initPlayer(playerIndex uint8, player *Player) {
player.window, player.logicalSurface = setupWindowAndSurface(playerIndex)
logicalColor := sdl.MapRGBA(player.logicalSurface.Format, 101, 101, 0, 255)
player.logicalSurface.FillRect(nil, logicalColor)
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
player.playSurface, player.playSurfaceRect, player.playSurfaceTargetRect = setupPlaySurface()
playColor := sdl.MapRGBA(player.playSurface.Format, 101, 0, 101, 255)
player.playSurface.FillRect(nil, playColor)
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
player.HUDSurface, player.HUDSurfaceRect, player.HUDSurfaceTargetRect = setupHUDSurface()
initHud(player.HUDSurface)
player.camera = &sdl.Rect{X: 0, Y: 0, W: 76, H: 76}
2024-08-29 00:05:28 +02:00
}
2024-08-29 18:48:27 +02:00
func doPlayerFrame(playerIndex uint8, player *Player, players *[]*Player, gameMap *GameMap, bases *[]*Base, bullets *[]*Bullet, bulletParticles *[]*BulletParticle) bool {
running := true
var (
totalHandleEventsTime, totalRenderTime, totalFrameTime uint64
totalScalingTime, frameCount uint64
isShooting, shouldContinue bool
)
frameStart := sdl.GetTicks64()
// Profile handleEvents
totalHandleEventsTime += profileSection(func() {
running = handleEvents(player.window, player.logicalSurface)
keyboard := sdl.GetKeyboardState()
shouldContinue, isShooting = handleInput(keyboard, bullets, player, gameMap, player.playSurface.Format, players)
running = running && shouldContinue
})
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
// Profile rendering (aggregate all renderings)
totalRenderTime += profileSection(func() {
player.track(player.camera)
gameMap.render(player.camera, player.playSurface)
2024-08-29 00:05:28 +02:00
2024-08-29 18:48:27 +02:00
for _, bullet := range *bullets {
(*bullet).render(player.camera, player.playSurface)
2024-08-29 00:05:28 +02:00
}
2024-08-29 18:48:27 +02:00
for _, base := range *bases {
(*base).render(player.camera, player.playSurface)
2024-08-29 00:05:28 +02:00
}
2024-08-29 18:48:27 +02:00
for _, playerLoop := range *players {
(*playerLoop).render(player.camera, player.playSurface)
}
for _, bulletParticle := range *bulletParticles {
bulletParticle.render(player.camera, player.playSurface)
2024-08-29 00:05:28 +02:00
}
2024-08-29 18:48:27 +02:00
player.tick(isShooting, bullets, player.playSurface.Format)
renderHud(player, player.HUDSurface)
player.playSurface.BlitScaled(player.playSurfaceRect, player.logicalSurface, player.playSurfaceTargetRect)
player.HUDSurface.BlitScaled(player.HUDSurfaceRect, player.logicalSurface, player.HUDSurfaceTargetRect)
})
// Profile window adjustments
totalScalingTime += profileSection(func() {
adjustWindow(player.window, player.logicalSurface)
})
frameEnd := sdl.GetTicks64()
totalFrameTime += frameEnd - frameStart
frameCount++
// Log profiling information every 1000 frames
if frameCount%1000 == 0 && ProfilerOn && playerIndex == 0 {
logProfilingInfo(totalHandleEventsTime, totalRenderTime, totalScalingTime, totalFrameTime, frameCount)
resetProfilingCounters(&totalHandleEventsTime, &totalRenderTime, &totalScalingTime, &totalFrameTime, &frameCount)
}
return running
2024-08-29 00:05:28 +02:00
}