diff --git a/main.go b/main.go index b8d4ee5..0d1faa3 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "math" rl "github.com/gen2brain/raylib-go/raylib" ) @@ -34,6 +35,7 @@ type player struct { pos rl.Vector2 moveSpeed float32 bulletMoveSpeed float32 + hitBoxRadius float32 } type enemy struct { @@ -41,6 +43,7 @@ type enemy struct { health int movePattern func(*enemy)rl.Vector2 shootPattern func() + hitBoxRadius float32 } func (g game) insideArena(v rl.Vector2) bool { @@ -48,12 +51,16 @@ func (g game) insideArena(v rl.Vector2) bool { v.Y <= float32(g.screenHeight) && v.X <= float32(g.screenWidth) } +func (g *game) removeBullet(index int) { + g.bullets[index] = g.bullets[len(g.bullets)-1] + g.bullets = g.bullets[:len(g.bullets)-1] +} + func (b *bullet) update(g *game, index int) { b.pos = rl.Vector2Add(b.pos, b.speed) if !g.insideArena(b.pos) { - g.bullets[index] = g.bullets[len(g.bullets)-1] - g.bullets = g.bullets[:len(g.bullets)-1] + g.removeBullet(index) return } @@ -65,6 +72,7 @@ func (e *enemy) shoot(g *game) { return } + g.bullets = append(g.bullets, &bullet{ speed: rl.Vector2{X: 0, Y: 10}, size: 4, @@ -87,13 +95,73 @@ func horizonalPattern(g *game) (func(*enemy)rl.Vector2) { } } +func circlePattern(g *game, center rl.Vector2) (func(*enemy)rl.Vector2) { -func (e *enemy) update(g *game) { + t := float64(0.5) + + return func(e *enemy) rl.Vector2 { + // x' = (x - x₀) * cos(θ) - (y - y₀) * sin(θ) + x₀ + // y' = (x - x₀) * sin(θ) + (y - y₀) * cos(θ) + y₀ + + // x' = x * cos(θ) - y * sin(θ) + // y' = x * sin(θ) + y * cos(θ) + + // result := center + // + // result.X = result.X + (e.pos.X - result.X) * float32(math.Cos(t)) - + // (e.pos.Y - result.Y) * float32(math.Sin(t)) + // + // result.Y = result.Y + (e.pos.Y - result.Y) * float32(math.Sin(t)) + + // (e.pos.Y - result.Y) * float32(math.Cos(t)) + + result := center + result.X = result.X * float32(math.Cos(t)) - result.Y * float32(math.Sin(t)) + result.Y = result.X * float32(math.Sin(t)) - result.Y * float32(math.Cos(t)) + + t += .08 + return result + } +} + +func (e *enemy) checkHit(g *game) (bool, *bullet, int) { + for index, bullet := range g.bullets { + + playerBullet := !bullet.enemy + if !playerBullet { + continue + } + distance := rl.Vector2Distance(e.pos, bullet.pos) - bullet.size + // fmt.Println(distance) + + if distance < e.hitBoxRadius { + return true, bullet, index + } + } + return false, nil, 0 +} + +func (g *game) killEnemy(index int) { + g.enemies[index] = g.enemies[len(g.enemies)-1] + g.enemies = g.enemies[:len(g.enemies)-1] +} + + +func (e *enemy) update(g *game, index int) { if e.movePattern != nil { e.pos = e.movePattern(e) } + if hit, bullet, idx := e.checkHit(g); hit { + e.health -= bullet.dmg + g.removeBullet(idx) + } + + if e.health <= 0 { + g.killEnemy(index) + return + } + e.shoot(g) rl.DrawCircleV(e.pos, 5, rl.Blue) @@ -134,7 +202,7 @@ func (p *player) checkHit(g *game) { distance := rl.Vector2Distance(p.pos, bullet.pos) - bullet.size // fmt.Println(distance) - if distance < 0 { + if distance < p.hitBoxRadius { fmt.Println("hit!") } } @@ -149,7 +217,7 @@ func (p *player) update(g *game) { p.checkHit(g) // hitbox - rl.DrawCircleV(p.pos, 5, rl.Red) + rl.DrawCircleV(p.pos, p.hitBoxRadius, rl.Red) // mira mouse := rl.GetMousePosition() @@ -157,7 +225,7 @@ func (p *player) update(g *game) { inverted = rl.Vector2Negate(inverted) inverted = rl.Vector2Normalize(inverted) inverted = rl.Vector2Scale(inverted, 2000) - rl.DrawLineV(p.pos, rl.Vector2Add(mouse, inverted), rl.Red) + rl.DrawLineV(p.pos, rl.Vector2Add(mouse, inverted), rl.NewColor(255, 0, 0, 100)) } @@ -169,29 +237,40 @@ func main() { pos: rl.Vector2{X: 100, Y: 100}, moveSpeed: 4, bulletMoveSpeed: 8, + hitBoxRadius: 5, } rl.SetTraceLog(rl.LogWarning | rl.LogDebug) rl.InitWindow(state.screenWidth, state.screenHeight, "danmaku") rl.SetTargetFPS(60) - state.enemies = append(state.enemies, &enemy{ - pos: rl.Vector2{X: 200, Y: 200}, - health: 10, - movePattern: horizonalPattern(state), - }) - state.enemies = append(state.enemies, &enemy{ - pos: rl.Vector2{X: 169, Y: 222}, - health: 10, - movePattern: horizonalPattern(state), - }) - state.enemies = append(state.enemies, &enemy{ - pos: rl.Vector2{X: 219, Y: 195}, - health: 10, - movePattern: horizonalPattern(state), - }) + state.enemies = []*enemy{ + { + pos: rl.Vector2{X: 200, Y: 200}, + health: 1, + hitBoxRadius: 5, + movePattern: horizonalPattern(state), + }, + { + pos: rl.Vector2{X: 169, Y: 222}, + health: 1, + hitBoxRadius:5, + movePattern: horizonalPattern(state), + }, + { + pos: rl.Vector2{X: 400, Y: 400}, + health: 1, + hitBoxRadius:5, + // movePattern: circlePattern(state, rl.Vector2{X: 200, Y: 200}), + }, + { + pos: rl.Vector2{X: 200, Y: 200}, + health: 1, + hitBoxRadius:5, + // movePattern: circlePattern(state, rl.Vector2{X: 200, Y: 200}), + }} - for ; !rl.WindowShouldClose(); state.time += 1 { + for ; !rl.WindowShouldClose(); state.time += 1 { rl.BeginDrawing() rl.ClearBackground(rl.Black) @@ -202,7 +281,7 @@ func main() { player.update(state) for i := range state.enemies { - state.enemies[i].update(state) + state.enemies[i].update(state, i) } for i := 0; i < len(state.bullets); i++ {