Cloud layer.
This commit is contained in:
BIN
assets/cloud.png
Normal file
BIN
assets/cloud.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -25,6 +25,7 @@ const (
|
|||||||
Weapon ImgAssetName = "Weapon"
|
Weapon ImgAssetName = "Weapon"
|
||||||
WormDamaged ImgAssetName = "WormDamaged"
|
WormDamaged ImgAssetName = "WormDamaged"
|
||||||
Worm ImgAssetName = "WormDefault"
|
Worm ImgAssetName = "WormDefault"
|
||||||
|
Cloud ImgAssetName = "Cloud"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -54,6 +55,8 @@ var (
|
|||||||
worm_img []byte
|
worm_img []byte
|
||||||
//go:embed wormdefault.png
|
//go:embed wormdefault.png
|
||||||
wormdefault_img []byte
|
wormdefault_img []byte
|
||||||
|
//go:embed cloud.png
|
||||||
|
cloud_img []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadImages() {
|
func LoadImages() {
|
||||||
@@ -71,6 +74,7 @@ func LoadImages() {
|
|||||||
ImageBank[Weapon] = LoadImagesFatal(weapon_img)
|
ImageBank[Weapon] = LoadImagesFatal(weapon_img)
|
||||||
ImageBank[WormDamaged] = LoadImagesFatal(worm_img)
|
ImageBank[WormDamaged] = LoadImagesFatal(worm_img)
|
||||||
ImageBank[Worm] = LoadImagesFatal(wormdefault_img)
|
ImageBank[Worm] = LoadImagesFatal(wormdefault_img)
|
||||||
|
ImageBank[Cloud] = LoadImagesFatal(cloud_img)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
62
elements/cloud.go
Normal file
62
elements/cloud.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package elements
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"mover/assets"
|
||||||
|
"mover/gamedata"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cloud struct {
|
||||||
|
Sprite *ebiten.Image
|
||||||
|
position gamedata.Coordinates
|
||||||
|
angle float64
|
||||||
|
velocity float64
|
||||||
|
Alpha float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCloud(a gamedata.Area, angle, velocity float64) *Cloud {
|
||||||
|
c := &Cloud{
|
||||||
|
Sprite: ebiten.NewImage(a.Width, a.Height),
|
||||||
|
angle: angle, //rand.Float64() * (math.Pi * 2),
|
||||||
|
velocity: velocity,
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cloud) Update() error {
|
||||||
|
|
||||||
|
c.position.X += c.velocity * math.Cos(c.angle)
|
||||||
|
c.position.Y += c.velocity * math.Sin(c.angle)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cloud) Draw() {
|
||||||
|
c.Sprite.Clear()
|
||||||
|
//c.Sprite.Fill(color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff})
|
||||||
|
//c.Sprite.Fill(color.White)
|
||||||
|
|
||||||
|
cloudsprite := assets.ImageBank[assets.Cloud]
|
||||||
|
|
||||||
|
spritex := cloudsprite.Bounds().Dx()
|
||||||
|
spritey := cloudsprite.Bounds().Dy()
|
||||||
|
|
||||||
|
cloudx := c.Sprite.Bounds().Dx()
|
||||||
|
cloudy := c.Sprite.Bounds().Dy()
|
||||||
|
|
||||||
|
scalex := float64(cloudx) / float64(spritex)
|
||||||
|
scaley := float64(cloudy) / float64(spritey)
|
||||||
|
|
||||||
|
op := &ebiten.DrawImageOptions{}
|
||||||
|
op.GeoM.Scale(scalex, scaley)
|
||||||
|
c.Sprite.DrawImage(assets.ImageBank[assets.Cloud], op)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cloud) SetPosition(p gamedata.Coordinates) {
|
||||||
|
c.position = p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cloud) GetPosition() gamedata.Coordinates {
|
||||||
|
return c.position
|
||||||
|
}
|
||||||
@@ -23,4 +23,5 @@ type Enemies interface {
|
|||||||
ExplosionInitiated() bool
|
ExplosionInitiated() bool
|
||||||
SetExplosionInitiated()
|
SetExplosionInitiated()
|
||||||
Health() int
|
Health() int
|
||||||
|
MaxHealth() int
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,5 +163,11 @@ func (f *FlyEye) SetExplosionInitiated() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlyEye) Health() int {
|
func (f *FlyEye) Health() int {
|
||||||
|
//health bars reserved for special enemies, flyeye is a one
|
||||||
|
//hitter so returning zero ensure no health bar is rendered
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FlyEye) MaxHealth() int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FG_MAXHEALTH = 100
|
||||||
|
)
|
||||||
|
|
||||||
type FlyGoblin struct {
|
type FlyGoblin struct {
|
||||||
Sprite *ebiten.Image
|
Sprite *ebiten.Image
|
||||||
Maks *ebiten.Image
|
Maks *ebiten.Image
|
||||||
@@ -18,10 +22,8 @@ type FlyGoblin struct {
|
|||||||
state gamedata.EnemyState
|
state gamedata.EnemyState
|
||||||
cycle int
|
cycle int
|
||||||
health int
|
health int
|
||||||
dyingcount int
|
|
||||||
damageduration int
|
damageduration int
|
||||||
right bool
|
right bool
|
||||||
hit bool
|
|
||||||
touched bool
|
touched bool
|
||||||
toggle bool
|
toggle bool
|
||||||
sploding bool
|
sploding bool
|
||||||
@@ -33,7 +35,7 @@ func NewFlyGoblin() *FlyGoblin {
|
|||||||
Sprite: ebiten.NewImage(96, 96),
|
Sprite: ebiten.NewImage(96, 96),
|
||||||
Maks: ebiten.NewImage(96, 96),
|
Maks: ebiten.NewImage(96, 96),
|
||||||
MaksDest: ebiten.NewImage(96, 96),
|
MaksDest: ebiten.NewImage(96, 96),
|
||||||
health: 100,
|
health: FG_MAXHEALTH,
|
||||||
damageduration: 0,
|
damageduration: 0,
|
||||||
}
|
}
|
||||||
fg.Maks.Fill(color.White)
|
fg.Maks.Fill(color.White)
|
||||||
@@ -176,3 +178,7 @@ func (f *FlyGoblin) SetExplosionInitiated() {
|
|||||||
func (f *FlyGoblin) Health() int {
|
func (f *FlyGoblin) Health() int {
|
||||||
return f.health
|
return f.health
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FlyGoblin) MaxHealth() int {
|
||||||
|
return FG_MAXHEALTH
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
"math"
|
"math"
|
||||||
|
"math/rand/v2"
|
||||||
"mover/assets"
|
"mover/assets"
|
||||||
"mover/elements"
|
"mover/elements"
|
||||||
"mover/fonts"
|
"mover/fonts"
|
||||||
@@ -50,6 +51,7 @@ func NewCanvas(a gamedata.Area) *Canvas {
|
|||||||
goblinspawned: false,
|
goblinspawned: false,
|
||||||
score: 0,
|
score: 0,
|
||||||
runtime: 0.,
|
runtime: 0.,
|
||||||
|
counter: 0,
|
||||||
}
|
}
|
||||||
c.eventmap = make(map[gamedata.GameEvent]func())
|
c.eventmap = make(map[gamedata.GameEvent]func())
|
||||||
return c
|
return c
|
||||||
@@ -70,9 +72,9 @@ func (c *Canvas) Update() error {
|
|||||||
c.UpdateCharge()
|
c.UpdateCharge()
|
||||||
c.UpdateEnemies()
|
c.UpdateEnemies()
|
||||||
c.CleanupTargets()
|
c.CleanupTargets()
|
||||||
|
c.counter++
|
||||||
}
|
}
|
||||||
c.counter++
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +107,7 @@ func (c *Canvas) Draw(drawimg *ebiten.Image) {
|
|||||||
if e.Health() > 0 {
|
if e.Health() > 0 {
|
||||||
x0 := e.GetPosition().X - float64(e.GetSprite().Bounds().Dx())
|
x0 := e.GetPosition().X - float64(e.GetSprite().Bounds().Dx())
|
||||||
y0 := e.GetPosition().Y - 2/3.*float64(e.GetSprite().Bounds().Dy())
|
y0 := e.GetPosition().Y - 2/3.*float64(e.GetSprite().Bounds().Dy())
|
||||||
vector.DrawFilledRect(c.Sprite, float32(x0), float32(y0), 204, 12, color.Black, true)
|
vector.DrawFilledRect(c.Sprite, float32(x0), float32(y0), float32(e.MaxHealth())*2+4, 12, color.Black, true)
|
||||||
vector.DrawFilledRect(c.Sprite, float32(x0+2), float32(y0+2), float32(e.Health())*2, 8, color.RGBA{R: 0xff, G: 0x00, B: 0x00, A: 0xff}, true)
|
vector.DrawFilledRect(c.Sprite, float32(x0+2), float32(y0+2), float32(e.Health())*2, 8, color.RGBA{R: 0xff, G: 0x00, B: 0x00, A: 0xff}, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,7 +353,8 @@ func (c *Canvas) UpdateEnemies() {
|
|||||||
e.Update()
|
e.Update()
|
||||||
}
|
}
|
||||||
if !c.gameover {
|
if !c.gameover {
|
||||||
/*
|
|
||||||
|
if !c.goblinspawned {
|
||||||
//spawn new enemies
|
//spawn new enemies
|
||||||
f := 40000 / (c.counter + 1)
|
f := 40000 / (c.counter + 1)
|
||||||
|
|
||||||
@@ -376,13 +379,15 @@ func (c *Canvas) UpdateEnemies() {
|
|||||||
newenemy.SetTarget(c.hero.Pos)
|
newenemy.SetTarget(c.hero.Pos)
|
||||||
|
|
||||||
c.enemies = append(c.enemies, newenemy)
|
c.enemies = append(c.enemies, newenemy)
|
||||||
}*/
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !c.goblinspawned {
|
if !c.goblinspawned && c.counter > 1200 {
|
||||||
newfg := elements.NewFlyGoblin()
|
newfg := elements.NewFlyGoblin()
|
||||||
c.enemies = append(c.enemies, newfg)
|
c.enemies = append(c.enemies, newfg)
|
||||||
c.goblinspawned = true
|
c.goblinspawned = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
109
gameelement/cloudlayer.go
Normal file
109
gameelement/cloudlayer.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package gameelement
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"math/rand/v2"
|
||||||
|
"mover/elements"
|
||||||
|
"mover/gamedata"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CloudLayer struct {
|
||||||
|
Sprite *ebiten.Image
|
||||||
|
clouds []*elements.Cloud
|
||||||
|
dimensions gamedata.Area
|
||||||
|
cycle int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCloudLayer(a gamedata.Area) *CloudLayer {
|
||||||
|
c := &CloudLayer{
|
||||||
|
Sprite: ebiten.NewImage(a.Width, a.Height),
|
||||||
|
cycle: 0,
|
||||||
|
dimensions: a,
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CloudLayer) SetInputs(gamedata.GameInputs) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CloudLayer) Update() error {
|
||||||
|
c.cycle++
|
||||||
|
|
||||||
|
for _, cloud := range c.clouds {
|
||||||
|
cloud.Update()
|
||||||
|
|
||||||
|
cpos := cloud.GetPosition()
|
||||||
|
if cpos.X > float64(c.dimensions.Width)+float64(cloud.Sprite.Bounds().Dx()) {
|
||||||
|
dx := -float64(cloud.Sprite.Bounds().Dx())
|
||||||
|
cloud.SetPosition(gamedata.Coordinates{X: dx, Y: cloud.GetPosition().Y})
|
||||||
|
}
|
||||||
|
if cpos.X < -float64(cloud.Sprite.Bounds().Dx()) {
|
||||||
|
dx := float64(c.dimensions.Width + cloud.Sprite.Bounds().Dx())
|
||||||
|
cloud.SetPosition(gamedata.Coordinates{X: dx, Y: cloud.GetPosition().Y})
|
||||||
|
}
|
||||||
|
if cpos.Y > float64(c.dimensions.Height)+float64(cloud.Sprite.Bounds().Dy()) {
|
||||||
|
dy := -float64(cloud.Sprite.Bounds().Dy())
|
||||||
|
cloud.SetPosition(gamedata.Coordinates{X: cloud.GetPosition().X, Y: dy})
|
||||||
|
}
|
||||||
|
if cpos.Y < -float64(cloud.Sprite.Bounds().Dy()) {
|
||||||
|
dy := float64(c.dimensions.Height + cloud.Sprite.Bounds().Dy())
|
||||||
|
cloud.SetPosition(gamedata.Coordinates{X: cloud.GetPosition().X, Y: dy})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CloudLayer) Draw(drawimg *ebiten.Image) {
|
||||||
|
c.Sprite.Clear()
|
||||||
|
|
||||||
|
for _, cloud := range c.clouds {
|
||||||
|
cloud.Draw()
|
||||||
|
op := &ebiten.DrawImageOptions{}
|
||||||
|
op.GeoM.Translate(cloud.GetPosition().X, cloud.GetPosition().Y)
|
||||||
|
op.ColorScale.ScaleAlpha(float32(cloud.Alpha))
|
||||||
|
c.Sprite.DrawImage(cloud.Sprite, op)
|
||||||
|
}
|
||||||
|
|
||||||
|
drawimg.DrawImage(c.Sprite, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CloudLayer) Initialize() {
|
||||||
|
|
||||||
|
//cull previous cloud layer
|
||||||
|
for i := 0; i < len(c.clouds); i++ {
|
||||||
|
c.clouds[i] = nil
|
||||||
|
}
|
||||||
|
c.clouds = c.clouds[:0]
|
||||||
|
|
||||||
|
numclouds := rand.IntN(20)
|
||||||
|
angle := rand.Float64() * math.Pi * 2
|
||||||
|
|
||||||
|
for i := 0; i < numclouds; i++ {
|
||||||
|
|
||||||
|
a := gamedata.Area{
|
||||||
|
Height: rand.IntN(c.dimensions.Width/2) + 1,
|
||||||
|
Width: rand.IntN(c.dimensions.Height/2) + 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
velocity := rand.Float64() * 3
|
||||||
|
//velocity := 0.
|
||||||
|
|
||||||
|
newcloud := elements.NewCloud(a, angle, velocity)
|
||||||
|
|
||||||
|
newcloud.Alpha = rand.Float64() / 2
|
||||||
|
|
||||||
|
newcloud.SetPosition(gamedata.Coordinates{
|
||||||
|
X: rand.Float64() * float64(c.dimensions.Width),
|
||||||
|
Y: rand.Float64() * float64(c.dimensions.Height),
|
||||||
|
})
|
||||||
|
|
||||||
|
c.clouds = append(c.clouds, newcloud)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CloudLayer) RegisterEvents(e gamedata.GameEvent, f func()) {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -32,19 +32,28 @@ func NewPrimary() *Primary {
|
|||||||
musicInitialized: false,
|
musicInitialized: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gamearea := gamedata.Area{Width: 640, Height: 480}
|
||||||
|
|
||||||
|
//initialize our layer map
|
||||||
p.gameevents = make(map[gamedata.GameEvent]bool)
|
p.gameevents = make(map[gamedata.GameEvent]bool)
|
||||||
|
|
||||||
p.elements = append(p.elements, gameelement.NewBackground(gamedata.Area{Width: 640, Height: 480}))
|
//create background layer
|
||||||
|
p.elements = append(p.elements, gameelement.NewBackground(gamearea))
|
||||||
|
|
||||||
canvas := gameelement.NewCanvas(gamedata.Area{Width: 640, Height: 480})
|
//create canvas (game) layer
|
||||||
|
canvas := gameelement.NewCanvas(gamearea)
|
||||||
canvas.RegisterEvents(gamedata.GameEventPlayerDeath, p.EventHandlerPlayerDeath)
|
canvas.RegisterEvents(gamedata.GameEventPlayerDeath, p.EventHandlerPlayerDeath)
|
||||||
canvas.RegisterEvents(gamedata.GameEventCharge, p.EventHandlerCharge)
|
canvas.RegisterEvents(gamedata.GameEventCharge, p.EventHandlerCharge)
|
||||||
canvas.RegisterEvents(gamedata.GameEventNewShot, p.EventHandlerNewShot)
|
canvas.RegisterEvents(gamedata.GameEventNewShot, p.EventHandlerNewShot)
|
||||||
canvas.RegisterEvents(gamedata.GameEventTargetHit, p.EventHandlerTargetHit)
|
canvas.RegisterEvents(gamedata.GameEventTargetHit, p.EventHandlerTargetHit)
|
||||||
canvas.RegisterEvents(gamedata.GameEventExplosion, p.EventHandlerExplosion)
|
canvas.RegisterEvents(gamedata.GameEventExplosion, p.EventHandlerExplosion)
|
||||||
|
|
||||||
p.elements = append(p.elements, canvas)
|
p.elements = append(p.elements, canvas)
|
||||||
|
|
||||||
|
//create foreground cloud layer
|
||||||
|
clouds := gameelement.NewCloudLayer(gamearea)
|
||||||
|
clouds.Initialize()
|
||||||
|
p.elements = append(p.elements, clouds)
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user