-
Notifications
You must be signed in to change notification settings - Fork 817
Add a new map object movement behavior
This tutorial is for how to add a new map object movement behavior.
Map objects are defined by object_event
s in map event scripts, and their assigned SPRITEMOVEDATA_*
constants define their movement behavior. This controls how the objects' sprite appears, how it moves, and how it interacts with the player. For example, objects with SPRITEMOVEDATA_WALK_UP_DOWN
appear as a 16x16 pixel sprite that walks up and down within a certain radius; while objects with SPRITEMOVEDATA_BIGDOLL
appear as a 32x32 pixel sprite that does not move.
(Map objects are not the same as sprites. A sprite is an 8x8 pixel entity, of which you can have 40 on-screen at a time. Map objects are composed of sprites—a 16x16 pixel object consists of four sprites, for instance—but sprites are used throughout the game, not just in the overworld map engine.)
At a minimum, you need to define a new SPRITEMOVEDATA_*
constant and its corresponding data. As an example, we'll define SPRITEMOVEDATA_SWIM_UP_DOWN
.
Edit constants/map_object_constants.asm:
; SpriteMovementData indexes (see data/sprites/map_objects.asm)
const_def
const SPRITEMOVEDATA_00 ; 00
...
const SPRITEMOVEDATA_SWIM_WANDER ; 24
+ const SPRITEMOVEDATA_SWIM_UP_DOWN
NUM_SPRITEMOVEDATA EQU const_value
And edit data/sprites/map_objects.asm:
SpriteMovementData::
; entries correspond to SPRITEMOVEDATA_* constants
; SPRITEMOVEDATA_00
db SPRITEMOVEFN_00 ; movement function
db DOWN ; facing
db OBJECT_ACTION_STAND ; action
db WONT_DELETE ; flags1
db 0 ; flags2
db 0 ; palette flags
...
; SPRITEMOVEDATA_SWIM_WANDER
db SPRITEMOVEFN_RANDOM_WALK_XY ; movement function
db DOWN ; facing
db OBJECT_ACTION_STAND ; action
db 0 ; flags1
db 0 ; flags2
db SWIMMING ; palette flags
-; 25
- db SPRITEMOVEFN_00 ; movement function
- db DOWN ; facing
- db OBJECT_ACTION_STAND ; action
- db 0 ; flags1
- db 0 ; flags2
- db 0 ; palette flags
+; SPRITEMOVEDATA_SWIM_UP_DOWN
+ db SPRITEMOVEFN_RANDOM_WALK_Y ; movement function
+ db DOWN ; facing
+ db OBJECT_ACTION_STAND ; action
+ db 0 ; flags1
+ db 0 ; flags2
+ db SWIMMING ; palette flags
Note that we had to delete some unused data at the bottom which didn't correspond to any SPRITEMOVEDATA_*
constant.
Here's what the individual db
values mean:
-
movement function: A
SPRITEMOVEFN_*
constant, as defined in constants/map_object_constants.asm. -
facing:
UP
,DOWN
,LEFT
, orRIGHT
. -
action: An
OBJECT_ACTION_*
constant, as defined in constants/map_object_constants.asm. -
flags1: A combination of any of these values, or 0 for none of them:
-
WONT_DELETE
: The object won't be deleted if it moves off-screen. Example:SPRITEMOVEDATA_STRENGTH_BOULDER
, which needs to stay where it's been pushed. -
FIXED_FACING
: The object doesn't change its facing direction if it moves. Example:SPRITEMOVEDATA_SHADOW
, which moves along with the player over a ledge but always looks the same. -
SLIDING
: The object doesn't animate its steps if it moves. Example:SPRITEMOVEDATA_GRASS
, which moves along with the player through tall grass but doesn't have a "stepping" animation. -
MOVE_ANYWHERE
: The object isn't limited to moving within a particular radius. Example:SPRITEMOVEDATA_STRENGTH_BOULDER
, which can be pushed anywhere. -
EMOTE_OBJECT
: The object is meant to be transient and gets deleted differently. Example:SPRITEMOVEDATA_EMOTE
, which pops up briefly above an NPC.
-
-
flags2: A combination of any of these values, or 0 for none of them:
-
LOW_PRIORITY
: The object will appear below other objects, which have normal priority by default. Example:SPRITEMOVEDATA_BOULDERDUST
, which appears below Strength boulders when they're pushed. -
HIGH_PRIORITY
: The object will appear above other objects. Do not combine withLOW_PRIORITY
. Example:SPRITEMOVEDATA_GRASS
, which appears above the player when walking through tall grass. -
USE_OBP1
: The object will use SGB palette #1 instead of #0. This was relevant for Gold and Silver since they could be played on the Super Game Boy, but not Crystal.
-
-
palette flags: A combination of any of these values, or 0 for none of them:
-
SWIMMING
: The object can move over water but is blocked by land, instead of vice-versa. Example:SPRITEMOVEDATA_SWIM_WANDER
, which is used for the Lapras in Union Cave. -
STRENGTH_BOULDER
: The object blocks the player if they haven't used Strength. Example:SPRITEMOVEDATA_STRENGTH_BOULDER
of course, but also theSPRITEMOVEDATA_BIGDOLL*
data for some reason. -
BIG_OBJECT
: The object blocks the spaces below it, to its right, and to its bottom-right, not just the space its coordinates are at. Example:SPRITEMOVEDATA_BIGDOLLSYM
, which is used for the Snorlax in Vermilion City.
-
In the example, we based SPRITEMOVEDATA_SWIM_UP_DOWN
off of SPRITEMOVEDATA_SWIM_WANDER
but gave it the same movement function as SPRITEMOVEDATA_WALK_UP_DOWN
. In particular, it needed the SWIMMING
palette flag.
One more thing: there happens to be a bug that affects objects which swim and move randomly; they're not actually limited by their movement radius. So be sure to fix that.
Anyway, that's all! Now you can use SPRITEMOVEDATA_SWIM_UP_DOWN
for object_event
s just like the rest.
TODO: define new SPRITEMOVEFN_*
, OBJECT_ACTION_*
, and FACING_*
data.
TODO: define new STEP_TYPE_*
and STEP_*
data.