-
Notifications
You must be signed in to change notification settings - Fork 995
Add a new map sprite
This tutorial will teach you how to add a new sprite for use indoors or in the overworld.
- Determining which kind of sprite will be needed
- Define a new constant
- Design and include the GFX files
- Defining properties
- Define which maps will use each sprite
Sprites can either face the player or be completely still. Depending on the purpose of the sprite you're adding, there is a small difference in how they're handled.
Most of the sprites in the game are regular ones, which can face any direction. Still sprites, on the other hand, won't face it's direction even if the player interacts with it. Some examples of still sprites are the overworld Pokéballs and the asleep Gambler in Viridian City.
For this tutorial, I'll add a regular sprite (Brock from GSC) and a still sprite (a 1-frame, edited GSC Equine icon as a sprite).
Edit constants/sprite_constants.asm.
For regular sprites:
; overworld sprites
; SpriteSheetPointerTable indexes (see data/sprites/sprites.asm)
const_def
const SPRITE_NONE ; $00
const SPRITE_RED ; $01
...
const SPRITE_SEEL ; $3c
+ const SPRITE_BROCK
For still sprites:
FIRST_STILL_SPRITE EQU const_value
const SPRITE_POKE_BALL ; $3d
const SPRITE_FOSSIL ; $3e
...
const SPRITE_GAMBLER_ASLEEP ; $48
+ const SPRITE_EQUINE
Edit gfx/sprites.asm.
Regular sprites can either be 16x48 if they don't need to move, or 16x96 if they need to move. Still sprites are 16x16.
SECTION "NPC Sprites 1", ROMX
ScientistSprite:: INCBIN "gfx/sprites/scientist.2bpp"
...
LoreleiSprite:: INCBIN "gfx/sprites/lorelei.2bpp"
SeelSprite:: INCBIN "gfx/sprites/seel.2bpp"
+
+SECTION "NPC Sprites 3", ROMX
+
+BrockSprite:: INCBIN "gfx/sprites/brock.2bpp"
+EquineSprite:: INCBIN "gfx/sprites/equine.2bpp"
Edit data/sprites/sprites.asm. Here you'll define how many tiles each graphics, defined in the prior session, will need.
SpriteSheetPointerTable:
table_width 4, SpriteSheetPointerTable
; graphics, tile count
overworld_sprite RedSprite, 12 ; SPRITE_RED
...
overworld_sprite SeelSprite, 12 ; SPRITE_SEEL
+ overworld_sprite BrockSprite, 12
...
overworld_sprite GamblerAsleepSprite, 4 ; SPRITE_GAMBLER_ASLEEP
+ overworld_sprite EquineSprite, 4
Edit the corresponding file in data/maps/objects. I changed SPRITE_SUPER_NERD
to SPRITE_BROCK
in data/maps/objects/PewterGym.asm so Brock's sprite would show up.
PewterGym_Object:
db $3 ; border block
def_warps
...
def_objects
- object SPRITE_SUPER_NERD, 4, 1, STAY, DOWN, 1, OPP_BROCK, 1
+ object SPRITE_BROCK, 4, 1, STAY, DOWN, 1, OPP_BROCK, 1
object SPRITE_COOLTRAINER_M, 3, 6, STAY, RIGHT, 2, OPP_JR_TRAINER_M, 1
object SPRITE_GYM_GUIDE, 7, 10, STAY, DOWN, 3 ; person
def_warps_to PEWTER_GYM
I decided to change the asleep Gambler sprite in data/maps/objects/ViridianCity.asm with the Equine sprite.
ViridianCity_Object:
db $f ; border block
def_warps
warp 23, 25, 0, VIRIDIAN_POKECENTER
...
object SPRITE_GIRL, 17, 9, STAY, RIGHT, 4 ; person
- object SPRITE_GAMBLER_ASLEEP, 18, 9, STAY, NONE, 5 ; person
+ object SPRITE_EQUINE, 18, 9, STAY, NONE, 5 ; person
object SPRITE_FISHER, 6, 23, STAY, DOWN, 6 ; person
object SPRITE_GAMBLER, 17, 5, WALK, LEFT_RIGHT, 7 ; person
def_warps_to VIRIDIAN_CITY
Since it's used in the overworld, data/maps/sprite_sets.asm needs to be edited as well.
MapSpriteSets:
table_width 1, MapSpriteSets
db $01 ; PALLET_TOWN
db $01 ; VIRIDIAN_CITY
...
; sprite set $01
table_width 1
db SPRITE_BLUE
db SPRITE_YOUNGSTER
db SPRITE_GIRL
db SPRITE_FISHER
db SPRITE_COOLTRAINER_M
db SPRITE_GAMBLER
db SPRITE_SEEL
db SPRITE_OAK
db SPRITE_SWIMMER
db SPRITE_POKE_BALL
- db SPRITE_GAMBLER_ASLEEP
+ db SPRITE_EQUINE
assert_table_length SPRITE_SET_LENGTH