How to manage character sprites in the scene

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
Let's say you create a new event during the game and want to add it to the map.


You have to do the following


1. Create your event


2. Add it to @events hash in $game_map


3. Create a Sprite_Character for your new event and add it to the scene's @spriteset


Which is pretty easy.


Now let's say you wanted to remove an event. The steps are similar


1. Delete the event from @events hash in $game_map


2. Delete the appropriate sprite from the array of character sprites in the scene's @spriteset


However, there is no convenient way to do this. One way is to do a linear search through the sprites to determine which one is the one you want to delete.


What is a good way to do this?
 
Last edited by a moderator:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
The sprite already has a link to the event, vehicle or follower it's attached to.


Maybe just do a check in the Sprite_Character's update method to see if the event still exists, and if it doesn't dispose of the sprite?
 

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
@character I believe is the link from Sprite_Character back to game_character/event.

But afaik there is no build-in way to get the sprite belonging to a specific event without altering the build-in code somehow. At least, I haven't found one yet.
 
Last edited by a moderator:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
No, you're right. It wouldn't be difficult to add an attr_accessor in Game_CharacterBase for @sprite, then in Sprite_Character pop a link to the sprite in there when you initialize it. I don't know if it would really be better or worse than my previous suggestion though. I've done a few scripts where I've wanted to get the width/height of a character, and have had to copy the sprite's code to calculate the size into Game_CharacterBase. Having a link to the sprite would have made that process a bit easier.
 

Mithran

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
404
Reaction score
217
First Language
English
Primarily Uses
Character Sprites already need to be iterated to be updated. Why not just throw a flag on the Game_Event object whose sprite you are going to remove and have it remove the sprite on the next iteration?

class Spriteset_Map def update_characters refresh_characters if @map_id != $game_map.map_id @character_sprites.each {|sprite| if sprite.to_be_removed sprite.dispose @character_sprites.delete(sprite) else sprite.update end } end endclass Sprite_Character def to_be_removed @character ? @character.delete_sprite : false end endclass Game_CharacterBase attr_accessor :delete_spriteendThen you could set the flag right before you remove the event from @events in Game_Map. Since the event is set for destruction anyway, you are removing its last reference when you remove the sprite (which has a reference back, via @character), you take care of that problem as well.Or, if you don't feel like modifying any of the underlying structure at all, you could simply maintain another reference list that points back to the sprite. Just register your sprite in the a when you create it, then you'll have a direct reference for when you remove it. Use a class variable here because you do not want any of the sprite data in your savegame. Use a hash with the actual character object as the key since @character_sprites are not limited to just events (hash lookups are generally pretty fast, but using an entire character object as a key may slow it a bit, so adjust this as necessary). You could have just created a global hash that simply pairs without the access method, but I liked this way better:

class Game_CharacterBase @@sprites = {} def sprite @@sprites[self] end def register_sprite(s) @@sprites[self] = s end def detach_sprite @@sprites.delete(self) endendclass Sprite_Character alias init_mith_charref initialize def initialize(*args) init_mith_charref(*args) @character.register_sprite(self) if @character end alias character_set_mith_charref character= def character=(char) @character.detach_sprite if @character character_set_mith_charref(char) @character.register_sprite(self) if @character endendThe problem there is that since you would (presumably) be using a Game_Map method to manage the removal of events, you would need to punch through a few layers of encapsulation (SceneManager > Scene > Spriteset) to be able to actually access the character_sprites array, which is a bit ugly. At that point I would probably have a public instance 'to be destroyed' array in Game_Map where I would move the events removed from @events, then remove the associated sprites when updating Spriteset_Map, detach the sprite from the event, and clear the array to remove the last reference.It would be less overhead in the long run, I suppose. It sounded cleaner in my head, anyway, than re-iterating through it if you have already iterated through it.

EDIT (just before posting)

@Shaz: To your original post, you can't just dispose the sprite from within the Sprite object, because you need to also remove it from the array in Spriteset_Map. You can punch through all the encapsulation, but it is really quite ugly.

To your last post, you shouldn't keep an instance variable for @sprite in Game_CharacterBase, because they are associated with savegames and sprites cannot be dump'd (you could define one for them, but you don't need or want them to)
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
What would be some reasons to store characters in the save file?


I've never needed to dump a character out and reloaded it, since most of the data can be retrieved from external sources.


I usually don't store any sort of data with a Game_CharacterBase object.
 

Mithran

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
404
Reaction score
217
First Language
English
Primarily Uses
Game_Events are subclassed from Game_CharacterBase. Events are stored in $game_map, which is dumped on save. If there were any associated sprites at that time and they were local variables, you'd have a problem. Of course, they should be gone at that point (you'd be in a different Scene), but some scripts perform a save right from the map, so it is something to consider.
 
Last edited by a moderator:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
@Shaz: To your original post, you can't just dispose the sprite from within the Sprite object, because you need to also remove it from the array in Spriteset_Map. You can punch through all the encapsulation, but it is really quite ugly.


To your last post, you shouldn't keep an instance variable for @sprite in Game_CharacterBase, because they are associated with savegames and sprites cannot be dump'd (you could define one for them, but you don't need or want them to)
I knew there'd be a voice of reason somewhere to show me the folly of my ways :D I suspected there would be reasons why it would not be a good idea. That one probably wouldn't have occurred to me, even if I'd had the time to think through them more carefully.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

How many parameters is 'too many'??
Yay, now back in action Happy Christmas time, coming back!






Back in action to develop the indie game that has been long overdue... Final Fallacy. A game that keeps on giving! The development never ends as the developer thinks to be the smart cookie by coming back and beginning by saying... "Oh bother, this indie game has been long overdue..." How could one resist such? No-one c
So I was playing with filters and this looked interesting...

Versus the normal look...

Kind of gives a very different feel. :LZSexcite:
To whom ever person or persons who re-did the DS/DS+ asset packs for MV (as in, they are all 48x48, and not just x2 the pixel scale) .... THANK-YOU!!!!!!!!! XwwwwX

Forum statistics

Threads
105,849
Messages
1,016,975
Members
137,563
Latest member
cexojow
Top