bullet-hell/player.go
2025-08-23 19:55:34 -03:00

243 lines
4.8 KiB
Go

package main
import (
"fmt"
rl "github.com/gen2brain/raylib-go/raylib"
)
type player struct {
pos rl.Vector2
speed rl.Vector2
direction rl.Vector2
moveSpeed float32
bulletMoveSpeed float32
hitBoxRadius float32
shoot shootingPattern
bulletSize float32
focusMode bool
focusSpeedDecrease float32
}
func (p *player) Pos() rl.Vector2 {
return p.pos
}
func (p *player) SetPos(x rl.Vector2) {
p.pos = x
}
func (p *player) Direction() rl.Vector2 {
return p.direction
}
func (p *player) move(g *game) {
var moveSpeed float32
if p.focusMode {
moveSpeed = p.moveSpeed * p.focusSpeedDecrease
} else {
moveSpeed = p.moveSpeed
}
p.speed = rl.Vector2{X: 0, Y: 0}
if rl.IsKeyDown(rl.KeyW) {
p.speed.Y -= 1
}
if rl.IsKeyDown(rl.KeyS) {
p.speed.Y += 1
}
if rl.IsKeyDown(rl.KeyA) {
p.speed.X -= 1
}
if rl.IsKeyDown(rl.KeyD) {
p.speed.X += 1
}
if !(p.speed.X == 0 && p.speed.Y == 0) {
// jogador se move mais rapido na diagonal caso o contrario
p.speed = rl.Vector2Normalize(p.speed)
p.speed = rl.Vector2Scale(p.speed, moveSpeed)
}
result := rl.Vector2Add(p.pos, rl.Vector2Scale(p.speed, rl.GetFrameTime()))
if result.Y-p.hitBoxRadius < 0 || result.Y+p.hitBoxRadius > float32(g.arenaHeight) {
p.speed.Y = 0
}
if result.X-p.hitBoxRadius < 0 || result.X+p.hitBoxRadius > float32(g.arenaWidth) {
p.speed.X = 0
}
p.pos = rl.Vector2Add(p.pos, rl.Vector2Scale(p.speed, rl.GetFrameTime()))
}
// func (p *player) shoot(g *game) {
// if p.focusMode {
// return
// }
//
// if int(g.frame)%3 != 0 {
// return
// }
//
// if rl.IsMouseButtonDown(rl.MouseLeftButton) {
// mouse := rl.GetMousePosition()
// direction := rl.Vector2Subtract(mouse, p.pos)
// direction = rl.Vector2Add(direction, p.speed)
// direction = rl.Vector2Normalize(direction)
// direction = rl.Vector2Scale(direction, p.bulletMoveSpeed)
//
// g.bullets = append(g.bullets, &bullet{
// pos: p.pos,
// size: p.bulletSize,
// speed: direction,
// dmg: 1,
// enemy: false,
// })
// }
// }
func (p *player) checkHit(g *game) {
for _, bullet := range g.bullets {
_, playerBullet := bullet.owner.(*player)
if playerBullet {
continue
}
distance := rl.Vector2Distance(p.pos, bullet.pos) - bullet.size
if distance < p.hitBoxRadius {
// fmt.Println("hit!")
}
}
}
func (p *player) checkFocus() {
// raylib não entende keybindings customizadas através do xmodmap?
p.focusMode = rl.IsKeyDown(rl.KeyLeftShift) || rl.IsKeyDown(rl.KeyRightShift)
}
func (p *player) update(g *game) {
p.checkFocus()
p.move(g)
if !p.focusMode && p.shoot != nil {
p.shoot(p)
}
p.checkHit(g)
// hitbox
rl.DrawCircleV(p.pos, p.hitBoxRadius, rl.Red)
if p.focusMode {
return
}
// mira
mouse := rl.GetMousePosition()
inverted := rl.Vector2Subtract(p.pos, mouse)
inverted = rl.Vector2Negate(inverted)
inverted = rl.Vector2Normalize(inverted)
inverted = rl.Vector2Scale(inverted, 2000)
rl.DrawLineEx(p.pos, rl.Vector2Add(mouse, inverted), 3, rl.NewColor(255, 0, 0, 100))
}
func tripleFire(g *game) shootingPattern {
t := newTimer(second * 0.05)
return func(b body) {
if !t.isTimeout() {
t.tick(g)
return
}
t.reset()
if rl.IsMouseButtonDown(rl.MouseLeftButton) {
g.bullets = append(g.bullets, &bullet{
pos: b.Pos(),
size: 9,
speed: rl.Vector2Scale(
rl.Mat2MultiplyVector2(rl.Mat2Radians(0.3), b.Direction()),
600,
),
dmg: 1,
owner: b,
})
g.bullets = append(g.bullets, &bullet{
pos: b.Pos(),
size: 9,
speed: rl.Vector2Scale(
rl.Mat2MultiplyVector2(rl.Mat2Radians(0), b.Direction()),
600,
),
dmg: 1,
owner: b,
})
g.bullets = append(g.bullets, &bullet{
pos: b.Pos(),
size: 9,
speed: rl.Vector2Scale(
rl.Mat2MultiplyVector2(rl.Mat2Radians(-0.3), b.Direction()),
600,
),
dmg: 1,
owner: b,
})
}
// rl.matrix
}
}
func snipe(g *game) shootingPattern {
t := newTimer(1)
hits := 0
return func(b body) {
p, ok := b.(*player)
if !ok {
panic(b)
}
if !t.isTimeout() {
t.tick(g)
return
}
if !rl.IsMouseButtonPressed(rl.MouseLeftButton) {
return
}
t.reset()
mouse := rl.GetMousePosition()
direction := rl.Vector2Subtract(mouse, p.pos)
direction = rl.Vector2Add(direction, rl.Vector2Scale(p.speed, rl.GetFrameTime()*g.gameSpeed))
direction = rl.Vector2Normalize(direction)
direction = rl.Vector2Scale(direction, p.bulletMoveSpeed*700)
g.bullets = append(g.bullets, &bullet{
pos: b.Pos(),
size: p.bulletSize,
speed: direction,
dmg: 10 * hits,
owner: b,
onHit: func(b body) {
hits += 2
fmt.Println("hit!", hits)
},
onDestroy: func() {
hits--
hits = max(hits, 0)
fmt.Println("hit!", hits)
},
})
}
}