timer
This commit is contained in:
parent
df56b0237e
commit
9a0383488d
1 changed files with 525 additions and 400 deletions
247
main.go
247
main.go
|
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
// "path"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "github.com/gen2brain/raylib-go/raylib"
|
||||||
|
|
@ -11,8 +10,10 @@ import (
|
||||||
|
|
||||||
// diz para um inimigo como ele deve se mover
|
// diz para um inimigo como ele deve se mover
|
||||||
type movementPattern func(*enemy) rl.Vector2
|
type movementPattern func(*enemy) rl.Vector2
|
||||||
|
|
||||||
// diz para um inimigo em que condições atirar. acionado pelo movementPattern
|
// diz para um inimigo em que condições atirar. acionado pelo movementPattern
|
||||||
type shootingPattern func(*enemy)
|
type shootingPattern func(*enemy)
|
||||||
|
|
||||||
// diz para uma bala como ela deve se mover.
|
// diz para uma bala como ela deve se mover.
|
||||||
type bulletMovementPattern func(*bullet) rl.Vector2
|
type bulletMovementPattern func(*bullet) rl.Vector2
|
||||||
|
|
||||||
|
|
@ -26,6 +27,8 @@ type game struct {
|
||||||
interfaceWidth int32
|
interfaceWidth int32
|
||||||
frame float32
|
frame float32
|
||||||
enemies []*enemy
|
enemies []*enemy
|
||||||
|
waves []*wave
|
||||||
|
currentWave int
|
||||||
bullets []*bullet
|
bullets []*bullet
|
||||||
score int
|
score int
|
||||||
gameSpeed float32 // 1 = velocidade normal
|
gameSpeed float32 // 1 = velocidade normal
|
||||||
|
|
@ -59,6 +62,11 @@ type enemy struct {
|
||||||
hitBoxRadius float32
|
hitBoxRadius float32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type wave struct {
|
||||||
|
enemies []*enemy
|
||||||
|
entrance movementPattern
|
||||||
|
}
|
||||||
|
|
||||||
func (g game) insideArena(v rl.Vector2) bool {
|
func (g game) insideArena(v rl.Vector2) bool {
|
||||||
return v.X >= 0 && v.Y >= 0 &&
|
return v.X >= 0 && v.Y >= 0 &&
|
||||||
v.Y <= float32(g.arenaHeight) && v.X <= float32(g.arenaWidth)
|
v.Y <= float32(g.arenaHeight) && v.X <= float32(g.arenaWidth)
|
||||||
|
|
@ -81,12 +89,14 @@ func (b *bullet) update(g *game, index int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func bulletExplosion(g *game, rate, amount int, bulletSpeed, size float32) shootingPattern {
|
func bulletExplosion(g *game, rate, amount int, bulletSpeed, size float32) shootingPattern {
|
||||||
|
t := newTimer(second)
|
||||||
return func(e *enemy) {
|
return func(e *enemy) {
|
||||||
if int(g.frame) % rate != 0 {
|
|
||||||
|
t.tick(g)
|
||||||
|
if !t.isTimeout() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
t.reset()
|
||||||
// radius := e.hitBoxRadius
|
|
||||||
|
|
||||||
var bullets []*bullet
|
var bullets []*bullet
|
||||||
|
|
||||||
|
|
@ -130,21 +140,62 @@ bulletMoveSpeed float32) shootingPattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func burstShootAtPlayer(g *game, p *player,
|
type timer struct {
|
||||||
rate int, bulletMoveSpeed float32) shootingPattern {
|
time, ttl float32
|
||||||
|
start float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *timer) tick(g *game) {
|
||||||
|
t.time += rl.GetFrameTime() * g.gameSpeed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *timer) isTimeout() bool {
|
||||||
|
return t.time >= t.ttl
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *timer) reset() {
|
||||||
|
t.start = float64(t.time)
|
||||||
|
t.time = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTimer(duration float32) *timer {
|
||||||
|
return &timer {
|
||||||
|
time: 0,
|
||||||
|
ttl: duration,
|
||||||
|
start: rl.GetTime(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var second float32 = 1
|
||||||
|
|
||||||
|
func burstShootAtPlayer(g *game, p *player, rate float32, bulletMoveSpeed float32) shootingPattern {
|
||||||
flag := true
|
flag := true
|
||||||
|
off := newTimer(second)
|
||||||
|
on := newTimer(second*rate)
|
||||||
return func(e *enemy) {
|
return func(e *enemy) {
|
||||||
if int(g.frame) % 100 == 0 {
|
|
||||||
|
fmt.Printf("\r %f %f", rl.GetTime(), rl.GetFrameTime())
|
||||||
|
|
||||||
|
off.tick(g)
|
||||||
|
|
||||||
|
if off.isTimeout() {
|
||||||
flag = !flag
|
flag = !flag
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(off)
|
||||||
|
off.reset()
|
||||||
|
fmt.Println(off)
|
||||||
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !flag {
|
if !flag {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(g.frame) % rate != 0 {
|
on.tick(g)
|
||||||
|
if !on.isTimeout() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
on.reset()
|
||||||
|
|
||||||
direction := rl.Vector2Subtract(p.pos, e.pos)
|
direction := rl.Vector2Subtract(p.pos, e.pos)
|
||||||
direction = rl.Vector2Normalize(direction)
|
direction = rl.Vector2Normalize(direction)
|
||||||
|
|
@ -196,42 +247,65 @@ func horizonalPattern(g *game) movementPattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func foobarPattern(g *game) movementPattern {
|
func sineHorizonalPattern(g *game) movementPattern {
|
||||||
//
|
direction := rl.Vector2{X: 4, Y: 0}
|
||||||
// pos := rl.Vector2{}
|
|
||||||
// state := 0
|
return func(e *enemy) rl.Vector2 {
|
||||||
// wait := 0
|
if e.shoot != nil {
|
||||||
//
|
e.shoot(e)
|
||||||
// return func(e *enemy) rl.Vector2 {
|
}
|
||||||
//
|
|
||||||
// switch state {
|
|
||||||
// case 0: // init
|
result := rl.Vector2Add(direction, e.pos)
|
||||||
// pos.X = e.pos.X
|
if !g.insideArena(result) {
|
||||||
// state = 1
|
direction = rl.Vector2Negate(direction)
|
||||||
// return pos
|
}
|
||||||
// case 1: // descer
|
|
||||||
// pos.Y += 1
|
sine := rl.Vector2{
|
||||||
// if pos.Y >= 100 { state = 2; wait = 50 }
|
X: 0,
|
||||||
// return pos
|
Y: float32(math.Sin(float64(g.frame*0.04))*2),
|
||||||
// case 2: // atirar por um tempo
|
}
|
||||||
// e.shoot(e)
|
|
||||||
// wait -= 1
|
return rl.Vector2Add(sine, direction)
|
||||||
// if wait <= 0 { state = 3; wait = 60 }
|
}
|
||||||
// return pos
|
}
|
||||||
// case 3: // wait
|
|
||||||
// wait -= 1
|
func foobarPattern(g *game) movementPattern {
|
||||||
// if wait <= 0 { state = 4 }
|
|
||||||
// return pos
|
pos := rl.Vector2{}
|
||||||
// case 4: // retornar
|
state := 0
|
||||||
// pos.Y -= 3
|
wait := 0
|
||||||
// if pos.Y - e.hitBoxRadius < 0 {
|
|
||||||
// e.health = 0
|
return func(e *enemy) rl.Vector2 {
|
||||||
// }
|
|
||||||
// return pos
|
switch state {
|
||||||
// }
|
case 0: // init
|
||||||
// panic(state)
|
pos.X = e.pos.X
|
||||||
// }
|
state = 1
|
||||||
// }
|
return pos
|
||||||
|
case 1: // descer
|
||||||
|
pos.Y += 1
|
||||||
|
if pos.Y >= 100 { state = 2; wait = 50 }
|
||||||
|
return pos
|
||||||
|
case 2: // atirar por um tempo
|
||||||
|
e.shoot(e)
|
||||||
|
wait -= 1
|
||||||
|
if wait <= 0 { state = 3; wait = 60 }
|
||||||
|
return pos
|
||||||
|
case 3: // wait
|
||||||
|
wait -= 1
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *enemy) checkHit(g *game) (bool, *bullet, int) {
|
func (e *enemy) checkHit(g *game) (bool, *bullet, int) {
|
||||||
for index, bullet := range g.bullets {
|
for index, bullet := range g.bullets {
|
||||||
|
|
@ -254,8 +328,11 @@ func (g *game) killEnemy(index int) {
|
||||||
g.enemies = g.enemies[:len(g.enemies)-1]
|
g.enemies = g.enemies[:len(g.enemies)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *enemy) update(g *game) {
|
||||||
|
|
||||||
func (e *enemy) update(g *game, index int) {
|
if e.health <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
enemyColor := rl.Blue
|
enemyColor := rl.Blue
|
||||||
|
|
||||||
|
|
@ -272,10 +349,6 @@ func (e *enemy) update(g *game, index int) {
|
||||||
g.backgroundColor = rl.NewColor(20, 20, 20, 255)
|
g.backgroundColor = rl.NewColor(20, 20, 20, 255)
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.health <= 0 {
|
|
||||||
g.killEnemy(index)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
rl.DrawCircleV(e.pos, e.hitBoxRadius, enemyColor)
|
rl.DrawCircleV(e.pos, e.hitBoxRadius, enemyColor)
|
||||||
}
|
}
|
||||||
|
|
@ -291,10 +364,18 @@ func (p *player) move(g *game) {
|
||||||
|
|
||||||
p.speed = rl.Vector2{X: 0, Y: 0}
|
p.speed = rl.Vector2{X: 0, Y: 0}
|
||||||
|
|
||||||
if rl.IsKeyDown(rl.KeyW) { p.speed.Y -= 1 }
|
if rl.IsKeyDown(rl.KeyW) {
|
||||||
if rl.IsKeyDown(rl.KeyS) { p.speed.Y += 1 }
|
p.speed.Y -= 1
|
||||||
if rl.IsKeyDown(rl.KeyA) { p.speed.X -= 1 }
|
}
|
||||||
if rl.IsKeyDown(rl.KeyD) { p.speed.X += 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) {
|
if !(p.speed.X == 0 && p.speed.Y == 0) {
|
||||||
// jogador se move mais rapido na diagonal caso o contrario
|
// jogador se move mais rapido na diagonal caso o contrario
|
||||||
|
|
@ -391,6 +472,15 @@ func (p *player) update(g *game) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *game) fullClear() bool {
|
||||||
|
for _, e := range g.waves[g.currentWave].enemies {
|
||||||
|
if e.health != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
state := &game{
|
state := &game{
|
||||||
|
|
@ -416,8 +506,8 @@ func main() {
|
||||||
|
|
||||||
rl.SetConfigFlags(rl.FlagMsaa4xHint)
|
rl.SetConfigFlags(rl.FlagMsaa4xHint)
|
||||||
rl.InitWindow(state.arenaWidth+state.interfaceWidth, state.arenaHeight, "danmaku")
|
rl.InitWindow(state.arenaWidth+state.interfaceWidth, state.arenaHeight, "danmaku")
|
||||||
rl.SetTargetFPS(60)
|
targetFPS := 120
|
||||||
|
rl.SetTargetFPS(int32(targetFPS))
|
||||||
|
|
||||||
// shader_path := path.Join("shaders", "trails.glsl")
|
// shader_path := path.Join("shaders", "trails.glsl")
|
||||||
// shader := rl.LoadShader("", shader_path)
|
// shader := rl.LoadShader("", shader_path)
|
||||||
|
|
@ -427,27 +517,54 @@ func main() {
|
||||||
// state.arenaHeight,
|
// state.arenaHeight,
|
||||||
// )
|
// )
|
||||||
|
|
||||||
state.enemies = []*enemy{
|
state.waves = []*wave{
|
||||||
|
{
|
||||||
|
enemies: []*enemy{
|
||||||
|
{
|
||||||
|
pos: rl.Vector2{X: 100, Y: 100},
|
||||||
|
health: 100,
|
||||||
|
hitBoxRadius: 20,
|
||||||
|
move: sineHorizonalPattern(state),
|
||||||
|
shoot: burstShootAtPlayer(state, &player, 0.1, 4),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enemies: []*enemy{
|
||||||
|
{
|
||||||
|
pos: rl.Vector2{X: 100, Y: 100},
|
||||||
|
health: 100,
|
||||||
|
hitBoxRadius: 20,
|
||||||
|
move: horizonalPattern(state),
|
||||||
|
shoot: bulletExplosion(state, targetFPS, 20, 2, 11),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enemies: []*enemy{
|
||||||
{
|
{
|
||||||
pos: rl.Vector2{X: 200, Y: 200},
|
pos: rl.Vector2{X: 200, Y: 200},
|
||||||
health: 100,
|
health: 100,
|
||||||
hitBoxRadius: 20,
|
hitBoxRadius: 20,
|
||||||
move: horizonalPattern(state),
|
move: horizonalPattern(state),
|
||||||
shoot: bulletExplosion(state, 60, 20, 2, 11),
|
shoot: bulletExplosion(state, targetFPS, 20, 2, 11),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pos: rl.Vector2{X: 100, Y: 100},
|
pos: rl.Vector2{X: 100, Y: 100},
|
||||||
health: 100,
|
health: 100,
|
||||||
hitBoxRadius: 20,
|
hitBoxRadius: 20,
|
||||||
move: horizonalPattern(state),
|
move: horizonalPattern(state),
|
||||||
shoot: burstShootAtPlayer(state, &player, 20, 4),
|
shoot: burstShootAtPlayer(state, &player, 0.2, 4),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pos: rl.Vector2{X: 50, Y: 250},
|
pos: rl.Vector2{X: 50, Y: 250},
|
||||||
health: 100,
|
health: 100,
|
||||||
hitBoxRadius: 20,
|
hitBoxRadius: 20,
|
||||||
move: horizonalPattern(state),
|
move: horizonalPattern(state),
|
||||||
shoot: bulletExplosion(state, 60, 20, 2, 11),
|
shoot: bulletExplosion(state, targetFPS, 20, 2, 11),
|
||||||
|
// shoot: shootStraightDown(state),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -462,8 +579,16 @@ func main() {
|
||||||
|
|
||||||
player.update(state)
|
player.update(state)
|
||||||
|
|
||||||
|
if state.fullClear() {
|
||||||
|
state.currentWave++
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.currentWave >= len(state.waves) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
state.enemies = state.waves[state.currentWave].enemies
|
||||||
for i := 0; i < len(state.enemies); i++ {
|
for i := 0; i < len(state.enemies); i++ {
|
||||||
state.enemies[i].update(state, i)
|
state.enemies[i].update(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(state.bullets); i++ {
|
for i := 0; i < len(state.bullets); i++ {
|
||||||
|
|
@ -481,6 +606,7 @@ func main() {
|
||||||
state.gameSpeed = 1
|
state.gameSpeed = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// rl.EndTextureMode()
|
// rl.EndTextureMode()
|
||||||
|
|
||||||
// { // shaders
|
// { // shaders
|
||||||
|
|
@ -526,7 +652,6 @@ func main() {
|
||||||
rl.DrawFPS(0, 0)
|
rl.DrawFPS(0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rl.EndDrawing()
|
rl.EndDrawing()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue