Fixing bug with window prompts and adding credits message box

The game would try to catch up in frames when a window prompt was
opened, so if the window was open for 140 frames the game would process
the next 140 frames instantly after the game was closed.  To fix this, I
have the window prompt time how long it's opened and then I tell the
game to sleep for however many frames it was opened for.

Credits message works but does not yet have all the desired features,
will finish up later.
This commit is contained in:
Michael Shirt 2016-10-29 18:44:06 -06:00
parent d43e176b4c
commit 1cba1adf66
6 changed files with 277 additions and 5 deletions

235
scripts/Credits_Message.rb Normal file
View File

@ -0,0 +1,235 @@
# Displays doc message boxes
class Credits_Message
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
@timer = 0
@viewport = Viewport.new(0, 0, 640, 480)
@sprite_bg = Sprite.new(@viewport)
@sprite_bg.bitmap = Bitmap.new(640, 480)
if $game_switches[104]
@sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(0, 0, 0, 255))
else
@sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(255, 255, 255, 255))
end
@sprite_text = Sprite.new(@viewport)
@contents = Bitmap.new(320, 240)
@contents.font.size = 16
@sprite_text.bitmap = @contents
@sprite_bg.z = 0
@sprite_text.z = 1
@sprite_text.zoom_x = @sprite_text.zoom_y = 2
@viewport.z = 9999
@viewport.visible = false
@sprite_bg.opacity = 0
@sprite_text.opacity = 0
# Animation flags
@fade_in = false
@fade_out = false
end
#--------------------------------------------------------------------------
# * Dispose
#--------------------------------------------------------------------------
def dispose
terminate_message
$game_temp.message_window_showing = false
@contents.dispose
#@sprite_bg.dispose
@sprite_text.dispose
@viewport.dispose
end
#--------------------------------------------------------------------------
# * Terminate Message
#--------------------------------------------------------------------------
def terminate_message
# Call message callback
if !@skip_message_proc && $game_temp.message_proc != nil
$game_temp.message_proc.call
$game_temp.message_proc = nil
end
$game_temp.message_credits_text = nil
end
#--------------------------------------------------------------------------
# * Refresh: Load new message text and pre-process it
#--------------------------------------------------------------------------
def refresh
if $game_switches[104]
@sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(0, 0, 0, 255))
else
@sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(255, 255, 255, 255))
end
# Initialize
@timer = 0
text = ''
y = -1
widths = []
# Pre-process text
text_raw = $game_temp.message_credits_text.to_str
# Substitute variables, actors, player name, newlines, etc
text_raw.gsub!(/\\v\[([0-9]+)\]/) do
$game_variables[$1.to_i]
end
text_raw.gsub!(/\\n\[([0-9]+)\]/) do
$game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
end
text_raw.gsub!("\\p", $game_oneshot.player_name)
text_raw.gsub!("\\n", "\n")
# Handle text-rendering escape sequences
text_raw.gsub!(/\\c\[([0-9]+)\]/, "\000[\\1]")
# Finally convert the backslash back
text_raw.gsub!("\\\\", "\\")
@contents.font.size = 16
# Now split text into lines by measuring text metrics
x = y = 0
maxwidth = @contents.width - 8
spacesize = @contents.text_size(' ')
for i in text_raw.split(/ /)
# Split each word around newlines
newline = false
for j in i.split("\n")
# Handle newline
if newline
text << "\n"
widths << x
x = 0
y += 1
@contents.font.size = 24
else
newline = true
end
# Get width of this word and see if it goes out of bounds
width = @contents.text_size(j.gsub(/\000\[[0-9]+\]/, '')).width
if x + width > maxwidth
text << "\n"
widths << x
x = 0
y += 1
@contents.font.size = 24
end
# Append word to list
if x == 0
text << j
else
text << ' ' << j
end
x += width + spacesize.width
end
end
widths << x
# Prepare renderer
@contents.clear
if $game_switches[104]
@contents.font.color = Color.new(255, 255, 255, 255)
else
@contents.font.color = Color.new(0, 0, 0, 255)
end
x = (320 - widths[0]) / 2
y = 0
y_top = (240 - widths.length * 24) / 2
@contents.font.size = 16
# Get 1 text character in c (loop until unable to get text)
while ((c = text.slice!(/./m)) != nil)
# \n
if c == "\n"
y += 1
@contents.font.size = 24
x = (320 - widths[y]) / 2
next
end
# \c[n]
if c == "\000"
# Change text color
text.sub!(/\[([0-9]+)\]/, "")
color = $1.to_i
if color >= 0 and color <= 7
@contents.font.color = Window_Base.text_color(color)
end
# go to next text
next
end
# Draw text
@contents.draw_text(x, y_top + (y * 24), 40, 18, c)
# Add x to drawn text width
x += @contents.text_size(c).width
end
Graphics.frame_reset
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Handle fade-out effect
if @fade_out
@sprite_text.opacity -= 5
@sprite_bg.opacity -= 5
if @sprite_text.opacity <= 0
@sprite_text.opacity = 0
@sprite_bg.opacity = 0
@fade_out = false
@viewport.visible = false
$game_temp.message_window_showing = false
end
return
end
# Handle fade-in effect
if @fade_in
@sprite_text.opacity += 5
@sprite_bg.opacity += 5
if @sprite_text.opacity >= 255
@sprite_text.opacity = 255
@sprite_bg.opacity = 255
@fade_in = false
$game_temp.message_window_showing = true
end
return
end
# Message is over and should be hidden or advanced to next
if $game_temp.message_credits_text == nil
@fade_out = true if @viewport.visible
else
if !@viewport.visible
# Fade in
refresh
@viewport.visible = true
@fade_in = true
end
end
if visible
@timer += 1
if @timer >= 150
terminate_message
@fade_out = true
end
end
end
#--------------------------------------------------------------------------
# * Variables
#--------------------------------------------------------------------------
def visible
@viewport.visible
end
def visible=(val)
@viewport.visible = val
end
end

View File

@ -3,11 +3,23 @@ module EdText
Oneshot.msgbox Oneshot::Msg::YESNO, tr("Do you understand what this means?") Oneshot.msgbox Oneshot::Msg::YESNO, tr("Do you understand what this means?")
end end
def self.info(text) def self.info(text)
timestart = Time.now
text.gsub!("\\p", $game_oneshot.player_name) text.gsub!("\\p", $game_oneshot.player_name)
Oneshot.msgbox Oneshot::Msg::INFO, tr(text) Oneshot.msgbox Oneshot::Msg::INFO, tr(text)
$game_temp.prompt_wait = ((Time.now - timestart) * 60).round
end end
def self.yesno(text) def self.yesno(text)
timestart = Time.now
text.gsub!("\\p", $game_oneshot.player_name) text.gsub!("\\p", $game_oneshot.player_name)
Oneshot.msgbox Oneshot::Msg::YESNO, tr(text) result = Oneshot.msgbox Oneshot::Msg::YESNO, tr(text)
$game_temp.prompt_wait = ((Time.now - timestart) * 60).round
return result
end
def self.err(text)
timestart = Time.now
text.gsub!("\\p", $game_oneshot.player_name)
result = Oneshot.msgbox Oneshot::Msg::ERR, tr(text)
$game_temp.prompt_wait = ((Time.now - timestart) * 60).round
return result
end end
end end

View File

@ -19,6 +19,7 @@ class Game_Temp
attr_accessor :message_ed_text # Ed message text attr_accessor :message_ed_text # Ed message text
attr_accessor :message_doc_text # Text message text attr_accessor :message_doc_text # Text message text
attr_accessor :message_desktop_text # Desktop message text attr_accessor :message_desktop_text # Desktop message text
attr_accessor :message_credits_text # Desktop message text
attr_accessor :choices # show choices: text attr_accessor :choices # show choices: text
attr_accessor :choice_cancel_type # show choices: cancel attr_accessor :choice_cancel_type # show choices: cancel
attr_accessor :choice_proc # show choices: callback (Proc) attr_accessor :choice_proc # show choices: callback (Proc)
@ -61,6 +62,7 @@ class Game_Temp
attr_accessor :debug_index # debug screen: for saving conditions attr_accessor :debug_index # debug screen: for saving conditions
attr_accessor :footstep_sfx # current footstep sfx array attr_accessor :footstep_sfx # current footstep sfx array
attr_accessor :filmsprite # film puzzle sprite attr_accessor :filmsprite # film puzzle sprite
attr_accessor :prompt_wait # wait for delay caused by prompt
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# * Object Initialization # * Object Initialization
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
@ -116,6 +118,7 @@ class Game_Temp
@debug_index = 0 @debug_index = 0
@footstep_sfx = nil @footstep_sfx = nil
@filmsprite = nil @filmsprite = nil
@prompt_wait = 0
end end
def bgm_fadein(game_system) def bgm_fadein(game_system)

View File

@ -11,7 +11,7 @@ class Interpreter
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def command_101 def command_101
# If other text has been set to message_text # If other text has been set to message_text
if $game_temp.message_text != nil || $game_temp.message_ed_text != nil || $game_temp.message_doc_text != nil || $game_temp.message_desktop_text != nil if $game_temp.message_text != nil || $game_temp.message_ed_text != nil || $game_temp.message_doc_text != nil || $game_temp.message_desktop_text != nil || $game_temp.message_credits_text != nil
# End # End
return false return false
end end
@ -22,6 +22,8 @@ class Interpreter
if text.start_with?('$') if text.start_with?('$')
is_doc = true is_doc = true
text.slice!(0) text.slice!(0)
elsif text.start_with?('@credits')
is_credits = true
else else
is_doc = false is_doc = false
end end
@ -30,13 +32,16 @@ class Interpreter
if @list[@index+1].code == 401 if @list[@index+1].code == 401
@index += 1 @index += 1
text << " " << @list[@index].parameters[0].rstrip text << " " << @list[@index].parameters[0].rstrip
elsif @list[@index+1].code == 101 && is_doc elsif @list[@index+1].code == 101 && (is_doc || is_credits)
# 101: Another message box # 101: Another message box
# Tack on if we're a doc # Tack on if we're a doc
new_text = @list[@index+1].parameters[0].strip new_text = @list[@index+1].parameters[0].strip
if new_text.start_with?('$') if new_text.start_with?('$')
text << "\n\n" << new_text[1..-1] text << "\n\n" << new_text[1..-1]
@index += 1 @index += 1
elsif new_text.start_with?('@credits')
text << new_text[9..-1]
@index += 1
else else
break break
end end
@ -71,12 +76,19 @@ class Interpreter
if face == 'ed' if face == 'ed'
is_desktop = false is_desktop = false
is_ed = true is_ed = true
is_credits = false
elsif face == 'desktop' elsif face == 'desktop'
is_desktop = true is_desktop = true
is_ed = false is_ed = false
is_credits = false
elsif face == 'credits'
is_desktop = false
is_ed = false
is_credits = true
else else
is_desktop = false is_desktop = false
is_ed = false is_ed = false
is_credits = false
$game_temp.message_face = face $game_temp.message_face = face
end end
@ -98,6 +110,8 @@ class Interpreter
$game_temp.message_doc_text = text $game_temp.message_doc_text = text
elsif is_desktop elsif is_desktop
$game_temp.message_desktop_text = text $game_temp.message_desktop_text = text
elsif is_credits
$game_temp.message_credits_text = text
else else
$game_temp.message_text = text $game_temp.message_text = text
end end

View File

@ -16,6 +16,7 @@ class Scene_Map
@ed_message = Ed_Message.new @ed_message = Ed_Message.new
@doc_message = Doc_Message.new @doc_message = Doc_Message.new
@desktop_message = Desktop_Message.new @desktop_message = Desktop_Message.new
@credits_message = Credits_Message.new
# Make menus # Make menus
@menu = Window_MainMenu.new @menu = Window_MainMenu.new
@item_menu = Window_Item.new @item_menu = Window_Item.new
@ -70,6 +71,7 @@ class Scene_Map
@ed_message.dispose @ed_message.dispose
@doc_message.dispose @doc_message.dispose
@desktop_message.dispose @desktop_message.dispose
@credits_message.dispose
# Dispose of menu # Dispose of menu
@menu.dispose @menu.dispose
@item_menu.dispose @item_menu.dispose
@ -102,6 +104,10 @@ class Scene_Map
end end
# Loop # Loop
loop do loop do
if $game_temp.prompt_wait > 0
$game_temp.prompt_wait -= 1
return
end
$game_temp.bgm_fadein($game_system) $game_temp.bgm_fadein($game_system)
# Update map, interpreter, and player order # Update map, interpreter, and player order
# (this update order is important for when conditions are fulfilled # (this update order is important for when conditions are fulfilled
@ -135,6 +141,7 @@ class Scene_Map
@ed_message.update @ed_message.update
@doc_message.update @doc_message.update
@desktop_message.update @desktop_message.update
@credits_message.update
# Deactivate item # Deactivate item
if Input.trigger?(Input::DEACTIVATE) && $game_variables[1] > 0 if Input.trigger?(Input::DEACTIVATE) && $game_variables[1] > 0
$game_system.se_play($data_system.cancel_se) $game_system.se_play($data_system.cancel_se)
@ -142,7 +149,7 @@ class Scene_Map
end end
# Update the menu # Update the menu
if @message_window.visible || @ed_message.visible || @doc_message.visible || @desktop_message.visible if @message_window.visible || @ed_message.visible || @doc_message.visible || @desktop_message.visible || @credits_message.visible
@item_menu_refresh = true @item_menu_refresh = true
else else
if @item_menu_refresh if @item_menu_refresh
@ -226,7 +233,7 @@ class Scene_Map
# Update fast travel # Update fast travel
@fast_travel.update @fast_travel.update
# If showing message window # If showing message window
if $game_temp.message_window_showing || @ed_message.visible || @doc_message.visible || @desktop_message.visible if $game_temp.message_window_showing || @ed_message.visible || @doc_message.visible || @desktop_message.visible || @credits_message.visible
return return
end end
# Process menu opening # Process menu opening

View File

@ -121,6 +121,7 @@ SaveLoad
Ed_Message Ed_Message
Doc_Message Doc_Message
Desktop_Message Desktop_Message
Credits_Message
Particles Particles
Demo Demo