マップ上のキャラクターに対して、指定した文字列を様々な方式で表示します。
表示方法
基本的にはスクリプトを実行して表示します。
「CraftLib」スクリプトを導入していれば、
マップ読み込み時にイベントページの一番上に配置した注釈を読み取り、
イベントを実行せずに表示することもできます。
また、表示方式は、比較的簡単に改造や追加が可能な構造になっています。
ポップテキストの使用方法・改造方法は別ページで詳しく解説しています。
更新履歴 | バージョン | 内容 |
---|---|---|
2023/11/23 | v2.0.1 | マップ移動時にテキストが解放されない不具合の修正 |
2023/11/22 | v2.0.0 | テキスト表示中にセーブロードした際に、 表示中のテキストがセーブデータに保持されない不具合の修正 (これにより表示方式のsprite, bitmap周りの管理が変わり、 従来の表示方式との互換性は失われます) |
2023/10/07 | v1.0.1 | 「:eject」方式で表示中、メニュー画面等を開いてから マップに戻るとクラッシュしてしまう不具合の修正 |
2023/09/18 | v1.0.0 | 初版 |
→スクリプト一覧へ
→「ポップテキストの使用・改造」解説ページへ
→「CraftLib」スクリプト配布ページへ
↓スクリプト(ダブルクリックで全選択)↓
=begin ========================================================================= ■ 「ポップテキスト」- PopText v2.0.1 by 地上の洞窟 ================================================================================ マップ上のキャラクターに対して、指定した文字列を様々な方式で表示します。 (全ての機能を使用するには「CraftLib」スクリプトが必要です) ================================================================================ ■ 設定項目 =end #========================================================================== module PopText # UNPOP_ON_EVENT_NEW_PAGE # イベントの改ページ時、そのイベントに表示中のテキストを削除します。 UNPOP_ON_EVENT_NEW_PAGE = true # DEFAULT_FONT_SIZE : 通常文字のサイズを指定します。 DEFAULT_FONT_SIZE = 16 # DEFAULT_FONT_BOLD : 通常文字を太字にします。 DEFAULT_FONT_BOLD = true # DEFAULT_HALF_WIDTH_RATE : 半角文字幅の計算に使う倍率 # フォントサイズに対して、半角文字の横幅はどれぐらいの倍率かを指定します。 # 必要があれば使用しているフォントの書体に合わせて調整してください。 DEFAULT_HALF_WIDTH_RATE = 0.6 #=============================================================================== # ■ 上級者向け設定(表示方式) #=============================================================================== # セットアップ module Setup def default # 基準サイズの設定 @size = DEFAULT_FONT_SIZE # スプライト・ビットマップの作成 create_graphic # フォントの設定 font = bitmap.font font.size = @size font.bold = DEFAULT_FONT_BOLD # テキストの描画 draw_text_defalut # 位置の設定 sprite.ox = bitmap.width / 2.0 sprite.oy = 32 + bitmap.height sprite.z = 1000 # コントロールの設定 @control = :control_default end def name default @control = :control_name end def eject default if @character @x = @character.real_x @y = @character.real_y @opacity = 255 @phase = 0 @count = 0 @character = nil end @control = :control_eject end end # 更新処理 module Control def control_default sprite.x = @character.screen_x sprite.y = @character.screen_y end def control_name dx = ($game_player.real_x - @character.real_x).abs dx = $game_map.width - dx if $game_map.loop_horizontal? && dx > $game_map.width / 2 dy = ($game_player.real_y - @character.real_y).abs dy = $game_map.height - dy if $game_map.loop_vertical? && dy > $game_map.height / 2 if Math.sqrt(dx * dx + dy * dy) < 4 sprite.visible = true sprite.x = @character.screen_x sprite.y = @character.screen_y else sprite.visible = false end end def control_eject case @phase when 0 distance = (20 * @count / 60.0) sprite.x = $game_map.adjust_x(@x) * 32 + 16 sprite.y = $game_map.adjust_y(@y) * 32 + 32 - 4 - distance if (@count += 1) > 60 @count = 0 @phase += 1 end when 1 progress = @count / 30.0 distance = 20 + 10 * progress - 6 * progress * progress sprite.x = $game_map.adjust_x(@x) * 32 + 16 sprite.y = $game_map.adjust_y(@y) * 32 + 32 - 4 - distance sprite.opacity = (@opacity -= 8.5) # 255 / 30 if (@count += 1) > 30 @count = 0 @phase += 1 end else remove end end end #=============================================================================== # ■ ここからソースコード #=============================================================================== HALF_WIDTH_REGEXP = /[。-゚[:ascii:]]/ DEFAULT_HALF_WIDTH_RATE_CALC = [[1 - DEFAULT_HALF_WIDTH_RATE, 0].max, 1].min # テキスト描画位置の補正(微妙にズレてる気がした故の調整) DEFAULT_DRAW_X_FIX = 1 COMMENT_REGEXP = /PopText\[((.*),(.*)|(.*))\]/ COMMENT_UNPOP = "UNPOP" if const_defined?(:CraftLib) CraftLib::SetupComment.register(COMMENT_REGEXP) do |event, m| if m[3] if (s = m[3].strip) == COMMENT_UNPOP PopText.unpop(event) else PopText.character(event, eval(s, TOPLEVEL_BINDING)) end else PopText.character( event, eval(m[1].strip, TOPLEVEL_BINDING), eval(m[2].strip, TOPLEVEL_BINDING) ) end end end class << self attr_accessor :font attr_reader :viewport def setup @controller ||= [] @queue = [] @unpop_character = {} clear end def create(viewport) @viewport = viewport refresh end def refresh $game_map.ptxt_controller.each { |controller| controller.refresh } end def clear $game_map.ptxt_controller.each { |controller| controller.remove }.clear end def dispose $game_map.ptxt_controller.each { |controller| controller.dispose } @viewport = nil end def update unless $game_map.ptxt_unpop_character.empty? $game_map.ptxt_controller.delete_if do |controller| if $game_map.ptxt_unpop_character[controller.character] controller.remove true else controller.update end end $game_map.ptxt_unpop_character.clear else $game_map.ptxt_controller.delete_if { |controller| controller.update } end unless $game_map.ptxt_queue.empty? $game_map.ptxt_controller.concat( $game_map.ptxt_queue.each { |controller| controller.refresh } ) $game_map.ptxt_queue.clear end end def character(character, text, setup = :default) $game_map.ptxt_queue << PopTextController.new(character, text, setup) end def player(text, setup = :default) $game_map.ptxt_queue << PopTextController.new($game_player, text, setup) end def event(id, text, setup = :default) if (event = $game_map.events[id]) $game_map.ptxt_queue << PopTextController.new(event, text, setup) end end def unpop(character) $game_map.ptxt_unpop_character[character] = true end def unpop_player $game_map.ptxt_unpop_character[$game_player] = true end def unpop_event(id) if (event = $game_map.events[id]) $game_map.ptxt_unpop_character[event] = true end end end class PopTextController include Setup include Control attr_reader :character attr_reader :sprite def initialize(character, text, setup) @character = character @text = text @setup = setup @remove = false @graphic_holder = GraphicHolder.new end def bitmap @graphic_holder.bitmap end def bitmap=(bitmap) @graphic_holder.bitmap = bitmap end def sprite @graphic_holder.sprite end def sprite=(sprite) @graphic_holder.sprite = sprite end def need_refresh? @graphic_holder.need_refresh end def create_graphic self.sprite = Sprite.new(PopText.viewport) self.sprite.bitmap = self.bitmap = ( Bitmap.new(@width ||= default_width, @height ||= default_height) ) end def default_width @size * (@text.to_s.length - @text.to_s.scan(HALF_WIDTH_REGEXP).size * DEFAULT_HALF_WIDTH_RATE_CALC) end def default_height @size end def draw_text_defalut bitmap.draw_text(DEFAULT_DRAW_X_FIX, 0, @width, @height, @text, 1) end def refresh send(@setup) send(@control) if @control @graphic_holder.need_refresh = false end def update refresh if need_refresh? send(@control) if @control @remove end def dispose @graphic_holder.dispose end def remove @remove = true @control = nil @character = nil dispose end class GraphicHolder attr_accessor :sprite, :bitmap, :need_refresh def marshal_dump true end def marshal_load(obj) @need_refresh = obj end def dispose @bitmap.dispose if @bitmap @sprite.dispose if @sprite end end end end class Game_Map attr_reader :ptxt_controller, :ptxt_queue, :ptxt_unpop_character alias ptxt_setup setup def setup(map_id) if @ptxt_controller PopText.clear else @ptxt_controller = [] end @ptxt_queue = [] @ptxt_unpop_character = {} ptxt_setup(map_id) end end class Game_Event < Game_Character alias ptxt_setup_page setup_page def setup_page(new_page) PopText.unpop(self) if PopText::UNPOP_ON_EVENT_NEW_PAGE ptxt_setup_page(new_page) end end class Spriteset_Map alias ptxt_create_characters create_characters def create_characters ptxt_create_characters PopText.create(@viewport1) end alias ptxt_update_characters update_characters def update_characters ptxt_update_characters PopText.update end alias ptxt_dispose_characters dispose_characters def dispose_characters ptxt_dispose_characters PopText.dispose end end