Calling method after 'new game_map'

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
The code below triggers&works perfectly when the player starts out on that map. But when the player is transferred to that map then it doesn't work:

class Scene_Base alias nap_ev_text_post_start post_start def post_start $game_map.events.each{ |ev| ev[1].nap_ev_text_commenttag } # array note: [0] = id, [1] = event nap_ev_text_post_start endend
The code below does nothing at all:

class Scene_Map alias nap_ev_text_post_transfer post_transfer def post_transfer $game_map.events.each{ |ev| ev[1].nap_ev_text_commenttag } # array note: [0] = id, [1] = event nap_ev_text_post_transfer endend
The nap_ev_text_commenttag() is using the following code for retrieving the Character_Sprite that belongs to the given event_id:

class Scene_Map < Scene_Base attr_reader :spritesetendclass Spriteset_Map attr_reader :character_spritesendmodule Nap def self.get_character_sprite(ev_id) return nil if !SceneManager.scene.is_a?(Scene_Map) || !SceneManager.scene.spriteset SceneManager.scene.spriteset.character_sprites.each{|cs| return cs if cs.character.id == ev_id } return nil endend

I don't understand where I have to call this line (from an alias):

$game_map.events.each{ |ev| ev[1].nap_ev_text_commenttag } # array note: [0] = id, [1] = eventGame_Event.setup_page_settings already calls that nap_ev_text_commenttag (which works perfectly when the event-page is switched). But the first time nap_ev_text_commenttag() is called on an event the SpriteSet is not initialized for the new map yet. Resulting in nil values or values from the previous map.

Hope this makes sense.
 

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
try the setup method of Game_Map...
 

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
Doesn't work either. Or is my code faulty? This does not even work even if I start out on that specific map.
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
What does nothing at all? The method doesn't run? When you print stuff out do you see what you expect to see? Is everything set up properly before your method is run?
 

Mithran

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
404
Reaction score
217
First Language
English
Primarily Uses
Spriteset_Map#create_characters possibly? This is called after $game_map has the correct map either after switching scenes or entering Scene_Map and it guarantees the sprites exists because it is the method that creates them. Not the most elegant solution though.


In all honesty, that is a pretty nightmarish way to go about pulling out a single character sprite. It would help if I knew more about what you were trying to accomplish.
 

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
@Tsukihime

The method runs. But nothing happens (nil values are returned so no text is displayed).

@Mithran

I was trying to create text above events. It works by script calls like nap_ev_text(ev_id, text). But I want the note-tags to work properly as well.

This script might be full of 'nightmarish ways' of accomplishing things. But the whole Spriteset and Sprite_Character thing are rather confusing to me. This is the best I could come up with but feel free to criticize so I can learn from it.

Full Script:

#===============================================================================# Configurable section#===============================================================================module NAP_EV_TEXT_CONF COMMENT_TAG = 'evtxt' # Do not use '<' or '>' characters! DEFAULT_FONT_SIZE = 22 DEFAULT_FG_COLOR = Color.new(255, 255, 255) DEFAULT_BG_COLOR = Color.new(0, 0, 0, 0) # Color.new(128,128,128,128) # grayend#===============================================================================# Below is to make this script standalone from Napoleons Core Script#===============================================================================if !$imported || !$imported[:nap_core] || $imported[:nap_core] < 1.05 # Global bitmap just for measuring text size # DO NOT FORGET to change the font size and stuff before measuring! $txt_measure_bmp = Bitmap.new(1,1) class Scene_Map < Scene_Base attr_reader :spriteset end class Spriteset_Map attr_reader :character_sprites end module Nap def self.get_character_sprite(ev_id) return nil if !SceneManager.scene.is_a?(Scene_Map) || !SceneManager.scene.spriteset SceneManager.scene.spriteset.character_sprites.each{|cs| return cs if cs.character.id == ev_id } return nil end endend#===============================================================================# Event Text Script#===============================================================================class Sprite_Character < Sprite_Base attr_accessor :ev_text_sprite attr_accessor :ev_text_font_size alias nap_ev_text_initialize initialize def initialize(*args) nap_ev_text_initialize(*args) @ev_text_font_size = NAP_EV_TEXT_CONF::DEFAULT_FONT_SIZE end def nap_ev_set_text(text) # If there already is a text in place then it will be overwritten. @ev_text_sprite.dispose if @ev_text_sprite # Do not create a (new) sprite if the text is nil (means that we want to erase it) if text.nil? @ev_text_sprite = nil return end # Create sprite @ev_text_sprite = Sprite.new # Measure text size $txt_measure_bmp.font.size = @ev_text_font_size txt_size = $txt_measure_bmp.text_size(text) # Create & render on bitmap @ev_text_sprite.bitmap = Bitmap.new(txt_size.width, txt_size.height) @ev_text_sprite.bitmap.font.size = @ev_text_font_size @ev_text_sprite.bitmap.fill_rect(0, 0, @ev_text_sprite.bitmap.width, @ev_text_sprite.bitmap.height, NAP_EV_TEXT_CONF::DEFAULT_BG_COLOR) @ev_text_sprite.bitmap.font.color = NAP_EV_TEXT_CONF::DEFAULT_FG_COLOR @ev_text_sprite.bitmap.draw_text(0, 0, @ev_text_sprite.bitmap.width, @ev_text_sprite.bitmap.height, text, 1) end alias nap_ev_text_update update def update nap_ev_text_update return if !@ev_text_sprite nap_ev_text_render_above_head end def nap_ev_text_render_above_head @ev_text_sprite.x = x - @ev_text_sprite.width / 2 @ev_text_sprite.y = y - height - @ev_text_sprite.height @ev_text_sprite.z = z + 1 end #~ def nap_ev_text_render_topleft#~ @ev_text_sprite.x = x - width / 2#~ @ev_text_sprite.y = y - height#~ @ev_text_sprite.z = z + 1#~ endendclass Game_Event < Game_Character alias nap_ev_text_setup_page_settings setup_page_settings def setup_page_settings nap_ev_text_setup_page_settings nap_ev_text_commenttag end def nap_ev_text_commenttag for command in self.list if command.code == 108 if command.parameters[0] =~ /<#{NAP_EV_TEXT_CONF::COMMENT_TAG}.*?)>/ix sprite_character = Nap.get_character_sprite(self.id) sprite_character.nap_ev_set_text($1) if sprite_character end end end end alias nap_ev_text_erase erase def erase @ev_text_sprite.dispose if @ev_text_sprite nap_ev_text_erase endend#===============================================================================# Game Interpreter# For: Adding commands#===============================================================================class Game_Interpreter def nap_ev_text(ev_id, text) return if !SceneManager.scene.is_a?(Scene_Map) || !SceneManager.scene.spriteset SceneManager.scene.spriteset.character_sprites.find{|e| e.character.id == ev_id}.nap_ev_set_text(text) end def nap_ev_erase_text(ev_id) return if !SceneManager.scene.is_a?(Scene_Map) || !SceneManager.scene.spriteset SceneManager.scene.spriteset.character_sprites.find{|e| e.character.id == ev_id}.nap_ev_set_text(nil) endend#===============================================================================# Scene Base# For: Showing the texts when the map starts. The initial setup_page_settings# is called before the map-scene is activated (like if the player came from# the title-scene or another map) and therefor could have the wrong or none# Spriteset set.#===============================================================================#~ class Scene_Base#~ alias nap_ev_text_post_start post_start#~ def post_start#~ $game_map.events.each{ |ev| ev[1].nap_ev_text_commenttag } # array note: [0] = id, [1] = event #~ nap_ev_text_post_start#~ end#~ end#~ class Scene_Map#~ alias nap_ev_text_post_transfer post_transfer#~ def post_transfer#~ $game_map.events.each{ |ev| ev[1].nap_ev_text_commenttag } # array note: [0] = id, [1] = event #~ nap_ev_text_post_transfer#~ end#~ endclass Game_Map alias nap_ev_text_setup setup def setup(map_id) nap_ev_text_setup(map_id) $game_map.events.each{ |ev| ev[1].nap_ev_text_commenttag } # array note: [0] = id, [1] = event endend
Example comment-tag in event:

Code:
<evtxt: Saving & Loading>
 
Last edited by a moderator:

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
maybe try printing from inside the spriteset loop?

Code:
module Nap  def self.get_character_sprite(ev_id)    p "get"    return nil if !SceneManager.scene.is_a?(Scene_Map) || !SceneManager.scene.spriteset    p "proceed to loop"    SceneManager.scene.spriteset.character_sprites.each{|cs| p cs.character.id ; return cs if cs.character.id == ev_id }    p "will return nil"    return nil  endend
 
Last edited by a moderator:

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
It only prints out:

getgetThat's it. Note that there is one event with the comment-tag in my test.

That is, if I use:

try the setup method of Game_Map...
 
Last edited by a moderator:

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
then it means it doesn't get past this line


return nil if !SceneManager.scene.is_a?(Scene_Map) || !SceneManager.scene.spriteset


so most probably, spriteset is really isn't yet created, since I think you're probably sure that you are in Scene_Map... in which case, I guess you should go with Mithran's suggestion of doing it in create_characters method...
 

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
Also, prints out 2x "get" and does nothing.

So I probably have a bug in my code then I suppose.

module Nap def self.get_character_sprite(ev_id) p "get" p "is map: #{SceneManager.scene.is_a?(Scene_Map)}" begin p "spriteset set: #{!SceneManager.scene.spriteset.nil?}" rescue p "spriteset set: NO!" end return nil if !SceneManager.scene.is_a?(Scene_Map) || !SceneManager.scene.spriteset p "proceed to loop" SceneManager.scene.spriteset.character_sprites.each{|cs| p cs.character.id ; return cs if cs.character.id == ev_id } p "will return nil" return nil end end
Code:
class Spriteset_Map alias nap_ev_text_create_characters create_characters def create_characters   nap_ev_text_create_characters   $game_map.events.each{ |ev| ev[1].nap_ev_text_commenttag } # array note: [0] = id, [1] = event endend
output:

"get""is map: true""spriteset set: false" # <<<<<<<<<<<<<<<<<<<Spriteset still nil...
 
Last edited by a moderator:

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
trying p SceneManager.scene before those lines... if it does print Scene_Map, then your spriteset check is faulty...
 

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
Output:

#<Scene_Map:0x81587ec @viewport=#<Viewport:0x8157f18>>So my spriteset check is faulty? If I remove either check then it will crash when starting on the title-screen instead and such.

So how do I properly check if the current map is a Game_Map then (as well as checking if the spriteset is set)?
 
Last edited by a moderator:

Mithran

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
404
Reaction score
217
First Language
English
Primarily Uses
Well, the relationship between Sprite_ and Game_ object is generally that the sprite is an observer of the game object and updates as necessary. The way you have your script currently structured, you are trying to 'force' the sprite to do something. Since the everything the sprite does is after the associated game object has already done it, you are running into some problems. Instead, you need to make the data available in the Game object and have the Sprite know what to do with it at its own pace (eg., next time it updates, rather than right now.

You can keep up the current model, it is still possible like that, you will just run into a lot more difficulties.

As for your get sprite check thingy, I just posted about this in another thread, so I guess I'll post it here too:

Code:
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      endend
All that is is a class variable hash that points the character object back to its Sprite without actually storing the data in the character. Using that you only need to get the event, then you can check the event.sprite directly.
 

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
Wow that works fantastic!

I have to add this line though:

return if self.list.nil?Because the 'list of commands' in the event can be nil when the map is loaded. But it works right away and a lot cleaner as well.

Hope you don't mind if I add that to my core script instead :) . So handy.
 

Mithran

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
404
Reaction score
217
First Language
English
Primarily Uses
No problem. If you are going ahead with the structure you have now, you should also know that you are trying to dispose @ev_text_sprite in Game_Event when it only exists in Sprite_Character.
 

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
I already fixed that dispose. As soon as I used your code I noticed that the event sprites were not disposed when changing maps. So I moved it already.

Yeah I should put everything in Character Sprite and just have it check a flag on it's update or something alike. But the setup_page_settings() method for example is always called from the Event. So I always need a reference to the Sprite Character anyway.

The new version below works too. I tried to keep the Sprite Character more in the 'observer state'. But it just feels worse than the previous version.

$imported ||= {}$imported[:nap_ev_text] = 1.00#===============================================================================# Configurable section#===============================================================================module NAP_EV_TEXT_CONF COMMENT_TAG = 'evtxt' # Do not use '<' or '>' characters! DEFAULT_FONT_SIZE = 22 DEFAULT_FG_COLOR = Color.new(255, 255, 255) DEFAULT_BG_COLOR = Color.new(0, 0, 0, 0) # Color.new(128,128,128,128) # grayend#===============================================================================# Below is to make this script standalone from Napoleons Core Script#===============================================================================if !$imported[:nap_core] || $imported[:nap_core] < 1.05 # Global bitmap just for measuring text size # DO NOT FORGET to change the font size and stuff before measuring! $txt_measure_bmp = Bitmap.new(1,1) class Game_CharacterBase @@sprites = {} def sprite @@sprites[self] end def register_sprite(s) @@sprites[self] = s end def detach_sprite @@sprites.delete(self) end end class 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 end end # class Sprite_Character end # if !$imported#===============================================================================# Event Text Script# class Sprite Character#===============================================================================class Sprite_Character < Sprite_Base attr_accessor :ev_text_sprite attr_accessor :ev_text_font_size attr_accessor :ev_text_flag_text attr_accessor :ev_text_flag_remove alias nap_ev_text_initialize initialize def initialize(*args) nap_ev_text_initialize(*args) @ev_text_font_size = NAP_EV_TEXT_CONF::DEFAULT_FONT_SIZE @ev_text_flag_text = nil @ev_text_flag_remove = false end def nap_ev_set_text(text) # If there already is a text in place then it will be overwritten. @ev_text_sprite.dispose if @ev_text_sprite # Do not create a (new) sprite if the text is nil (means that we want to erase it) if text.nil? @ev_text_sprite = nil return end # Create sprite @ev_text_sprite = Sprite.new # Measure text size $txt_measure_bmp.font.size = @ev_text_font_size txt_size = $txt_measure_bmp.text_size(text) # Create & render on bitmap @ev_text_sprite.bitmap = Bitmap.new(txt_size.width, txt_size.height) @ev_text_sprite.bitmap.font.size = @ev_text_font_size @ev_text_sprite.bitmap.fill_rect(0, 0, @ev_text_sprite.bitmap.width, @ev_text_sprite.bitmap.height, NAP_EV_TEXT_CONF::DEFAULT_BG_COLOR) @ev_text_sprite.bitmap.font.color = NAP_EV_TEXT_CONF::DEFAULT_FG_COLOR @ev_text_sprite.bitmap.draw_text(0, 0, @ev_text_sprite.bitmap.width, @ev_text_sprite.bitmap.height, text, 1) @ev_text_need_refresh = false end alias nap_ev_text_update update def update nap_ev_text_update nap_ev_set_text(@ev_text_flag_text) if @ev_text_flag_text nap_ev_set_text(nil) if @ev_text_flag_remove nap_ev_text_update_location if @ev_text_sprite end def nap_ev_text_update_location @ev_text_sprite.x = x - @ev_text_sprite.width / 2 @ev_text_sprite.y = y - height - @ev_text_sprite.height @ev_text_sprite.z = z + 1 end alias nap_ev_text_dispose dispose def dispose @ev_text_sprite.dispose if @ev_text_sprite nap_ev_text_dispose endend#===============================================================================# class Game Event#===============================================================================class Game_Event < Game_Character alias nap_ev_text_setup_page_settings setup_page_settings def setup_page_settings nap_ev_text_setup_page_settings nap_ev_text_commenttag end def nap_ev_text_commenttag return if self.list.nil? for command in self.list if command.code == 108 if command.parameters[0] =~ /<#{NAP_EV_TEXT_CONF::COMMENT_TAG}.*?)>/ix sprite_character = self.sprite sprite_character.ev_text_flag_text = $1 if sprite_character end end end end # nap_ev_text_commenttag end # class Game_Event < Game_Character#===============================================================================# Game Interpreter# For: Adding commands#===============================================================================class Game_Interpreter  def nap_ev_text(ev_id, text)    return if !SceneManager.scene.is_a?(Scene_Map) || !SceneManager.scene.spriteset    $game_map.events[ev_id].sprite.nap_ev_set_text(text)  end   def nap_ev_erase_text(ev_id)    return if !SceneManager.scene.is_a?(Scene_Map) || !SceneManager.scene.spriteset    $game_map.events[ev_id].sprite.nap_ev_set_text(nil)  endend#===============================================================================# Class Spriteset Map# For: Showing the texts when the map starts. The initial setup_page_settings# is called before the map-scene is activated (like if the player came from# the title-scene or another map) and therefor could have the wrong or none# Spriteset set.#===============================================================================class Spriteset_Map alias nap_ev_text_create_characters create_characters def create_characters nap_ev_text_create_characters $game_map.events.each{ |ev| ev[1].nap_ev_text_commenttag } # array note: [0] = id, [1] = event endend
I suppose that character_sprites are only updated when they are within a certain range from the Player. I hope I'm not adding 2 more if-checks to something that is always updated every update because on a large map with 300 events that would be 600*60 extra if-checks per second on 60 fps. I tested it by adding an event far away from the player and then a print in the Sprite Characters update() but sadly it did print every cycle..
 
Last edited by a moderator:

Mithran

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
404
Reaction score
217
First Language
English
Primarily Uses
Yeah, it was just a suggestion to keep it in line with the way the rest of the stuff works. It looks like you don't even need that update in this case - you have already handled the three ways that text can change with your other code (right after a new map has been loaded, after the event has switched pages, and through direct assignment). You shouldn't need to do both; either the sprite should check the event's status every time it updates and get the necessary data there, or the event should notify the sprite that it needs to change whenever a change is made.


If you are concerned about the two 'if' checks though, you should know that the overhead for keeping extra sprites in memory and updating their position every frame is much higher.


Anyway, I approved the full script here:


http://forums.rpgmakerweb.com/index.php?/topic/21787-event-text/
 

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
97
First Language
Dutch
Primarily Uses
Yeah I chose my first approach in the end. But I agree, it's not in line with the rest of the stuff from Character Sprite.

True, it will have some performance impact on big maps with lots and lots of events that all make use of this script. But I believe that only a handful of events per map will use it though and not hundreds.
 

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

Latest Threads

Latest Posts

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,864
Messages
1,017,056
Members
137,573
Latest member
nikisknight
Top