KEnterText HC
#1
KEnterText HC

by Kyonides

Introduction

Ever since HiddenChest version 1.1.98 was released, game developers are now able to implement a very simple text input interface in their games.
It heavily depends on the new additions to the Input module to make it work normally.

The CapsLock and Shift keys DO alter the outcome while typing a text.

You can count on the basic ASCII characters to enter a name or nickname or even a number. Hyphen -, period ., and space " " are recognized automatically.
WARNING: Accents will be ignored by default. Sorry about that. Laughing + Tongue sticking out

Screenshots

RMXP
Code:
# * KEnterText HC for XP * #
#   Scripter : Kyonides
#   2025-12-13

# $scene = KEnter::TextScene.new

module KEnter

class TextBox
  def initialize(bw, bh, color)
    @char_limit = 1
    bitmap = Bitmap.new(bw, bh)
    bitmap.fill_rect(bitmap.rect, color)
    @box = Sprite.new
    @box.bitmap = bitmap
    bitmap = Bitmap.new(bw - 8, bh - 4)
    bitmap.font.size = 24
    bitmap.font.outline = true
    @text = Sprite.new
    @text.bitmap = bitmap
    @sprites = [@text, @box]
  end

  def move2(bx, by, n, lh)
    @box.set_xy(bx, by + n * lh)
    @text.set_xy(bx + 4, by + 2 + n * lh)
  end

  def chars=(ary)
    @chars = ary
    refresh
  end

  def process_char
    char = Input.last_char
    if Input.press?(Input::SHIFT)
      char = Input.capslock_state ? char.downcase : char.upcase
    end
    @chars << char
    @chars.compact!
    refresh
  end

  def delete_char
    @chars.pop
    refresh
  end

  def refresh
    @text.bitmap.clear
    @text.bitmap.draw_text(@text.bitmap.rect, @chars.join)
  end

  def bitmap
    @text.bitmap
  end

  def char_max?
    @chars.size == @char_limit
  end

  def dispose
    @sprites.each do |sprite|
      sprite.bitmap.dispose
      sprite.dispose
    end
    @sprites.clear
  end
  attr_writer :char_limit
  attr_reader :chars
end

class TextScene
  CHAR_LIMIT = 18
  BACKDROP = "catacombs"
  LABELS = ["Your Name", "Your Nickname"]
  @@texts = Array.new(2) {[]}
  def main
    @stage = :main
    @blink_timer = Graphics.frame_rate / 5
    @blink_state = false
    @index = 0
    @text_sprites = []
    black = Color.new(0, 0, 0)
    @blue = Color.new(80, 80, 255)
    custom = Color.new(255, 255, 40)
    lbit = Bitmap.new(208, 160)
    lbit.font.outline = true
    lbit.draw_text(16, 0, 208, 24, LABELS[0])
    lbit.draw_text(16, 78, 208, 24, LABELS[1])
    @backdrop = Sprite.new
    @backdrop.bitmap = RPG::Cache.title(BACKDROP)
    @label_sprite = Sprite.new
    @label_sprite.set_xy(16, 12)
    @label_sprite.bitmap = lbit
    make_box_text_sprites
    cb = Bitmap.new(200, 4)
    @main_cursor = Sprite.new
    @main_cursor.set_xy(20, 38)
    @main_cursor.bitmap = cb
    cb.fill_rect(cb.rect, black)
    cb.fill_rect(2, 1, 196, 2, custom)
    cbit = Bitmap.new(20, 28)
    cbit.font.size = 24
    cbit.font.outline = true
    cbit.draw_text(cbit.rect, "|")
    @text_cursor = Sprite.new
    @text_cursor.set_xy(22, 50)
    @text_cursor.visible = @blink_state
    @text_cursor.bitmap = cbit
    Graphics.transition
    while @stage
      Graphics.update
      Input.update
      update
    end
    Graphics.freeze
    cbit.dispose
    cb.dispose
    @text_cursor.dispose
    @main_cursor.dispose
    @text_sprites.each_with_index do |box, n|
      box.dispose
      @@texts[n] = box.chars
    end
    @label_sprite.dispose
    @backdrop.bitmap.dispose
    @backdrop.dispose
  end

  def make_box_text_sprites
    2.times do |n|
      textbox = TextBox.new(208, 32, @blue)
      textbox.move2(16, 48, n, 78)
      textbox.chars = @@texts[n]
      textbox.char_limit = CHAR_LIMIT
      @text_sprites << textbox
    end
  end

  def update
    case @stage
    when :main
      update_index
    when :text_input
      update_text_input
    end
  end

  def update_blink
    @blink_timer -= 1
    if @blink_timer == 0
      @blink_timer = Graphics.frame_rate / 5
      @blink_state = !@blink_state
      @text_cursor.visible = @blink_state
    end
  end

  def process_text_box_cancel
    Input.text_input = false
    Input.clear_text_input
    Input.update
    @text_cursor.visible = @blink_state = false
    @blink_timer = Graphics.frame_rate / 5
    @stage = :main
  end

  def update_index
    if Input.trigger?(Input::Escape)
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Map.new
      return @sprite = @stage = nil
    elsif Input.trigger?(Input::UP)
      set_index(-1)
      return
    elsif Input.trigger?(Input::DOWN)
      set_index(1)
      return
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)
      $game_system.se_play($data_system.decision_se)
      Input.text_input = true
      Input.update
      @stage = :text_input
      @sprite = @text_sprites[@index]
      @bitmap = @sprite.bitmap
      text = @sprite.chars.join
      tw = @bitmap.text_width(text)
      @text_cursor.x = 22 + tw
      @text_cursor.visible = @blink_state = true
    end
  end

  def set_index(n)
    $game_system.se_play($data_system.cursor_se)
    @index = (@index + n) % 2
    @main_cursor.y = 38 + @index * 78
    @text_cursor.y = 50 + @index * 78
  end

  def update_text_input
    update_blink
    if Input.trigger?(Input::Escape)
      $game_system.se_play($data_system.cancel_se)
      process_text_box_cancel
      return
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)
      $game_system.se_play($data_system.decision_se)
      Graphics.screenshot
      process_text_box_cancel
      return
    elsif Input.repeat?(Input::Backspace)
      $game_system.se_play($data_system.buzzer_se)
      @sprite.delete_char
      refresh_text(@sprite.chars.join)
      return
    elsif Input.trigger_any? and Input.last_key?
      if @sprite.char_max?
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.equip_se)
      @sprite.process_char
      refresh_text(@sprite.chars.join)
    end
  end

  def refresh_text(text)
    tw = @bitmap.text_width(text)
    @text_cursor.x = 22 + tw
  end
end
  
end

RMVX + RMVX ACE
Code:
# * KEnterText HC for VX + ACE * #
#   Scripter : Kyonides
#   2025-12-13

# For VX:
# $scene = KEnter::TextScene.new

# For VX ACE:
# SceneManager.call(KEnter::TextScene)

module KEnter

class TextBox
  def initialize(bw, bh, color)
    @char_limit = 1
    bitmap = Bitmap.new(bw, bh)
    bitmap.fill_rect(bitmap.rect, color)
    @box = Sprite.new
    @box.bitmap = bitmap
    bitmap = Bitmap.new(bw - 8, bh - 4)
    bitmap.font.size = 24
    bitmap.font.outline = true
    @text = Sprite.new
    @text.bitmap = bitmap
    @sprites = [@text, @box]
  end

  def move2(bx, by, n, lh)
    @box.set_xy(bx, by + n * lh)
    @text.set_xy(bx + 4, by + 2 + n * lh)
  end

  def chars=(ary)
    @chars = ary
  end

  def process_char
    char = Input.last_char
    if Input.press?(Input::SHIFT)
      char = Input.capslock_state ? char.downcase : char.upcase
    end
    @chars << char
    @chars.compact!
    refresh
  end

  def delete_char
    @chars.pop
    refresh
  end

  def refresh
    @text.bitmap.clear
    @text.bitmap.draw_text(@text.bitmap.rect, @chars.join)
  end

  def bitmap
    @text.bitmap
  end

  def char_max?
    @chars.size == @char_limit
  end

  def dispose
    @sprites.each do |sprite|
      sprite.bitmap.dispose
      sprite.dispose
    end
    @sprites.clear
  end
  attr_writer :char_limit
  attr_reader :chars
end

class TextScene
  CHAR_LIMIT = 18
  BACKDROP = "catacombs"
  LABELS = ["Your Name", "Your Nickname"]
  @@texts = Array.new(2) {[]}
  def main
    @vx_ace = Game::RGSS_VERSION == 3
    @stage = :main
    @blink_timer = Graphics.frame_rate / 5
    @blink_state = false
    @index = 0
    @text_sprites = []
    black = Color.new(0, 0, 0)
    @blue = Color.new(80, 80, 255)
    custom = Color.new(255, 255, 40)
    lbit = Bitmap.new(208, 160)
    lbit.font.outline = true
    lbit.draw_text(16, 0, 208, 24, LABELS[0])
    lbit.draw_text(16, 78, 208, 24, LABELS[1])
    @backdrop = Sprite.new
    @backdrop.bitmap = Cache.system(BACKDROP)
    @label_sprite = Sprite.new
    @label_sprite.set_xy(16, 12)
    @label_sprite.bitmap = lbit
    make_box_text_sprites
    cb = Bitmap.new(200, 4)
    @main_cursor = Sprite.new
    @main_cursor.set_xy(20, 38)
    @main_cursor.bitmap = cb
    cb.fill_rect(cb.rect, black)
    cb.fill_rect(2, 1, 196, 2, custom)
    cbit = Bitmap.new(20, 28)
    cbit.font.size = 24
    cbit.font.outline = true
    cbit.draw_text(cbit.rect, "|")
    @text_cursor = Sprite.new
    @text_cursor.set_xy(22, 50)
    @text_cursor.visible = @blink_state
    @text_cursor.bitmap = cbit
    Graphics.transition
    while @stage
      Graphics.update
      Input.update
      update
    end
    Graphics.freeze
    cbit.dispose
    cb.dispose
    @text_cursor.dispose
    @main_cursor.dispose
    @text_sprites.each_with_index do |box, n|
      box.dispose
      @@texts[n] = box.chars
    end
    @label_sprite.dispose
    @backdrop.bitmap.dispose
    @backdrop.dispose
  end

  def make_box_text_sprites
    2.times do |n|
      textbox = TextBox.new(208, 32, @blue)
      textbox.move2(16, 48, n, 78)
      textbox.chars = @@texts[n]
      textbox.char_limit = CHAR_LIMIT
      @text_sprites << textbox
    end
  end

  def update
    case @stage
    when :main
      update_index
    when :text_input
      update_text_input
    end
  end

  def update_blink
    @blink_timer -= 1
    if @blink_timer == 0
      @blink_timer = Graphics.frame_rate / 5
      @blink_state = !@blink_state
      @text_cursor.visible = @blink_state
    end
  end

  def process_text_box_cancel
    Input.text_input = false
    Input.clear_text_input
    Input.update
    @text_cursor.visible = @blink_state = false
    @blink_timer = Graphics.frame_rate / 5
    @stage = :main
  end

  def update_index
    if Input.trigger?(Input::Escape)
      Sound.play_cancel
      $scene = Scene_Map.new
      return @stage = nil
    elsif Input.trigger?(Input::UP)
      set_index(-1)
      return
    elsif Input.trigger?(Input::DOWN)
      set_index(1)
      return
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)
      @vx_ace ? Sound.play_ok : Sound.play_decision
      Input.text_input = true
      Input.update
      @stage = :text_input
      @sprite = @text_sprites[@index]
      @bitmap = @sprite.bitmap
      text = @sprite.chars.join
      tw = @bitmap.text_width(text)
      @text_cursor.x = 22 + tw
      @text_cursor.visible = @blink_state = true
    end
  end

  def set_index(n)
    Sound.play_cursor
    @index = (@index + n) % 2
    @main_cursor.y = 38 + @index * 78
    @text_cursor.y = 50 + @index * 78
  end

  def update_text_input
    update_blink
    if Input.trigger?(Input::Escape)
      Sound.play_cancel
      process_text_box_cancel
      return
    elsif Input.trigger?(Input::Enter) or Input.trigger?(Input::Return)
      @vx_ace ? Sound.play_ok : Sound.play_decision
      Graphics.screenshot
      process_text_box_cancel
      return
    elsif Input.repeat?(Input::Backspace)
      Sound.play_buzzer
      @sprite.delete_char
      refresh_text(@sprite.chars.join)
      return
    elsif Input.trigger_any? and Input.last_key?
      if @sprite.char_max?
        Sound.play_buzzer
        return
      end
      Sound.play_equip
      @sprite.process_char
      refresh_text(@sprite.chars.join)
    end
  end

  def refresh_text(text)
    tw = @bitmap.text_width(text)
    @text_cursor.x = 22 + tw
  end
end

end

Terms & Conditions

The same as HiddenChest's.
That's it!  Tongue sticking out
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply
#2
Script Update

Today's release features a custom backdrop, some catacombs to be precise, and a main cursor to let you know which text box is currently selected.
Yes, there are other changes that affect how the contents are processed internally. And I also altered some X & Y bitmap coordinates to keep the scene's appearance as neat and uniform as possible. Grinning

These scripts have also been uploaded to HiddenChest's GitHub page, namely to the extras directory.
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply
#3
Second Script Update

This release doesn't really offer anything new, yet, it might allow Gamer game developers to easily use or reuse the KEnter::TextBox class in other contexts or menus. It now keeps track of everything related to the box and the custom text to be displayed there.

KEnter::TextBox's Methods
  • move2(x, y, line_number, line_height)
  • chars=(array)
  • char_limit=(number)
  • process_char
  • delete_char
  • char_max?

Custom Input's Singleton Methods
  • text_input=(boolean)
  • clear_text_input
  • trigger_any?
  • last_key?
  • last_char
  • capslock_state

NOTES

Nope, you don't need to to type some (parentheses) when you want to assign a value to a variable or object's method. They're just there as some sort of placeholder for a specific value, namely a boolean or a number, as you can see above.
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply




Users browsing this thread: 1 Guest(s)