Added weapon system. Animated laser.
This commit is contained in:
@@ -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
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,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 {
|
||||
|
||||
@@ -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
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/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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
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