Skip to content

Commit

Permalink
unit/ability: Added the ability 'Attack'
Browse files Browse the repository at this point in the history
And all the logic around it. Basically targetting towers to destroy them
  • Loading branch information
xescugc committed Jun 12, 2024
1 parent 7bcde6c commit 48ba8e9
Show file tree
Hide file tree
Showing 18 changed files with 315 additions and 115 deletions.
5 changes: 5 additions & 0 deletions action/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@ type SyncStateTowerPayload struct {
LineID int
PlayerID string

Health float64

LastAttack time.Time
}

Expand Down Expand Up @@ -498,6 +500,9 @@ type SyncStateUnitPayload struct {

Abilities map[string]interface{}
Buffs map[string]interface{}

TargetTowerID string
LastAttack time.Time
}

// TODO: or make the action.Action separated or make the store.Player separated
Expand Down
Binary file added assets/LifeBarBigProgress.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/LifeBarBigUnder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions assets/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ var RobotFaceset_png []byte
//go:embed ninja_adventure_asset_pack/Actor/Characters/MonkeyBoxerRed/SeparateAnim/Walk.png
var MonkeyBoxerWalk_png []byte

//go:embed ninja_adventure_asset_pack/Actor/Characters/MonkeyBoxerRed/SeparateAnim/Attack.png
var MonkeyBoxerAttack_png []byte

//go:embed ninja_adventure_asset_pack/Actor/Characters/MonkeyBoxerRed/SeparateAnim/Idle.png
var MonkeyBoxerIdle_png []byte

//go:embed ninja_adventure_asset_pack/Actor/Characters/MonkeyBoxerRed/Faceset.png
var MonkeyBoxerFaceset_png []byte

Expand Down Expand Up @@ -120,5 +126,11 @@ var LifeBarMiniUnder_png []byte
//go:embed ShieldBarMiniProgress.png
var ShieldBarMiniProgress_png []byte

//go:embed LifeBarBigProgress.png
var LifeBarBigProgress_png []byte

//go:embed LifeBarBigUnder.png
var LifeBarBigUnder_png []byte

//go:embed Arrow.png
var Arrow_png []byte
5 changes: 4 additions & 1 deletion assets/units.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@
"gold": 30,
"keybind":"0",
"environment":"terrestrial",
"movement_speed": 40
"movement_speed": 40,
"abilities":["attack"],
"damage": 1,
"attack_speed":1
}
}
26 changes: 19 additions & 7 deletions client/game/hud.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@ import (
"github.com/xescugc/maze-wars/store"
"github.com/xescugc/maze-wars/tower"
"github.com/xescugc/maze-wars/unit"
"github.com/xescugc/maze-wars/unit/ability"
"github.com/xescugc/maze-wars/utils"
)

const (
unitToolTipTmpl = "Lvl: %d\nGold: %d\nHP: %.0f\nSpeed: %.f\nIncome: %d\nEnv: %s\nKeybind: %s"
unitUpdateToolTipTmpl = "Lvl: %d\nCost: %d\nGold: %d\nHP: %.0f\nIncome: %d"

unitAttackToolTipTmpl = "Lvl: %d\nGold: %d\nHP: %.0f\nDamage: %.0f\nAttack Speed: %.0f\nSpeed: %.f\nIncome: %d\nEnv: %s\nKeybind: %s"
unitAttackUpdateToolTipTmpl = "Lvl: %d\nCost: %d\nGold: %d\nHP: %.0f\nDamage: %.0f\nIncome: %d"

towerRemoveToolTipTmpl = "Gold back: %d\nKeybind: %s"
towerUpdateToolTipTmpl = "Cost: %d\nDamage: %.1f\nKeybind: %s"
towerUpdateToolTipTmpl = "Cost: %d\nDamage: %.0f\nAttack Speed: %.0f\nHealth: %.0f\nKeybind: %s"
towerUpdateLimit = "Tower is at it's max level"
)

Expand Down Expand Up @@ -297,14 +301,22 @@ func (hs *HUDStore) Draw(screen *ebiten.Image) {
for i, u := range sortedUnits() {
uu := cp.UnitUpdates[u.Type.String()]
wuts[i].GetWidget().Disabled = !cp.CanSummonUnit(u.Type.String())
hs.unitsTooltip[u.Type.String()].Label = fmt.Sprintf(unitToolTipTmpl, uu.Level, uu.Current.Gold, uu.Current.Health, uu.Current.MovementSpeed, uu.Current.Income, u.Environment, u.Keybind)
if u.HasAbility(ability.Attack) {
hs.unitsTooltip[u.Type.String()].Label = fmt.Sprintf(unitAttackToolTipTmpl, uu.Level, uu.Current.Gold, uu.Current.Health, uu.Current.Damage, uu.Current.AttackSpeed, uu.Current.MovementSpeed, uu.Current.Income, u.Environment, u.Keybind)
} else {
hs.unitsTooltip[u.Type.String()].Label = fmt.Sprintf(unitToolTipTmpl, uu.Level, uu.Current.Gold, uu.Current.Health, uu.Current.MovementSpeed, uu.Current.Income, u.Environment, u.Keybind)
}
}

wuuts := hs.unitUpdatesC.Children()
for i, u := range sortedUnits() {
uu := cp.UnitUpdates[u.Type.String()]
wuuts[i].GetWidget().Disabled = !cp.CanUpdateUnit(u.Type.String())
hs.unitUpdatesTooltip[u.Type.String()].Label = fmt.Sprintf(unitUpdateToolTipTmpl, uu.Level+1, uu.UpdateCost, uu.Next.Gold, uu.Next.Health, uu.Next.Income)
if u.HasAbility(ability.Attack) {
hs.unitUpdatesTooltip[u.Type.String()].Label = fmt.Sprintf(unitAttackUpdateToolTipTmpl, uu.Level+1, uu.UpdateCost, uu.Next.Gold, uu.Next.Health, uu.Next.Damage, uu.Next.Income)
} else {
hs.unitUpdatesTooltip[u.Type.String()].Label = fmt.Sprintf(unitUpdateToolTipTmpl, uu.Level+1, uu.UpdateCost, uu.Next.Gold, uu.Next.Health, uu.Next.Income)
}
}

wtws := hs.towersC.Children()
Expand Down Expand Up @@ -343,15 +355,15 @@ func (hs *HUDStore) Draw(screen *ebiten.Image) {
hs.towerUpdateButton1.Image = cutils.ButtonImageFromImage(imagesCache.Get(tw.FacesetKey()))
hs.towerUpdateButton1.GetWidget().Visibility = widget.Visibility_Show
hs.towerUpdateButton1.GetWidget().Disabled = cp.Gold < tw.Gold
hs.towerUpdateToolTip1.Label = fmt.Sprintf(towerUpdateToolTipTmpl, tw.Gold, tw.Damage, updateTowerKeybind1)
hs.towerUpdateToolTip1.Label = fmt.Sprintf(towerUpdateToolTipTmpl, tw.Gold, tw.Damage, tw.AttackSpeed, tw.Health, updateTowerKeybind1)
hs.towerUpdateButton2.GetWidget().Visibility = widget.Visibility_Hide
}
if len(tu) >= 2 {
tw := tower.Towers[tu[1].String()]
hs.towerUpdateButton2.Image = cutils.ButtonImageFromImage(imagesCache.Get(tw.FacesetKey()))
hs.towerUpdateButton2.GetWidget().Visibility = widget.Visibility_Show
hs.towerUpdateButton2.GetWidget().Disabled = cp.Gold < tw.Gold
hs.towerUpdateToolTip2.Label = fmt.Sprintf(towerUpdateToolTipTmpl, tw.Gold, tw.Damage, updateTowerKeybind2)
hs.towerUpdateToolTip2.Label = fmt.Sprintf(towerUpdateToolTipTmpl, tw.Gold, tw.Damage, tw.AttackSpeed, tw.Health, updateTowerKeybind2)
}
}
hs.towerRemoveToolTip.Label = fmt.Sprintf(towerRemoveToolTipTmpl, removeTowerGoldReturn, removeTowerKeybind)
Expand Down Expand Up @@ -1050,7 +1062,7 @@ func (hs *HUDStore) guiBottomLeft() *widget.Container {

updateToolTxt1 := widget.NewText(
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
widget.TextOpts.Text(fmt.Sprintf(towerUpdateToolTipTmpl, 0, 0.0, updateTowerKeybind1), cutils.SmallFont, color.White),
widget.TextOpts.Text(fmt.Sprintf(towerUpdateToolTipTmpl, 0, 0.0, 0.0, 0.0, updateTowerKeybind1), cutils.SmallFont, color.White),
widget.TextOpts.WidgetOpts(widget.WidgetOpts.MinSize(100, 0)),
)
hs.towerUpdateToolTip1 = updateToolTxt1
Expand Down Expand Up @@ -1100,7 +1112,7 @@ func (hs *HUDStore) guiBottomLeft() *widget.Container {

updateToolTxt2 := widget.NewText(
widget.TextOpts.Position(widget.TextPositionCenter, widget.TextPositionCenter),
widget.TextOpts.Text(fmt.Sprintf(towerUpdateToolTipTmpl, 0, 0.0, updateTowerKeybind2), cutils.SmallFont, color.White),
widget.TextOpts.Text(fmt.Sprintf(towerUpdateToolTipTmpl, 0, 0.0, 0.0, 0.0, updateTowerKeybind2), cutils.SmallFont, color.White),
widget.TextOpts.WidgetOpts(widget.WidgetOpts.MinSize(100, 0)),
)
hs.towerUpdateToolTip2 = updateToolTxt2
Expand Down
28 changes: 20 additions & 8 deletions client/game/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,28 @@ import (
"github.com/xescugc/maze-wars/store"
"github.com/xescugc/maze-wars/tower"
"github.com/xescugc/maze-wars/unit"
"github.com/xescugc/maze-wars/unit/ability"
)

var (
imagesCache *ImagesCache
)

const (
crossImageKey string = "cross-image"
arrowImageKey string = "arrow"
crossImageKey = "cross-image"
arrowImageKey = "arrow"

buffBurrowedKey string = "buff-burrowed"
buffBurrowedReadyKey string = "buff-burrowed-ready"
buffBurrowedKey = "buff-burrowed"
buffBurrowedReadyKey = "buff-burrowed-ready"

buffResurrectingKey string = "buff-resurrecting"
buffResurrectingKey = "buff-resurrecting"

lifeBarProgressKey = "life-bar-progress"
lifeBarUnderKey = "life-bar-under"
shieldBarProgressKey = "shield-bar-progress"

towersKey = "towers-key"
lifeBarBigProgressKey = "life-bar-big-progress"
lifeBarBigUnderKey = "life-bar-big-under"
)

// ImagesCache is a simple cache for all the images, so instead
Expand All @@ -47,6 +49,10 @@ func init() {
for _, u := range unit.Units {
imagesCache.images[u.FacesetKey()] = ebiten.NewImageFromImage(u.Faceset)
imagesCache.images[u.WalkKey()] = ebiten.NewImageFromImage(u.Walk)
if u.HasAbility(ability.Attack) {
imagesCache.images[u.AttackKey()] = ebiten.NewImageFromImage(u.Attack)
imagesCache.images[u.IdleKey()] = ebiten.NewImageFromImage(u.Idle)
}
}
for _, t := range tower.Towers {
imagesCache.images[t.FacesetKey()] = ebiten.NewImageFromImage(t.Faceset)
Expand Down Expand Up @@ -99,11 +105,17 @@ func init() {
}
imagesCache.images[shieldBarProgressKey] = ebiten.NewImageFromImage(sbpi)

atpi, _, err := image.Decode(bytes.NewReader(assets.Towers_png))
lbbpi, _, err := image.Decode(bytes.NewReader(assets.LifeBarBigProgress_png))
if err != nil {
panic(err)
}
imagesCache.images[towersKey] = ebiten.NewImageFromImage(atpi)
imagesCache.images[lifeBarBigProgressKey] = ebiten.NewImageFromImage(lbbpi)

lbbui, _, err := image.Decode(bytes.NewReader(assets.LifeBarBigUnder_png))
if err != nil {
panic(err)
}
imagesCache.images[lifeBarBigUnderKey] = ebiten.NewImageFromImage(lbbui)
}

// Get will return the image from 'key', if it does not
Expand Down
40 changes: 36 additions & 4 deletions client/game/lines.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/hajimehoshi/ebiten/v2"
"github.com/xescugc/maze-wars/assets"
"github.com/xescugc/maze-wars/store"
"github.com/xescugc/maze-wars/tower"
"github.com/xescugc/maze-wars/unit/ability"
"github.com/xescugc/maze-wars/unit/buff"
"github.com/xescugc/maze-wars/utils"
)
Expand Down Expand Up @@ -59,6 +61,9 @@ func (ls *Lines) Draw(screen *ebiten.Image) {
for _, u := range l.ListSortedUnits() {
ls.DrawUnit(screen, ls.game.Camera, u)
}
for _, t := range l.Towers {
ls.DrawTowerHelath(screen, ls.game.Camera, t)
}
}
}

Expand All @@ -73,6 +78,27 @@ func (ls *Lines) DrawTower(screen *ebiten.Image, c *CameraStore, t *store.Tower)
screen.DrawImage(imagesCache.Get(t.FacetKey()), op)
}

func (ls *Lines) DrawTowerHelath(screen *ebiten.Image, c *CameraStore, t *store.Tower) {
cs := c.GetState().(CameraState)
if !t.IsColliding(cs.Object) {
return
}

ot := tower.Towers[t.Type]
// Only draw the Health bar if the Tower has been hit
if t.Health != ot.Health {
lbui := imagesCache.Get(lifeBarBigUnderKey)
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(t.X-cs.X-1, t.Y-cs.Y-float64(lbui.Bounds().Dy()))
screen.DrawImage(lbui, op)

lbpi := imagesCache.Get(lifeBarBigProgressKey)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(t.X-cs.X-1, t.Y-cs.Y-float64(lbpi.Bounds().Dy()))
screen.DrawImage(lbpi.SubImage(image.Rect(0, 0, int(float64(lbpi.Bounds().Dx())*(t.Health/ot.Health)), lbpi.Bounds().Dy())).(*ebiten.Image), op)
}
}

func (ls *Lines) DrawUnit(screen *ebiten.Image, c *CameraStore, u *store.Unit) {
cs := c.GetState().(CameraState)
// This is to display the full unit calculated path as a line
Expand All @@ -97,6 +123,12 @@ func (ls *Lines) DrawUnit(screen *ebiten.Image, c *CameraStore, u *store.Unit) {
}
} else if u.HasBuff(buff.Resurrecting) {
screen.DrawImage(imagesCache.Get(buffResurrectingKey), op)
} else if u.HasAbility(ability.Attack) && len(u.Path) == 0 {
if (u.AnimationCount/10)%2 == 0 {
screen.DrawImage(imagesCache.Get(u.AttackKey()).SubImage(image.Rect(sx, 0, sx+u.W, u.H)).(*ebiten.Image), op)
} else {
screen.DrawImage(imagesCache.Get(u.IdleKey()).SubImage(image.Rect(sx, 0, sx+u.W, u.H)).(*ebiten.Image), op)
}
} else {
screen.DrawImage(imagesCache.Get(u.WalkKey()).SubImage(image.Rect(sx, sy, sx+u.W, sy+u.H)).(*ebiten.Image), op)
}
Expand All @@ -105,25 +137,25 @@ func (ls *Lines) DrawUnit(screen *ebiten.Image, c *CameraStore, u *store.Unit) {
if u.Health != u.MaxHealth {
lbui := imagesCache.Get(lifeBarUnderKey)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(u.X-cs.X, u.Y-cs.Y-float64(lbui.Bounds().Dy()))
op.GeoM.Translate(u.X-cs.X-1, u.Y-cs.Y-float64(lbui.Bounds().Dy()))
screen.DrawImage(lbui, op)

lbpi := imagesCache.Get(lifeBarProgressKey)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(u.X-cs.X, u.Y-cs.Y-float64(lbpi.Bounds().Dy()))
op.GeoM.Translate(u.X-cs.X-1, u.Y-cs.Y-float64(lbpi.Bounds().Dy()))
screen.DrawImage(lbpi.SubImage(image.Rect(0, 0, int(float64(lbpi.Bounds().Dx())*(u.Health/u.MaxHealth)), lbpi.Bounds().Dy())).(*ebiten.Image), op)
}

// Only draw the Shield bar if the unit has been hit
if u.Shield != u.MaxShield && u.Shield != 0 {
lbui := imagesCache.Get(lifeBarUnderKey)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(u.X-cs.X, u.Y-cs.Y-float64(lbui.Bounds().Dy()))
op.GeoM.Translate(u.X-cs.X-1, u.Y-cs.Y-float64(lbui.Bounds().Dy()))
screen.DrawImage(lbui, op)

sbpi := imagesCache.Get(shieldBarProgressKey)
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(u.X-cs.X, u.Y-cs.Y-float64(sbpi.Bounds().Dy()))
op.GeoM.Translate(u.X-cs.X-1, u.Y-cs.Y-float64(sbpi.Bounds().Dy()))
screen.DrawImage(sbpi.SubImage(image.Rect(0, 0, int(float64(sbpi.Bounds().Dx())*(u.Shield/u.MaxShield)), sbpi.Bounds().Dy())).(*ebiten.Image), op)
}

Expand Down
Binary file modified server/assets/wasm/maze-wars.wasm
Binary file not shown.
Loading

0 comments on commit 48ba8e9

Please sign in to comment.