implementar padrões de tiro
This commit is contained in:
parent
fdacb47681
commit
1ddc892c70
1 changed files with 122 additions and 64 deletions
174
main.go
174
main.go
|
|
@ -2,25 +2,24 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "github.com/gen2brain/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type movementPattern int
|
type movementPattern func(*enemy)rl.Vector2
|
||||||
type shootingPattern int
|
type shootingPattern func(*enemy)
|
||||||
|
type bulletMovementPattern func(*bullet)rl.Vector2
|
||||||
|
|
||||||
const (
|
type hazard interface { // inimigos e projéteis
|
||||||
horizontal movementPattern = iota
|
Pos() rl.Vector2
|
||||||
circular movementPattern = iota
|
}
|
||||||
)
|
|
||||||
|
|
||||||
type game struct {
|
type game struct {
|
||||||
arenaWidth int32
|
arenaWidth int32
|
||||||
arenaHeight int32
|
arenaHeight int32
|
||||||
interfaceWidth int32
|
interfaceWidth int32
|
||||||
time int
|
frame int
|
||||||
enemies []*enemy
|
enemies []*enemy
|
||||||
bullets []*bullet
|
bullets []*bullet
|
||||||
score int
|
score int
|
||||||
|
|
@ -46,9 +45,10 @@ type player struct {
|
||||||
type enemy struct {
|
type enemy struct {
|
||||||
pos rl.Vector2
|
pos rl.Vector2
|
||||||
health int
|
health int
|
||||||
movePattern func(*enemy)rl.Vector2
|
move movementPattern
|
||||||
shootPattern func()
|
shoot shootingPattern
|
||||||
hitBoxRadius float32
|
hitBoxRadius float32
|
||||||
|
bulletMoveSpeed float32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g game) insideArena(v rl.Vector2) bool {
|
func (g game) insideArena(v rl.Vector2) bool {
|
||||||
|
|
@ -72,25 +72,66 @@ func (b *bullet) update(g *game, index int) {
|
||||||
rl.DrawCircleV(b.pos, b.size, rl.Yellow)
|
rl.DrawCircleV(b.pos, b.size, rl.Yellow)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *enemy) shoot(g *game) {
|
|
||||||
if g.time % 15 != 0 {
|
func burstShootAtPlayer(g *game, p *player) shootingPattern {
|
||||||
|
flag := true
|
||||||
|
return func(e *enemy) {
|
||||||
|
if g.frame % 100 == 0 {
|
||||||
|
flag = !flag
|
||||||
|
}
|
||||||
|
|
||||||
|
if !flag {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if g.frame % 2 == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
direction := rl.Vector2Subtract(p.pos, e.pos)
|
||||||
|
direction = rl.Vector2Normalize(direction)
|
||||||
|
direction = rl.Vector2Scale(direction, e.bulletMoveSpeed)
|
||||||
|
|
||||||
g.bullets = append(g.bullets, &bullet{
|
g.bullets = append(g.bullets, &bullet{
|
||||||
speed: rl.Vector2{X: 0, Y: 10},
|
speed: direction,
|
||||||
size: 4,
|
size: 12,
|
||||||
dmg: 1,
|
dmg: 1,
|
||||||
enemy: true,
|
enemy: true,
|
||||||
pos: e.pos,
|
pos: e.pos,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func horizonalPattern(g *game) (func(*enemy)rl.Vector2) {
|
func shootStraightDown(g *game) shootingPattern {
|
||||||
|
return func(e *enemy) {
|
||||||
|
if g.frame % 10 != 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.bullets = append(g.bullets, &bullet{
|
||||||
|
speed: rl.Vector2{X: 0, Y: 5},
|
||||||
|
size: 12,
|
||||||
|
dmg: 1,
|
||||||
|
enemy: true,
|
||||||
|
pos: e.pos,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func shootStill() movementPattern {
|
||||||
|
return func(e *enemy) rl.Vector2 {
|
||||||
|
e.shoot(e)
|
||||||
|
return e.pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func horizonalPattern(g *game) movementPattern {
|
||||||
direction := rl.Vector2{X: 4, Y: 0}
|
direction := rl.Vector2{X: 4, Y: 0}
|
||||||
|
|
||||||
return func(e *enemy) rl.Vector2 {
|
return func(e *enemy) rl.Vector2 {
|
||||||
result := rl.Vector2Add(direction, e.pos)
|
result := rl.Vector2Add(direction, e.pos)
|
||||||
|
|
||||||
|
e.shoot(e)
|
||||||
|
|
||||||
if !g.insideArena(result) {
|
if !g.insideArena(result) {
|
||||||
direction = rl.Vector2Negate(direction)
|
direction = rl.Vector2Negate(direction)
|
||||||
}
|
}
|
||||||
|
|
@ -98,31 +139,43 @@ func horizonalPattern(g *game) (func(*enemy)rl.Vector2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func circlePattern(g *game, center rl.Vector2) (func(*enemy)rl.Vector2) {
|
// func aimPlayerPattern(g *game, p *player) movementPattern {
|
||||||
|
// }
|
||||||
|
|
||||||
t := float64(0.5)
|
func foobarPattern(g *game) movementPattern {
|
||||||
|
|
||||||
|
pos := rl.Vector2{}
|
||||||
|
state := 0
|
||||||
|
wait := 0
|
||||||
|
|
||||||
return func(e *enemy) rl.Vector2 {
|
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(θ)
|
switch state {
|
||||||
// y' = x * sin(θ) + y * cos(θ)
|
case 0: // init
|
||||||
|
pos.X = e.pos.X
|
||||||
// result := center
|
state = 1
|
||||||
//
|
return pos
|
||||||
// result.X = result.X + (e.pos.X - result.X) * float32(math.Cos(t)) -
|
case 1: // descer
|
||||||
// (e.pos.Y - result.Y) * float32(math.Sin(t))
|
pos.Y += 1
|
||||||
//
|
if pos.Y >= 100 { state = 2; wait = 50 }
|
||||||
// result.Y = result.Y + (e.pos.Y - result.Y) * float32(math.Sin(t)) +
|
return pos
|
||||||
// (e.pos.Y - result.Y) * float32(math.Cos(t))
|
case 2: // atirar por um tempo
|
||||||
|
e.shoot(e)
|
||||||
result := center
|
wait -= 1
|
||||||
result.X = result.X * float32(math.Cos(t)) - result.Y * float32(math.Sin(t))
|
if wait <= 0 { state = 3; wait = 60 }
|
||||||
result.Y = result.X * float32(math.Sin(t)) - result.Y * float32(math.Cos(t))
|
return pos
|
||||||
|
case 3: // wait
|
||||||
t += .08
|
wait -= 1
|
||||||
return result
|
if wait <= 0 { state = 4 }
|
||||||
|
return pos
|
||||||
|
case 4: // retornar
|
||||||
|
pos.Y -= 3
|
||||||
|
if pos.Y - e.hitBoxRadius < 0 {
|
||||||
|
e.health = 0
|
||||||
|
}
|
||||||
|
return pos
|
||||||
|
}
|
||||||
|
panic(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,7 +187,6 @@ func (e *enemy) checkHit(g *game) (bool, *bullet, int) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
distance := rl.Vector2Distance(e.pos, bullet.pos) - bullet.size
|
distance := rl.Vector2Distance(e.pos, bullet.pos) - bullet.size
|
||||||
// fmt.Println(distance)
|
|
||||||
|
|
||||||
if distance < e.hitBoxRadius {
|
if distance < e.hitBoxRadius {
|
||||||
return true, bullet, index
|
return true, bullet, index
|
||||||
|
|
@ -153,8 +205,8 @@ func (e *enemy) update(g *game, index int) {
|
||||||
|
|
||||||
enemyColor := rl.Blue
|
enemyColor := rl.Blue
|
||||||
|
|
||||||
if e.movePattern != nil {
|
if e.move != nil {
|
||||||
e.pos = e.movePattern(e)
|
e.pos = e.move(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if hit, bullet, idx := e.checkHit(g); hit {
|
if hit, bullet, idx := e.checkHit(g); hit {
|
||||||
|
|
@ -169,8 +221,6 @@ func (e *enemy) update(g *game, index int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
e.shoot(g)
|
|
||||||
|
|
||||||
rl.DrawCircleV(e.pos, e.hitBoxRadius, enemyColor)
|
rl.DrawCircleV(e.pos, e.hitBoxRadius, enemyColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,12 +253,11 @@ func (p *player) move(g *game) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *player) shoot(g *game){
|
func (p *player) shoot(g *game){
|
||||||
if g.time % 5 != 0 {
|
if g.frame % 5 != 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if rl.IsMouseButtonDown(rl.MouseLeftButton) {
|
if rl.IsMouseButtonDown(rl.MouseLeftButton) {
|
||||||
// (mal) leva em consideração a velocidade do jogador
|
|
||||||
mouse := rl.GetMousePosition()
|
mouse := rl.GetMousePosition()
|
||||||
direction := rl.Vector2Subtract(mouse, p.pos)
|
direction := rl.Vector2Subtract(mouse, p.pos)
|
||||||
direction = rl.Vector2Add(direction, p.speed)
|
direction = rl.Vector2Add(direction, p.speed)
|
||||||
|
|
@ -281,31 +330,40 @@ func main() {
|
||||||
pos: rl.Vector2{X: 200, Y: 200},
|
pos: rl.Vector2{X: 200, Y: 200},
|
||||||
health: 10,
|
health: 10,
|
||||||
hitBoxRadius: 10,
|
hitBoxRadius: 10,
|
||||||
movePattern: horizonalPattern(state),
|
bulletMoveSpeed: 6,
|
||||||
},
|
move: horizonalPattern(state),
|
||||||
{
|
// shoot: shootStraightDown(state),
|
||||||
pos: rl.Vector2{X: 169, Y: 222},
|
shoot: burstShootAtPlayer(state, &player),
|
||||||
health: 10,
|
|
||||||
hitBoxRadius:10,
|
|
||||||
movePattern: horizonalPattern(state),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pos: rl.Vector2{X: 400, Y: 400},
|
|
||||||
health: 10,
|
|
||||||
hitBoxRadius:10,
|
|
||||||
// movePattern: circlePattern(state, rl.Vector2{X: 200, Y: 200}),
|
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// pos: rl.Vector2{X: 169, Y: 222},
|
||||||
|
// health: 10,
|
||||||
|
// hitBoxRadius:10,
|
||||||
|
// bulletMoveSpeed: 6,
|
||||||
|
// move: horizonalPattern(state),
|
||||||
|
// shoot: shootStraightDown(state),
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// pos: rl.Vector2{X: 400, Y: 400},
|
||||||
|
// health: 10,
|
||||||
|
// hitBoxRadius:10,
|
||||||
|
// bulletMoveSpeed: 6,
|
||||||
|
// move: foobarPattern(state),
|
||||||
|
// shoot: shootStraightDown(state),
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
pos: rl.Vector2{X: 200, Y: 200},
|
pos: rl.Vector2{X: 200, Y: 200},
|
||||||
health: 10,
|
health: 10,
|
||||||
hitBoxRadius:10,
|
hitBoxRadius:10,
|
||||||
// movePattern: circlePattern(state, rl.Vector2{X: 200, Y: 200}),
|
bulletMoveSpeed: 6,
|
||||||
|
move: shootStill(),
|
||||||
|
shoot: shootStraightDown(state),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
currectScore := 0
|
currectScore := 0
|
||||||
|
|
||||||
for ; !rl.WindowShouldClose(); state.time += 1 {
|
for ; !rl.WindowShouldClose(); state.frame += 1 {
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
rl.ClearBackground(rl.Black)
|
rl.ClearBackground(rl.Black)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue