O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

[TSDA] Book System

Iniciado por thiago_d_d, 08/01/2013 às 11:15



TSDA Book System

www.mundorpgmaker.com
This work is licensed under a Creative Commons Atribuição-Uso não-comercial-Compartilhamento pela mesma licença 3.0 Unported License.
Equipe Sidereaque Angeli


[info float=left border=#6587E4]
Informações:
--------------------------------------------------
.
• Autor: thiago_d_d
• Versão: 1.0
• Incompatibilidade: Desprezível
• Lag gerado: Desprezível
• Customizável: Sim
• Requer Recursos Extras: Possivelmente
[/info][box class=catbg2]
Resumo
[/box][box class=catbg4]E aqui venho com mais um script! Dessa vez, um visualizador de livros! Mas, não pensem que é só um simples visualizador! Veja o que tem embutido:
- Faz quebra automática de linhas
- Justifica o texto.
- Possibilita uso de BG, fonte, sons, capa customizados.
- Tem tag de mudança de cor.
- Guarda o texto dos livros de forma segura, na pasta Data do seu projeto, convertendo para um arquivo .rvdata[/box]


[box class=catbg2]
Instalação e configuração
[/box]
Para instalar, cole o seguinte script acima de Main. Não se esqueça de ler as instruções contidas no script:
=begin
#===============================================================================
# TSDA Book System
#===============================================================================
# Feito por: thiago_d_d
# Versão: 1.0
#===============================================================================
# O script é um sistema de visualizador de livros. Características:
#  - Faz quebra automática de linhas
#  - Justifica o texto.
#  - Possibilita uso de BG, fonte, sons, capa customizados.
#  - Tem tag de mudança de cor.
#  - Guarda o texto dos livros de forma segura, na pasta Data do seu projeto,
#    convertendo para um arquivo .rvdata
#===============================================================================
# Não se esqueça de configurar o script no módulo TSDA!
#===============================================================================
 -----> Criando os livros
    Como foi falado acima, os livros são salvos na pasta Data, e isso é um 
requerimento para o uso de um livro. Para criar um novo livro, você deve
digitar seu texto no módulo TSDA, no seguinte formato:

NomeDoLivro = [
"Texto do parágrafo1",
"Texto do parágrafo2",
"Texto do parágrafo3",
]

Não coloque caracteres de nova linha, o script faz quebra automática, se lembra?

Como podem ver o nome do livro não pode ter espaços, caracteres especiais etc.
Apenas caracteres normais e o underline(_). Isso não é um problema, já que
o nome do livro é mostrado através da imagem de capa, e não através do nome usado

Depois disso, modifique a linha do módulo TSDA na qual está escrito isso:
BOOKS = [blablabla]
Ponha o nome do seu livro nessa lista.

Depois disso, vá até a última linha deste script, e delete o # presente antes 
dessa linha. Execute então o game. Após executar, ponha o # de volta no final 
do script.

Sobre essas linhas:
NomeDoLivro = [
"Texto do parágrafo1",
"Texto do parágrafo2",
"Texto do parágrafo3",
]

Você pode e deve deletá-las no dia em que for encriptar seu projeto, pois elas 
não são lidas quando se lê um livro, mas sim quando se cria ele usando o 
processo acima.

 -----> Chamando o visualizador de livros
 Use um comando de scripts:
 $scene = Scene_Book.new("nome do livro")
 
 -----> Mudando a cor do texto
 Ponha no texto do livro o seguinte:
 \\C[número da cor]
 
 -----> Sobre a capa e BG
 Devem estar na pasta Pictures
#===============================================================================
=end
module TSDA
  # Aqui está o livro usado como exemplo
  Exemplo = [
    "        No mundo de \\C[2]Stella Anima\\C[0], o planeta Terra é constituído por uma substância imperceptível porém tão abundante quanto o próprio ar que os seres humanos respiram. Alguns chamam essa tal substância de "mana", outros a chamam de "pó dos deuses", mas para regra geral, foi oficialmente adotado o nome de aura estelar.A partir da aura estelar o universo foi dividido em diversas "dimensões" ou como foram oficialmente chamadas: dobras astrais.Não se sabe muito sobre as dobras astrais, apenas que Chronus é a dobra onde os humanos vivem, e outra chamada Mitrandis, onde habitam os espíritos.",
    "        Na dimensão Chronus, cada ser humano tem sua aura estelar, catalizada num ponto específico do corpo chamado vortex polar, podendo ser lunar ou solar. Neste plano as pessoas estão acostumadas a utilizar sua aura estelar para alterar a realidade, o que alguns chamam de Astralogia. Porém, nem todos os humanos tem interesse e habilidade para dominar sua aura, preferindo pagar serviços de outras pessoas. Os seres humanos que usam sua aura estelar são chamados de Espiritualistas.",
  ]
  #Windowskin que será usada para pegar as cores pela tag \\C
  WINDOWSKIN = "Window"
  #Lista de livros
  BOOKS = ["Exemplo"]
  #Scene para qual transferir quando sair do livro
  SCENE_TO_GO = "Scene_Map.new"
  #Configure aqui se o livro terá uma capa mostrando o título
  # Formato:
  # {
  #     "Livro" => true ou false,
  #     "Livro2" => true ou false
  # }
  USE_TITLE = {
    "Exemplo" => false
  }
  #Configure aqui a imagem usada como capa do livro
  # Formato:
  # {
  #     "Livro" => "IMg1",
  #     "Livro2" => "IMg2"
  # }
  TITLE_IMAGE = {
    "Exemplo" => false
  }
  #Configure aqui se o livro usa windowskin ou um BG
  # Formato:
  # {
  #     "Livro" => true ou false,
  #     "Livro2" => true ou false
  # }
  USE_WINDOWSKIN = {
    "Exemplo" => false
  }
  #Configure o BG que o livro usa, caso use.
  # Formato:
  # {
  #     "Livro" => "BG1",
  #     "Livro2" => "GB2"
  # }
  BG_IMAGE = {
    "Exemplo" => "ExemploBG"
  }
  #Configure o som ao mudar de página do livro
  # Formato:
  # {
  #     "Livro" => "Sound1",
  #     "Livro2" => "Sound1"
  # }
  PAGE_SOUND = {
    "Exemplo" => "Book"
  }
  #Configure a fonte usada no livro
  # Formato:
  # {
  #     "Livro" => "Trebuchet MS",
  #     "Livro2" => "Arial"
  # }
  FONT_NAME = {
    "Exemplo" => "Arial"
  }
end
#===============================================================================
class String
  def true_size
    copy = self.clone;size = 0
    while(copy.slice!(/./m)) != nil;size += 1;end;size
  end
  #=============================================================================
  def starts_with?(string2)
    if self[0,string2.size] == string2
      $ind = string2.size;return true;else;return false;end
  end
  #=============================================================================
  def substring(starting_index,final_index)
    self[starting_index,final_index - starting_index]
  end
  #=============================================================================
  def index_of(starting_index,st)
    return -1 if starting_index > size or starting_index < 0
    for i in starting_index...size
      return i if self[i,1] == st;end;return -1
  end
  #=============================================================================
  def last_index_of(st)
    pos = -1
    while (pos = index_of(pos + 1," ")) != -1
      tpos = pos;end;return tpos
  end
  #=============================================================================
  def contains_starting_space
    (self[0,1] == " ") ? (return true) : (return false)
  end
  #=============================================================================
  def rot13
    dup.unpack("C*").map{|i| (i + 13) % 256}.pack("C*")
  end
  #=============================================================================
  def unrot13
    dup.unpack("C*").map{|i| (i - 13) % 256}.pack("C*")
  end
end
#===============================================================================
class Scene_Title
  alias book_script_load_database load_database
  #=============================================================================
  def load_database
    book_script_load_database
    if FileTest.exist?("Data/Books.rvdata") 
      $data_books         = load_data("Data/Books.rvdata")
      $data_books.each{|book_name,book|
        book.unobfuscate
      }
    end
  end
end
#===============================================================================
module TSDA
  class Book
    attr_reader            :name
    attr_accessor            :contents
    #===========================================================================
    def initialize(name)
      @name = name
      @contents = []
    end
    #===========================================================================
    def obfuscate
      @name = @name.rot13
      for i in 0...@contents.size
        @contents[i] = @contents[i].rot13
      end
    end
    #===========================================================================
    def unobfuscate
      @name = @name.unrot13
      for i in 0...@contents.size
        @contents[i] = @contents[i].unrot13
      end
    end
  end
  #=============================================================================
  module_function
  #=============================================================================
  def make_books(list)
    books = {}
    for book_name in list
      book = Book.new(book_name)
      ary = eval("TSDA::" + book_name)
      book.contents = ary
      book.obfuscate
      books[book_name] = book
    end
    save_data(books, "Data/Books.rvdata")
  end
end
#===============================================================================
class Scene_Book < Scene_Base
  attr_reader       :book
  include TSDA
  #=============================================================================
  def initialize(book_name)
    @book = $data_books[book_name]
    @pages = []
    test_bitmap = Bitmap.new(512,384)
    test_bitmap.font.name = FONT_NAME[book_name]
    page = []
    temp_string = ""
    for l in @book.contents
      copy = l.clone
      copy.gsub!(/\\C\[([0-9]+)\]/i) { "\x01[#{$1}]" }
      x = 0
      while(letter = copy.slice!(/./m)) != nil
        if page.size == 16
          @pages.push(page)
          page = []
        end
        if letter == "\x01"
          temp_string.concat(letter)
          copy.sub!(/\[([0-9]+)\]/, "")
          temp_string.concat("[" + $1.to_i.to_s + "]")
          next
        end
        l_width = test_bitmap.text_size(letter).width
        temp_string.concat(letter)
        x += l_width
        if x >= 512
          pos = temp_string.last_index_of(" ")
          use_string = temp_string.substring(0,pos)
          temp_string = temp_string.substring(pos,temp_string.size)
          if temp_string.contains_starting_space
            temp_string = temp_string.substring(1,temp_string.size)
          end
          page.push(use_string)
          x = test_bitmap.text_size(temp_string).width
        end
      end
      page.push(temp_string)
      temp_string = ""
    end
    page.push(temp_string) 
    @pages.push(page)
  end
  #=============================================================================
  def start
    if USE_TITLE[@book.name]
      bg = Sprite.new
      bg.bitmap = Cache.picture(TITLE_IMAGE[@book.name])
      while true
        Graphics.update
        Input.update
        bg.update
        if Input.trigger?(Input::C)
          Sound.play_decision
          break
        end
      end
    end
    create_pages
    if USE_WINDOWSKIN[@book.name]
      @book_window = Window_Base.new(0,0,544,416)
      @book_window.contents = @bt_pages[0]
      @page_index = 0
    else
      @page_index = 0
      @bg = Sprite.new
      @bg.bitmap = Cache.picture(BG_IMAGE[@book.name])
      @page_sprite = Sprite.new
      @page_sprite.z = 10
      @page_sprite.x = 16
      @page_sprite.y = 16
      @page_sprite.bitmap = @bt_pages[@page_index]
    end
  end
  #=============================================================================
  def update
    @book_window.update unless @book_window.nil?
    @bg.update unless @bg.nil?
    @page_sprite.update unless @page_sprite.nil?
    if Input.trigger?(Input::RIGHT)
      last_index = @page_index
      @page_index += 1
      if @page_index > @pages.size - 1
        @page_index = @pages.size - 1
      end
      Audio.se_play("Audio/SE/" + PAGE_SOUND[@book.name]) if last_index != @page_index
      wait(40)
      if last_index != @page_index
        if USE_WINDOWSKIN[@book.name]
          @book_window.contents = @bt_pages[@page_index]
        else
          @page_sprite.bitmap = @bt_pages[@page_index]
        end
      end
    elsif Input.trigger?(Input::LEFT)
      last_index = @page_index
      @page_index -= 1
      if @page_index < 0
        @page_index = 0
      end
      Audio.se_play("Audio/SE/" + PAGE_SOUND[@book.name]) if last_index != @page_index
      wait(40)
      if last_index != @page_index
        if USE_WINDOWSKIN[@book.name]
          @book_window.contents = @bt_pages[@page_index]
        else
          @page_sprite.bitmap = @bt_pages[@page_index]
        end
      end
    elsif Input.trigger?(Input::B)
      Sound.play_cancel
      eval("$scene = " + SCENE_TO_GO)
    end
  end
  #=============================================================================
  def wait(value)
    value.times{|n| Graphics.update}
  end
  #=============================================================================
  def terminate
    if USE_WINDOWSKIN[@book.name]
      @book_window.dispose
    else
      @bg.dispose
      @page_sprite.dispose
    end
  end
  #=============================================================================
  def create_pages
    @bt_pages = []
    for page in @pages
      bt = Bitmap.new(512,384)
      for i in 0...page.size
        draw_item(i,page[i],bt)
      end
      @bt_pages.push(bt)
    end
  end
  #=============================================================================
  def draw_item(index,item,bt)
    width = bt.text_size(item).width
    if width > 380
      draw_justified_text(0,index * 24,512,24,item,bt)
    else
      draw_text2(0,index * 24,512,24,item,bt)
    end
  end
  #=============================================================================
  def draw_justified_text(x,y,width,height,text,bt)
    bt.font.name = FONT_NAME[@book.name]
    bt.font.color = @font unless @font.nil?
    use_x = x
    copy = text.clone
    tmp = ""
    copy2 = text.clone
    while ((letter = copy2.slice!(/./m)).nil? == false)
      if letter == "\x01"
        copy2.sub!(/\[([0-9]+)\]/, "")
        next
      end
      tmp.concat(letter)
    end
    total_width = bt.text_size(tmp).width
    plus = ((width.to_f - total_width.to_f - 5) / tmp.true_size)
    while ((letter = copy.slice!(/./m)).nil? == false)
      if letter == "\x01"
        copy.sub!(/\[([0-9]+)\]/, "")
        bt.font.color = text_color($1.to_i)
        @font = bt.font.color
        next
      end
      letter_width = bt.text_size(letter).width
      bt.draw_text(use_x.to_i,y,letter_width,height,letter)
      use_x += (letter_width + plus)
    end
  end
  #=============================================================================
  def text_color(n)
    x = 64 + (n % 8) * 8
    y = 96 + (n / 8) * 8
    return Cache.system(WINDOWSKIN).get_pixel(x, y)
  end
  #=============================================================================
  def draw_text2(x,y,width,height,text,bt)
    use_x = x
    copy = text.clone
    while ((letter = copy.slice!(/./m)).nil? == false)
      if letter == "\x01"
        copy.sub!(/\[([0-9]+)\]/, "")
        bt.font.color = text_color($1.to_i)
        next
      end
      letter_width = bt.text_size(letter).width
      bt.draw_text(use_x.to_i,y,letter_width,height,letter)
      use_x += letter_width
    end
  end
end
# Remova o # para recria o arquivo Books.rvdata dentro da pasta data do projeto
#TSDA.make_books(TSDA::BOOKS)



[box class=catbg2]
Demo e Imagens
[/box]






[box class=catbg2]
Créditos
[/box]

  • thiago_d_d por fazer o script
  • King Gerar pelo fundo utilizado como exemplo
  • Deen por dar a ideia e acompanhar o desenvolvimento

Cara, quebra automática de linha, é uma das coisas mais legais em scripts, ficou muito show o code do script, parabéns Thiago :)

Obrigado por comentar, amigo.  :ok:
E sim, quebra de linhas é algo muito interessante, e deu até um certo trabalhinho de fazer. Envolve muita lógica, sabe.