Coyote time

This commit is contained in:
Noah 2024-02-06 20:56:07 -08:00
parent 8216e5863b
commit 85523d8311
5 changed files with 64 additions and 6 deletions

View File

@ -1,5 +1,41 @@
# Changes # Changes
## v0.14.0 TBD
Level screenshots and thumbnails:
* Level files will begin to take thumbnail screenshots of themselves and
store them as PNG images embedded with the level data, and are displayed
on the Story Mode level select screen.
* A thumbnail is saved the first time your level is saved, and can be
viewed and re-computed in the Level->Level Properties window of the
editor.
* Tip: for bounded levels when you want to screenshot the bottom edge,
try setting the page type to Unbounded to get a good screenshot and
then set it back to Bounded before saving the level.
* In the editor, a new Level->Take Screenshot menu item is available which
will save just your editor viewport as a PNG image to your screenshots
folder.
* In the editor, the Level->Giant Screenshot feature has been improved.
* It now will show a confirmation modal, warning that it may take a
while to screenshot a very large level.
* While the giant screenshot is processing, a progress bar modal will
block interaction with the game so that you don't accidentally modify
the level while the screenshot is generating.
Some minor changes:
* Tweaked the player movement physics and adjusted doodads accordingly.
* The player is given a lower gravity while they are jumping into the air
than the standard (faster) gravity when they are falling. This results
in a smoother jump animation instead of the player launching quickly from
the ground in order to overcome the constant (fast) gravity.
* Coyote time where the player can still jump a few frames late when they
walk off a cliff and jump late.
* Sound effects are now preferred to be in OGG format over MP3 as it is more
reliable to compile the game cross-platform without the dependency on mpg123.
* The game window maximizes on startup to fill the screen.
## v0.13.2 (Dec 2 2023) ## v0.13.2 (Dec 2 2023)
This release brings some new features and optimization for the game's file This release brings some new features and optimization for the game's file

View File

@ -31,7 +31,7 @@ var (
Y: 60, Y: 60,
} }
// Player speeds // Player speeds, gravity and movement physics.
PlayerMaxVelocity float64 = 7 PlayerMaxVelocity float64 = 7
PlayerJumpVelocity float64 = -15 PlayerJumpVelocity float64 = -15
PlayerAcceleration float64 = 0.04 // 0.12 PlayerAcceleration float64 = 0.04 // 0.12
@ -44,6 +44,7 @@ var (
SwimGravity float64 = 3 SwimGravity float64 = 3
SwimJumpVelocity float64 = -12 SwimJumpVelocity float64 = -12
SwimJumpCooldown uint64 = 24 // number of frames of cooldown between swim-jumps SwimJumpCooldown uint64 = 24 // number of frames of cooldown between swim-jumps
CoyoteFrames uint64 = 4 // Coyote time, frames after we walk off a cliff but can still jump late
SlopeMaxHeight = 8 // max pixel height for player to walk up a slope SlopeMaxHeight = 8 // max pixel height for player to walk up a slope
// Number of game ticks to insist the canvas follows the player at the start // Number of game ticks to insist the canvas follows the player at the start

View File

@ -9,7 +9,7 @@ import (
const ( const (
AppName = "Sketchy Maze" AppName = "Sketchy Maze"
Summary = "A drawing-based maze game" Summary = "A drawing-based maze game"
Version = "0.13.2" Version = "0.14.0"
Website = "https://www.sketchymaze.com" Website = "https://www.sketchymaze.com"
Copyright = "2023 Noah Petherbridge" Copyright = "2023 Noah Petherbridge"
Byline = "a game by Noah Petherbridge." Byline = "a game by Noah Petherbridge."

View File

@ -62,7 +62,7 @@ func (s *PlayScene) movePlayer(ev *event.State) {
s.jumpCooldownUntil = shmem.Tick + balance.SwimJumpCooldown s.jumpCooldownUntil = shmem.Tick + balance.SwimJumpCooldown
velocity.Y = balance.SwimJumpVelocity velocity.Y = balance.SwimJumpVelocity
} }
} else if s.Player.Grounded() { } else if s.Player.Grounded() || s.Player.IsCoyoteTime(true) {
velocity.Y = balance.PlayerJumpVelocity velocity.Y = balance.PlayerJumpVelocity
} }
} else { } else {

View File

@ -6,11 +6,13 @@ import (
"sort" "sort"
"sync" "sync"
"git.kirsle.net/SketchyMaze/doodle/pkg/balance"
"git.kirsle.net/SketchyMaze/doodle/pkg/collision" "git.kirsle.net/SketchyMaze/doodle/pkg/collision"
"git.kirsle.net/SketchyMaze/doodle/pkg/doodads" "git.kirsle.net/SketchyMaze/doodle/pkg/doodads"
"git.kirsle.net/SketchyMaze/doodle/pkg/level" "git.kirsle.net/SketchyMaze/doodle/pkg/level"
"git.kirsle.net/SketchyMaze/doodle/pkg/log" "git.kirsle.net/SketchyMaze/doodle/pkg/log"
"git.kirsle.net/SketchyMaze/doodle/pkg/physics" "git.kirsle.net/SketchyMaze/doodle/pkg/physics"
"git.kirsle.net/SketchyMaze/doodle/pkg/shmem"
"git.kirsle.net/go/render" "git.kirsle.net/go/render"
"github.com/dop251/goja" "github.com/dop251/goja"
"github.com/google/uuid" "github.com/google/uuid"
@ -50,6 +52,7 @@ type Actor struct {
position render.Point position render.Point
velocity physics.Vector velocity physics.Vector
grounded bool grounded bool
lostGroundAt uint64 // tick where grounded last became false, for coyote time
// Animation variables. // Animation variables.
animations map[string]*Animation animations map[string]*Animation
@ -205,12 +208,30 @@ func (a *Actor) Grounded() bool {
// SetGrounded sets the actor's grounded value. If true, also sets their Y velocity to zero. // SetGrounded sets the actor's grounded value. If true, also sets their Y velocity to zero.
func (a *Actor) SetGrounded(v bool) { func (a *Actor) SetGrounded(v bool) {
if a.grounded && !v {
a.lostGroundAt = shmem.Tick
}
a.grounded = v a.grounded = v
// if v && a.velocity.Y > 0 { // if v && a.velocity.Y > 0 {
// a.velocity.Y = 0 // a.velocity.Y = 0
// } // }
} }
// IsCoyoteTime returns whether the actor has only just lost ground, so can still
// jump a few frames late.
//
// Pass a true value to unset, or "consume" the coyote time. The next call will
// then return that it is not coyote time, even if the lost ground frame is still
// within the CoyoteFrames threshold.
func (a *Actor) IsCoyoteTime(reset bool) (result bool) {
result = shmem.Tick-a.lostGroundAt <= balance.CoyoteFrames
if reset {
a.lostGroundAt = 0
}
return result
}
// Hide makes the actor invisible. // Hide makes the actor invisible.
func (a *Actor) Hide() { func (a *Actor) Hide() {
a.hidden = true a.hidden = true