Added weapon system. Animated laser.
This commit is contained in:
@@ -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
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 |
@@ -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 {
|
||||||
|
|||||||
@@ -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
9
gamedata/weapontype.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package gamedata
|
||||||
|
|
||||||
|
type WeaponType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
WeaponTypeGun = iota
|
||||||
|
WeaponTypeLaser
|
||||||
|
WeaponTypeMax
|
||||||
|
)
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
26
weapons/gun.go
Normal 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
51
weapons/holster.go
Normal 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
26
weapons/laser.go
Normal 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
9
weapons/weapon.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package weapons
|
||||||
|
|
||||||
|
import "mover/gamedata"
|
||||||
|
|
||||||
|
type Weapon interface {
|
||||||
|
IsActive() bool
|
||||||
|
SetActivity(bool)
|
||||||
|
GetWeaponType() gamedata.WeaponType
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user