"Look At Me" for Doodad Scripts
* New script API method: Self.CameraFollowMe() to draw camera focus toward your doodad (it sets the Canvas.FollowActor target.) * The camera will go back to following the player on any action inputs (arrow keys, jump, use, etc.); if the player is constantly on the move the camera stays on him even if another actor is trying to take the focus. * The first few ticks of Play Mode the player character is always followed, to allow for Anvils to settle into place without taking the focus. * Canvas FollowActor: if the actor is 4 times the max scroll speed away, allow scrolling in greater leaps of 4 times the max scroll speed. New and Changed Doodads * Anvils will take the camera focus while they are falling. * New doodad: "Look At Me" - a 'camera region' technical doodad. Link it to any power source such as a Button - when this doodad receives power it will take the camera focus for a few frames. Use it to highlight a door that opened far off screen by linking the Button to both an Electric Door and a "Look At Me" near the door.
This commit is contained in:
parent
653184b8f8
commit
7d15651ff6
|
@ -46,6 +46,11 @@ var (
|
||||||
SwimJumpCooldown uint64 = 24 // number of frames of cooldown between swim-jumps
|
SwimJumpCooldown uint64 = 24 // number of frames of cooldown between swim-jumps
|
||||||
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
|
||||||
|
// of a level - to overcome Anvils settling into their starting positions so
|
||||||
|
// they don't steal the camera focus straight away.
|
||||||
|
FollowPlayerFirstTicks uint64 = 60
|
||||||
|
|
||||||
// Default chunk size for canvases.
|
// Default chunk size for canvases.
|
||||||
ChunkSize = 128
|
ChunkSize = 128
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ type PlayScene struct {
|
||||||
godModeUntil time.Time // Invulnerability timer at respawn.
|
godModeUntil time.Time // Invulnerability timer at respawn.
|
||||||
playerJumpCounter int // limit jump length
|
playerJumpCounter int // limit jump length
|
||||||
jumpCooldownUntil uint64 // future game tick for jump cooldown (swimming esp.)
|
jumpCooldownUntil uint64 // future game tick for jump cooldown (swimming esp.)
|
||||||
|
mustFollowPlayerUntil uint64 // first frames where anvils don't take focus from player
|
||||||
|
|
||||||
// Inventory HUD. Impl. in play_inventory.go
|
// Inventory HUD. Impl. in play_inventory.go
|
||||||
invenFrame *ui.Frame
|
invenFrame *ui.Frame
|
||||||
|
|
|
@ -115,5 +115,18 @@ func (s *PlayScene) movePlayer(ev *event.State) {
|
||||||
// If the "Use" key is pressed, set an actor flag on the player.
|
// If the "Use" key is pressed, set an actor flag on the player.
|
||||||
s.Player.SetUsing(keybind.Use(ev))
|
s.Player.SetUsing(keybind.Use(ev))
|
||||||
|
|
||||||
|
// Camera behaviors: Anvils can take the camera's focus while they're falling
|
||||||
|
// but player inputs will take control back to the player. Most anvils will fall
|
||||||
|
// a couple pixels upon level load - prevent them taking the camera's focus for
|
||||||
|
// the first few frames of gameplay.
|
||||||
|
if s.mustFollowPlayerUntil == 0 {
|
||||||
|
s.mustFollowPlayerUntil = shmem.Tick + balance.FollowPlayerFirstTicks
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we insist that the canvas follow the player doodad.
|
||||||
|
if shmem.Tick < s.mustFollowPlayerUntil || keybind.Up(ev) || keybind.Left(ev) || keybind.Right(ev) || keybind.Use(ev) {
|
||||||
|
s.drawing.FollowActor = s.Player.ID()
|
||||||
|
}
|
||||||
|
|
||||||
s.scripting.To(s.Player.ID()).Events.RunKeypress(keybind.FromEvent(ev))
|
s.scripting.To(s.Player.ID()).Events.RunKeypress(keybind.FromEvent(ev))
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,7 +413,9 @@ func (a *Actor) ShowLayerNamed(name string) error {
|
||||||
a.Actor.Filename,
|
a.Actor.Filename,
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
return fmt.Errorf("the layer named %s was not found", name)
|
|
||||||
|
// XX: returning an error raises a JavaScript exception in doodads. :/ Warning log is enough.
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy deletes the actor from the running level.
|
// Destroy deletes the actor from the running level.
|
||||||
|
|
|
@ -246,6 +246,18 @@ func (w *Canvas) loopFollowActor(ev *event.State) error {
|
||||||
scrollBy.Y = delta
|
scrollBy.Y = delta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are VERY FAR away, allow greater leaps.
|
||||||
|
if scrollBy.X > balance.FollowActorMaxScrollSpeed*4 {
|
||||||
|
scrollBy.X = balance.FollowActorMaxScrollSpeed * 4
|
||||||
|
} else if scrollBy.X < -balance.FollowActorMaxScrollSpeed*4 {
|
||||||
|
scrollBy.X = -balance.FollowActorMaxScrollSpeed * 4
|
||||||
|
}
|
||||||
|
if scrollBy.Y > balance.FollowActorMaxScrollSpeed*4 {
|
||||||
|
scrollBy.Y = balance.FollowActorMaxScrollSpeed * 4
|
||||||
|
} else if scrollBy.Y < -balance.FollowActorMaxScrollSpeed*4 {
|
||||||
|
scrollBy.Y = -balance.FollowActorMaxScrollSpeed * 4
|
||||||
|
}
|
||||||
|
|
||||||
// Constrain the maximum scroll speed.
|
// Constrain the maximum scroll speed.
|
||||||
if scrollBy.X > balance.FollowActorMaxScrollSpeed {
|
if scrollBy.X > balance.FollowActorMaxScrollSpeed {
|
||||||
scrollBy.X = balance.FollowActorMaxScrollSpeed
|
scrollBy.X = balance.FollowActorMaxScrollSpeed
|
||||||
|
|
|
@ -132,5 +132,11 @@ func (w *Canvas) MakeSelfAPI(actor *Actor) map[string]interface{} {
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Attract the camera's attention.
|
||||||
|
"CameraFollowMe": func() {
|
||||||
|
// Update the doodad that the camera should focus on.
|
||||||
|
w.FollowActor = actor.ID()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user