PSDK UI System
In PSDK the UI are built inside the UI
module. Most of the UI parts inherit from SpriteStack
and accept a data
input that helps to tell each component what to show.
The different UI objects
SpriteStack
The SpriteStack is a conceptual object that basically store all the atomic UI element inside an Array. This allow to do the following thing :
- Defining the sprites in a subspace where the origin (0, 0) is the coordinate of the stack. This allows you to define the stack only once and display it at different coordinates on the screen (the sprites will be moved accordingly)
- Move all the sprites in the stack to another coordinate
- Feed all the sprites respond to
data=
with an object like a Pokémon, the trainer or anything else. - Update all the sprites inside the stack (if needed)
- Optionally, you can also dispose all the sprites in the stack but it's considered as bad practices.
initialize
Currently, the initialize method takes 3 positional argument and 1 keyword argument :
viewport
: The viewport in which the stack should showx
: X coordinate of the stack origin (optional)y
: Y coordinate of the stack origin (optional)default_cache:
: name of the cache used to the images in the stack (default to:interface
).
add_background
This method allow to show the background of the stack (at the origin coordinate). It takes the following arguments :
filename
: Name of the image to use as background (resolved from the default cache).type:
: Class used to display the background (default to Sprite)rect:
: Rect to use in order to show the background (if you don't want to use the whole surface, optional)
add_sprite
This method allow to show a sprite with various settings. It takes the following arguments :
x
: X coordinate of the sprite in the stacky
: Y coordinate of the sprite in the stackbmp
: Filename of the image to show (can be nil if you don't want to show a image or use specific Sprite)*args
: Arguments that comes afterviewport
in thetype.new
callrect:
: Rect to use in order to show the background (if you don't want to use the whole surface, optional)type:
: Class used to show the sprite (default to Sprite)ox:
: ox of the sprite (default to 0)oy:
: oy of the sprite (default to 0)
add_text
This method allow to add text to the stack, it takes the following arguments :
x
: X coordinate of the text in the Stack Spacey
: Y coordinate of the text in the Stack Spacewidth
: Width used for the text surface (usefull for left align)height
: Height of one line of textstr
: String to show or Symbol of the method to call to retreive the string (SymText)align
: Horizontal alignment of the text in the surface (default to 0)outlinesize
: Size of the outline (defaults to nil => shadow)type:
: Class to use to display the text (defaults to Text)color:
: Color to use to display the text (same as messages)size_id:
: Size to use to display the text (default to nil)
Example of use :
add_text(0, 0, 320, 16, "Pokémon:", color: 10) # Will show Pokemon on the first line in white add_text(0, 16, 320, 16, :name, type: UI::SymText) # Will show the name of the Pokemon
with_cache
This method allows you to define sprites using another cache source than the default. It takes one parameter that is the cache name. Example :
def initialize(viewport) super(viewport, default_cache: :interface) with_cache(:picture) do add_background('GTS') end add_sprite(25, 32, 'something_in_interface') end
with_font
This method is a bit like with_cache
but for the text. It allows you to use another font than 0
for some text. In PSDK the default font (0) has a size of 13px, the alternative font (1) has a size of 26px and the tiny font (20) allows you to show more text for the same horizontal space (used in battle bar for the Pokémon names). Example :
def initialize(viewport) super with_font(1) do add_text(0, 0, 320, 32, "Big Text", 0, 0) end with_font(20) do add_text(0, 32, 320, 10, "Small Text line 1", 0, 1) add_text(0, 42, 320, 10, "Small Text line 2", 0, 1) end add_text(0, 64, 320, 16, "Regular Text") end
set_position
This method is the same as the one for the sprites, it sets the SpriteStack x & y coordinate to the requested one.
Example :
stack = UI::SpriteStack.new(viewport, 5, 5) # ... stack.set_position(10, 20) # stack.x = 10, stack.y = 20
move
This method allows you to move the whole stack relatively to its current position.
Example :
stack = UI::SpriteStack.new(viewport, 10, 20) # ... stack.move(5, 5) # stack.x = 15, stack.y = 25
simple_mouse_in?
This method allows to check if the mouse is inside the first sprite of the stack (usually the background). It helps to make UI that react to mouse.
Example :
stack = UI::SpriteStack.new(viewport) stack.add_background('button') # ... if stack.simple_mouse_in? p "User mouse is inside the button" end
Type1Sprite
This class allows you to show the Type1 of a Pokemon. It takes a boolean parameter (optional) that tells if the type1 is shown from the Pokedex or not (graphics are different).
Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::Type1Sprite) # ... stack.data = $actors[0] # Shows the type 1 of the first Pokémon in the party
Type2Sprite
This class allows you to show the Type2 of a Pokemon. It takes a boolean parameter (optional) that tells if the type1 is shown from the Pokedex or not (graphics are different).
Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, true, type: UI::Type2Sprite) # ... stack.data = $actors[0] # Shows the type 2 (Pokédex type image) of the first Pokémon in the party
nil
here) are sent to the initialize
of the Sprite (UI::Type2Sprite
here). In this case we sent true which says use Pokédex image.
TypeSprite
This class allows you to show the Type of a move or anything responding to type
and returning an integer.
Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::TypeSprite) # ... stack.data = $actors[0].skills_set[0] # Show the type of the first move of the first Pokémon in the party
GenderSprite
Shows the gender of a Pokemon. Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::GenderSprite) # ... stack.data = $actors[0] # Show the gender of the first Pokemon in the party
StatusSprite
Shows the status of a Pokemon. Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::StatusSprite) # ... stack.data = $actors[0] # Show the status of the first Pokemon in the party
HoldSprite
Shows the Pokemon is holding an item image (if it's holding an item). Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::HoldSprite) # ... stack.data = $actors[0] # Show the hold indicator of the first Pokemon in the party
RealHoldSprite
Shows the item Icon a Pokemon is holding. Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::RealHoldSprite) # ... stack.data = $actors[0] # Show the held item of the first Pokemon in the party
CategorySprite
Shows the category of a move (physical, special, status). Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::CategorySprite) # ... stack.data = $actors[0].skills_set[0] # Show the type of the first move of the first Pokémon in the party
PokemonFaceSprite
Shows the front sprite of a Pokemon. This object accept a boolean (that is true by default) that tells if the Sprite should be bottom center aligned. (Which mean the coordinate of the sprite is the coordinate of the Pokémon's feet).
Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::PokemonFaceSprite) # ... stack.data = $actors[0] # Show the face sprite of the first Pokemon in the party
PokemonBackSprite
Shows the back sprite of a Pokemon. This object accept a boolean (that is true by default) that tells if the Sprite should be bottom center aligned. (Which mean the coordinate of the sprite is the coordinate of the Pokémon's feet).
Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::PokemonBackSprite) # ... stack.data = $actors[0] # Show the back sprite of the first Pokemon in the party
PokemonIconSprite
Shows the icon sprite of a Pokemon. This object accept a boolean (that is true by default) that tells if the Sprite should be center aligned.
Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::PokemonIconSprite) # ... stack.data = $actors[0] # Show the icon sprite of the first Pokemon in the party
PokemonFootSprite
Shows the foot print of a Pokemon. Example :
stack = UI::SpriteStack.new(viewport) stack.add_sprite(0, 0, nil, type: UI::PokemonFootSprite) # ... stack.data = $actors[0] # Show the foot print of the first Pokemon in the party
SymText
Show a text using a method of the data
object as text source. Example :
stack = UI::SpriteStack.new(viewport) stack.add_text(0, 0, 320, 16, :given_nale, type: UI::SymText) # ... stack.data = $actors[0] # Show the nickname of the first Pokemon in the party
SymMultilineText
Show a multiline text using a method of the data
object as text source. Example :
stack = UI::SpriteStack.new(viewport) stack.add_text(0, 0, 320, 16, :description, type: UI::SymMultilineText) # ... stack.data = $actors[0].skills_set[0] # Show the description of the first move of the first Pokemon in the party
Important information
In the example we mostly saw only one add of the UI element that can be dynamically changed according to the data sent to the sprite stack. You can add several UI element that change according to the data in the same stack.
If you want deepness like showing the Pokemon Info and it's 4 moves info. You can add sub stack to the stack and modify the data=
method of the Pokemon Info stack in order to send the right information to the child stack. Example :
class PokemonInfo < UI::SpriteStack def initialize(viewport) super # ... @moves = Array.new(4) do |i| PokemonMoveInfo.new(viewport, i) end end def data=(pokemon) super(pokemon) # Update the sprites of the PokemonInfoStack @moves.each_with_index do |move, i| move.data = pokemon&.skills_set&.at(i) end end # Ensure the moves can move the this stack def move(delta_x, delta_y) super @moves.each { |move| move.move(delta_x, delta_y) } end end
data=
and would have received a Pokemon instead of a Move.