Add dash ability
parent
639b0b8ab1
commit
a1abf7eab5
936
asset/map/m1.tmx
936
asset/map/m1.tmx
File diff suppressed because it is too large
Load Diff
1
flags.go
1
flags.go
|
@ -22,6 +22,7 @@ func parseFlags() {
|
|||
flag.BoolVar(&fullscreen, "fullscreen", false, "run in fullscreen mode")
|
||||
flag.StringVar(&spawn, "spawn", "", "spawn X,Y position")
|
||||
flag.BoolVar(&world.World.CanDoubleJump, "doublejump", false, "start with double jump ability")
|
||||
flag.BoolVar(&world.World.CanDash, "dash", false, "start with dash ability")
|
||||
flag.BoolVar(&world.World.CanLevitate, "levitate", false, "start with levitate ability")
|
||||
flag.IntVar(&world.World.Debug, "debug", 0, "print debug information")
|
||||
flag.Parse()
|
||||
|
|
6
go.mod
6
go.mod
|
@ -3,7 +3,7 @@ module code.rocketnine.space/tslocum/monovania
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
code.rocketnine.space/tslocum/gohan v0.0.0-20211210034951-3c7785e5e57f
|
||||
code.rocketnine.space/tslocum/gohan v0.0.0-20211212050415-e08cfe7970d8
|
||||
github.com/fogleman/ease v0.0.0-20170301025033-8da417bf1776
|
||||
github.com/hajimehoshi/ebiten/v2 v2.2.3
|
||||
github.com/lafriks/go-tiled v0.5.0
|
||||
|
@ -15,8 +15,8 @@ require (
|
|||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211204153444-caad923f49f4 // indirect
|
||||
github.com/hajimehoshi/oto/v2 v2.1.0-alpha.4 // indirect
|
||||
github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240 // indirect
|
||||
golang.org/x/exp v0.0.0-20211209182145-6e94b45d164d // indirect
|
||||
golang.org/x/exp v0.0.0-20211210185655-e05463a05a18 // indirect
|
||||
golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20211209171907-798191bca915 // indirect
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 // indirect
|
||||
)
|
||||
|
|
12
go.sum
12
go.sum
|
@ -1,5 +1,5 @@
|
|||
code.rocketnine.space/tslocum/gohan v0.0.0-20211210034951-3c7785e5e57f h1:stxIGII7DonP7xIsUaEthEj5j3JNnMzVek5fK9hRAMU=
|
||||
code.rocketnine.space/tslocum/gohan v0.0.0-20211210034951-3c7785e5e57f/go.mod h1:nOvFBFvFPl5sDtkMy2Fn/7QZcWq5RE98/mK+INLqIWg=
|
||||
code.rocketnine.space/tslocum/gohan v0.0.0-20211212050415-e08cfe7970d8 h1:tsIId//EUkKtk0v2wNEv6qUmS2yDnOTd7cmXhQemDyE=
|
||||
code.rocketnine.space/tslocum/gohan v0.0.0-20211212050415-e08cfe7970d8/go.mod h1:nOvFBFvFPl5sDtkMy2Fn/7QZcWq5RE98/mK+INLqIWg=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -38,8 +38,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||
golang.org/x/exp v0.0.0-20211209182145-6e94b45d164d h1:kyDnjigapVz/aaGinVfqN3EK7SGZrOCNjcYuf5to0KE=
|
||||
golang.org/x/exp v0.0.0-20211209182145-6e94b45d164d/go.mod h1:b9TAUYHmRtqA6klRHApnXMnj+OyLce4yF5cZCUbk2ps=
|
||||
golang.org/x/exp v0.0.0-20211210185655-e05463a05a18 h1:5GT90y+j5D8fWZ22z0SH3iQ8ZeTWX8quGjetD8Symgg=
|
||||
golang.org/x/exp v0.0.0-20211210185655-e05463a05a18/go.mod h1:b9TAUYHmRtqA6klRHApnXMnj+OyLce4yF5cZCUbk2ps=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
|
@ -72,8 +72,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211209171907-798191bca915 h1:P+8mCzuEpyszAT6T42q0sxU+eveBAF/cJ2Kp0x6/8+0=
|
||||
golang.org/x/sys v0.0.0-20211209171907-798191bca915/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
|
2
main.go
2
main.go
|
@ -20,7 +20,7 @@ func main() {
|
|||
ebiten.SetRunnableOnUnfocused(true) // Note - this currently does nothing in ebiten
|
||||
ebiten.SetWindowClosingHandled(true)
|
||||
ebiten.SetFPSMode(ebiten.FPSModeVsyncOn)
|
||||
ebiten.SetCursorShape(ebiten.CursorShapeCrosshair)
|
||||
ebiten.SetCursorMode(ebiten.CursorModeHidden)
|
||||
|
||||
g, err := game.NewGame()
|
||||
if err != nil {
|
||||
|
|
|
@ -63,12 +63,28 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
|
|||
maxSpeed := 0.5
|
||||
maxLevitateSpeed := 1.0
|
||||
maxYSpeed := 0.5
|
||||
const jumpVelocity = -1
|
||||
const jumpVelocity = -1.02
|
||||
const dashVelocity = 5
|
||||
|
||||
velocity := component.Velocity(ctx)
|
||||
|
||||
var walkKeyPressed bool
|
||||
|
||||
// Jump.
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyJ) {
|
||||
if ((s.movement.OnGround != -1 || s.movement.OnLadder != -1) && world.World.Jumps == 0) || (world.World.CanDoubleJump && world.World.Jumps < 2) {
|
||||
velocity.Y = jumpVelocity
|
||||
s.movement.Jumping = true
|
||||
s.movement.LastJump = time.Now()
|
||||
world.World.Jumps++
|
||||
} else if world.World.CanLevitate && world.World.Jumps == 2 {
|
||||
world.World.Levitating = true
|
||||
}
|
||||
}
|
||||
if s.movement.Jumping && (!ebiten.IsKeyPressed(ebiten.KeyJ) || time.Since(s.movement.LastJump) >= 200*time.Millisecond) {
|
||||
s.movement.Jumping = false
|
||||
}
|
||||
|
||||
if s.movement.OnGround != -1 && ebiten.IsKeyPressed(ebiten.KeyS) && !world.World.NoClip {
|
||||
if ebiten.IsKeyPressed(ebiten.KeyA) {
|
||||
s.lastWalkDirL = true
|
||||
|
@ -176,6 +192,24 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
|
|||
s.lastWalkDirL = false
|
||||
}
|
||||
}
|
||||
|
||||
// Dash.
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyK) && world.World.CanDash && world.World.Dashes == 0 && s.movement.OnGround == -1 && s.movement.OnLadder == -1 {
|
||||
if s.lastWalkDirL {
|
||||
velocity.X = -dashVelocity
|
||||
} else {
|
||||
velocity.X = dashVelocity
|
||||
}
|
||||
velocity.Y = 0
|
||||
s.movement.Dashing = true
|
||||
s.movement.LastDash = time.Now()
|
||||
world.World.Dashes = 1
|
||||
}
|
||||
if s.movement.Dashing && (!ebiten.IsKeyPressed(ebiten.KeyK) || time.Since(s.movement.LastDash) >= 250*time.Millisecond) {
|
||||
velocity.X = 0
|
||||
s.movement.Dashing = false
|
||||
}
|
||||
|
||||
if s.movement.OnLadder != -1 || world.World.NoClip {
|
||||
setLadderFrames := func() {
|
||||
if world.World.NoClip {
|
||||
|
@ -216,26 +250,6 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
|
|||
setLadderFrames()
|
||||
walkKeyPressed = true
|
||||
}
|
||||
} else {
|
||||
// Jump.
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyW) {
|
||||
if (s.movement.OnGround != -1 && world.World.Jumps == 0) || (world.World.CanDoubleJump && world.World.Jumps < 2) {
|
||||
velocity.Y = jumpVelocity
|
||||
s.movement.Jumping = true
|
||||
s.movement.LastJump = time.Now()
|
||||
world.World.Jumps++
|
||||
// Allow one double jump when falling.
|
||||
if world.World.Jumps == 1 && s.movement.OnGround == -1 {
|
||||
world.World.Jumps = 2
|
||||
}
|
||||
} else if world.World.CanLevitate && world.World.Jumps == 2 {
|
||||
world.World.Levitating = true
|
||||
}
|
||||
}
|
||||
|
||||
if s.movement.Jumping && (!ebiten.IsKeyPressed(ebiten.KeyW) || time.Since(s.movement.LastJump) >= 200*time.Millisecond) {
|
||||
s.movement.Jumping = false
|
||||
}
|
||||
}
|
||||
|
||||
if world.World.Levitating {
|
||||
|
@ -248,17 +262,17 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
|
|||
}
|
||||
}
|
||||
|
||||
if !walkKeyPressed || (s.movement.OnGround == -1 && s.movement.OnLadder == -1) || world.World.NoClip {
|
||||
if !walkKeyPressed || s.movement.Jumping || (s.movement.OnGround == -1 && s.movement.OnLadder == -1) || world.World.NoClip {
|
||||
sprite := component.Sprite(ctx)
|
||||
sprite.NumFrames = 0
|
||||
if s.lastWalkDirL {
|
||||
if (s.movement.OnGround == -1 && s.movement.OnLadder == -1) || world.World.NoClip {
|
||||
if (s.movement.OnGround == -1 && s.movement.OnLadder == -1) || s.movement.Jumping || world.World.NoClip {
|
||||
sprite.Image = asset.PlayerSS.WalkL2
|
||||
} else {
|
||||
sprite.Image = asset.PlayerSS.IdleL
|
||||
}
|
||||
} else {
|
||||
if (s.movement.OnGround == -1 && s.movement.OnLadder == -1) || world.World.NoClip {
|
||||
if (s.movement.OnGround == -1 && s.movement.OnLadder == -1) || s.movement.Jumping || world.World.NoClip {
|
||||
sprite.Image = asset.PlayerSS.WalkR2
|
||||
} else {
|
||||
sprite.Image = asset.PlayerSS.IdleR
|
||||
|
|
|
@ -21,6 +21,9 @@ type MovementSystem struct {
|
|||
Jumping bool
|
||||
LastJump time.Time
|
||||
|
||||
Dashing bool
|
||||
LastDash time.Time
|
||||
|
||||
collisionRects []image.Rectangle
|
||||
|
||||
ladderRects []image.Rectangle
|
||||
|
@ -227,9 +230,12 @@ func (s *MovementSystem) checkFire(r image.Rectangle) {
|
|||
func (s *MovementSystem) checkTriggers(r image.Rectangle) {
|
||||
for i, triggerRect := range world.World.TriggerRects {
|
||||
if r.Overlaps(triggerRect) {
|
||||
if world.World.TriggerNames[i] == "DOUBLEJUMP" {
|
||||
switch world.World.TriggerNames[i] {
|
||||
case "DOUBLEJUMP":
|
||||
world.World.CanDoubleJump = true
|
||||
} else {
|
||||
case "DASH":
|
||||
world.World.CanDash = true
|
||||
default:
|
||||
panic("unknown trigger " + world.World.TriggerNames[i])
|
||||
}
|
||||
|
||||
|
@ -265,12 +271,6 @@ func (s *MovementSystem) Update(ctx *gohan.Context) error {
|
|||
for i, rect := range s.ladderRects {
|
||||
if playerRect.Overlaps(rect) {
|
||||
onLadder = i
|
||||
|
||||
// Grab the ladder when jumping on to it.
|
||||
if onLadder != lastOnLadder && !world.World.NoClip {
|
||||
velocity.Y = 0
|
||||
//velocity.X /= 2
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -283,17 +283,19 @@ func (s *MovementSystem) Update(ctx *gohan.Context) error {
|
|||
const maxGravity = 9
|
||||
const gravityAccel = 0.04
|
||||
if !bullet {
|
||||
if s.OnLadder != -1 || world.World.Levitating || world.World.NoClip {
|
||||
if world.World.Levitating || world.World.NoClip {
|
||||
velocity.X *= decel
|
||||
velocity.Y *= decel
|
||||
} else if s.OnLadder != -1 { // TODO incorrect
|
||||
velocity.X *= decel
|
||||
velocity.Y *= ladderDecel
|
||||
} else if s.Dashing {
|
||||
velocity.X *= 0.96
|
||||
} else if velocity.Y < maxGravity {
|
||||
velocity.X *= decel
|
||||
|
||||
if !s.Jumping {
|
||||
velocity.Y += gravityAccel
|
||||
if s.OnLadder == -1 {
|
||||
velocity.Y += gravityAccel
|
||||
} else {
|
||||
velocity.Y *= decel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -349,9 +351,15 @@ func (s *MovementSystem) Update(ctx *gohan.Context) error {
|
|||
velocity.X, velocity.Y = 0, 0
|
||||
}
|
||||
s.OnGround = collideG
|
||||
// Reset jump counter.
|
||||
if s.OnGround != -1 && world.World.Jumps != 0 && time.Since(s.LastJump) >= 50*time.Millisecond {
|
||||
world.World.Jumps = 0
|
||||
if s.OnGround != -1 || s.OnLadder != -1 {
|
||||
// Reset jump counter.
|
||||
if world.World.Jumps != 0 && time.Since(s.LastJump) >= 50*time.Millisecond {
|
||||
world.World.Jumps = 0
|
||||
}
|
||||
// Reset dash counter.
|
||||
if world.World.Dashes != 0 {
|
||||
world.World.Dashes = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Update debug rects.
|
||||
|
|
|
@ -67,14 +67,14 @@ func (s *RenderSystem) renderSprite(x float64, y float64, offsetx float64, offse
|
|||
|
||||
// Skip drawing off-screen tiles.
|
||||
drawX, drawY := s.levelCoordinatesToScreen(x, y)
|
||||
padding := float64(TileWidth) * 2
|
||||
const padding = TileWidth * 4
|
||||
width, height := float64(TileWidth), float64(TileWidth)
|
||||
left := drawX
|
||||
right := drawX + width
|
||||
top := drawY
|
||||
bottom := drawY + height
|
||||
if (left < -padding || left > float64(s.ScreenW)+padding) && (top < -padding || top > float64(s.ScreenH)+padding) &&
|
||||
(right < -padding || right > float64(s.ScreenW)+padding) && (bottom < -padding || bottom > float64(s.ScreenH)+padding) {
|
||||
if (left < -padding || left > float64(s.ScreenW)+padding) || (top < -padding || top > float64(s.ScreenH)+padding) ||
|
||||
(right < -padding || right > float64(s.ScreenW)+padding) || (bottom < -padding || bottom > float64(s.ScreenH)+padding) {
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
@ -49,9 +49,11 @@ type GameWorld struct {
|
|||
|
||||
// Abilities
|
||||
CanDoubleJump bool
|
||||
CanDash bool
|
||||
CanLevitate bool
|
||||
|
||||
Jumps int
|
||||
Dashes int
|
||||
Levitating bool
|
||||
|
||||
TriggerRects []image.Rectangle
|
||||
|
|
Loading…
Reference in New Issue