Ditch keyboard mover, shooter, interval shooter. All of that is game code not engine. Added key handler and scheduler. Can also now duplicate components on an element (key readers for example)

This commit is contained in:
stevenhowes
2022-01-04 22:00:31 +00:00
parent 45c553150c
commit bc5cd16447
7 changed files with 98 additions and 223 deletions
-4
View File
@@ -43,10 +43,6 @@ func (dr *damageReceiver) onUpdate() error {
lm := dr.container.getComponent(&moverLinear{}).(*moverLinear)
lm.speed = 0
}
if dr.container.checkComponentIsPresent(&moverKeyboard{}) {
km := dr.container.getComponent(&moverKeyboard{}).(*moverKeyboard)
km.speed = 0
}
}
// If we've finished our destroy animation then we're not active and can be removed
+44
View File
@@ -0,0 +1,44 @@
package GoRetro
/*
* --------------------
* KeyboardReader
* --------------------
* Checks for a keyboard event and fires the callback on the
* element it is attached to
*/
import (
"github.com/veandco/go-sdl2/sdl"
)
type inputKeyboard struct {
container *Element
key int
keyFunc func(element *Element, key int)
}
func NewInputKeyboard(container *Element, keyCode int, Keyhandle func(element *Element, key int)) *inputKeyboard {
return &inputKeyboard{
container: container,
key: keyCode,
keyFunc: Keyhandle,
}
}
func (input *inputKeyboard) onDraw() error {
return nil
}
func (input *inputKeyboard) onUpdate() error {
keys := sdl.GetKeyboardState()
if keys[input.key] == 1 {
input.keyFunc(input.container, input.key)
}
return nil
}
func (input *inputKeyboard) onCollision(other *Element) error {
return nil
}
-90
View File
@@ -1,90 +0,0 @@
package GoRetro
/*
* --------------------
* moverKeyboard
* --------------------
* A simple mover that moves the container a fixed
* distance each tick when arrow keys are used
*
* NOTE: Container must have a spriteRenderer to
* read dimesions from!
*/
import (
"github.com/veandco/go-sdl2/sdl"
)
type moverKeyboard struct {
container *Element
speed float64
}
func NewMoverKeyboard(container *Element, speed float64) *moverKeyboard {
return &moverKeyboard{
container: container,
speed: speed,
}
}
func (mover *moverKeyboard) onDraw() error {
return nil
}
func (mover *moverKeyboard) onUpdate() error {
keys := sdl.GetKeyboardState()
// For now, spoof a 1 radius circle above, below, left and right of the player
// to keep them within the screen. bounder_screen would make the player cease
// to exist if we did that
cLeft := Circle{
Radius: 1,
Center: Vector{X: 0, Y: mover.container.Position.Y},
}
cRight := Circle{
Radius: 1,
Center: Vector{X: float64(Config.ScreenWidth), Y: mover.container.Position.Y},
}
cTop := Circle{
Radius: 1,
Center: Vector{X: mover.container.Position.X, Y: 0},
}
cBottom := Circle{
Radius: 1,
Center: Vector{X: mover.container.Position.X, Y: float64(Config.ScreenHeight)},
}
// Handle direction keys and check of we collide.
if keys[sdl.SCANCODE_LEFT] == 1 {
for _, c2 := range mover.container.Collisions {
if !collides(cLeft, circleOffset(c2, mover.container.Position)) {
mover.container.Position.X -= mover.speed * Delta
}
}
} else if keys[sdl.SCANCODE_RIGHT] == 1 {
for _, c2 := range mover.container.Collisions {
if !collides(cRight, circleOffset(c2, mover.container.Position)) {
mover.container.Position.X += mover.speed * Delta
}
}
}
if keys[sdl.SCANCODE_UP] == 1 {
for _, c2 := range mover.container.Collisions {
if !collides(cTop, circleOffset(c2, mover.container.Position)) {
mover.container.Position.Y -= mover.speed * Delta
}
}
} else if keys[sdl.SCANCODE_DOWN] == 1 {
for _, c2 := range mover.container.Collisions {
if !collides(cBottom, circleOffset(c2, mover.container.Position)) {
mover.container.Position.Y += mover.speed * Delta
}
}
}
return nil
}
func (mover *moverKeyboard) onCollision(other *Element) error {
return nil
}
+49
View File
@@ -0,0 +1,49 @@
package GoRetro
/*
* --------------------
* schedulerInterval
* --------------------
* Calls a callback at fixed intervals
*/
import (
"time"
)
type schedulerInterval struct {
container *Element
interval time.Duration // Time between triggers
lastTrigger time.Time // Last trigger
scheduleFunc func(element *Element)
}
func NewSchedulerInterval(container *Element, interval time.Duration, lastTrigger time.Time, Callback func(element *Element)) *schedulerInterval {
return &schedulerInterval{
container: container,
interval: interval,
lastTrigger: lastTrigger,
scheduleFunc: Callback,
}
}
func (scheduler *schedulerInterval) onDraw() error {
return nil
}
func (scheduler *schedulerInterval) onUpdate() error {
//pos := shooter.container.Position
if time.Since(scheduler.lastTrigger) >= scheduler.interval {
scheduler.scheduleFunc(scheduler.container)
scheduler.lastTrigger = time.Now()
}
return nil
}
func (scheduler *schedulerInterval) onCollision(other *Element) error {
return nil
}
-64
View File
@@ -1,64 +0,0 @@
package GoRetro
/*
* --------------------
* intervalShooter
* --------------------
* Fire projectiles at fixed intervals
*/
import (
"time"
"github.com/veandco/go-sdl2/sdl"
)
type intervalShooter struct {
container *Element
cooldown time.Duration // Time between shots
lastShot time.Time // Last shot
shootFunc func(renderer *sdl.Renderer, collisionLayer int) *Element
}
func NewIntervalShooter(container *Element, cooldown time.Duration, lastShot time.Time, NewBullet func(renderer *sdl.Renderer, collisionLayer int) *Element) *intervalShooter {
return &intervalShooter{
container: container,
cooldown: cooldown,
lastShot: lastShot,
shootFunc: NewBullet}
}
func (shooter *intervalShooter) onDraw() error {
return nil
}
func (shooter *intervalShooter) onUpdate() error {
//pos := shooter.container.Position
if time.Since(shooter.lastShot) >= shooter.cooldown {
// TODO: These positions should not be hard coded. Store as offset from
// container (i.e. gun positions)
shooter.shoot(shooter.container.Position.X+15, shooter.container.Position.Y-10, shooter.container.Rotation, shooter.container)
shooter.shoot(shooter.container.Position.X-15, shooter.container.Position.Y-10, shooter.container.Rotation, shooter.container)
shooter.lastShot = time.Now()
}
return nil
}
func (shooter *intervalShooter) shoot(x, y, rotation float64, parent *Element) {
bul := shooter.shootFunc(parent.Renderer, parent.CollisionLayer+1)
bul.Active = true
bul.Position.X = x
bul.Position.Y = y
bul.Rotation = rotation
bul.parentElement = parent
}
func (shooter *intervalShooter) onCollision(other *Element) error {
return nil
}
-64
View File
@@ -1,64 +0,0 @@
package GoRetro
/*
* --------------------
* keyboardShooter
* --------------------
* Fire projectiles on keypress, rate limited
*/
import (
"time"
"github.com/veandco/go-sdl2/sdl"
)
type keyboardShooter struct {
container *Element
cooldown time.Duration // Time between shots
lastShot time.Time // Last shot
shootFunc func(renderer *sdl.Renderer, collisionLayer int) *Element
}
func NewKeyboardShooter(container *Element, cooldown time.Duration, NewBullet func(renderer *sdl.Renderer, collisionLayer int) *Element) *keyboardShooter {
return &keyboardShooter{
container: container,
cooldown: cooldown,
shootFunc: NewBullet}
}
func (shooter *keyboardShooter) onDraw() error {
return nil
}
func (shooter *keyboardShooter) onUpdate() error {
keys := sdl.GetKeyboardState()
//pos := shooter.container.Position
if keys[sdl.SCANCODE_SPACE] == 1 {
if time.Since(shooter.lastShot) >= shooter.cooldown {
// TODO: These positions should not be hard coded. Store as offset from
// container (i.e. gun positions)
shooter.shoot(shooter.container.Position.X+15, shooter.container.Position.Y-10, shooter.container.Rotation, shooter.container)
shooter.shoot(shooter.container.Position.X-15, shooter.container.Position.Y-10, shooter.container.Rotation, shooter.container)
shooter.lastShot = time.Now()
}
}
return nil
}
func (shooter *keyboardShooter) shoot(x, y, rotation float64, parent *Element) {
bul := shooter.shootFunc(parent.Renderer, parent.CollisionLayer+1)
bul.Active = true
bul.Position.X = x
bul.Position.Y = y
bul.Rotation = rotation
bul.parentElement = parent
}
func (shooter *keyboardShooter) onCollision(other *Element) error {
return nil
}
+5 -1
View File
@@ -61,7 +61,7 @@ func (elem *Element) collision(other *Element) error {
return nil
}
func (elem *Element) AddComponent(new component) {
func (elem *Element) AddComponentUnique(new component) {
for _, existing := range elem.components {
if reflect.TypeOf(new) == reflect.TypeOf(existing) {
panic(fmt.Sprintf(
@@ -69,6 +69,10 @@ func (elem *Element) AddComponent(new component) {
reflect.TypeOf(new)))
}
}
elem.AddComponent(new)
}
func (elem *Element) AddComponent(new component) {
elem.components = append(elem.components, new)
}