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"
Fireball ImgAssetName = "Fireball"
Splash ImgAssetName = "Splash"
LaserBeam ImgAssetName = "LaserBeam"
)
var (
@@ -63,6 +64,8 @@ var (
fireball_img []byte
//go:embed splash.png
splash_img []byte
//go:embed laserbeam.png
laserbeam_img []byte
)
func LoadImages() {
@@ -83,6 +86,7 @@ func LoadImages() {
ImageBank[Cloud] = LoadImagesFatal(cloud_img)
ImageBank[Fireball] = LoadImagesFatal(fireball_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,27 +1,30 @@
package elements
import (
"image/color"
"image"
"mover/assets"
"mover/gamedata"
"github.com/hajimehoshi/ebiten/v2"
)
type Laser struct {
Sprite *ebiten.Image
position gamedata.Coordinates
angle float64
cycle int
firing bool
Sprite *ebiten.Image
position gamedata.Coordinates
angle float64
cycle int
firing bool
numcycles int
}
func NewLaser(pos gamedata.Coordinates, angle float64) *Laser {
l := &Laser{
Sprite: ebiten.NewImage(200, 20),
angle: angle,
cycle: 0,
position: pos,
firing: false,
Sprite: ebiten.NewImage(200, 20),
angle: angle,
cycle: 0,
position: pos,
firing: false,
numcycles: 5,
}
return l
}
@@ -33,7 +36,16 @@ func (l *Laser) Update() error {
func (l *Laser) Draw() {
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 {

View File

@@ -1,12 +1,13 @@
package gamedata
type GameInputs struct {
XAxis float64
YAxis float64
ShotAngle float64
Shot bool
Start bool
Charge bool
Quit bool
Reset bool
XAxis float64
YAxis float64
ShotAngle float64
Shot bool
Start bool
Charge bool
Quit 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/fonts"
"mover/gamedata"
"mover/weapons"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/text"
@@ -43,6 +44,7 @@ type Canvas struct {
gameover bool
lasercoords []gamedata.Coordinates
holster *weapons.Holster
}
func NewCanvas(a gamedata.Area) *Canvas {
@@ -63,6 +65,7 @@ func NewCanvas(a gamedata.Area) *Canvas {
score: 0,
runtime: 0.,
counter: 0,
holster: weapons.NewHolster(),
}
c.laserMask.Clear()
c.eventmap = make(map[gamedata.GameEvent]func())
@@ -79,8 +82,8 @@ func (c *Canvas) Update() error {
c.Initialize()
} else {
c.UpdateHero()
c.UpdateWeapons()
c.UpdateProjectiles()
c.UpdateLaser()
c.UpdateCharge()
c.UpdateEnemies()
c.SpawnEnemies()
@@ -227,7 +230,6 @@ func (c *Canvas) UpdateHero() {
if !c.gameover {
c.UpdateHeroPosition()
c.ComputeHeroCollisions()
c.AddProjectiles()
}
}
@@ -275,31 +277,26 @@ func (c *Canvas) ComputeHeroCollisions() {
func (c *Canvas) AddProjectiles() {
//add new projectiles
/*
if c.lastInputs.Shot && c.counter%14 == 0 {
loc := gamedata.Coordinates{
X: c.hero.Pos.X,
Y: c.hero.Pos.Y,
}
angle := c.lastInputs.ShotAngle
velocity := 5.
c.projectiles = append(c.projectiles, elements.NewProjectile(loc, angle, velocity))
if c.hero.Upgrade {
c.projectiles = append(c.projectiles, elements.NewProjectile(loc, angle+math.Pi, velocity))
}
if c.eventmap[gamedata.GameEventNewShot] != nil {
c.eventmap[gamedata.GameEventNewShot]()
}
if c.lastInputs.Shot && c.counter%14 == 0 {
loc := gamedata.Coordinates{
X: c.hero.Pos.X,
Y: c.hero.Pos.Y,
}
*/
if c.lastInputs.Shot {
c.laser.SetPosition(c.hero.Pos)
c.laser.SetAngle(c.lastInputs.ShotAngle)
angle := c.lastInputs.ShotAngle
velocity := 5.
c.projectiles = append(c.projectiles, elements.NewProjectile(loc, angle, velocity))
if c.hero.Upgrade {
c.projectiles = append(c.projectiles, elements.NewProjectile(loc, angle+math.Pi, velocity))
}
if c.eventmap[gamedata.GameEventNewShot] != nil {
c.eventmap[gamedata.GameEventNewShot]()
}
}
}
@@ -362,7 +359,11 @@ func (c *Canvas) UpdateProjectiles() {
}
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)
if c.lastInputs.Shot {
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
d = math.Abs(x1 - x0)
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
d = math.Abs(y1 - y0)
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
m0 := math.Tan(a)
m1 := -1 / m0
@@ -838,9 +839,9 @@ func (c *Canvas) LaserAttempt4() {
yi := xi*m0 - x0*m0 + y0
c.lasercoords[3] = gamedata.Coordinates{X: xi, Y: yi}
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 {
@@ -857,7 +858,7 @@ func (c *Canvas) LaserAttempt4() {
if c.eventmap[gamedata.GameEventTargetHit] != nil {
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]
}
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.CycleWeapon = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonFrontTopRight)
gi.Charge = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonRightStick)
gi.Start = inpututil.IsStandardGamepadButtonJustPressed(0, ebiten.StandardGamepadButtonCenterRight)
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
}