I'm brand new to scripting and thought I'd start by trying to display some simple text on screen; specifically your score.
So I added this new script
class Score < Window_Base
def initialize
super(120, 320, 300, 80)
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
self.contents.clear
self.contents.draw_text(120, 0, 75, 75, "Score : ")
end
end
Worked great and it displays the text "Score : " in it's own little window at the bottom.
I have a variable (22) called "Score" which is, obviously, your score.
So my question is... how do I call a variable and appent it to my existing draw_text?
Sorry to ask such a noobish question. I tried searching but, unfortunately, most responses seem to be about using /v[22] to display the variable as part of a default text box... not much use in my script :(
What you will be wanting is $game_variables[n], where 'n' is the variable you are using to hold the number. Don't forget to add '.to_s' to transform the integer into a string!
class Score < Window_Base
def initialize
super(120, 320, 300, 80)
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
self.contents.clear
self.contents.draw_text(120, 0, 75, 75, "Score : " + $game_variables[1].to_s)
end
end
Thanks, I'd actually got it to work, kind of, using this
score = $game_variables[5]
self.contents.clear
self.contents.draw_text(120, 0, 75, 75, "Score : ")
self.contents.draw_text(180, 0, 75, 75, score)
however I'll try yours now as, unfortunately, mine doesn't update.
So it displays the window at all times
Score : 0
You grab some treasure which, as part of the event, runs $window = Score.new
But the display doesn't change. I set up another event where I can check the variable value and it's definitely incrementing...
anyway I'll go try yours and post results.
Thank you VM :)
When I have
self.contents.draw_text(120, 0, 75, 75, "Score : " + $game_variable[22].to_s)
I get the error
Script 'Game_Interpreter' line 1141: NoMethodError occured.
undefined method '[]' for nil:NilClass
but only when I include + $game_variable[22].to_s. If I drop that it displays fine... well, except it's sans variable of course :)
You forgot to pluralize variable; it should be $game_variables[22].to_s, not $game_variable[22].to_s.
In any event, that won't update by itself either. You would need to make an update method that refreshes the window every time the score changes. This would make your script look something like this:
class Score < Window_Base
def initialize
super(120, 320, 300, 80)
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
@last_score = $game_variables[1]
self.contents.clear
self.contents.draw_text(120, 0, 75, 75, "Score : " + @last_score.to_s)
end
def update
super
refresh if @last_score != $game_variables[1]
end
end
Assuming you set the window up as an instance variable in Scene_Map, that should be sufficient since the way Scene_Base is set up, it will automatically call the update method for Window objects that are saved as instance variables. If you haven't, then you would need to manually call that update method every frame.
This code would keep the window open at all times on the map, and update the score, as well.
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# This class performs the map screen processing.
#==============================================================================
class Scene_Map < Scene_Base
#--------------------------------------------------------------------------
# * Start Processing
#--------------------------------------------------------------------------
alias score_start start unless $@
def start
score_start
@score = Score.new
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
alias score_update update unless $@
def update
score_update
@score.update
end
end
#==============================================================================
# ** Score Window
#==============================================================================
class Score < Window_Base
def initialize
super(120, 320, 300, 80)
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
@last_score = $game_variables[1]
self.contents.clear
self.contents.draw_text(120, 0, 75, 75, "Score : " + @last_score.to_s)
end
def update
super
refresh if @last_score != $game_variables[1]
end
end
EDIT : And this addition would allow you to show and hide your score window using switch number one. I am sure there is a snazzier way to do so, but I have been away from scripting for quite some time. At any rate, this should give you some ammunition for thought.
#==============================================================================
# ** Score Window
#==============================================================================
class Score < Window_Base
def initialize
super(120, 320, 300, 80)
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
@last_score = $game_variables[1]
@last_toggle = $game_switches[1]
self.contents.clear
self.contents.draw_text(120, 0, 75, 75, "Score : " + @last_score.to_s)
end
def update
super
refresh if @last_score != $game_variables[1]
case $game_switches[1]
when true
self.visible = true
when false
self.visible = false
end
end
end
Thanks guys. This line
QuoteYou forgot to pluralize variable; it should be $game_variables[22].to_s, not $game_variable[22].to_s.
fixed all my problems. I'd evented a $window.dispose followed by $window = Score.new alongside each line that added or removed from the score.
That said there's "working" and "working better" right? Time to implement some of your other ideas as running an ongoing refresh will be easier in the long run.
Thank you very much for your help. Really, really appreciate it.
Yeah, re-initializing the window everytime the score changes is not a good idea, nor is saving it in a global variable generally.
@Exhydra - you wouldn't need to alias the update method of Scene_Map in VXA, since all instance variables that hold a Window object are automatically updated in the update_all_windows method.
Quote from: modern algebra on October 10, 2012, 10:36:38 AM@Exhydra - you wouldn't need to alias the update method of Scene_Map in VXA, since all instance variables that hold a Window object are automatically updated in the update_all_windows method.
Aah, I see, I see. Interesting! I still much to re-learn after the lengthy break away from RM.
Well, it's good to have you back!
Quote from: modern algebra on October 10, 2012, 10:36:38 AM
Yeah, re-initializing the window everytime the score changes is not a good idea, nor is saving it in a global variable generally.
How come? Not meaning to be difficult, genuinely interested as I would have thought a manual refresh would be a less memory intensive way to manage it (although a lot heavier when eventing)
In my particular case it's for a mini game. I want the score, health, etc. to display on screen when you're on the "mini game" map. When you finish the map, the mini game is over, so I get rid of it. I need it to retain that score though in a manner that events can use. In that instance would you still recommend the above method in favour of a segregated global variable/manual refresh one?
It is a good idea to refresh it only when the score changes - it's not a good idea to recreate the entire window.
Creating a window is not a particularly fast operation, and it is wasteful to recreate the entire window when all you need to do is change the contents of the bitmap. For that reason, the code Exhydra suggested is better, since it only refreshes the contents of the window when the score changes; it doesn't dispose the window and recreate it. That said, it would also be fine to not do it in update and manually refresh in every event where the score could change - but only if it is a refresh, not disposal and recreation. However, a simple equality check is very efficient and the cost of running the eval out of the event only when necessary is probably higher than the equality check every frame. Besides, it's less work.
Secondly, when I say "global variable", I am not referring to the in-game variable; it's fine to save the score in an in-game variable. I was saying that it's not a good idea to save the window itself in a global variable, which it sounds like you were doing with $window. Global variables break encapsulation, since they can be modified anywhere and classes or methods which rely on them can thus begin to act in unexpected ways. They are also hard to debug. Most importantly, it is simply not necessary in this case. You would only ever need to create the window in Scene_Map, and it would be better to include it as in instance variable in Scene_Map, as Exhydra does in his or her code.
As for whether it is less memory-intensive, in your situation, to simply make the window invisible when not in the mini-game or to dispose it altogether, then I would be on-board with only creating the window when the mini-game starts and disposing it when the mini-game ends and setting the instance variable back to nil, particularly if the mini-game only occurs rarely. But I am not on board with disposing and recreating it every time the score changes.
Also, if it had been necessary to use a global variable, I would never recommend giving it a generic name like $window.
Thank you very much for the detailed response. Really appreciate it.