Added weapon system. Animated laser.

This commit is contained in:
2024-11-21 16:26:25 -05:00
parent 75d464b5e2
commit 257318926d
12 changed files with 210 additions and 50 deletions

View File

@@ -28,6 +28,7 @@ const (
Cloud ImgAssetName = "Cloud" Cloud ImgAssetName = "Cloud"
Fireball ImgAssetName = "Fireball" Fireball ImgAssetName = "Fireball"
Splash ImgAssetName = "Splash" Splash ImgAssetName = "Splash"
LaserBeam ImgAssetName = "LaserBeam"
) )
var ( var (
@@ -63,6 +64,8 @@ var (
fireball_img []byte fireball_img []byte
//go:embed splash.png //go:embed splash.png
splash_img []byte splash_img []byte
//go:embed laserbeam.png
laserbeam_img []byte
) )
func LoadImages() { func LoadImages() {
@@ -83,6 +86,7 @@ func LoadImages() {
ImageBank[Cloud] = LoadImagesFatal(cloud_img) ImageBank[Cloud] = LoadImagesFatal(cloud_img)
ImageBank[Fireball] = LoadImagesFatal(fireball_img) ImageBank[Fireball] = LoadImagesFatal(fireball_img)
ImageBank[Splash] = LoadImagesFatal(splash_img) ImageBank[Splash] = LoadImagesFatal(splash_img)
ImageBank[LaserBeam] = LoadImagesFatal(laserbeam_img)
} }

BIN
assets/laserbeam.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 470 B

After

Width:  |  Height:  |  Size: 615 B

View File

@@ -1,7 +1,8 @@
package elements package elements
import ( import (
"image/color" "image"
"mover/assets"
"mover/gamedata" "mover/gamedata"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
@@ -13,6 +14,7 @@ type Laser struct {
angle float64 angle float64
cycle int cycle int
firing bool firing bool
numcycles int
} }
func NewLaser(pos gamedata.Coordinates, angle float64) *Laser { func NewLaser(pos gamedata.Coordinates, angle float64) *Laser {
@@ -22,6 +24,7 @@ func NewLaser(pos gamedata.Coordinates, angle float64) *Laser {
cycle: 0, cycle: 0,
position: pos, position: pos,
firing: false, firing: false,
numcycles: 5,
} }
return l return l
} }
@@ -33,7 +36,16 @@ func (l *Laser) Update() error {
func (l *Laser) Draw() { func (l *Laser) Draw() {
l.Sprite.Clear() l.Sprite.Clear()
l.Sprite.Fill(color.White) //l.Sprite.Fill(color.White)
idx := (l.cycle / 4) % l.numcycles
x0 := 0
y0 := 20 * idx
x1 := 200
y1 := y0 + 20
l.Sprite.DrawImage(assets.ImageBank[assets.LaserBeam].SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil)
} }
func (l *Laser) GetPosition() gamedata.Coordinates { func (l *Laser) GetPosition() gamedata.Coordinates {

View File

@@ -9,4 +9,5 @@ type GameInputs struct {
Charge bool Charge bool
Quit bool Quit bool
Reset bool Reset bool
CycleWeapon bool
} }

9
gamedata/weapontype.go Normal file
View File

@@ -0,0 +1,9 @@
package gamedata
type WeaponType int
const (
WeaponTypeGun = iota
WeaponTypeLaser
WeaponTypeMax
)

View File

@@ -10,6 +10,7 @@ import (
"mover/elements" "mover/elements"
"mover/fonts" "mover/fonts"
"mover/gamedata" "mover/gamedata"
"mover/weapons"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/text" "github.com/hajimehoshi/ebiten/v2/text"
@@ -43,6 +44,7 @@ type Canvas struct {
gameover bool gameover bool
lasercoords []gamedata.Coordinates lasercoords []gamedata.Coordinates
holster *weapons.Holster
} }
func NewCanvas(a gamedata.Area) *Canvas { func NewCanvas(a gamedata.Area) *Canvas {
@@ -63,6 +65,7 @@ func NewCanvas(a gamedata.Area) *Canvas {
score: 0, score: 0,
runtime: 0., runtime: 0.,
counter: 0, counter: 0,
holster: weapons.NewHolster(),
} }
c.laserMask.Clear() c.laserMask.Clear()
c.eventmap = make(map[gamedata.GameEvent]func()) c.eventmap = make(map[gamedata.GameEvent]func())
@@ -79,8 +82,8 @@ func (c *Canvas) Update() error {
c.Initialize() c.Initialize()
} else { } else {
c.UpdateHero() c.UpdateHero()
c.UpdateWeapons()
c.UpdateProjectiles() c.UpdateProjectiles()
c.UpdateLaser()
c.UpdateCharge() c.UpdateCharge()
c.UpdateEnemies() c.UpdateEnemies()
c.SpawnEnemies() c.SpawnEnemies()
@@ -227,7 +230,6 @@ func (c *Canvas) UpdateHero() {
if !c.gameover { if !c.gameover {
c.UpdateHeroPosition() c.UpdateHeroPosition()
c.ComputeHeroCollisions() c.ComputeHeroCollisions()
c.AddProjectiles()
} }
} }
@@ -275,7 +277,7 @@ func (c *Canvas) ComputeHeroCollisions() {
func (c *Canvas) AddProjectiles() { func (c *Canvas) AddProjectiles() {
//add new projectiles //add new projectiles
/*
if c.lastInputs.Shot && c.counter%14 == 0 { if c.lastInputs.Shot && c.counter%14 == 0 {
loc := gamedata.Coordinates{ loc := gamedata.Coordinates{
@@ -296,11 +298,6 @@ func (c *Canvas) AddProjectiles() {
} }
} }
*/
if c.lastInputs.Shot {
c.laser.SetPosition(c.hero.Pos)
c.laser.SetAngle(c.lastInputs.ShotAngle)
}
} }
@@ -362,7 +359,11 @@ func (c *Canvas) UpdateProjectiles() {
} }
func (c *Canvas) UpdateLaser() { func (c *Canvas) UpdateLaser() {
c.laser.Update()
if c.lastInputs.Shot {
c.laser.SetPosition(c.hero.Pos)
c.laser.SetAngle(c.lastInputs.ShotAngle)
}
c.laser.SetFiring(c.lastInputs.Shot) c.laser.SetFiring(c.lastInputs.Shot)
if c.lastInputs.Shot { if c.lastInputs.Shot {
c.laserMask.Clear() c.laserMask.Clear()
@@ -826,11 +827,11 @@ func (c *Canvas) LaserAttempt4() {
if math.Abs(math.Mod(a, math.Pi)) == math.Pi/2 { // Check for vertical beam if math.Abs(math.Mod(a, math.Pi)) == math.Pi/2 { // Check for vertical beam
d = math.Abs(x1 - x0) d = math.Abs(x1 - x0)
c.lasercoords[3] = gamedata.Coordinates{X: x0, Y: y1} // Align on x-axis c.lasercoords[3] = gamedata.Coordinates{X: x0, Y: y1} // Align on x-axis
fmt.Printf("vertical beam\n") //fmt.Printf("vertical beam\n")
} else if math.Tan(a) == 0 { // Check for horizontal beam } else if math.Tan(a) == 0 { // Check for horizontal beam
d = math.Abs(y1 - y0) d = math.Abs(y1 - y0)
c.lasercoords[3] = gamedata.Coordinates{X: x1, Y: y0} // Align on y-axis c.lasercoords[3] = gamedata.Coordinates{X: x1, Y: y0} // Align on y-axis
fmt.Printf("horizontal beam\n") //fmt.Printf("horizontal beam\n")
} else { // General case } else { // General case
m0 := math.Tan(a) m0 := math.Tan(a)
m1 := -1 / m0 m1 := -1 / m0
@@ -838,9 +839,9 @@ func (c *Canvas) LaserAttempt4() {
yi := xi*m0 - x0*m0 + y0 yi := xi*m0 - x0*m0 + y0
c.lasercoords[3] = gamedata.Coordinates{X: xi, Y: yi} c.lasercoords[3] = gamedata.Coordinates{X: xi, Y: yi}
d = math.Sqrt(math.Pow(x1-xi, 2) + math.Pow(y1-yi, 2)) d = math.Sqrt(math.Pow(x1-xi, 2) + math.Pow(y1-yi, 2))
fmt.Printf("%f \n", d) //fmt.Printf("%f \n", d)
} }
fmt.Printf("%f \n", a) //fmt.Printf("%f \n", a)
if d <= 50 && e.GetEnemyState() <= gamedata.EnemyStateHit { if d <= 50 && e.GetEnemyState() <= gamedata.EnemyStateHit {
@@ -857,7 +858,7 @@ func (c *Canvas) LaserAttempt4() {
if c.eventmap[gamedata.GameEventTargetHit] != nil { if c.eventmap[gamedata.GameEventTargetHit] != nil {
c.eventmap[gamedata.GameEventTargetHit]() c.eventmap[gamedata.GameEventTargetHit]()
} }
fmt.Println("laser'd") //fmt.Println("laser'd")
} }
} }
} }
@@ -884,3 +885,23 @@ func (c *Canvas) CleanSplashes() {
c.splashes = c.splashes[:i] c.splashes = c.splashes[:i]
} }
func (c *Canvas) UpdateWeapons() {
if !c.gameover {
//check for weapon inputs
if c.lastInputs.CycleWeapon {
c.holster.CycleWeapon()
}
//now let's update some shit based on the weapon
switch c.holster.GetActiveWeapon().GetWeaponType() {
case gamedata.WeaponTypeGun:
c.AddProjectiles()
case gamedata.WeaponTypeLaser:
c.UpdateLaser()
}
} else {
c.laser.SetFiring(false)
}
}

View File

@@ -155,6 +155,7 @@ func (p *Primary) CollectInputs() gamedata.GameInputs {
gi.ShotAngle = math.Atan2(yaxis, xaxis) gi.ShotAngle = math.Atan2(yaxis, xaxis)
gi.CycleWeapon = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonFrontTopRight)
gi.Charge = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonRightStick) gi.Charge = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonRightStick)
gi.Start = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonCenterRight) gi.Start = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonCenterRight)
gi.Shot = ebiten.IsStandardGamepadButtonPressed(0, ebiten.StandardGamepadButtonFrontBottomRight) gi.Shot = ebiten.IsStandardGamepadButtonPressed(0, ebiten.StandardGamepadButtonFrontBottomRight)

26
weapons/gun.go Normal file
View File

@@ -0,0 +1,26 @@
package weapons
import "mover/gamedata"
type Gun struct {
active bool
}
func NewGun() *Gun {
g := &Gun{
active: false,
}
return g
}
func (g *Gun) IsActive() bool {
return g.active
}
func (g *Gun) SetActivity(active bool) {
g.active = active
}
func (g *Gun) GetWeaponType() gamedata.WeaponType {
return gamedata.WeaponTypeGun
}

51
weapons/holster.go Normal file
View File

@@ -0,0 +1,51 @@
package weapons
import "mover/gamedata"
type Holster struct {
activewp gamedata.WeaponType
guns map[gamedata.WeaponType]Weapon
}
func NewHolster() *Holster {
holster := &Holster{
guns: make(map[gamedata.WeaponType]Weapon),
activewp: gamedata.WeaponTypeGun,
}
holster.AddWeapon(NewGun())
holster.AddWeapon(NewLaser())
return holster
}
func (h *Holster) GetActiveWeapon() Weapon {
return h.guns[h.activewp]
}
func (h *Holster) GetActiveWeaponType() gamedata.WeaponType {
return h.guns[h.activewp].GetWeaponType()
}
func (h *Holster) AddWeapon(w Weapon) {
_, ok := h.guns[w.GetWeaponType()]
if !ok {
h.guns[w.GetWeaponType()] = w
}
}
func (h *Holster) CycleWeapon() {
//no weapons, nothing to do
if len(h.guns) == 0 {
return
}
//keep searching until we find the next weapon that exists
for ok := false; !ok; {
nextwp := (h.activewp + 1) % gamedata.WeaponTypeMax
_, ok = h.guns[nextwp]
if ok {
h.activewp = nextwp
}
}
}

26
weapons/laser.go Normal file
View File

@@ -0,0 +1,26 @@
package weapons
import "mover/gamedata"
type Laser struct {
active bool
}
func NewLaser() *Laser {
l := &Laser{
active: false,
}
return l
}
func (g *Laser) IsActive() bool {
return g.active
}
func (g *Laser) SetActivity(active bool) {
g.active = active
}
func (g *Laser) GetWeaponType() gamedata.WeaponType {
return gamedata.WeaponTypeLaser
}

9
weapons/weapon.go Normal file
View File

@@ -0,0 +1,9 @@
package weapons
import "mover/gamedata"
type Weapon interface {
IsActive() bool
SetActivity(bool)
GetWeaponType() gamedata.WeaponType
}