From 730e697258afbe27bfb95f2288f434a5aeba303f Mon Sep 17 00:00:00 2001 From: silva guimaraes Date: Sat, 23 Aug 2025 19:53:45 -0300 Subject: [PATCH] Commit --- main.go | 671 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 336 insertions(+), 335 deletions(-) diff --git a/main.go b/main.go index 51178e2..c4160dc 100644 --- a/main.go +++ b/main.go @@ -4,508 +4,509 @@ import ( "fmt" "math" "math/rand" + "slices" + rl "github.com/gen2brain/raylib-go/raylib" ) const ( - WIDTH = 1100 - HEIGHT = 700 - buildingSpacing = 2.5 - buildingSize = 1.2 - maxBuildingHeight = 10 - maxColumns = 5 - enemyAcc = 0.01 - maxSpeed = 0.1 - buildingsHealth = 3 + WIDTH = 1100 + HEIGHT = 700 + buildingSpacing = 2.5 + buildingSize = 1.2 + maxBuildingHeight = 10 + maxColumns = 5 + enemyAcc = 0.01 + maxSpeed = 0.1 + buildingsHealth = 3 ) type enemy struct { - pos rl.Vector3 - speed float32 + pos rl.Vector3 + speed float32 } type remainingFrames int -type animationFunc func()remainingFrames +type animationFunc func() remainingFrames type building struct { - pos rl.Vector3 - size rl.Vector3 - color rl.Color - life int - boundingBox rl.BoundingBox - animate animationFunc + pos rl.Vector3 + size rl.Vector3 + color rl.Color + life int + boundingBox rl.BoundingBox + animate animationFunc } type healthBar struct { - life int - damageTaken float32 - lastUpdate float64 + life int + damageTaken float32 + lastUpdate float64 } type character struct { - camera rl.Camera - damage int + camera rl.Camera + damage int } type projectile struct { - pos rl.Vector3 - speed rl.Vector3 + pos rl.Vector3 + speed rl.Vector3 } type scene struct { - buildings []*building - healthBar *healthBar - projectiles []*projectile - character *character - emitters []*emitter + buildings []*building + healthBar *healthBar + projectiles []*projectile + character *character + emitters []*emitter } type particle struct { - // birth float32 - lifetime float64 - pos rl.Vector3 - speed rl.Vector3 + // birth float32 + lifetime float64 + pos rl.Vector3 + speed rl.Vector3 } type emitter struct { - particles []*particle - pos rl.Vector3 - particleAmount int + particles []*particle + pos rl.Vector3 + particleAmount int } var city *scene func update_emitters() { - for i, e := range city.emitters { - if remainingParticles := e.update(); remainingParticles == 0 { - city.emitters[i] = city.emitters[len(city.emitters)-1] - city.emitters = city.emitters[:len(city.emitters)-1] - } - } + for i := 0; i < len(city.emitters); i++ { + + e := city.emitters[i] + remainingParticles := e.update() + + if remainingParticles == 0 { + city.emitters = slices.Delete(city.emitters, i, i+1) + i-- + } + + } } func newEmitter(pos rl.Vector3, particleAmount int) *emitter { - emitter := emitter{ - pos: pos, - particleAmount: particleAmount, - } + emitter := emitter{ + pos: pos, + particleAmount: particleAmount, + } - for i := 0; i < particleAmount; i++ { - direction := rl.NewVector3( - rand.Float32()*2 - 1, - 1, - rand.Float32()*2 - 1, - ) - direction = rl.Vector3Normalize(direction) - direction = rl.Vector3Scale(direction, 0.3 + rand.Float32()/3) - particle := particle{ - lifetime: rl.GetTime() + 2, - speed: direction, - pos: pos, - } - emitter.particles = append(emitter.particles, &particle) - } + for i := 0; i < particleAmount; i++ { + direction := rl.NewVector3( + rand.Float32()*2-1, + 1, + rand.Float32()*2-1, + ) + direction = rl.Vector3Normalize(direction) + direction = rl.Vector3Scale(direction, 0.3+rand.Float32()/3) + particle := particle{ + lifetime: rl.GetTime() + 2, + speed: direction, + pos: pos, + } + emitter.particles = append(emitter.particles, &particle) + } - return &emitter + return &emitter } func (e *emitter) update() int { - gravity := rl.NewVector3(0, -0.02, 0) + gravity := rl.NewVector3(0, -0.02, 0) - remainingParticles := 0 + remainingParticles := 0 - rl.BeginBlendMode(rl.BlendAdditive) - { - for _, particle := range e.particles { - if rl.GetTime() > particle.lifetime { - continue - } + rl.BeginBlendMode(rl.BlendAdditive) + { + for _, particle := range e.particles { + if rl.GetTime() > particle.lifetime { + continue + } - particle.speed = rl.Vector3Add(particle.speed, gravity) - newPos := rl.Vector3Add(particle.pos, particle.speed) - if newPos.Y <= 0 { - particle.pos.Y = 0 - } else { - particle.pos = newPos - } + particle.speed = rl.Vector3Add(particle.speed, gravity) + newPos := rl.Vector3Add(particle.pos, particle.speed) + if newPos.Y <= 0 { + particle.pos.Y = 0 + } else { + particle.pos = newPos + } - rl.DrawCubeV(particle.pos, rl.NewVector3(.1, .1, .1), rl.Yellow) + rl.DrawCubeV(particle.pos, rl.NewVector3(.1, .1, .1), rl.Yellow) - remainingParticles += 1 - } - } - rl.EndBlendMode() + remainingParticles += 1 + } + } + rl.EndBlendMode() - return remainingParticles + return remainingParticles } // retona true caso projétil precise ser destruido func (p *projectile) isHit() bool { - gravity := rl.NewVector3(0, -0.02, 0) - p.speed = rl.Vector3Add(p.speed, gravity) - p.pos = rl.Vector3Add(p.pos, p.speed) + gravity := rl.NewVector3(0, -0.02, 0) + p.speed = rl.Vector3Add(p.speed, gravity) + p.pos = rl.Vector3Add(p.pos, p.speed) - if p.pos.Y < 0 { - city.emitters = append(city.emitters, newEmitter(p.pos, 500)) - for _, building := range city.buildings { - if dist := rl.Vector3Distance(p.pos, building.pos); dist < 10 { - building.causeDamage(3) - } - } - return true - } + if p.pos.Y < 0 { + city.emitters = append(city.emitters, newEmitter(p.pos, 500)) + for _, building := range city.buildings { + if dist := rl.Vector3Distance(p.pos, building.pos); dist < 10 { + building.causeDamage(3) + } + } + return true + } - rl.DrawSphere(p.pos, 0.5, rl.Gray) - return false + rl.DrawSphere(p.pos, 0.5, rl.Gray) + return false } func update_projectiles() { - for i, p := range city.projectiles { - if hit := p.isHit(); hit { - city.projectiles[i] = city.projectiles[len(city.projectiles)-1] - city.projectiles = city.projectiles[:len(city.projectiles)-1] - } - } + for i, p := range city.projectiles { + if hit := p.isHit(); hit { + city.projectiles[i] = city.projectiles[len(city.projectiles)-1] + city.projectiles = city.projectiles[:len(city.projectiles)-1] + } + } } - func (c *character) kill_aurea() { - const min = 10 - for _, b := range city.buildings { - if distance := rl.Vector3Distance(c.camera.Position, b.pos); distance < min { - b.causeDamage(c.damage) - } - } + const min = 10 + for _, b := range city.buildings { + if distance := rl.Vector3Distance(c.camera.Position, b.pos); distance < min { + b.causeDamage(c.damage) + } + } } -func (c *character) throw_bomb(){ - if !rl.IsMouseButtonPressed(rl.MouseRightButton) { - return - } +func (c *character) throw_bomb() { + if !rl.IsMouseButtonPressed(rl.MouseRightButton) { + return + } - direction := rl.Vector3Subtract(c.camera.Target, c.camera.Position) + direction := rl.Vector3Subtract(c.camera.Target, c.camera.Position) - projectile := projectile{ - pos: c.camera.Position, - speed: rl.Vector3Scale(direction, 0.15), - } + projectile := projectile{ + pos: c.camera.Position, + speed: rl.Vector3Scale(direction, 0.15), + } - city.projectiles = append(city.projectiles, &projectile) + city.projectiles = append(city.projectiles, &projectile) } func (c *character) update() { - shake := rl.NewVector3( - randomShake(0.003) * city.healthBar.damageTaken, - randomShake(0.003) * city.healthBar.damageTaken, - randomShake(0.003) * city.healthBar.damageTaken, - ) - c.camera.Target = rl.Vector3Add(c.camera.Target, shake) + shake := rl.NewVector3( + randomShake(0.003)*city.healthBar.damageTaken, + randomShake(0.003)*city.healthBar.damageTaken, + randomShake(0.003)*city.healthBar.damageTaken, + ) + c.camera.Target = rl.Vector3Add(c.camera.Target, shake) - c.laser_beam() + c.laser_beam() - // c.kill_aurea() + // c.kill_aurea() - c.throw_bomb() + c.throw_bomb() } func newCharacter() *character { camera := rl.Camera3D{ - Position: rl.NewVector3(4.0, 2.0, 4.0), - Target: rl.NewVector3(0.0, 1.8, 0.0), - Up: rl.NewVector3(0.0, 1.0, 0.0), - Fovy: 80.0, - Projection: rl.CameraPerspective, - } - return &character{ - camera: camera, - damage: 1, - } + Position: rl.NewVector3(4.0, 2.0, 4.0), + Target: rl.NewVector3(0.0, 1.8, 0.0), + Up: rl.NewVector3(0.0, 1.0, 0.0), + Fovy: 80.0, + Projection: rl.CameraPerspective, + } + return &character{ + camera: camera, + damage: 1, + } } func draw_plane() { - rl.DrawPlane( - rl.NewVector3(16, 0.0, 16), - rl.NewVector2(128.0, 128.0), - rl.NewColor(50, 50, 50, 255), - ) + rl.DrawPlane( + rl.NewVector3(16, 0.0, 16), + rl.NewVector2(128.0, 128.0), + rl.NewColor(50, 50, 50, 255), + ) } func randomShake(amount float32) float32 { - return rand.Float32() * amount - amount/2 + return rand.Float32()*amount - amount/2 } func (hb *healthBar) update() { - const MARGIN = 20 - const BARWIDTH = (WIDTH - MARGIN*2) + const MARGIN = 20 + const BARWIDTH = (WIDTH - MARGIN*2) - currentLife := 0 - maxLife := buildingsHealth * len(city.buildings) - for _, b := range city.buildings { - currentLife += b.life - } - position := rl.NewVector2(MARGIN, 10) - barWidth := BARWIDTH * currentLife/maxLife + currentLife := 0 + maxLife := buildingsHealth * len(city.buildings) + for _, b := range city.buildings { + currentLife += b.life + } + position := rl.NewVector2(MARGIN, 10) + barWidth := BARWIDTH * currentLife / maxLife - size := rl.NewVector2(float32(barWidth), 10) + size := rl.NewVector2(float32(barWidth), 10) - hb.damageTaken += float32(hb.life - currentLife) + hb.damageTaken += float32(hb.life - currentLife) - damageTakenBar := size - damageTakenBar.X = BARWIDTH * - (float32(currentLife) + hb.damageTaken) / float32(maxLife) + damageTakenBar := size + damageTakenBar.X = BARWIDTH * + (float32(currentLife) + hb.damageTaken) / float32(maxLife) - shake := rl.NewVector2( - randomShake(0.4) * hb.damageTaken, - randomShake(0.4) * hb.damageTaken, - ) - position = rl.Vector2Add(position, shake) + shake := rl.NewVector2( + randomShake(0.4)*hb.damageTaken, + randomShake(0.4)*hb.damageTaken, + ) + position = rl.Vector2Add(position, shake) - rl.DrawRectangleV(position, damageTakenBar, rl.Orange) - rl.DrawRectangleV(position, size, rl.Red) + rl.DrawRectangleV(position, damageTakenBar, rl.Orange) + rl.DrawRectangleV(position, size, rl.Red) - hb.lastUpdate = rl.GetTime() - hb.life = currentLife - hb.damageTaken *= 0.95 + hb.lastUpdate = rl.GetTime() + hb.life = currentLife + hb.damageTaken *= 0.95 } func newHealthBar(buildings []*building) *healthBar { - return &healthBar{ - life: buildingsHealth * len(buildings), - } + return &healthBar{ + life: buildingsHealth * len(buildings), + } } func (b *building) causeDamage(damage int) { - if b.animate != nil || b.life <= 0 { - return - } - b.animate = shakeBuilding(b) - b.life -= damage - // fmt.Println("damage:", damage, "life:", b.life) + if b.animate != nil || b.life <= 0 { + return + } + b.animate = shakeBuilding(b) + b.life -= damage + // fmt.Println("damage:", damage, "life:", b.life) } func newBuilding(x, z float32) *building { - color := rl.NewColor( - uint8(rl.GetRandomValue(0, 180)), - uint8(rl.GetRandomValue(0, 180)), - uint8(rl.GetRandomValue(0, 180)), - 255, - ) + color := rl.NewColor( + uint8(rl.GetRandomValue(0, 180)), + uint8(rl.GetRandomValue(0, 180)), + uint8(rl.GetRandomValue(0, 180)), + 255, + ) - pos := rl.NewVector3(x * buildingSpacing, 0, z * buildingSpacing) - size := rl.NewVector3( - buildingSize, - float32(rl.GetRandomValue(1, maxBuildingHeight)), - buildingSize, - ) - min := rl.NewVector3( - pos.X - buildingSize/2, - 0, - pos.Z - buildingSize/2, - ) - max := rl.NewVector3( - pos.X + buildingSize/2, - size.Y/2, - pos.Z + buildingSize/2, - ) + pos := rl.NewVector3(x*buildingSpacing, 0, z*buildingSpacing) + size := rl.NewVector3( + buildingSize, + float32(rl.GetRandomValue(1, maxBuildingHeight)), + buildingSize, + ) + min := rl.NewVector3( + pos.X-buildingSize/2, + 0, + pos.Z-buildingSize/2, + ) + max := rl.NewVector3( + pos.X+buildingSize/2, + size.Y/2, + pos.Z+buildingSize/2, + ) - return &building{ - color: color, - life: buildingsHealth, - pos: pos, - size: size, - boundingBox: rl.NewBoundingBox(min, max), - } + return &building{ + color: color, + life: buildingsHealth, + pos: pos, + size: size, + boundingBox: rl.NewBoundingBox(min, max), + } } - func drawWireframe(building building) { - increasedSize := rl.Vector3Scale(building.size, 1.05) + increasedSize := rl.Vector3Scale(building.size, 1.05) - invertedColor := building.color - invertedColor.R += 127 - invertedColor.G += 127 - invertedColor.B += 127 + invertedColor := building.color + invertedColor.R += 127 + invertedColor.G += 127 + invertedColor.B += 127 - rl.DrawCubeWiresV( - building.pos, - increasedSize, - invertedColor, - ) + rl.DrawCubeWiresV( + building.pos, + increasedSize, + invertedColor, + ) } func shakeBuilding(b *building) animationFunc { - var frame remainingFrames = 60 * 0.7 - return func() remainingFrames { + var frame remainingFrames = 60 * 0.7 + return func() remainingFrames { - building := *b + building := *b - if frame % 4 == 0 { - if b.life == 0 { - building.color = rl.NewColor(255, 0, 0, 255) - } else { - building.color = rl.RayWhite - } - } + if frame%4 == 0 { + if b.life == 0 { + building.color = rl.NewColor(255, 0, 0, 255) + } else { + building.color = rl.RayWhite + } + } - drawWireframe(building) + drawWireframe(building) - shake := rl.NewVector3( - rand.Float32() * .2 - .1, - rand.Float32() * .1 - .05, - rand.Float32() * .2 - .1, - ) - // shake = rl.Vector3Scale(shake, float32(math.Sin(rl.GetTime()) + 1)/3) - rl.DrawCubeV( - rl.Vector3Add(building.pos, shake), - building.size, - building.color, - ) + shake := rl.NewVector3( + rand.Float32()*.2-.1, + rand.Float32()*.1-.05, + rand.Float32()*.2-.1, + ) + // shake = rl.Vector3Scale(shake, float32(math.Sin(rl.GetTime()) + 1)/3) + rl.DrawCubeV( + rl.Vector3Add(building.pos, shake), + building.size, + building.color, + ) - frame -= 1 - return frame - } + frame -= 1 + return frame + } } - func draw_buildings() { - for _, building := range city.buildings { + for _, building := range city.buildings { - hasAnimation := building.animate != nil + hasAnimation := building.animate != nil - if building.life <= 0 && !hasAnimation { - continue - } + if building.life <= 0 && !hasAnimation { + continue + } - if hasAnimation { + if hasAnimation { - remainingFrames := building.animate() + remainingFrames := building.animate() - if remainingFrames == 0 { - building.animate = nil - } + if remainingFrames == 0 { + building.animate = nil + } - continue - } + continue + } - drawWireframe(*building) - rl.DrawCubeV(building.pos, building.size, building.color) - } + drawWireframe(*building) + rl.DrawCubeV(building.pos, building.size, building.color) + } } func (c *character) laser_beam() { - if !rl.IsMouseButtonDown(rl.MouseLeftButton) { - return - } - ray := rl.Ray{ - Position: c.camera.Position, - Direction: rl.Vector3Subtract(c.camera.Target, c.camera.Position), - } + if !rl.IsMouseButtonDown(rl.MouseLeftButton) { + return + } + ray := rl.Ray{ + Position: c.camera.Position, + Direction: rl.Vector3Subtract(c.camera.Target, c.camera.Position), + } - closestDistance := math.Inf(1) - var closest *building + closestDistance := math.Inf(1) + var closest *building - for _, building := range city.buildings { + for _, building := range city.buildings { - if building.life == 0 { - continue - } + if building.life == 0 { + continue + } - playerDistance := rl.Vector3Distance(c.camera.Position, building.pos) + playerDistance := rl.Vector3Distance(c.camera.Position, building.pos) - if playerDistance < float32(closestDistance) { + if playerDistance < float32(closestDistance) { - collision := rl.GetRayCollisionBox(ray, building.boundingBox) + collision := rl.GetRayCollisionBox(ray, building.boundingBox) - if collision.Hit { + if collision.Hit { - closestDistance = float64(playerDistance) - closest = building - } - } - } + closestDistance = float64(playerDistance) + closest = building + } + } + } - if closest != nil { - closest.causeDamage(c.damage) - } + if closest != nil { + closest.causeDamage(c.damage) + } } func newBuildings() []*building { - var buildings []*building + var buildings []*building - for i := 0; i < 32; i++ { - for j := 0; j < 32; j++ { - buildings = append(buildings, newBuilding(float32(i), float32(j))) - } - } + for i := 0; i < 32; i++ { + for j := 0; j < 32; j++ { + buildings = append(buildings, newBuilding(float32(i), float32(j))) + } + } - return buildings + return buildings } func main() { - fmt.Println("hello world") - rl.SetConfigFlags(rl.FlagMsaa4xHint) + fmt.Println("hello world") + rl.SetConfigFlags(rl.FlagMsaa4xHint) rl.InitWindow(WIDTH, HEIGHT, "raylib [core] example - 3d camera first person") rl.SetTargetFPS(60) - rl.HideCursor() - rl.DisableCursor() - rl.SetMousePosition(WIDTH/2, HEIGHT/2) + rl.HideCursor() + rl.DisableCursor() + rl.SetMousePosition(WIDTH/2, HEIGHT/2) - character := newCharacter() - buildings := newBuildings() - healthBar := newHealthBar(buildings) + character := newCharacter() + buildings := newBuildings() + healthBar := newHealthBar(buildings) - city = &scene{ - buildings: buildings, - healthBar: healthBar, - character: character, - } + city = &scene{ + buildings: buildings, + healthBar: healthBar, + character: character, + } - // direction := rl.Vector3Subtract(character.camera.Target, character.camera.Position) - // aim := direction + // direction := rl.Vector3Subtract(character.camera.Target, character.camera.Position) + // aim := direction for !rl.WindowShouldClose() { - rl.UpdateCamera(&character.camera, rl.CameraFirstPerson) rl.BeginDrawing() rl.ClearBackground(rl.LightGray) - rl.BeginMode3D(character.camera) - { - character.update() + rl.BeginMode3D(character.camera) + { + character.update() - draw_plane() + draw_plane() - update_projectiles() + update_projectiles() - draw_buildings() + draw_buildings() - update_emitters() - + update_emitters() - - // direction = rl.Vector3Subtract( - // character.camera.Target, character.camera.Position) - // aim = rl.Vector3Lerp(direction, aim, 0.95) - // rl.DrawSphere(rl.Vector3Add(character.camera.Position, aim), 0.1, rl.Red) - } - rl.EndMode3D() + // direction = rl.Vector3Subtract( + // character.camera.Target, character.camera.Position) + // aim = rl.Vector3Lerp(direction, aim, 0.95) + // rl.DrawSphere(rl.Vector3Add(character.camera.Position, aim), 0.1, rl.Red) + } + rl.EndMode3D() - rl.DrawLineV( - rl.NewVector2(WIDTH/2-5, HEIGHT/2-5), - rl.NewVector2(WIDTH/2+5, HEIGHT/2+5), - rl.Red, - ) - rl.DrawLineV( - rl.NewVector2(WIDTH/2-5, HEIGHT/2+5), - rl.NewVector2(WIDTH/2+5, HEIGHT/2-5), - rl.Red, - ) + rl.DrawLineV( + rl.NewVector2(WIDTH/2-5, HEIGHT/2-5), + rl.NewVector2(WIDTH/2+5, HEIGHT/2+5), + rl.Red, + ) + rl.DrawLineV( + rl.NewVector2(WIDTH/2-5, HEIGHT/2+5), + rl.NewVector2(WIDTH/2+5, HEIGHT/2-5), + rl.Red, + ) - rl.DrawFPS(0, HEIGHT-30) + rl.DrawFPS(0, HEIGHT-30) - healthBar.update() + healthBar.update() rl.EndDrawing() }