-
-
Save syureri/36aef853c20ec6d39f1653171b3eca6c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ O core principal. Ocasionalmente será referenciado como "o prism". ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
module Prism; extend self | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Constantes │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
NOTE_SEPARATOR = "<>" # Separador de notas do Database. | |
FIXED_UPDATE_COUNT = 15 # Tempo de espera para o fixed update. | |
SECOND_UPDATE_COUNT = 60 # Tempo de espera para o update de segundos. | |
MAIN = {} # Registra scripts oficiais do prism. | |
REGISTERED = {} # Usado para registrar scripts no prism. | |
STANDALONE = Module.new # Módulo para a criação de scripts standalone. | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
@fx_up_count = 15 # Contagem inicial do fixed update. | |
@sc_up_count = 60 # Contagem inicial do second update. | |
#┌────────────┬──────────────────────────────────────────────────────────────┐ | |
#│ ♦ register │ Sistema de registro de scripts. │ | |
#├────────────┴──────────────────────────────────────────────────────────────┤ | |
#│ Se o script for oficial do prism (script que faz parte dele), então o │ | |
#│ argumento official precisa ser true. Do contrário, caso o script esteja │ | |
#│ apenas usando o prism como um core, official deve ser false. │ | |
#│ → name: o nome do script. │ | |
#│ → version: a versão do script. │ | |
#│ → author: o autor do script. Não usado caso official == true. │ | |
#│ → official: se o script é oficial do prism. Padrão: false │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def register(name, version, author, official = false) | |
if official | |
MAIN[name] = {:name => name, :version => version} | |
else | |
REGISTERED[name] = {:name => name, :version => version, :author => author} | |
end | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ check_register │ Checa se um script está registrado. │ | |
#├──────────────────┴────────────────────────────────────────────────────────┤ | |
#│ Retorna uma hash com as informações de registro do script. │ | |
#│ Caso não esteja registrado, retorna nil, como previsto. │ | |
#│ → name: o nome do script. │ | |
#│ → official: se o script é oficial do prism. Padrão: false │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def check_register(name, official = false) | |
return official ? MAIN[name] : REGISTERED[name] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ export │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Usado para exportar conteúdo usando a compressão Zlib::BEST_COMPRESSION. │ | |
#│ → data: o conteúdo a ser exportado. │ | |
#│ → ext: o caminho de destino do arquivo que será salvo. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def export(data, ext) | |
save_data(Zlib::Deflate.deflate(data, Zlib::BEST_COMPRESSION), ext) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ import │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Usado para importar conteúdo que foi comprimido com Zlib. │ | |
#│ → data: o conteúdo a ser importado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def import(data) | |
return Zlib::Inflate.inflate(load_data(data)).force_encoding("UTF-8") | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualiza todos os elementos do prism. │ | |
#├───────────┴───────────────────────────────────────────────────────────────┤ | |
#│ → requer: Graphics, na área de complementos. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update | |
fixed_update | |
second_update | |
Prism::Event_Utils.update rescue nil | |
Prism::Touch.update rescue nil | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ fixed_update │ Atualiza a contagem para o fixed_update. │ | |
#├─────────────────┴─────────────────────────────────────────────────────────┤ | |
#│ O Fixed Update é um update que atualiza a cada 15 frames, ao invés de 60 │ | |
#│ frames. Sabe-se lá pra quê isso seria necessário no RM, mas de qualquer │ | |
#│ modo, achei que seria bom deixar aqui. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def fixed_update | |
next_count = @fx_up_count + 1 | |
next_count > FIXED_UPDATE_COUNT ? @fx_up_count = 0 : @fx_up_count += 1 | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ second_update │ Atualiza a contagem para o second_update. │ | |
#├──────────────────┴────────────────────────────────────────────────────────┤ | |
#│ Seguindo a onda do Fixed Update, o Second Update é um update que atualiza │ | |
#│ a cada 1 segundo. Bem útil para criar timers. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def second_update | |
next_count = @sc_up_count + 1 | |
next_count > SECOND_UPDATE_COUNT ? @sc_up_count = 0 : @sc_up_count += 1 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ folder_name_check │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Substitui os caracteres "\ / : ? * < > |" por caracteres válidos para │ | |
#│ serem usados como nomes de pastas/arquivos. │ | |
#│ → string: supostamente o nome da pasta/arquivo em uma string. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def folder_name_check(string) | |
result = string | |
result.gsub!(/\\\//) {"_"} | |
result.gsub!(/:/) {"-"} | |
result.gsub!(/\*\?<>\|/) {""} | |
return result | |
end | |
#┌──────────────────────┬────────────────────────────────────────────────────┐ | |
#│ ♦ run_fixed_update? │ Informa se o fixed update pode executar. │ | |
#└──────────────────────┴────────────────────────────────────────────────────┘ | |
def run_fixed_update? | |
@fx_up_count == 15 | |
end | |
#┌───────────────────────┬───────────────────────────────────────────────────┐ | |
#│ ♦ run_second_update? │ Informa se o second update pode executar. │ | |
#└───────────────────────┴───────────────────────────────────────────────────┘ | |
def run_second_update? | |
@sc_up_count == 60 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_center_screen │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Permite obter a posição do centro da tela. │ | |
#│ Caso um bitmap seja especificado, ele irá obter a posição do centro para │ | |
#│ o bitmap. │ | |
#│ → pos: :x ou :y │ | |
#│ → bitmap: um bitmap de base. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_center_screen(pos, bitmap = nil) | |
x = Graphics.width * 0.5 | |
y = Graphics.height * 0.5 | |
unless bitmap.nil? | |
x -= bitmap.width * 0.5 | |
y -= bitmap.height * 0.5 | |
end | |
pos == :x ? result = x : result = y | |
return result | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ rate │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém a taxa de um valor. Útil para obter porcentagem de hp e etc... │ | |
#│ → value: o valor atual. │ | |
#│ → max_value: o valor máximo. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def rate(value, max_value) | |
result = value.to_f / max_value | |
return result | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ decrease │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Diminui um valor para movimentação de uma janela/sprite/viewport │ | |
#│ O valor será dimiduído de pouco em pouco para que ele não passe do │ | |
#│ limite especificado. │ | |
#│ → source: o valor que será diminuído. │ | |
#│ → value: o quanto o valor deve diminuir. │ | |
#│ → min: o limite para o qual o valor deve diminuir. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def decrease(source, value, min) | |
if source - value < min && !value.is_a?(Float) | |
if value.even? | |
source -= value / 2 | |
else | |
source -= (value + 1) / 2 | |
end | |
else | |
source -= value | |
end | |
source = min if source < min | |
return source | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ increase │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ O contrário do decrease. Serve para aumentar um valor até o limite. │ | |
#│ → source: o valor que será aumentado. │ | |
#│ → value: o quanto o valor deve aumentar. │ | |
#│ → max: o limite para o qual o valor deve aumentar. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def increase(source, value, max) | |
if source + value > max && !value.is_a?(Float) | |
if value.even? | |
source += value / 2 | |
else | |
source += (value + 1) / 2 | |
end | |
else | |
source += value | |
end | |
source = max if source > max | |
return source | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ string_to_num │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Usado para transformar uma string em uma array de códigos dos caracteres │ | |
#│ em UTF-8 (basicamente, transformar letras em números) │ | |
#│ → string: uma string qualquer. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def string_to_num(string) | |
result = [] | |
for i in 0...string.size | |
result.push(string[i].unpack("U")[0]) | |
end | |
return result | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ num_to_string │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Converte uma array de códigos de caracteres em UTF-8 em uma string. │ | |
#│ O formato precisa ser o mesmo gerado pelo Prism.string_to_num. │ | |
#│ Ex: "Heya" seria [72, 101, 121, 97]. │ | |
#│ → array: uma array no formato mostrado acima. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def num_to_string(array) | |
result = "" | |
array.each do |n| | |
result << [n].pack("C")[0] | |
end | |
return result | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ to_hex │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Converte um número inteiro em hexadecimal. O resultado será retornado │ | |
#│ como uma string. │ | |
#│ → array: uma array no formato mostrado acima. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def to_hex(num) | |
result = sprintf("%#x", num.to_i) | |
return result | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ color_convert │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Converte uma string contendo valores de cores em hex (HTML/CSS) no objeto │ | |
#│ Color. │ | |
#│ Ex: color_convert("0a0b41") retorna Color.new(10, 11, 65) │ | |
#│ → array: uma array no formato mostrado acima. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def color_convert(color, alpha = 255) | |
r = eval("0x#{color[0..1]}") | |
g = eval("0x#{color[2..3]}") | |
b = eval("0x#{color[4..5]}") | |
return Color.new(r, g, b, alpha) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ wrap_text │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Retorna um texto com quebra de linha se ele passar da largura definida. │ | |
#│ → text: o texto em si. │ | |
#│ → width: a largura limite do texto. │ | |
#│ → src_bitmap: um bitmap de base para ser usado para medir a largura. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def wrap_text(text, width, src_bitmap = nil) | |
if src_bitmap | |
bitmap = src_bitmap | |
else | |
bitmap = Bitmap.new(width, 24) | |
end | |
result = "" | |
words = text.split(/ /) | |
pointer = 0 | |
for w in words | |
word_width = bitmap.text_size(w).width + 2 | |
space_width = bitmap.text_size(" ").width + 2 | |
if pointer < width | |
if pointer + word_width > width | |
result << "\n" << w << " " | |
pointer = word_width + space_width | |
else | |
result << w << " " | |
pointer += word_width + space_width | |
end | |
else | |
result << "\n" << w << " " | |
pointer = word_width + space_width | |
end | |
end | |
return result | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ cut_bitmap │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Corta um bitmap usando outro bitmap como base. Preserva anti-aliasing. │ | |
#│ Este método consome tempo. │ | |
#│ → sb: o bitmap que será usado como base. │ | |
#│ → db: o bitmap que será recortado. │ | |
#│ → x: a posição em x que será cortada. Padrão: nil │ | |
#│ → y: a posição em y que será cortada. Padrão: nil │ | |
#│ → width: a largura que será cortada. Padrão: nil │ | |
#│ → height: a altura que será cortada. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def cut_bitmap(sb, db, x = nil, y = nil, width = nil, height = nil) | |
x ||= 0 | |
y ||= 0 | |
width ||= db.width | |
height ||= db.height | |
for w in 0...width | |
for h in 0...height | |
pixel = sb.get_pixel(w, h) | |
npixel = db.get_pixel(w + x, h + y) | |
next if pixel.alpha.zero? || npixel.alpha.zero? | |
npixel.alpha -= pixel.alpha | |
db.set_pixel(w + x, h + y, npixel) | |
end | |
end | |
end | |
#┌─────────────┬─────────────────────────────────────────────────────────────┐ | |
#│ ♦ warn_box │ Chama uma caixa de aviso com a mensagem especificada. │ | |
#├─────────────┴─────────────────────────────────────────────────────────────┤ | |
#│ → title: o título da caixa. │ | |
#│ → text: o texto da caixa. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def warn_box(title, text) | |
wb = Win32API.new("user32", "MessageBox", "lppl", "i") | |
tx = text.unpack("U*").pack("C*") | |
tl = title.unpack("U*").pack("C*") | |
wb.call(0, tx, tl, 0x0020) | |
end | |
#┌────────┬──────────────────────────────────────────────────────────────────┐ | |
#│ ♦ log │ Similar ao msgbox_p. │ | |
#├────────┴──────────────────────────────────────────────────────────────────┤ | |
#│ → info: a informação a ser mostrada. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def log(info) | |
warn_box("Log", info.to_s) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ load_notetags │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ É iniciado junto do database. Serve para carregar as notas de todos os │ | |
#│ campos que possuam notas (do database). │ | |
#│ → requer: DataManager, na área de complementos. │ | |
#│ → requer: RPG::BaseItem, na área de complementos. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def load_notetags | |
container = [$data_actors, $data_classes, $data_skills, $data_items, | |
$data_weapons, $data_armors, $data_enemies, $data_states] | |
container.each do |object| | |
object.each do |item| | |
next unless item | |
item.start_note_container | |
end | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ extract_scripts │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Extrai todos os scripts da lista do RPG Maker para a pasta especificada. │ | |
#│ → folder: A pasta ou diretório. Deve terminar com / │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def extract_scripts(folder) | |
Dir.mkdir(folder) unless Dir.exists?(folder) | |
c = 0 | |
$RGSS_SCRIPTS.each {|sc| | |
n = folder_name_check(folder + sprintf("%d - #{sc[1]}.rb", c)) | |
t = sc[3] | |
next if t.empty? | |
begin | |
f = File.open(n, "w") | |
f.write(t) | |
ensure | |
f.close | |
end | |
c += 1 | |
} | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ► Complementos ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Esta área serve para guardar os complementos necessários do Prism. ║ | |
#║ Todos os extras requeridos ficam aqui. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Graphics ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class << Graphics | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ prism_update │ update │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
alias :prism_update :update | |
def update | |
prism_update | |
Prism.update | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Graphics ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Marshal ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class << Marshal | |
#┌───────────────┬──────┬────────────────────────────────────────────────────┐ | |
#│ ♦ prism_load │ load │ Permite a leitura de arquivos que não sejam do RM. │ | |
#└───────────────┴──────┴────────────────────────────────────────────────────┘ | |
alias :prism_load :load | |
def load(port, proc = nil) | |
prism_load(port, proc) | |
rescue TypeError | |
if port.kind_of?(File) | |
port.rewind | |
port.read | |
else | |
port | |
end | |
end | |
end unless Marshal.respond_to?(:prism_load) # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Marshal ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ DataManager ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class << DataManager | |
#┌────────────────────────┬───────────────┬─────────────────────────────────┐ | |
#│ ♦ prism_load_database │ load_database │ Inicia as notas do Database. │ | |
#└────────────────────────┴───────────────┴─────────────────────────────────┘ | |
alias :prism_load_database :load_database | |
def load_database | |
prism_load_database | |
Prism.load_notetags | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ DataManager ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ RPG::BaseItem ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class RPG::BaseItem | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :note_container | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ start_note_container │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Cria um depósito (container) onde todos os campos que estejam dentro do │ | |
#│ NOTE_SEPARATOR do Prism sejam guardados individualmente. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def start_note_container | |
sp = Prism::NOTE_SEPARATOR | |
@note_container = [] | |
self.note.scan(/#{sp[0]}[^>]*#{sp[1]}/).collect {|tag| | |
@note_container.push(tag) | |
} | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ in_container? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Checa se uma tag existe dentro do container. │ | |
#│ → expr: uma expressão regular (regular expression). │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def in_container?(expr) | |
@note_container.find {|tag| tag =~ expr} | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_tag │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém uma tag existente no container e o primeiro valor dela. │ | |
#│ → expr: uma expressão regular (regular expression). │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_tag(expr) | |
tag = in_container?(expr) | |
if tag && tag =~ expr | |
return $1 | |
else | |
return "" | |
end | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ RPG::BaseItem ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Game_Map ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Game_Map | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_x │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def adjust_x(x) | |
pos = (@display_x * 32).floor.to_f / 32 | |
if loop_horizontal? && x < pos - (width - screen_tile_x) / 2 | |
x - pos + @map.width | |
else | |
x - pos | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_y │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def adjust_y(y) | |
pos = (@display_y * 32).floor.to_f / 32 | |
if loop_vertical? && y < pos - (height - screen_tile_y) / 2 | |
y - pos + @map.height | |
else | |
y - pos | |
end | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Game_Map ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Export_Prism ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Isto serve para extrair o Prism inteiro em um arquivo Prism.data comprimido ║ | |
#║ usando a compressão Zlib. ║ | |
#║ O nome do script deve estar registrado logo abaixo para ser extraído. ║ | |
#║ A ordem dos scripts no arquivo extraído é a mesma ordem dele na lista de ║ | |
#║ scripts do editor. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Export_Prism | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Assim que você cria a classe, o initialize vai realizar todo o processo │ | |
#│ de extração. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize | |
# Lembre-se de adicionar o script nessa lista. | |
@list = [ | |
"♦ Prism", | |
"♦ Prism::File_Management", | |
"♦ Prism::Grid", | |
"♦ Prism::Point", | |
"♦ Prism::Scene", | |
"♦ Prism::Input", | |
"♦ Prism::Touch", | |
"♦ Prism::Touch_Input", | |
"♦ Prism::Event_Utils", | |
"♦ Prism::Base_Window", | |
"♦ Prism::Window_Select", | |
"♦ Prism::Window_Command", | |
"♦ Prism::Horz_Command", | |
"♦ Prism::Input_Window", | |
"♦ Prism::Base_Sprite", | |
"♦ Prism::Opening_Sprite", | |
"♦ Prism::Text_Sprite", | |
"♦ Prism::Gauge_Sprite", | |
"♦ Prism::Animated_Sprite", | |
"♦ Prism::Aura_Sprite", | |
"♦ Prism::Circular_Sprite", | |
"♦ Prism::Numeric_Sprite", | |
"♦ Prism::Jump_Sprite", | |
"♦ Prism::Flashing_Sprite", | |
"♦ Prism::Touch_Sprite", | |
"♦ Prism::Drag_Sprite", | |
"♦ Prism::GUI"] | |
extract_prism | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ extract_prism │ Nome auto-explicativo. │ | |
#└─────────────────┴─────────────────────────────────────────────────────────┘ | |
def extract_prism | |
data = "" | |
$RGSS_SCRIPTS.each {|script| | |
name = script[1] | |
code = script[3] | |
next unless @list.include?(name) | |
data += code + "\n\n" | |
} | |
Prism.export(data.force_encoding("UTF-8"), "Prism.data") | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Export_Prism ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::File_Management ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sistema de gerenciamento de arquivos em um subshell. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
module Prism::File_Management | |
extend self | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ move │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Move um arquivo ou pasta para o diretório especificado. │ | |
#│ Se um arquivo já existir na pasta de destino, ele será substituído. │ | |
#│ Para mover uma pasta, from não deve terminar em \\. │ | |
#│ Note que o diretório de destino deve existir antes de ser movido. │ | |
#│ → from: o diretório do arquivo/pasta. │ | |
#│ → to: o destino do arquivo/pasta. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def move(from, to) | |
Kernel.system("move \"#{from}\" \"#{to}\"") | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ copy │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Copia um arquivo para o diretório especificado. │ | |
#│ Se um arquivo já existir na pasta de destino, ele será substituído. │ | |
#│ Note que o diretório de destino deve existir antes de ser movido. │ | |
#│ → from: o diretório do arquivo. │ | |
#│ → to: o destino do arquivo. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def copy(from, to) | |
Kernel.system("copy \"#{from}\" \"#{to}\"") | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ copy_folder │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Copia um diretório e todos os seus arquivos para outro diretório. │ | |
#│ Se já existirem arquivos ou pastas no destino, eles serão substituídos. │ | |
#│ A menos, é claro, que substitute seja false. │ | |
#│ → from: a pasta que será movida (sem \\ no final). │ | |
#│ → to: o destino da pasta (sem \\ no final). │ | |
#│ → substitute: se ele deve substituir ou perguntar antes. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def copy_folder(from, to, substitute = true) | |
sub = substitute ? " /y" : "" | |
Kernel.system("xcopy \"#{from}\" \"#{to}\" /e /i /h#{sub}") | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ rename │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Renomeia um arquivo ou pasta. │ | |
#│ → source: o diretório do arquivo ou pasta que será renomeado. │ | |
#│ → name: o nome, e apenas o novo nome do arquivo ou pasta. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def rename(source, name) | |
Kernel.system("rename \"#{source}\" \"#{name}\"") | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::File_Management ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Grid ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ O Prism::Grid é uma coleção de arrays, contendo espaços verticais e ║ | |
#║ horizontais, e também camadas. Basicamente uma grade de arrays. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Grid | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ Cria a grade. │ | |
#├───────────────┴───────────────────────────────────────────────────────────┤ | |
#│ → x_size: o número de espaços horizontais na grade. │ | |
#│ → y_size: o número de espaços verticais na grade. │ | |
#│ → layers: o número de camadas da grade. Padrão: 1. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x_size, y_size, layers = 1) | |
@x_size = x_size | |
@y_size = y_size | |
@layers = layers | |
make_grid | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ make_grid │ Isto irá criar a grade. Não é preciso chamar novamente. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def make_grid | |
@grid = {} | |
layers = Array.new(@layers) | |
rows = Array.new(@y_size) | |
cols = Array.new(@x_size) | |
for i in 0...layers.size | |
@grid[i] = rows.clone | |
end | |
@grid.each_key do |layer| | |
for i in 0...@grid[layer].size | |
@grid[layer][i] = cols.clone | |
end | |
end | |
layers = rows = cols = nil | |
end | |
#┌───────┬───────────────────────────────────────────────────────────────────┐ | |
#│ ♦ [] │ Obtém um elemento da grade. │ | |
#├───────┴───────────────────────────────────────────────────────────────────┤ | |
#│ Este método serve para que você obtenha qualquer elemento da grade. │ | |
#│ Elementos que não existem na grade sempre retornarão nil. │ | |
#│ Caso você tente obter informações sobre elementos que estejam além do │ | |
#│ limite da grade, haverá uma mensagem de notificação e o resultado será │ | |
#│ nil. │ | |
#│ Os seguintes argumentos são necessários. │ | |
#│ → x: a posição horizontal do objeto na grade. │ | |
#│ → y: a posição vertical do objeto na grade. │ | |
#│ → z: a camada do objeto na grade. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def [](*val) | |
x = val[0] | |
y = val[1] | |
z = val[2] ? val[2] : 0 | |
begin | |
if @grid[z] | |
res = @grid[z][y][x] | |
else | |
res = nil | |
end | |
rescue | |
w = "O conteúdo que você está tentando obter\nestá fora do limite da grade." | |
Prism.warn_box("Atenção", w) | |
return nil | |
end | |
return res | |
end | |
#┌────────┬──────────────────────────────────────────────────────────────────┐ | |
#│ ♦ []= │ Altera um elemento da grade. │ | |
#├────────┴──────────────────────────────────────────────────────────────────┤ | |
#│ Similar ao [], porém serve para alterar um elemento da grade. │ | |
#│ Se você tentar alterar um elemento que esteja fora dos limites da grade, │ | |
#│ haverá uma mensagem de aviso e nenhuma alteração será feita. │ | |
#│ Os seguintes argumentos são necessários. │ | |
#│ → x: a posição horizontal do objeto na grade. │ | |
#│ → y: a posição vertical do objeto na grade. │ | |
#│ → z: a camada do objeto na grade. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def []=(*val) | |
x = val[0] | |
y = val[1] | |
z = val[2] ? val[2] : 0 | |
res = val[3] | |
begin | |
@grid[z][y][x] = res if @grid[z] | |
rescue | |
w = "O conteúdo que você está tentando alterar\nestá fora do limite da grade.\n" | |
w2 = "Nenhuma alteração será feita." | |
Prism.warn_box("Atenção", w << w2) | |
end | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ horizontal_size │ Retorna o número de espaços horizontais da grade. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def horizontal_size | |
@x_size | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ vertical_size │ Retorna o número de espaços verticais da grade. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def vertical_size | |
@y_size | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ layers_size │ Retorna o número de camadas da grade. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def layers_size | |
@layers | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ layer │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém todos os elementos existentes em uma específica camada. │ | |
#│ Elementos que não existem (nil) serão ignorados. │ | |
#│ → num: o número da camada específica. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def layer(num) | |
array = [] | |
for col in @grid[num] | |
next if col.compact.empty? | |
array.push(col.compact) | |
end | |
return array | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ up │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Retorna o elemento que esteja logo acima do objeto especificado. │ | |
#│ Os seguintes argumentos são necessários: │ | |
#│ → x: a posição horizontal do objeto. │ | |
#│ → y: a posição vertical do objeto. │ | |
#│ → z: a camada do objeto. │ | |
#│ Lembrando que o que será retornado não será o objeto especificado, e sim │ | |
#│ o que está logo acima dele. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def up(*val) | |
layer = val[2] | |
row = val[1] | |
col = val[0] | |
return @grid[layer][row - 1][col] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ right │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Mesma coisa do up, porém retorna o elemento que está logo à direita do │ | |
#│ objeto especificado. │ | |
#│ Os argumentos são os mesmos do up. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def right(*val) | |
layer = val[2] | |
row = val[1] | |
col = val[0] | |
return @grid[layer][row][col + 1] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ left │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Mesma coisa do up, porém retorna o elemento que está logo à esquerda do │ | |
#│ objeto especificado. │ | |
#│ Os argumentos são os mesmos do up. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def left(*val) | |
layer = val[2] | |
row = val[1] | |
col = val[0] | |
return @grid[layer][row][col - 1] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ down │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Mesma coisa do up, porém retorna o elemento que está logo abaixo do │ | |
#│ objeto especificado. │ | |
#│ Os argumentos são os mesmos do up. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def down(*val) | |
layer = val[2] | |
row = val[1] | |
col = val[0] | |
return @grid[layer][row + 1][col] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ resize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Altera o tamanho da grade para as dimensões especificadas. │ | |
#│ Os dados já existentes serão mantidos. │ | |
#│ → x_size: o número de espaços horizontais na grade. │ | |
#│ → y_size: o número de espaços verticais na grade. │ | |
#│ → layers: o número de camadas da grade. Requerido. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def resize(x, y, z) | |
new_grid = {} | |
for i in 0...z | |
new_grid[i] = Array.new(y) | |
end | |
new_grid.each_key do |row| | |
for i in 0...new_grid[row].size | |
new_grid[row][i] = Array.new(x) | |
end | |
end | |
new_grid.each_key do |row| | |
for i in 0...new_grid[row].size | |
for j in 0...new_grid[row][i].size | |
new_grid[row][i][j] = @grid[row][i][j] | |
end | |
end | |
end | |
@x_size = x | |
@y_size = y | |
@layers = z | |
@grid = new_grid | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ resize! │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Altera "destrutivamente" o tamanho da grade para as dimensões │ | |
#│ especificadas. │ | |
#│ Obviamente, os dados já existentes serão deletados. │ | |
#│ → x_size: o número de espaços horizontais na grade. │ | |
#│ → y_size: o número de espaços verticais na grade. │ | |
#│ → layers: o número de camadas da grade. Requerido. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def resize!(x, y, z) | |
new_grid = {} | |
for i in 0...z | |
new_grid[i] = Array.new(y) | |
end | |
new_grid.each_key do |row| | |
for i in 0...new_grid[row].size | |
new_grid[row][i] = Array.new(x) | |
end | |
end | |
@x_size = x | |
@y_size = y | |
@layers = z | |
@grid = new_grid | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ move │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Move o objeto especificado para outro lugar da grade. │ | |
#│ Se houver um objeto no lugar de destino, ele será substituído, cuidado. │ | |
#│ Se você estiver tentando obter posições que estejam além do limite da │ | |
#│ grade, você receberá uma mensagem de aviso e nenhuma alteração será │ | |
#│ feita. │ | |
#│ Exemplo: move([1, 1, 1], [1, 2, 1]) │ | |
#│ → from: uma array contendo a posição do objeto que será movido. │ | |
#│ → to: uma array contendo a posição de destino do objeto. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def move(from, to) | |
if from[0] > @x_size || from[1] > @y_size || from[2] > @layers | |
w = "O conteúdo que você está tentando obter\nestá fora do limite da grade." | |
Prism.warn_box("Atenção", w) | |
return nil | |
elsif to[0] > @x_size || to[1] > @y_size || to[2] > @layers | |
w = "O conteúdo que você está tentando obter\nestá fora do limite da grade." | |
Prism.warn_box("Atenção", w) | |
return nil | |
end | |
current = @grid[from[2]][from[1]][from[0]] | |
@grid[to[2]][to[1]][to[0]] = current | |
@grid[from[2]][from[1]][from[0]] = nil | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Grid ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Point ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ A classe dos pontos do Prism. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Point | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância públicas │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :x | |
attr_accessor :y | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize | |
@x = 0 | |
@y = 0 | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Point ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Scene ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Uma scene que dá automaticamente o update em todas os sprites que forem ║ | |
#║ herdados de Prism::Base_Sprite. E umas coisinhas a mais. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Scene < Scene_Base | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ start │ Inicia a cena. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def start | |
super | |
make_reserved_bitmap_list | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ make_reserved_bitmap_list │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Não processa o dispose nos bitmaps dos sprites que estiverem nessa │ | |
#│ lista. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def make_reserved_bitmap_list | |
@reserved_bitmaps = [] | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
fixed_update if Prism.run_fixed_update? | |
second_update if Prism.run_second_update? | |
update_all_images | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ fixed_update │ Atualização a cada 15 frames. │ | |
#└─────────────────┴─────────────────────────────────────────────────────────┘ | |
def fixed_update | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ second_update │ Atualização a cada 1 segundo. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def second_update | |
end | |
#┌──────────────────────┬────────────────────────────────────────────────────┐ | |
#│ ♦ update_all_images │ Atualiza todas as imagens do Prism. │ | |
#└──────────────────────┴────────────────────────────────────────────────────┘ | |
def update_all_images | |
instance_variables.each do |var| | |
ivar = instance_variable_get(var) | |
ivar.update if ivar.is_a?(Prism::Base_Sprite) | |
end | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ terminate │ Finalização da cena. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def terminate | |
Input.update | |
super | |
dispose_all_images | |
end | |
#┌───────────────────────┬───────────────────────────────────────────────────┐ | |
#│ ♦ dispose_all_images │ Se livra de todas as imagens. │ | |
#└───────────────────────┴───────────────────────────────────────────────────┘ | |
def dispose_all_images | |
instance_variables.each do |var| | |
ivar = instance_variable_get(var) | |
if ivar.is_a?(Sprite) | |
unless @reserved_bitmaps.include?(ivar) | |
ivar.bitmap.dispose unless ivar.bitmap.disposed? | |
end | |
ivar.dispose unless ivar.disposed? | |
end | |
end | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Scene ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Input ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um Input que aceita mais teclas do teclado. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
module Prism::Input | |
extend self | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Códigos virtuais de tecla │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
KEYS = { | |
:NUM0 => 0x60, :NUM5 => 0x65, :N0 => 0x30, :N5 => 0x35, | |
:NUM1 => 0x61, :NUM6 => 0x66, :N1 => 0x31, :N6 => 0x36, | |
:NUM2 => 0x62, :NUM7 => 0x67, :N2 => 0x32, :N7 => 0x37, | |
:NUM3 => 0x63, :NUM8 => 0x68, :N3 => 0x33, :N8 => 0x38, | |
:NUM4 => 0x64, :NUM9 => 0x69, :N4 => 0x34, :N9 => 0x39, | |
:A => 0x41, :E => 0x45, :I => 0x49, :M => 0x4D, :Q => 0x51, :U => 0x55, | |
:B => 0x42, :F => 0x46, :J => 0x4A, :N => 0x4E, :R => 0x52, :V => 0x56, | |
:C => 0x43, :G => 0x47, :K => 0x4B, :O => 0x4F, :S => 0x53, :W => 0x57, | |
:D => 0x44, :H => 0x48, :L => 0x4C, :P => 0x50, :T => 0x54, :X => 0x58, | |
:Y => 0x59, :Z => 0x5A, :Ç => 0xBA, | |
:BACKSPACE => 0x08, :CAPS => 0x14, :CTRL => 0x11, :PGDN => 0x22, | |
:TAB => 0x1B, :ESC => 0x1B, :ALT => 0x12, :PGUP => 0x21, | |
:ENTER => 0x23, :SPACE => 0x20, :End => 0x23, :MOUSEL => 0x01, | |
:SHIFT => 0x02, :DELETE => 0x2E, :INSERT => 0x2D, :MOUSER => 0x02, | |
:MOUSEM => 0x04, :PAUSE => 0x13, :RETURN => 0x0D, | |
:MULTIPLY => 0x6A, :DECIMAL => 0x6E, :MINUS => 0xBD, :ACCUTE => 0xDB, | |
:ADD => 0x6B, :DIVIDE => 0x6F, :DOT => 0xBE, :QUOTE => 0xC0, | |
:SEPARATOR => 0x6C, :PLUS => 0xBB, :COLON => 0xBF, :BRACKET => 0xDD, | |
:SUBTRACT => 0x6D, :COMMA => 0xBC, :LASH => 0xC1, :BRACKET2 => 0xDC, | |
:TIL => 0xDE, :BACKLASH => 0xE2, | |
:F1 => 0x70, :F5 => 0x74, :F9 => 0x78, :F13 => 0x7C, :F17 => 0x80, | |
:F2 => 0x71, :F6 => 0x75, :F10 => 0x79, :F14 => 0x7D, :F18 => 0x81, | |
:F3 => 0x72, :F7 => 0x76, :F11 => 0x7A, :F15 => 0x7E, :F19 => 0x82, | |
:F4 => 0x73, :F8 => 0x77, :F12 => 0x7B, :F16 => 0x7F, :F20 => 0x83, | |
:F21 => 0x84, :F22 => 0x85, :F23 => 0x86, :F24 => 0x87 | |
} | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Hash que converte a tecla pressionada em texto. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
CHARACTERS = { | |
:caps => { | |
:NUM0 => '0', :NUM1 => '1', :NUM2 => '2', :NUM3 => '3', :NUM4 => '4', | |
:NUM5 => '5', :NUM6 => '6', :NUM7 => '7', :NUM8 => '8', :NUM9 => '9', | |
:N0 => ')', :N1 => '!', :N2 => '@', :N3 => '#', :N4 => '$', | |
:N5 => '%', :N6 => '¨', :N7 => '&', :N8 => '*', :N9 => '(', | |
:A => 'A', :B => 'B', :C => 'C', :D => 'D', :E => 'E', :F => 'F', | |
:G => 'G', :H => 'H', :I => 'I', :J => 'J', :K => 'K', :L => 'L', | |
:M => 'M', :N => 'N', :O => 'O', :P => 'P', :Q => 'Q', :R => 'R', | |
:S => 'S', :T => 'T', :U => 'U', :V => 'V', :W => 'W', :X => 'X', | |
:Y => 'Y', :Z => 'Z', :Ç => 'Ç', | |
:MULTIPLY => '*', :ADD => '+', :SEPARATOR => '.', | |
:SUBTRACT => '-', :DECIMAL => ',', :DIVIDE => '/', | |
:PLUS => '+', :COMMA => '<', :MINUS => '_', | |
:DOT => '>', :COLON => ':', :LASH => '?', | |
:ACCUTE => '`', :QUOTE => '"', :BRACKET => '{', | |
:BRACKET2 => '}', :BACKLASH => '|', :TIL => '^', | |
:SPACE => ' '}, | |
:lower => { | |
:NUM0 => '0', :NUM1 => '1', :NUM2 => '2', :NUM3 => '3', :NUM4 => '4', | |
:NUM5 => '5', :NUM6 => '6', :NUM7 => '7', :NUM8 => '8', :NUM9 => '9', | |
:N0 => '0', :N1 => '1', :N2 => '2', :N3 => '3', :N4 => '4', | |
:N5 => '5', :N6 => '6', :N7 => '7', :N8 => '8', :N9 => '9', | |
:A => 'a', :B => 'b', :C => 'c', :D => 'd', :E => 'e', :F => 'f', | |
:G => 'g', :H => 'h', :I => 'i', :J => 'j', :K => 'k', :L => 'l', | |
:M => 'm', :N => 'n', :O => 'o', :P => 'p', :Q => 'q', :R => 'r', | |
:S => 's', :T => 't', :U => 'u', :V => 'v', :W => 'w', :X => 'x', | |
:Y => 'y', :Z => 'z', :Ç => 'ç', | |
:MULTIPLY => '*', :ADD => '+', :SEPARATOR => '.', | |
:SUBTRACT => '-', :DECIMAL => ',', :DIVIDE => '/', | |
:PLUS => '=', :COMMA => ',', :MINUS => '-', | |
:DOT => '.', :COLON => ';', :LASH => '/', | |
:ACCUTE => '´', :QUOTE => "'", :BRACKET => '[', | |
:BRACKET2 => ']', :BACKLASH => '\\', :TIL => '~', | |
:SPACE => ' '}, | |
:accented => { | |
'a' => %w(á ã â à ä), 'A' => %w(Á Ã Â À Ä), | |
'e' => %w(é ~e ê è ë), 'E' => %w(É ~E Ê È Ë), | |
'i' => %w(í ~i î ì ï), 'I' => %w(Í ~I Î Ì Ï), | |
'o' => %w(ó õ ô ò ö), 'O' => %w(Ó Õ Ô Ò Ö), | |
'u' => %w(ú ~u û ù ü), 'U' => %w(Ú ~U Û Ù Ü), | |
'y' => %w(ý ~y ^y `y ÿ), 'Y' => %w(Ý ~Y ^Y `Y ¨Y)}, | |
:accents => %w(´ ~ ^ ` ¨), | |
:accent_list => %w(A a E e I i O o U u Y y), | |
} | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Api │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
KEYSTATE = Win32API.new("user32", "GetAsyncKeyState", "i", "i") | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ state │ Abreviação para adquirir o estado do teclado. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def state | |
KEYSTATE | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ shift? │ Indica se a tecla SHIFT está sendo pressionada. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def shift? | |
state.call(16) != 0 ? true : false | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de instância │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
@trigger = [] | |
@repeat_trigger = [] | |
@count = [] | |
@timer = 0 | |
@touch = {} | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_pressed? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Informa se uma tecla está sendo pressionada. │ | |
#│ → key: uma constante da lista acima. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_pressed?(key) | |
if key.is_a?(Symbol) | |
k = KEYS[key] | |
else | |
k = key | |
end | |
state.call(k) != 0 if k | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_triggered? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Informa se uma tecla foi pressionada uma vez. │ | |
#│ → key: uma constante da lista acima. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_triggered?(key) | |
if is_pressed?(key) | |
if @trigger.include?(key) | |
return false | |
else | |
@trigger.push(key) | |
return true | |
end | |
else | |
@trigger.delete(key) if @trigger.include?(key) | |
return false | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_repeated? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Informa se uma tecla está sendo pressionada repetidamente. │ | |
#│ → key: uma constante da lista acima. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_repeated?(key) | |
if is_pressed?(key) | |
@repeat_trigger.push(key) unless @repeat_trigger.include?(key) | |
ind = @repeat_trigger.index(key) | |
@count[ind].nil? ? @count[ind] = 0 : @count[ind] += 1 | |
condition = (@count[ind] >= 30 && @count[ind] % 3 == 1) | |
return @count[ind] == 1 ? true : condition | |
else | |
ind = @repeat_trigger.index(key) if @repeat_trigger.include?(key) | |
@count[ind] = nil if ind | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_touch_triggered? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Mesma coisa do is_triggered?, porém é usado apenas pelo Touch_Input. │ | |
#│ → obj: objeto que servirá como referência única do registro. │ | |
#│ → key: uma constante da lista acima. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_touch_triggered?(obj, key) | |
@touch[obj] ||= {}; @touch[obj][:trigger] ||= [] | |
if is_pressed?(key) | |
if @touch[obj][:trigger].include?(key) | |
return false | |
else | |
@touch[obj][:trigger].push(key) | |
return true | |
end | |
else | |
@touch[obj][:trigger].delete(key) if @touch[obj][:trigger].include?(key) | |
return false | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_touch_repeated? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Mesma coisa do is_repeated?, porém é usado apenas pelo Touch_Input. │ | |
#│ → obj: objeto que servirá como referência única do registro. │ | |
#│ → key: uma constante da lista acima. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_touch_repeated?(obj, key) | |
@touch[obj] ||= {}; @touch[obj][:repeat] ||= [] | |
@touch[obj] ||= {}; @touch[obj][:repeat_count] ||= [] | |
if is_pressed?(key) | |
@touch[obj][:repeat].push(key) unless @touch[obj][:repeat].include?(key) | |
ind = @touch[obj][:repeat].index(key) | |
@touch[obj][:repeat_count][ind].nil? ? @touch[obj][:repeat_count][ind] = 0 : @touch[obj][:repeat_count][ind] += 1 | |
condition = (@touch[obj][:repeat_count][ind] >= 30 && @touch[obj][:repeat_count][ind] % 3 == 1) | |
return @touch[obj][:repeat_count][ind] == 1 ? true : condition | |
else | |
ind = @touch[obj][:repeat].index(key) if @touch[obj][:repeat].include?(key) | |
@touch[obj][:repeat_count][ind] = nil if ind | |
end | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Input ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Touch ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ A base para o sistema de toque do Prism. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
module Prism::Touch | |
extend self | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Apis do sistema │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
Sys = { | |
:gcp => Win32API.new("user32", "GetCursorPos", "p", "i"), | |
:stc => Win32API.new("user32", "ScreenToClient", "lp", "i"), | |
:pps => Win32API.new("kernel32", "GetPrivateProfileStringA", "pppplp", "l"), | |
:fwn => Win32API.new("user32", "FindWindowA", "pp", "l"), | |
:scp => Win32API.new("user32", "SetCursorPos", "ll", "i"), | |
:scr => Win32API.new("user32", "ShowCursor", "i", "i") | |
} | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de posição. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
@real_mouse_x = 0 # A posição X real do mouse na tela. | |
@real_mouse_y = 0 # A posição Y real do mouse na tela. | |
@x = 0 # A posição X do mouse na tela do jogo. | |
@y = 0 # A posição Y do mouse na tela do jogo. | |
@last_x = 0 # A posição do último toque do mouse em X. | |
@last_y = 0 # A posição do último toque do mouse em Y. | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update | |
update_last_info | |
pos = [0, 0].pack("ll") | |
win = ->() { | |
gm = "\0" * 256 | |
Sys[:pps].call("Game", "Title", "", gm, 255, ".\\Game.ini") | |
gm.delete!("\0") | |
return Sys[:fwn].call("RGSS Player", gm || "0") | |
} | |
Sys[:gcp].call(pos) | |
@real_mouse_x = pos.unpack("ll")[0] | |
@real_mouse_y = pos.unpack("ll")[1] | |
Sys[:stc].call(win.call(), pos) | |
@x = pos.unpack("ll")[0] | |
@y = pos.unpack("ll")[1] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update_last_info │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update_last_info | |
if Prism::Input.is_pressed?(1) || Prism::Input.is_pressed?(2) | |
@last_x = @x | |
@last_y = @y | |
end | |
end | |
#┌─────────────┬─────────────────────────────────────────────────────────────┐ | |
#│ ♦ last_pos │ Obtém a última posição de toque. │ | |
#└─────────────┴─────────────────────────────────────────────────────────────┘ | |
def last_pos | |
return [@last_x, @last_y] | |
end | |
#┌────────┬──────────────────────────────────────────────────────────────────┐ | |
#│ ♦ pos │ Obtém as coordenadas do cursor. │ | |
#└────────┴──────────────────────────────────────────────────────────────────┘ | |
def pos | |
return [@x, @y] | |
end | |
#┌─────────────┬─────────────────────────────────────────────────────────────┐ | |
#│ ♦ real_pos │ Obtém as coordenadas reais do cursor. │ | |
#└─────────────┴─────────────────────────────────────────────────────────────┘ | |
def real_pos | |
return [@real_mouse_x, @real_mouse_y] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Muda a posição do cursor para a posição desejada. │ | |
#│ → x: a posição horizontal. │ | |
#│ → y: a posição vertical. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set(x, y) | |
Sys[:scp].call(x, y) | |
end | |
#┌─────────┬─────────────────────────────────────────────────────────────────┐ | |
#│ ♦ show │ Mostra o cursor. │ | |
#└─────────┴─────────────────────────────────────────────────────────────────┘ | |
def show | |
Sys[:scr].call(1) | |
end | |
#┌─────────┬─────────────────────────────────────────────────────────────────┐ | |
#│ ♦ hide │ Esconde o cursor. │ | |
#└─────────┴─────────────────────────────────────────────────────────────────┘ | |
def hide | |
Sys[:scr].call(0) | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Touch ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Touch_Input ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ O sistema de toque do Prism. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
module Prism::Touch_Input | |
extend self | |
#┌──────┬────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ x │ A posição horizontal do mouse. │ | |
#└──────┴────────────────────────────────────────────────────────────────────┘ | |
def x | |
return Prism::Touch.pos[0] | |
end | |
#┌──────┬────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ y │ A posição vertical do mouse. │ | |
#└──────┴────────────────────────────────────────────────────────────────────┘ | |
def y | |
return Prism::Touch.pos[1] | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ is_pressed? │ Indica se está sendo tocado. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def is_pressed? | |
return Prism::Input.is_pressed?(1) | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ is_triggered? │ Indica se foi tocado uma vez. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def is_triggered?(obj = nil) | |
return Prism::Input.is_touch_triggered?(obj || self, 1) | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ is_repeated? │ Indica se está sendo tocado repetidamente. │ | |
#└─────────────────┴─────────────────────────────────────────────────────────┘ | |
def is_repeated?(obj = nil) | |
return Prism::Input.is_touch_repeated?(obj || self, 1) | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ is_cancelling? │ Indica se está sendo cancelado. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def is_cancelling? | |
return Prism::Input.is_pressed?(2) | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ is_cancelled? │ Indica se foi cancelado uma vez. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def is_cancelled?(obj = nil) | |
return Prism::Input.is_touch_triggered?(obj || self, 2) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ hovering? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se o cursor está acima de algo. │ | |
#│ → sx: a posição horizontal do objeto. │ | |
#│ → sy: a posição vertical do objeto. │ | |
#│ → width: a largura do objeto. │ | |
#│ → height: a altura do objeto. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def hovering?(sx, sy, width, height) | |
c1 = x >= sx && x <= sx + width | |
c2 = y >= sy && y <= sy + height | |
return c1 && c2 | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Touch_Input ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Event_Utils ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Alguns métodos que podem ajudar na hora de obter informações sobre os ║ | |
#║ eventos no mapa. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
module Prism::Event_Utils | |
extend self | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Classe │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
@@px = 0 | |
@@py = 0 | |
@@di = 0 | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ player_pos │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Informa a posição do jogador, também informa a direção dele. │ | |
#│ → type: um tipo da lista abaixo: │ | |
#│ :x retorna a posição horizontal do jogador no mapa. │ | |
#│ :y retorna a posição vertical do jogador no mapa. │ | |
#│ :d retorna um número com a direção do jogador. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def player_pos(type) | |
case type | |
when :x; return @@px | |
when :y; return @@py | |
when :d; return @@di | |
else; return false | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_player_direction │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Retorna a direção do jogador em :left, :right, :up ou :down. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_player_direction | |
res = :void | |
case @@di | |
when 4; res = :left | |
when 6; res = :right | |
when 8; res = :up | |
when 2; res = :down | |
end | |
return res | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_map_event │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém um evento no mapa nas coordenadas especificadas. │ | |
#│ → x: a coordenada horizontal do evento no mapa. │ | |
#│ → y: a coordenada vertical do evento no mapa. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_map_event(x, y) | |
ev = nil | |
$game_map.events.each {|event| | |
next unless event[1] && event[1].is_a?(Game_Event) | |
next unless event[1].x == x && event[1].y == y | |
ev = event[1] | |
break | |
} | |
return ev | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_right_event │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o evento que está exatamente à direita do jogador. │ | |
#│ → range: a distância que o evento estará. │ | |
#│ → in_range: se o evento deve estar dentro da distância ou não. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_right_event(range = 1, in_range = false) | |
res = nil | |
if in_range | |
for i in 0...range | |
if get_map_event(@@px + (i + 1), @@py) | |
res = get_map_event(@@px + (i + 1), @@py) | |
break | |
end | |
end | |
else | |
res = get_map_event(@@px + range, @@py) | |
end | |
return res | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_left_event │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o evento que está exatamente à esquerda do jogador. │ | |
#│ → range: a distância que o evento estará. │ | |
#│ → in_range: se o evento deve estar dentro da distância ou não. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_left_event(range = 1, in_range = false) | |
res = nil | |
if in_range | |
for i in 0...range | |
if get_map_event(@@px - (i + 1), @@py) | |
res = get_map_event(@@px - (i + 1), @@py) | |
break | |
end | |
end | |
else | |
res = get_map_event(@@px - range, @@py) | |
end | |
return res | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_up_event │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o evento que está exatamente acima do jogador. │ | |
#│ → range: a distância que o evento estará. │ | |
#│ → in_range: se o evento deve estar dentro da distância ou não. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_up_event(range = 1, in_range = false) | |
res = nil | |
if in_range | |
for i in 0...range | |
if get_map_event(@@px, @@py - (i + 1)) | |
res = get_map_event(@@px, @@py - (i + 1)) | |
break | |
end | |
end | |
else | |
res = get_map_event(@@px, @@py - range) | |
end | |
return res | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_down_event │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o evento que está exatamente abaixo do jogador. │ | |
#│ → range: a distância que o evento estará. │ | |
#│ → in_range: se o evento deve estar dentro da distância ou não. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_down_event(range = 1, in_range = false) | |
res = nil | |
if in_range | |
for i in 0...range | |
if get_map_event(@@px, @@py + (i + 1)) | |
res = get_map_event(@@px, @@py + (i + 1)) | |
break | |
end | |
end | |
else | |
res = get_map_event(@@px, @@py + range) | |
end | |
return res | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_diagonal_up_event │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Retorna uma array com os eventos que estiverem acima do jogador na │ | |
#│ diagonal. │ | |
#│ → range: a distância que o evento estará. │ | |
#│ → in_range: se o evento deve estar dentro da distância ou não. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_diagonal_up_event(range = 1, in_range = false) | |
res = [] | |
if in_range | |
for i in 0...range | |
up_right = get_map_event(@@px + (i + 1), @@py - (i + 1)) | |
up_left = get_map_event(@@px - (i + 1), @@py - (i + 1)) | |
if up_right | |
res.push(up_right) | |
end | |
if up_left | |
res.push(up_left) | |
end | |
end | |
else | |
up_right = get_map_event(@@px + 1, @@py - 1) | |
up_left = get_map_event(@@px - 1, @@py - 1) | |
res.push(up_right) if up_right | |
res.push(up_left) if up_left | |
end | |
return res | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_diagonal_down_event │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Retorna uma array com os eventos que estiverem abaixo do jogador na │ | |
#│ diagonal. │ | |
#│ → range: a distância que o evento estará. │ | |
#│ → in_range: se o evento deve estar dentro da distância ou não. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_diagonal_down_event(range = 1, in_range = false) | |
res = [] | |
if in_range | |
for i in 0...range | |
down_right = get_map_event(@@px + (i + 1), @@py + (i + 1)) | |
down_left = get_map_event(@@px - (i + 1), @@py + (i + 1)) | |
if down_right | |
res.push(down_right) | |
end | |
if down_left | |
res.push(down_left) | |
end | |
end | |
else | |
down_right = get_map_event(@@px + 1, @@py + 1) | |
down_left = get_map_event(@@px - 1, @@py + 1) | |
res.push(down_right) if down_right | |
res.push(down_left) if down_left | |
end | |
return res | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_event_comments │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém todos os comentários da página principal de um evento. │ | |
#│ Se params for um Game_Event ou qualquer superclasse, ele irá obter │ | |
#│ os comentários diretamente daquele evento. │ | |
#│ Porém se params for x e y, ele irá obter o evento no mapa, e então irá │ | |
#│ pegar os comentários dele. │ | |
#│ → params: (x, y) ou (evento) │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_event_comments(*params) | |
text = "" | |
if params.size > 1 | |
x = params[0] | |
y = params[1] | |
ev = get_map_event(x, y) | |
if ev.list | |
for cmd in ev.list | |
next unless cmd.is_a?(RPG::EventCommand) | |
next unless cmd.code == 108 || cmd.code == 408 | |
text += cmd.parameters[0] + "\n" | |
end | |
end | |
else | |
ev = params[0] | |
if ev.list | |
for cmd in ev.list | |
next unless cmd.is_a?(RPG::EventCommand) | |
next unless cmd.code == 108 || cmd.code == 408 | |
text += cmd.parameters[0] + "\n" | |
end | |
end | |
end | |
return text | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualização das informações. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update | |
update_components | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update_components │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualização de componentes. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update_components | |
@@px = $game_player.x | |
@@py = $game_player.y | |
@@di = $game_player.direction | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Event_Utils ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Base_Window ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Uma janela de base do Prism. Ela possui diversos métodos que podem ser bem ║ | |
#║ úteis, e são essenciais para todas as outras janelas herdadas dela. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Base_Window < Window | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal. │ | |
#│ → y: posição vertical. │ | |
#│ → width: largura. │ | |
#│ → height: altura. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height) | |
super | |
self.windowskin = Cache.system("Window") | |
update_padding | |
update_tone | |
create_contents | |
make_animation_list | |
@opening = @closing = @busy = false | |
@move_speed = 4 | |
@opacity_speed = 4 | |
@opening_speed = 18 | |
@move_route = [] | |
@write_message = {} | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ opening_speed │ Velocidade de abertura. Vale para o fechamento também. │ | |
#└─────────────────┴─────────────────────────────────────────────────────────┘ | |
def opening_speed | |
return @opening_speed | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ opening_speed= │ Altera a velocidade de abertura e fechamento. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def opening_speed=(v) | |
@opening_speed = v | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ make_animation_list │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Cria uma lista de animações de movimento para serem usadas a qualquer │ | |
#│ momento. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def make_animation_list | |
@anim_list = {} | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ add_animation │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Adiciona uma animação à lista de animações. │ | |
#│ → name: o nome da animação na lista de animações. │ | |
#│ → x: a posição de destino horizontal da janela. │ | |
#│ → y: a posição de destino vertical da janela. │ | |
#│ → width: a largura de destino da janela. │ | |
#│ → height: a altura de destino da janela. │ | |
#│ → op: a opacidade de destino da janela. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def add_animation(name, x, y, w, h, op) | |
@anim_list[name] = [x, y, w, h, op] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ start_animation │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Executa uma animação da lista de animações de movimento. │ | |
#│ → anim: o símbolo da animação na lista de animações. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def start_animation(anim) | |
list = @anim_list[anim] | |
case list.size | |
when 1; move_to(list[0]) | |
when 2; move_to(list[0], list[1]) | |
when 3; move_to(list[0], list[1], list[2]) | |
when 4; move_to(list[0], list[1], list[2], list[3]) | |
when 5; move_to(list[0], list[1], list[2], list[3], list[4]) | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ opening_sound │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Reproduz um som ao abrir a janela. │ | |
#│ → enable: true para ativar, false para desativar. Padrão: false │ | |
#│ → sound: o som para reproduzir. Deve estar na pasta Audio/SE │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def opening_sound(enable = false, sound = RPG::SE.new("Ice1", 80, 100)) | |
if enable | |
sound.play | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ closing_sound │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Reproduz um som ao fechar a janela. │ | |
#│ → enable: true para ativar, false para desativar. Padrão: false │ | |
#│ → sound: o som para reproduzir. Deve estar na pasta Audio/SE │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def closing_sound(enable = false, sound = RPG::SE.new("Ice2", 80, 100)) | |
if enable | |
sound.play | |
end | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ window_padding │ A distância entre a borda da janela e o conteúdo. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def window_padding | |
return 12 | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ line_height │ A altura da linha da janela. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def line_height | |
return 24 | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ fitting_height │ Calcula a altura da janela para o número de linhas. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def fitting_height(line_number) | |
line_number * line_height + window_padding * 2 | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ create_contents │ Cria e recria o bitmap para o conteúdo da janela. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def create_contents | |
self.contents.dispose | |
if contents_width > 0 && contents_height > 0 | |
self.contents = Bitmap.new(contents_width, contents_height) | |
else | |
self.contents = Bitmap.new(1, 1) | |
end | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ contents_width │ A largura do conteúdo visível da janela. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def contents_width | |
if self.width - window_padding * 2 < 1 | |
return 1 | |
end | |
return self.width - window_padding * 2 | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ contents_height │ A altura do conteúdo visível da janela. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def contents_height | |
if self.height - window_padding * 2 < 1 | |
return 1 | |
end | |
return self.height - window_padding * 2 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ busy_mode │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ O modo de ocupação da janela. │ | |
#│ → open_mode: estará ocupada quando estiver aberta. │ | |
#│ → active_mode: estará ocupada quando estiver ativa. │ | |
#│ → moving_mode: estará ocupada quando estiver se movendo. │ | |
#│ → all_mode: quando estiver aberta e ativa ou se movendo. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def busy_mode | |
return :active_mode | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ move_speed │ A velocidade de movimento da janela (em pixels). │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def move_speed | |
return @move_speed | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ opacity_speed │ A velocidade de alteração da opacidade. │ | |
#└─────────────────┴─────────────────────────────────────────────────────────┘ | |
def opacity_speed | |
return @opacity_speed | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ move_speed= │ Altera a velocidade de movimento para v. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def move_speed=(v) | |
@move_speed = v | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ opacity_speed= │ Altera a velocidade de alteração da opacidade para v. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def opacity_speed=(v) | |
@opacity_speed = v | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
fixed_update if Prism.run_fixed_update? | |
second_update if Prism.run_second_update? | |
update_tone | |
update_padding | |
update_busy | |
update_movement | |
update_write_message | |
update_open if @opening | |
update_close if @closing | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ fixed_update │ Atualização a cada 15 frames. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def fixed_update | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ second_update │ Atualização a cada 1 segundo (60 frames). │ | |
#└─────────────────┴─────────────────────────────────────────────────────────┘ | |
def second_update | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ update_tone │ Atualiza a tonalidade da janela. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def update_tone | |
self.tone.set($game_system.window_tone) | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ update_padding │ Atualiza o padding da janela. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def update_padding | |
self.padding = window_padding | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ update_busy │ Atualiza a ocupação da janela. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def update_busy | |
if busy_mode == :open_mode | |
open? ? @busy = true : @busy = false | |
elsif busy_mode == :active_mode | |
self.active ? @busy = true : @busy = false | |
elsif busy_mode == :moving_mode | |
moving? ? @busy = true : @busy = false | |
elsif busy_mode == :all_mode | |
con = open? && self.active | |
con2 = moving? | |
if con || con2 | |
@busy = true | |
elsif !con || !con2 | |
@busy = false | |
end | |
end | |
end | |
#┌─────────┬─────────────────────────────────────────────────────────────────┐ | |
#│ ♦ busy? │ Checa se a janela está ocupada. │ | |
#└─────────┴─────────────────────────────────────────────────────────────────┘ | |
def busy? | |
@busy == true | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ moving? │ Checa se a janela está se movendo. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def moving? | |
!@move_route.empty? | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ showing_message? │ Checa se a janela está mostrando uma mensagem. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def showing_message? | |
!@write_message.empty? | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ waiting_message_input? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Checa se a janela está esperando o botão de confirmação ser pressionado │ | |
#│ ao mostrar uma mensagem. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def waiting_message_input? | |
@write_message[:wait_for_input].nil? ? false : true | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ update_open │ Atualiza a abertura da janela. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def update_open | |
self.openness += opening_speed | |
@opening = false if open? | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ update_close │ Atualiza o fechamento da janela. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def update_close | |
self.openness -= opening_speed | |
@closing = false if close? | |
end | |
#┌────────┬──────────────────────────────────────────────────────────────────┐ | |
#│ ♦ open │ Abre a janela. │ | |
#└────────┴──────────────────────────────────────────────────────────────────┘ | |
def open | |
opening_sound unless open? | |
@opening = true unless open? | |
@closing = false | |
end | |
#┌─────────┬─────────────────────────────────────────────────────────────────┐ | |
#│ ♦ close │ Fecha a janela. │ | |
#└─────────┴─────────────────────────────────────────────────────────────────┘ | |
def close | |
closing_sound unless close? | |
@closing = true unless close? | |
@opening = false | |
end | |
#┌────────────┬──────────────────────────────────────────────────────────────┐ | |
#│ ♦ activate │ Ativa a janela. │ | |
#└────────────┴──────────────────────────────────────────────────────────────┘ | |
def activate | |
self.active = true | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ deactivate │ Desativa a janela. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def deactivate | |
self.active = false | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ move_to │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Move a janela até a posição especificada (ela vai se mover até lá). │ | |
#│ → x: o destino em x. │ | |
#│ → y: o destino em y. Padrão: self.y │ | |
#│ → opacity: o destino da opacidade (do conteúdo também). │ | |
#│ Padrão: self.opacity │ | |
#│ → width: o destino da largura. Padrão: self.width │ | |
#│ → height: o destino da altura. Padrão: self.height │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def move_to(x, y = self.y, opacity = self.opacity, width = self.width, height = self.height) | |
@move_route.clear | |
@move_route.push(x, y, width, height, opacity) | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ update_movement │ Atualiza o movimento da janela. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def update_movement | |
return if @move_route.empty? | |
x = @move_route[0]; y = @move_route[1] | |
w = @move_route[2]; h = @move_route[3] | |
op = @move_route[4] | |
if x < self.x | |
self.x = Prism.decrease(self.x, move_speed, x) | |
else | |
self.x = Prism.increase(self.x, move_speed, x) | |
end | |
if y < self.y | |
self.y = Prism.decrease(self.y, move_speed, y) | |
else | |
self.y = Prism.increase(self.y, move_speed, y) | |
end | |
if w < self.width | |
self.width = Prism.decrease(self.width, move_speed, w) | |
else | |
self.width = Prism.increase(self.width, move_speed, w) | |
end | |
if h < self.height | |
self.height = Prism.decrease(self.height, move_speed, h) | |
else | |
self.height = Prism.increase(self.height, move_speed, h) | |
end | |
if op < self.opacity | |
self.opacity = Prism.decrease(self.opacity, opacity_speed, op) | |
self.contents_opacity = Prism.decrease(self.opacity, opacity_speed, op) | |
else | |
self.opacity = Prism.increase(self.opacity, opacity_speed, op) | |
self.contents_opacity = Prism.increase(self.opacity, opacity_speed, op) | |
end | |
con = self.x == x && self.y == y && self.width == w && self.height == h | |
con2 = self.opacity == op | |
@move_route.clear if con && con2 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update_write_message │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualiza o desenho do write_message, desenhando caractere por caractere. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update_write_message(m = @write_message) | |
return if m.empty? | |
return if self.openness < 255 | |
if m[:wait_for_input] | |
if Input.trigger?(:C) | |
m[:wait_for_input] = nil | |
else | |
return | |
end | |
elsif m[:wait] && m[:wait] > 0 | |
m[:wait] -= 1 if m[:wait] > 0 | |
if m[:wait] == 0 | |
m[:wait] = nil | |
else | |
return | |
end | |
end | |
txt = m[:text]; ind = m[:text_index] | |
cnt = m[:count]; mcnt = m[:max_count] | |
if cnt >= mcnt | |
m[:count] = 0 | |
else | |
m[:count] += 1 | |
end | |
if cnt == mcnt | |
if txt[ind] == "\n" | |
txt[ind] = "" | |
m[:x] = m[:rx] | |
m[:y] += line_height | |
elsif txt[ind, 2] == "\\." | |
m[:wait_for_input] = true | |
m[:text_index] += 2 | |
return | |
elsif txt[ind, 2] == "\\|" | |
m[:wait] = 15 | |
m[:text_index] += 2 | |
return | |
elsif txt[ind, 5] =~ /\\i\[(\d+)\]/i | |
txt[ind, 5] = "" | |
process_draw_icon $1.to_i, m | |
end | |
text_rect = self.contents.text_size(txt[ind]) | |
draw_text(m[:x], m[:y], txt[ind]) | |
m[:x] += text_rect.width | |
m[:text_index] += 1 if ind < txt.length | |
if ind >= txt.length | |
@write_message.clear | |
end | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ draw_text │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha um texto normal na janela. │ | |
#│ → x: a posição horizontal do texto. │ | |
#│ → y: a posição vertical do texto. │ | |
#│ → text: o texto em si. │ | |
#│ → align: alinhamento do texto. 0: esquerda, 1: centro, 2: direita. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def draw_text(x, y, text, align = 0) | |
width = self.contents.text_size(text).width + 4 | |
if align != 0 | |
width = contents_width | |
end | |
height = line_height + 4 | |
self.contents.draw_text(x, y, width, height, text, align) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ write_text │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Escreve um texto na janela com função de quebra de linha (\n). │ | |
#│ → x: a posição horizontal do texto. │ | |
#│ → y: a posição vertical do texto. │ | |
#│ → text: o texto em si. │ | |
#│ → align: alinhamento do texto. 0: esquerda, 1: centro, 2: direita. │ | |
#│ → wrap: faz o texto quebrar uma linha automaticamente caso passe da │ | |
#│ largura da janela. Padrão: false │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def write_text(x, y, text, align = 0, wrap = false) | |
lines = [] | |
if wrap | |
text = Prism.wrap_text(text, contents_width) | |
end | |
text.scan(/[^\n]*/) {|line| lines.push(line) unless line == ""} | |
for i in 0...lines.size | |
width = self.contents.text_size(lines[i]).width + 4 | |
height = line_height + 4 | |
pos_y = y + line_height * i | |
if align != 0 | |
width = contents_width | |
end | |
self.contents.draw_text(x, pos_y, width, height, lines[i], align) | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ write_message │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha um texto com as letras aparecendo lentamente. │ | |
#│ Obs: Uso em loops não recomendado. │ | |
#│ É como se fosse uma versão portátil da Window_Message. │ | |
#│ Eu não usaria ele como uma Window_Message de verdade, mas ele tem lá suas │ | |
#│ utilidades. │ | |
#│ Há três comandos que podem ser utilizados: │ | |
#│ \\. irá esperar o botão de confirmação ser pressionado antes de mostrar │ | |
#│ o resto da mensagem. Enquanto \\| irá esperar 15 frames. │ | |
#│ \\i[id] irá desenhar o ícone de número id. │ | |
#│ O texto não será desenhado até que a janela esteja totalmente aberta. │ | |
#│ A mensagem irá pular uma linha automaticamente se o texto for maior que │ | |
#│ a largura da janela. │ | |
#│ → x: a posição em x do texto. │ | |
#│ → y: a posição em y do texto. │ | |
#│ → text: o texto em si. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def write_message(x, y, text) | |
@write_message[:x] = x | |
@write_message[:rx] = x | |
@write_message[:y] = y | |
@write_message[:max_count] = 1 | |
@write_message[:count] = 15 | |
@write_message[:text] = (Prism.wrap_text text, contents_width - 48) | |
@write_message[:text_index] = 0 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ process_draw_icon │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Processa o desenho de ícone para o write_message. │ | |
#│ → icon_index: o index do ícone no iconset. │ | |
#│ → pos: uma hash que contenha uma posição :x. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def process_draw_icon(icon_index, pos) | |
draw_icon(icon_index, pos[:x], pos[:y]) | |
pos[:x] += 24 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ draw_icon │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha um ícone na janela. │ | |
#│ → icon_index: o index do ícone no iconset. │ | |
#│ → x: posição horizontal do ícone. │ | |
#│ → y: posição vertical do ícone. │ | |
#│ → enabled: se o ícone irá aparecer translúcido ou completamente │ | |
#│ visível. Padrão: true │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def draw_icon(icon_index, x, y, enabled = true) | |
bitmap = Cache.system("Iconset") | |
rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24) | |
self.contents.blt(x, y, bitmap, rect, enabled ? 255 : 160) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ draw_face │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha um gráfico de rosto. │ | |
#│ → face_name: o nome do arquivo da face. │ | |
#│ → face_index: o index da face (começando por 0). │ | |
#│ → x: posição horizontal da face. │ | |
#│ → y: posição vertical da face. │ | |
#│ → enabled: se a face irá aparecer translúcida ou completamente │ | |
#│ visível. Padrão: true │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def draw_face(face_name, face_index, x, y, enabled = true) | |
bitmap = Cache.face(face_name) | |
rect = Rect.new(face_index % 4 * 96, face_index / 4 * 96, 96, 96) | |
self.contents.blt(x, y, bitmap, rect, enabled ? 255 : 160) | |
bitmap.dispose | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ draw_character │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha um char na janela. │ | |
#│ → character_name: o nome do arquivo do char. │ | |
#│ → character_index: o index do char (começando por 0). │ | |
#│ → x: posição horizontal do char. │ | |
#│ → y: posição vertical do char. │ | |
#│ → enabled: se o char irá aparecer translúcido ou completamente │ | |
#│ visível. Padrão: true │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def draw_character(character_name, character_index, x, y, enabled = true) | |
return unless character_name | |
bitmap = Cache.character(character_name) | |
sign = character_name[/^[\!\$]./] | |
if sign && sign.include?("$") | |
cw = bitmap.width / 3 | |
ch = bitmap.height / 4 | |
else | |
cw = bitmap.width / 12 | |
ch = bitmap.height / 8 | |
end | |
n = character_index | |
src_rect = Rect.new((n % 4 * 3 + 1) * cw, (n / 4 * 4) * ch, cw, ch) | |
self.contents.blt(x, y, bitmap, src_rect, enabled ? 255 : 160) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ draw_gauge │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha um gauge na janela. │ | |
#│ → x: posição horizontal. │ | |
#│ → y: posição vertical. │ | |
#│ → width: largura do gauge. │ | |
#│ → height: altura do gauge. │ | |
#│ → rate: a taxa de preenchimento do gauge (de 0.0 a 1.0). │ | |
#│ → color1: a cor inicial do gauge. │ | |
#│ → color2: a cor final do gauge. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def draw_gauge(x, y, width, rate, color1, color2) | |
fill_w = (width * rate).to_i | |
gauge_y = y + line_height - 8 | |
n = 19 | |
gbc = self.windowskin.get_pixel(64 + (n % 8) * 8, 96 + (n / 8) * 8) | |
self.contents.fill_rect(x, gauge_y, width, 6, gbc) | |
self.contents.gradient_fill_rect(x, gauge_y, fill_w, 6, color1, color2) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ draw_item │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha o nome de um item juntamente do ícone dele. │ | |
#│ → item: o item. Precisa ser um RPG::Item ($data_items, por exemplo). │ | |
#│ → x: posição horizontal. │ | |
#│ → y: posição vertical. │ | |
#│ → enabled: se irá aparecer translúcido ou visível. Padrão: true │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def draw_item(item, x, y, enabled = true) | |
return unless item | |
draw_icon(item.icon_index, x, y, enabled) | |
draw_text(x + 24, y, item.name) | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ dispose │ Efetua o dispose da janela. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def dispose | |
self.contents.dispose unless disposed? | |
super | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Base_Window ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Window_Select ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Uma janela de seleção que desliza o cursor suavemente. Ela é necessária ║ | |
#║ para a Prism::Window_Command. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Window_Select < Prism::Base_Window | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância públicas. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :mouse_enabled | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal. │ | |
#│ → y: posição vertical. │ | |
#│ → width: largura. │ | |
#│ → height: altura. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height) | |
super | |
@index = 0 | |
@hovering_over_option = false | |
@mouse_enabled = true | |
@new_rect = Rect.new(0, 0, selection_width, selection_height) | |
@new_scroll = 0 | |
@rapid_scroll = false | |
self.cursor_rect.set(@new_rect) | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ selection_width │ A largura dos itens na janela. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def selection_width | |
(width - window_padding * 2 + spacing) / col_max - spacing | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ selection_height │ A altura dos itens na janela. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def selection_height | |
return 24 | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ contents_height │ A altura do bitmap da janela. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def contents_height | |
[super - super % selection_height, row_max * selection_height].max | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_speed │ A velocidade de movimento do cursor em pixels. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def cursor_speed | |
return 4 + col_max | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ scroll_speed │ A velocidade de scroll da janela em pixels. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def scroll_speed | |
return 4 + col_max | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ spacing │ O espaço entre os itens desenhados horizontalmente. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def spacing | |
return 12 | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ vertical_spacing │ O espaço entre os itens desenhados verticalmente. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def vertical_spacing | |
return 0 | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ col_max │ O número máximo de colunas da janela. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def col_max | |
return 1 | |
end | |
#┌────────────┬──────────────────────────────────────────────────────────────┐ | |
#│ ♦ item_max │ O número máximo de itens na janela. │ | |
#└────────────┴──────────────────────────────────────────────────────────────┘ | |
def item_max | |
return 0 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ select │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Muda a posição do cursor para o número especificado. │ | |
#│ → index: o número (index) da seleção na janela. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def select(index) | |
@index = index | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ instant_select │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Seleciona instantâneamente um index. │ | |
#│ → index: o index a ser selecionado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def instant_select(index) | |
select(index) | |
@new_rect.set(item_rect(@index)) | |
self.cursor_rect.set(@new_rect) | |
ensure_cursor_visible | |
self.oy = @new_scroll | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ hide_cursor │ Esconde o cursor. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def hide_cursor | |
self.cursor_rect.width = self.cursor_rect.height = 0 | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ show_cursor │ Mostra o cursor. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def show_cursor | |
instant_select(@index) | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_index │ O número da opção atual. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def cursor_index | |
@index | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ horizontal? │ Indica se há mais de uma coluna. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def horizontal? | |
col_max >= 2 | |
end | |
#┌───────┬───────────────────────────────────────────────────────────────────┐ | |
#│ ♦ row │ A fileira atual (para mais de uma coluna). │ | |
#└───────┴───────────────────────────────────────────────────────────────────┘ | |
def row | |
@index / col_max | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ top_row │ Quantas fileiras não visíveis existem no topo. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def top_row | |
self.oy / selection_height | |
end | |
#┌────────────┬──────────────────────────────────────────────────────────────┐ | |
#│ ♦ top_row= │ Altera as fileiras do topo. │ | |
#└────────────┴──────────────────────────────────────────────────────────────┘ | |
def top_row= row | |
row = 0 if row < 0 | |
row = row_max - 1 if row > row_max - 1 | |
@new_scroll = row * selection_height | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ row_max │ O número máximo de fileiras. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def row_max | |
[(item_max + col_max - 1) / col_max, 1].max | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ page_row_max │ O número máximo de fileiras visíveis na janela. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def page_row_max | |
(self.height - self.padding - self.padding_bottom) / selection_height | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ bottom_row │ O inverso do top_row. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def bottom_row | |
top_row + page_row_max - 1 | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ bottom_row= │ Altera as fileiras de baixo. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def bottom_row= row | |
self.top_row = row - (page_row_max - 1) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ item_rect │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ O tamanho exato de um item na janela. Assim como a posição correta │ | |
#│ dependendo do index especificado. │ | |
#│ → i: o index da posição de um item. Use isso para desenhar itens na │ | |
#│ janela com loops, caso queira. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def item_rect(i) | |
x = i % col_max * (selection_width + spacing) | |
y = i / col_max * (selection_height + vertical_spacing) | |
rect = Rect.new(x, y, selection_width, selection_height) | |
return rect | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ hovering_option? │ Indica se o cursor está acima de uma opção. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def hovering_option? | |
return @hovering_over_option | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ mouse_enabled? │ Indica se o mouse está ativado para a janela. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def mouse_enabled? | |
return @mouse_enabled | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
update_mouse if @mouse_enabled && self.active | |
update_index if self.active | |
update_cursor_pos | |
ensure_cursor_visible | |
update_scrolling | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ update_mouse │ Atualiza a seleção com o mouse. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def update_mouse | |
@delay = @delay ? @delay + 1 : 0 | |
return if @delay % 3 > 0 | |
tx = Prism::Touch_Input.x | |
ty = Prism::Touch_Input.y | |
vx = self.viewport ? self.x - self.viewport.ox + self.viewport.rect.x : self.x | |
vy = self.viewport ? self.y - self.viewport.oy + self.viewport.rect.y : self.y | |
if tx.between?(vx, vx + self.width) && ty.between?(vy, vy + self.height) | |
tx -= vx + padding | |
ty -= vy + padding | |
ty += oy | |
(0...item_max).each { |i| | |
rect = item_rect(i) | |
if tx.between?(rect.x, rect.x + rect.width) && ty.between?(rect.y, rect.y + rect.height) | |
@hovering_over_option = true | |
last_index = @index | |
select(i) | |
Sound.play_cursor unless @index == last_index | |
break | |
else | |
@hovering_over_option = false | |
end | |
} | |
else | |
@hovering_over_option = false | |
end | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ update_scrolling │ Atualiza o scrolling da janela, como o nome indica. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def update_scrolling | |
spd = scroll_speed | |
if @rapid_scroll | |
spd = contents_height / 3 | |
end | |
if @new_scroll > self.oy | |
self.oy = Prism.increase(self.oy, spd, @new_scroll) | |
elsif @new_scroll < self.oy | |
self.oy = Prism.decrease(self.oy, spd, @new_scroll) | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ ensure_cursor_visible │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Vai executar o processo de scrolling caso o cursor saia da visão. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def ensure_cursor_visible | |
self.top_row = row if row < top_row | |
self.bottom_row = row if row > bottom_row | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ update_index │ Atualiza a posição do cursor caso pressionado um botão. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def update_index | |
return unless item_max > 0 | |
last_index = @index | |
cursor_down(Input.trigger?(:DOWN)) if Input.repeat?(:DOWN) | |
cursor_up(Input.trigger?(:UP)) if Input.repeat?(:UP) | |
cursor_right(Input.trigger?(:RIGHT)) if Input.repeat?(:RIGHT) | |
cursor_left(Input.trigger?(:LEFT)) if Input.repeat?(:LEFT) | |
Sound.play_cursor if @index != last_index | |
end | |
#┌─────────────────────┬─────────────────────────────────────────────────────┐ | |
#│ ♦ update_cursor_pos │ Vai ajustar a posição do cursor. │ | |
#└─────────────────────┴─────────────────────────────────────────────────────┘ | |
def update_cursor_pos | |
@new_rect.set(item_rect(@index)) | |
update_x_pos | |
update_y_pos | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ update_x_pos │ Ajusta a posição do cursor em x. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def update_x_pos | |
spd = cursor_speed | |
if @rapid_scroll | |
spd = contents_height / 3 | |
end | |
if @new_rect.x < self.cursor_rect.x | |
self.cursor_rect.x = Prism.decrease(self.cursor_rect.x, spd, @new_rect.x) | |
elsif @new_rect.x > self.cursor_rect.x | |
self.cursor_rect.x = Prism.increase(self.cursor_rect.x, spd, @new_rect.x) | |
end | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ update_y_pos │ Ajusta a posição do cursor em y. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def update_y_pos | |
spd = cursor_speed | |
if @rapid_scroll | |
spd = contents_height / 2 | |
end | |
if @new_rect.y < self.cursor_rect.y | |
self.cursor_rect.y = Prism.decrease(self.cursor_rect.y, spd, @new_rect.y) | |
elsif @new_rect.y > self.cursor_rect.y | |
self.cursor_rect.y = Prism.increase(self.cursor_rect.y, spd, @new_rect.y) | |
end | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_down │ Move o index da posição do cursor para baixo. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def cursor_down(wrap = false) | |
if @index < item_max - col_max || (wrap && col_max == 1) | |
if (@index + col_max) % item_max == 0 | |
@rapid_scroll = true | |
else | |
@rapid_scroll = false | |
end | |
select((@index + col_max) % item_max) | |
end | |
end | |
#┌─────────────┬─────────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_up │ Move o index da posição do cursor para cima. │ | |
#└─────────────┴─────────────────────────────────────────────────────────────┘ | |
def cursor_up(wrap = false) | |
if @index >= col_max || (wrap && col_max == 1) | |
if (@index - col_max + item_max) % item_max == item_max - 1 | |
@rapid_scroll = true | |
else | |
@rapid_scroll = false | |
end | |
select((@index - col_max + item_max) % item_max) | |
end | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_right │ Move o index da posição do cursor para a direita. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def cursor_right(wrap = false) | |
if horizontal? && (@index < item_max - 1 || (wrap && page_row_max == 1)) | |
select((@index + 1) % item_max) | |
end | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_left │ Move o index da posição do cursor para a esquerda. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def cursor_left(wrap = false) | |
if horizontal? && (@index > 0 || (wrap && page_row_max == 1)) | |
select((@index - 1 + item_max) % item_max) | |
end | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ refresh │ Recria o bitmap da janela. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def refresh | |
create_contents | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Window_Select ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Window_Command ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Uma janela de comandos que aumenta bastante a produtividade na hora de ║ | |
#║ desenhar os comandos. Ela possui alguns métodos inteligentes para desenhar ║ | |
#║ os comandos. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Window_Command < Prism::Window_Select | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_reader :list | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal. │ | |
#│ → y: posição vertical. │ | |
#│ → width: largura. │ | |
#│ → height: altura. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height) | |
@list = {} | |
make_command_list | |
super | |
set_font_settings | |
draw_commands | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ make_command_list │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ É nesta área que as opções são adicionadas. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def make_command_list | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ redraw_command_list │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Redesenha todos os comandos. Se external_commands for especificado, │ | |
#│ ele irá criar os comandos do external_commands ao invés. │ | |
#│ external_commands precisa ser uma array contendo os comandos em uma │ | |
#│ hash (bloco), onde os parâmetros do add_command não podem ser omitidos. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def redraw_command_list(external_commands = nil) | |
e = external_commands | |
if e | |
@list = {} | |
for i in 0...e.size | |
add_command(e[i][:type], e[i][:symbol], e[i][:enabled], e[i][:handler]) | |
end | |
refresh | |
set_font_settings | |
draw_commands | |
else | |
make_command_list | |
refresh | |
set_font_settings | |
draw_commands | |
end | |
select(0) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ add_command │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → typ: ver logo abaixo. │ | |
#│ → sym: o símbolo único do comando. │ | |
#│ → enab: se a opção pode ser usada ou não. Padrão: true │ | |
#│ → han: o método que será chamado ao confirmar a opção (interno). │ | |
#│ Padrão: nil │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Em typ (type), você irá colocar a opção em si. │ | |
#│ Se a opção for qualquer coisa exceto as abaixo, ele irá desenhar essa │ | |
#│ opção. │ | |
#│ Se a opção for um RPG::BaseItem ($data_items, $data_enemies, etc...), │ | |
#│ ver logo abaixo. │ | |
#│ Se a opção for um bitmap, ele irá, destrutivamente, desenhar esse │ | |
#│ bitmap. │ | |
#│ Caso você use um bitmap como Cache.picture('Nome'), use um clone. │ | |
#│ Ex: Cache.picture('Nome').clone. Pois ele será destruído logo depois. │ | |
#│ Agora você não precisa usar um clone se estiver criando um bitmap novo. │ | |
#│ Ex: Bitmap.new('Graphics/Pictures/Nome') │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ No caso das opções que são um RPG::BaseItem, os seguintes itens podem ser │ | |
#│ usados: $data_actors, $data_classes, $data_skills, $data_items, │ | |
#│ $data_weapons, $data_armors, $data_enemies e $data_states. │ | |
#│ Os seguintes métodos podem ser usados em sua janela: │ | |
#│ → icon_only?: true para desenhar apenas ícones. │ | |
#│ → face_only?: true para desenhar apenas faces. │ | |
#│ → name_only?: true para desenhar apenas nomes (nas opções com ícones │ | |
#│ ou faces). │ | |
#│ → face_or_character?: caso esteja usando $data_actors: │ | |
#│ :face irá desenhar a face ao invés do char. │ | |
#│ :character irá desenhar o char ao invés da face. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def add_command(typ, sym, enab = true, han = nil) | |
@list[sym] = {type: typ, symbol: sym, enabled: enab, handler: han} | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_font_settings │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Você pode usar esse método para realizar configurações de fonte antes │ | |
#│ dos itens serem desenhados. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_font_settings | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ draw_commands │ Desenha todos os comandos. │ | |
#└─────────────────┴─────────────────────────────────────────────────────────┘ | |
def draw_commands | |
cmd = [] | |
@list.each_value do |com| | |
cmd.push(com) | |
end | |
@ind = cmd | |
for i in 0...cmd.size | |
if cmd[i][:type].is_a?(RPG::BaseItem); process_base_item(cmd[i], i) | |
elsif cmd[i][:type].is_a?(Bitmap); process_bitmap(cmd[i], i) | |
else; process_string(cmd[i], i) | |
end | |
end | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ clear_commands │ Limpa a lista de comandos. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def clear_commands | |
@list.clear | |
@ind.clear | |
self.contents.clear | |
select(0) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_handler │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Configura o método que será chamado ao confirmar a opção (externamente). │ | |
#│ Obs: Se já existir um método interno, o interno será chamado primeiro. │ | |
#│ → symbol: o símbolo único da opção. │ | |
#│ → handler: o método externo que será chamado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_handler(symbol, handler) | |
@list[symbol][:external_handler] = handler | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ process_string │ Processa o desenho de texto. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def process_string(cmd, i) | |
old_alpha = self.contents.font.color.alpha | |
enabled = cmd[:enabled] | |
!enabled ? self.contents.font.color.alpha = 160 : nil | |
rect = item_rect(i) | |
draw_text(rect.x + 4, rect.y, cmd[:type].to_s) | |
self.contents.font.color.alpha = old_alpha | |
end | |
#┌─────────────────────┬─────────────────────────────────────────────────────┐ | |
#│ ♦ process_base_item │ Identifica o tipo de item e o desenha de acordo. │ | |
#└─────────────────────┴─────────────────────────────────────────────────────┘ | |
def process_base_item(cmd, i) | |
if cmd[:type].is_a?(RPG::Actor) | |
process_actor(cmd, i) | |
elsif cmd[:type].is_a?(RPG::Class) || cmd[:type].is_a?(RPG::Enemy) | |
process_item_text(cmd, i) | |
else | |
process_normal_item(cmd, i) | |
end | |
end | |
#┌───────────────────────┬───────────────────────────────────────────────────┐ | |
#│ ♦ process_normal_item │ Desenha um item normal. │ | |
#└───────────────────────┴───────────────────────────────────────────────────┘ | |
def process_normal_item(cmd, i) | |
old_alpha = self.contents.font.color.alpha | |
enabled = cmd[:enabled] | |
!enabled ? self.contents.font.color.alpha = 160 : nil | |
plus_x = name_only? ? 4 : 24 | |
rect = item_rect(i) | |
draw_icon(cmd[:type].icon_index, rect.x, rect.y, enabled) unless name_only? | |
draw_text(rect.x + plus_x, rect.y, cmd[:type].name) unless icon_only? | |
self.contents.font.color.alpha = old_alpha | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ process_actor │ Desenha um RPG::Actor. │ | |
#└─────────────────┴─────────────────────────────────────────────────────────┘ | |
def process_actor(cmd, i) | |
old_alpha = self.contents.font.color.alpha | |
enabled = cmd[:enabled] | |
!enabled ? self.contents.font.color.alpha = 160 : nil | |
rect = item_rect(i) | |
min = (self.contents.font.size * 0.5).to_i + 1 | |
plus_x = name_only? ? 4 : face_or_character? == :face ? 100 : 32 | |
plus_y = name_only? ? 0 : face_or_character? == :face ? (48 - min) : (16 - min) | |
fn = cmd[:type].face_name; fi = cmd[:type].face_index | |
cn = cmd[:type].character_name; ci = cmd[:type].character_index | |
if face_or_character? == :face | |
draw_face(fn, fi, rect.x, rect.y, enabled) unless name_only? | |
else | |
draw_character(cn, ci, rect.x + 4, rect.y, enabled) unless name_only? | |
end | |
draw_text(rect.x + plus_x, rect.y + plus_y, cmd[:type].name) unless face_only? | |
self.contents.font.color.alpha = old_alpha | |
end | |
#┌─────────────────────┬─────────────────────────────────────────────────────┐ | |
#│ ♦ process_item_text │ Desenha o nome de um item. │ | |
#└─────────────────────┴─────────────────────────────────────────────────────┘ | |
def process_item_text(cmd, i) | |
old_alpha = self.contents.font.color.alpha | |
enabled = cmd[:enabled] | |
!enabled ? self.contents.font.color.alpha = 160 : nil | |
rect = item_rect(i) | |
draw_text(rect.x + 4, rect.y, cmd[:type].name) | |
self.contents.font.color.alpha = old_alpha | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ process_bitmap │ Desenha um bitmap. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def process_bitmap(cmd, i) | |
enabled = cmd[:enabled] | |
opacity = enabled ? 255 : 160 | |
rect = item_rect(i) | |
bit_rect = Rect.new(0, 0, cmd[:type].width, cmd[:type].height) | |
self.contents.blt(rect.x, rect.y, cmd[:type], bit_rect, opacity) | |
cmd[:type].dispose | |
end | |
#┌────────────┬──────────────────────────────────────────────────────────────┐ | |
#│ ♦ item_max │ Número máximo de itens na janela. │ | |
#└────────────┴──────────────────────────────────────────────────────────────┘ | |
def item_max | |
@list.size | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ icon_only? │ Indica se apenas os ícones dos itens devem ser desenhados. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def icon_only? | |
return false | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ face_only? │ Indica se apenas as faces dos actors devem ser desenhadas. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def face_only? | |
return false | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ name_only? │ Indica se apenas os nomes devem ser desenhados. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def name_only? | |
return false | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ selected_item │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o item atualmente selecionado em formato de array com 2 elementos. │ | |
#│ O primeiro elemento é o símbolo configurado em :sym. │ | |
#│ O segundo elemento são os componentes em uma hash. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def selected_item | |
selected = @list.to_a[cursor_index] | |
return selected | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ face_or_character? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se a face do actor deve ser desenhada ou o char dele. │ | |
#│ → :face: desenha a face. │ | |
#│ → :character: desenha o char. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def face_or_character? | |
return :character | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
if mouse_enabled? | |
if (Input.trigger?(:C) || Prism::Touch_Input.is_triggered? && hovering_option?) | |
on_option_ok if self.active && !no_confirm | |
end | |
else | |
on_option_ok if Input.trigger?(:C) && self.active && !no_confirm | |
end | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ on_option_ok │ Confirma a opção, se o no_confirm for false. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def on_option_ok | |
Input.update | |
unless @ind[cursor_index] | |
Sound.play_buzzer | |
return | |
end | |
opt = @ind[cursor_index][:symbol] | |
if @list[opt][:enabled] | |
Sound.play_ok | |
@list[opt][:handler].call if @list && @list[opt][:handler] | |
@list[opt][:external_handler].call if @list[opt][:external_handler] rescue nil | |
deactivate if @list[opt][:handler] || @list[opt][:external_handler] rescue nil | |
else | |
Sound.play_buzzer | |
end | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ no_confirm │ Desativa confirmação de opções na janela. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def no_confirm | |
return false | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Window_Command ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Horz_Command ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Mesma coisa da Prism::Window_Command, mas com configurações horizontais. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Horz_Command < Prism::Window_Command | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal. │ | |
#│ → y: posição vertical. │ | |
#│ → width: largura. │ | |
#│ → height: altura. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height) | |
super | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ col_max │ O número máximo de colunas da janela. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def col_max | |
return 4 | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ spacing │ O espaço entre os itens desenhados horizontalmente. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def spacing | |
return 8 | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ hide_cursor │ Esconde o cursor. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def hide_cursor | |
self.cursor_rect.width = self.cursor_rect.height = 0 | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ show_cursor │ Mostra o cursor. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def show_cursor | |
instant_select(@index) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ instant_select │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Seleciona instantâneamente um index. │ | |
#│ → index: o index a ser selecionado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def instant_select(index) | |
select(index) | |
@new_rect.set(item_rect(@index)) | |
self.cursor_rect.set(@new_rect) | |
ensure_cursor_visible | |
self.ox = @new_scroll | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ contents_width │ A largura do conteúdo visível da janela. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def contents_width | |
(selection_width + spacing) * item_max - spacing | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ contents_height │ A altura do conteúdo visível da janela. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def contents_height | |
selection_height | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ top_col │ Dígitos dianteiros. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def top_col | |
ox / (selection_width + spacing) | |
end | |
#┌────────────┬──────────────────────────────────────────────────────────────┐ | |
#│ ♦ top_col= │ Ajusta os dígitos dianteiros. │ | |
#└────────────┴──────────────────────────────────────────────────────────────┘ | |
def top_col=(col) | |
col = 0 if col < 0 | |
@new_scroll = col * (selection_width + spacing) | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ bottom_col │ O inverso do top_col. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def bottom_col | |
top_col + col_max - 1 | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ bottom_col= │ Ajusta os dígitos traseiros. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def bottom_col=(col) | |
self.top_col = col - (col_max - 1) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ ensure_cursor_visible │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Vai executar o processo de scrolling caso o cursor saia da visão. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def ensure_cursor_visible | |
self.top_col = @index if @index < top_col | |
self.bottom_col = @index if @index > bottom_col | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ update_scrolling │ Atualiza o scrolling da janela, como o nome indica. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def update_scrolling | |
spd = scroll_speed | |
if @rapid_scroll | |
spd = contents_width / 3 | |
end | |
if @new_scroll > self.ox | |
self.ox = Prism.increase(self.ox, spd, @new_scroll) | |
elsif @new_scroll < self.ox | |
self.ox = Prism.decrease(self.ox, spd, @new_scroll) | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ item_rect │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ O tamanho exato de um item na janela. Assim como a posição correta │ | |
#│ dependendo do index especificado. │ | |
#│ → i: o index da posição de um item. Use isso para desenhar itens na │ | |
#│ janela com loops, caso queira. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def item_rect(index) | |
rect = super | |
rect.x = index * (selection_width + spacing) | |
rect.y = 0 | |
rect | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_right │ Move o index da posição do cursor para a direita. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def cursor_right(wrap = false) | |
if @index < item_max - 1 || (wrap && page_row_max == 1) | |
select((@index + 1) % item_max) | |
end | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_left │ Move o index da posição do cursor para a esquerda. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def cursor_left(wrap = false) | |
if @index > 0 || (wrap && page_row_max == 1) | |
select((@index - 1 + item_max) % item_max) | |
end | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_down │ Move o index da posição do cursor para baixo. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def cursor_down(wrap = false) | |
end | |
#┌─────────────┬─────────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_up │ Move o index da posição do cursor para cima. │ | |
#└─────────────┴─────────────────────────────────────────────────────────────┘ | |
def cursor_up(wrap = false) | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Horz_Command ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Input_Window ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Uma janela onde o jogador pode digitar qualquer coisa que ele quiser. ║ | |
#║ Você pode obter o texto inserido pelo jogador com user_text. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Input_Window < Prism::Base_Window | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_reader :user_text | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal. │ | |
#│ → y: posição vertical. │ | |
#│ → width: largura. │ | |
#│ → height: altura. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height) | |
super | |
@user_text = "" | |
reset_input_settings | |
create_input_sprite | |
end | |
#┌────────────────────────┬──────────────────────────────────────────────────┐ | |
#│ ♦ reset_input_settings │ Reseta o texto inserido. │ | |
#└────────────────────────┴──────────────────────────────────────────────────┘ | |
def reset_input_settings | |
@text = "" | |
@accents = [] | |
end | |
#┌───────────────────────┬───────────────────────────────────────────────────┐ | |
#│ ♦ create_input_sprite │ Cria o sprite do cursor. │ | |
#└───────────────────────┴───────────────────────────────────────────────────┘ | |
def create_input_sprite | |
@input_sprite = Sprite.new | |
@input_sprite.bitmap = Bitmap.new(24, 24) | |
@input_sprite.bitmap.draw_text(0, 0, 24, 24, "|") | |
@input_sprite.x = self.x + self.padding | |
@input_sprite.y = self.y + self.padding + 1 | |
@input_sprite.z = self.z + 1 | |
@input_sprite.opacity = 0 | |
@count = 0 | |
end | |
#┌──────┬────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ z= │ Ajusta a prioridade z do sprite do cursor. │ | |
#└──────┴────────────────────────────────────────────────────────────────────┘ | |
def z=(v) | |
@input_sprite.z = v + 1 | |
super | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ character_limit │ O limite de caracteres que podem ser inseridos. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def character_limit | |
return 25 | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
return if !self.active | |
update_input | |
update_input_sprite | |
process_confirmation | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ update_input │ Atualiza o processamento do texto. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def update_input | |
input = Prism::Input | |
key = input::KEYS | |
cap = input.shift? ? :caps : :lower | |
char = input::CHARACTERS | |
dl = input.is_repeated?(key[:BACKSPACE]) || input.is_repeated?(key[:DELETE]) | |
ac = char[:accents] | |
li = char[:accent_list] | |
ctd = char[:accented] | |
char[cap].each_pair do |n, ch| | |
if dl; process_delete; return; end | |
i = Prism::Input::KEYS[n] | |
if input.is_repeated?(i) | |
if ac.include?(ch) && @accents.empty? | |
@accents.push(ch) | |
next | |
elsif !@accents.empty? && li.include?(ch) | |
char = ctd[ch][ac.index(@accents[0])] | |
process_character(char) | |
@accents.clear | |
else | |
@accents.clear | |
process_character(ch) | |
end | |
end | |
end | |
end | |
#┌───────────────────────┬───────────────────────────────────────────────────┐ | |
#│ ♦ update_input_sprite │ Atualiza o sprite do cursor. │ | |
#└───────────────────────┴───────────────────────────────────────────────────┘ | |
def update_input_sprite | |
@count += 1 unless @count >= 60 | |
@count = 0 if @count >= 60 | |
if @count < 30 | |
@input_sprite.opacity += 15 | |
else | |
@input_sprite.opacity -= 15 | |
end | |
end | |
#┌─────────────────────┬─────────────────────────────────────────────────────┐ | |
#│ ♦ process_character │ Desenha o caractere que acabou de ser inserido. │ | |
#└─────────────────────┴─────────────────────────────────────────────────────┘ | |
def process_character(ch) | |
if @text.size - 1 >= character_limit; Sound.play_buzzer; return; end | |
@text << ch | |
refresh_text | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ process_delete │ Apaga o último caractere do texto. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def process_delete | |
@text.chop! | |
refresh_text | |
end | |
#┌────────────────────────┬──────────────────────────────────────────────────┐ | |
#│ ♦ process_confirmation │ Processa a confirmação e desativa a janela. │ | |
#└────────────────────────┴──────────────────────────────────────────────────┘ | |
def process_confirmation | |
rt = Prism::Input.is_triggered?(Prism::Input::KEYS[:RETURN]) | |
en = Prism::Input.is_triggered?(Prism::Input::KEYS[:ENTER]) | |
if rt || en | |
Sound.play_ok | |
@user_text = @text | |
@input_sprite.opacity = 0 | |
reset_input_settings | |
refresh_text | |
deactivate | |
end | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ refresh_text │ Redesenha o texto. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def refresh_text | |
self.contents.clear | |
draw_text(0, 0, @text) | |
ox = self.x + self.padding | |
@input_sprite.x = ox + self.contents.text_size(@text).width | |
end | |
#┌────────────┬──────────────────────────────────────────────────────────────┐ | |
#│ ♦ activate │ Reseta as configurações ao ativar a janela. │ | |
#└────────────┴──────────────────────────────────────────────────────────────┘ | |
def activate | |
super | |
reset_input_settings | |
refresh_text | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ dispose │ Se livra do cursor ao dar dispose na janela. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def dispose | |
@input_sprite.bitmap.dispose | |
@input_sprite.dispose | |
super | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Input_Window ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Base_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite que serve de base para todos os outros sprites do Prism. ║ | |
#║ Ele inclui propriedades de movimento da Prism::Base_Window. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Base_Sprite < Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: automaticamente configura o bitmap se for especificado. │ | |
#│ → viewport: o viewport associado ao sprite, se for especificado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, viewport = nil) | |
super viewport | |
@move_speed = 4 | |
@opacity_speed = 4 | |
set(0, 0, 0, 255, bitmap) | |
@move_route = [] | |
make_animation_list | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ bitmap= │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta as configurações de fonte ao definir um novo bitmap. │ | |
#│ → bitmap: o novo bitmap. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def bitmap=(bitmap) | |
super | |
set_font_settings | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_font_settings │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Este método serve para configurar a fonte toda vez que um novo bitmap for │ | |
#│ especificado para o sprite. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_font_settings | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ make_animation_list │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Cria uma lista de animações de movimento para serem usadas a qualquer │ | |
#│ momento. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def make_animation_list | |
@anim_list = {} | |
# Usado por classes herdeiras. | |
# Para criar uma animação, use o modelo: | |
# @anim_list[:nome] = [x, y, op] # Apenas o x é exigido. | |
# op = opacidade. | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ start_animation │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Executa uma animação da lista de animações de movimento. │ | |
#│ → anim: o símbolo da animação na lista de animações. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def start_animation(anim) | |
list = @anim_list[anim] | |
case list.size | |
when 1; move_to(list[0]) | |
when 2; move_to(list[0], list[1]) | |
when 3; move_to(list[0], list[1], list[2]) | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ move_to │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Move o sprite até a posição especificada (ele vai se mover até lá). │ | |
#│ → x: o destino em x. │ | |
#│ → y: o destino em y. Padrão: self.y │ | |
#│ → opacity: o destino da opacidade. Padrão: 255 │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def move_to(x, y = self.y, opacity = self.opacity) | |
@move_route.clear | |
@move_route.push(x, y, opacity) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta de uma vez a posição, opacidade e o bitmap do sprite. │ | |
#│ → x: a posição horizontal. │ | |
#│ → y: a posição vertical. │ | |
#│ → z: a prioridade do sprite. Padrão: 0 │ | |
#│ → opacity: a opacidade do sprite. Padrão: 255 │ | |
#│ → bitmap: o bitmap do sprite. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set(x, y, z = 0, opacity = 255, bitmap = nil) | |
self.x = x + self.oy | |
self.y = y + self.oy | |
self.z = z | |
self.opacity = opacity | |
if bitmap | |
self.bitmap.dispose if self.bitmap | |
self.bitmap = bitmap | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_pos │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Coloca o sprite na posição especificada. │ | |
#│ É necessário um bitmap existente. │ | |
#│ → pos: um número das posições abaixo: │ | |
#│ 1: Superior Equerda │ | |
#│ 2: Superior │ | |
#│ 3: Superior Direita │ | |
#│ 4: Esquerda │ | |
#│ 5: Centro │ | |
#│ 6: Direita │ | |
#│ 7: Inferior Esquerda │ | |
#│ 8: Inferior │ | |
#│ 9: Inferior Direita │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_pos(pos) | |
case pos | |
when 1; self.x = 0 + self.ox; self.y = 0 + self.oy | |
when 2 | |
self.x = Prism.get_center_screen(:x, self.bitmap) + self.ox | |
self.y = 0 + self.oy | |
when 3 | |
self.x = Graphics.width - self.bitmap.width + self.ox | |
self.y = 0 + self.oy | |
when 4 | |
self.x = 0 + self.ox | |
self.y = Prism.get_center_screen(:y, self.bitmap) + self.oy | |
when 5 | |
self.x = Prism.get_center_screen(:x, self.bitmap) + self.ox | |
self.y = Prism.get_center_screen(:y, self.bitmap) + self.oy | |
when 6 | |
self.x = Graphics.width - self.bitmap.width + self.ox | |
self.y = Prism.get_center_screen(:y, self.bitmap) + self.oy | |
when 7 | |
self.x = 0 + self.ox | |
self.y = Graphics.height - self.bitmap.height + self.oy | |
when 8 | |
self.x = Prism.get_center_screen(:x, self.bitmap) + self.ox | |
self.y = Graphics.height - self.bitmap.height + self.oy | |
when 9 | |
self.x = Graphics.width - self.bitmap.width + self.ox | |
self.y = Graphics.height - self.bitmap.height + self.oy | |
end | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ move_speed │ A velocidade de movimento do sprite (em pixels). │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def move_speed | |
return @move_speed | |
end | |
#┌─────────────────┬─────────────────────────────────────────────────────────┐ | |
#│ ♦ opacity_speed │ A velocidade de alteração da opacidade. │ | |
#└─────────────────┴─────────────────────────────────────────────────────────┘ | |
def opacity_speed | |
return @opacity_speed | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ move_speed= │ Altera a velocidade de movimento para v. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def move_speed=(v) | |
@move_speed =(v) | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ opacity_speed= │ Altera a velocidade de alteração da opacidade para v. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def opacity_speed=(v) | |
@opacity_speed =(v) | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ moving? │ Checa se o sprite está se movendo. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def moving? | |
!@move_route.empty? | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
update_movement | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ update_movement │ Atualiza o movimento do sprite. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def update_movement | |
return if @move_route.empty? | |
x = @move_route[0]; y = @move_route[1] | |
op = @move_route[2] | |
if x < self.x | |
self.x = Prism.decrease(self.x, move_speed, x) | |
else | |
self.x = Prism.increase(self.x, move_speed, x) | |
end | |
if y < self.y | |
self.y = Prism.decrease(self.y, move_speed, y) | |
else | |
self.y = Prism.increase(self.y, move_speed, y) | |
end | |
if op < self.opacity | |
self.opacity = Prism.decrease(self.opacity, opacity_speed, op) | |
else | |
self.opacity = Prism.increase(self.opacity, opacity_speed, op) | |
end | |
con = self.x == x && self.y == y | |
con2 = self.opacity == op | |
@move_route.clear if con && con2 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ write_text │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Escreve um texto no sprite com função de quebra de linha (\n). │ | |
#│ → x: a posição horizontal do texto. │ | |
#│ → y: a posição vertical do texto. │ | |
#│ → text: o texto em si. │ | |
#│ → align: alinhamento do texto. 0: esquerda, 1: centro, 2: direita. │ | |
#│ → wrap: faz o texto quebrar uma linha automaticamente caso passe da │ | |
#│ largura do bitmap do sprite. Padrão: false │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def write_text(x, y, text, align = 0, wrap = false) | |
lines = [] | |
if wrap | |
text = Prism.wrap_text(text, self.bitmap.width, self.bitmap) | |
end | |
text.scan(/[^\n]*/) {|line| lines.push(line) unless line == ""} | |
for i in 0...lines.size | |
width = self.bitmap.text_size(lines[i]).width + 4 | |
height = self.bitmap.font.size + 4 | |
pos_y = y + self.bitmap.font.size * i | |
if align != 0 | |
width = self.bitmap.width | |
end | |
self.bitmap.draw_text(x, pos_y, width, height, lines[i], align) | |
end | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Base_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Opening_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite que abre e fecha, tanto horizontal quanto vertical... ou os dois. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Opening_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: automaticamente configura o bitmap se for especificado. │ | |
#│ → open_mode: o modo de abertura. :horizontal, :vertical ou :both │ | |
#│ → viewport: o viewport associado ao sprite, se for especificado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, open_mode = :both, viewport = nil) | |
super(bitmap, viewport) | |
if open_mode == :horizontal | |
self.zoom_x = 0 | |
elsif open_mode == :vertical | |
self.zoom_y = 0 | |
else | |
self.zoom_x = 0; self.zoom_y = 0 | |
end | |
@open_mode = open_mode | |
@open = false | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_properties │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Deve ser chamado exatamente após o sprite ser criado para configurar o │ | |
#│ ponto de origem. │ | |
#│ → bitmap: configura o bitmap, se já não foi criado antes. │ | |
#│ → open_mode: o modo de abertura. :horizontal, :vertical ou :both │ | |
#│ → viewport: o viewport associado ao sprite, se for especificado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_properties(bitmap = nil) | |
unless self.bitmap | |
self.bitmap = bitmap | |
end | |
self.ox = self.bitmap.width * 0.5 | |
self.oy = self.bitmap.height * 0.5 | |
end | |
#┌────────┬──────────────────────────────────────────────────────────────────┐ | |
#│ ♦ open │ Abre o sprite. │ | |
#└────────┴──────────────────────────────────────────────────────────────────┘ | |
def open | |
@open = true | |
end | |
#┌─────────┬─────────────────────────────────────────────────────────────────┐ | |
#│ ♦ close │ Fecha o sprite. │ | |
#└─────────┴─────────────────────────────────────────────────────────────────┘ | |
def close | |
@open = false | |
end | |
#┌─────────┬─────────────────────────────────────────────────────────────────┐ | |
#│ ♦ open? │ Indica se o sprite está aberto. │ | |
#└─────────┴─────────────────────────────────────────────────────────────────┘ | |
def open? | |
self.zoom_x >= 0.9 || self.zoom_y >= 0.9 | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ close? │ Indica se o sprite está fechado. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def close? | |
self.zoom_x <= 0.1 || self.zoom_y <= 0.1 | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
update_openness | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ update_openness │ Atualiza a abertura do sprite. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def update_openness | |
m = @open_mode; o = @open | |
if m == :horizontal | |
self.zoom_x += 0.1 if self.zoom_x < 0.9 && o | |
self.zoom_x -= 0.1 if self.zoom_x > 0.1 && !o | |
elsif m == :vertical | |
self.zoom_y += 0.1 if self.zoom_y < 0.9 && o | |
self.zoom_y -= 0.1 if self.zoom_y > 0.1 && !o | |
else | |
self.zoom_x += 0.1 if self.zoom_x < 0.9 && o | |
self.zoom_x -= 0.1 if self.zoom_x > 0.1 && !o | |
self.zoom_y += 0.1 if self.zoom_y < 0.9 && o | |
self.zoom_y -= 0.1 if self.zoom_y > 0.1 && !o | |
end | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Opening_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Text_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite que serve justamente para mostrar um texto. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Text_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_reader :text | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → viewport: o viewport associado ao sprite, se for especificado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(viewport = nil) | |
super | |
@text = "" | |
@enable_line_spacing = false | |
@line_spacing = Font.default_size | |
@font = {} | |
set_font_settings | |
@rect_bitmap = Bitmap.new(1, 1) | |
end | |
#┌─────────────────────┬─────────────────────────────────────────────────────┐ | |
#│ ♦ set_font_settings │ Configurações de fonte para restauração. │ | |
#└─────────────────────┴─────────────────────────────────────────────────────┘ | |
def set_font_settings | |
@font[:name] = Font.default_name | |
@font[:size] = Font.default_size | |
@font[:bold] = Font.default_bold | |
@font[:italic] = Font.default_italic | |
@font[:outline] = Font.default_outline | |
@font[:shadow] = Font.default_shadow | |
@font[:color] = Font.default_color | |
@font[:out_color] = Font.default_out_color | |
end | |
#┌────────┬──────────────────────────────────────────────────────────────────┐ | |
#│ ♦ font │ Permite obter informações sobre a fonte. │ | |
#└────────┴──────────────────────────────────────────────────────────────────┘ | |
def font | |
@font | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ enable_line_spacing? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se é para utilizar o espaço customizado de altura entre as linhas. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def enable_line_spacing? | |
@enable_line_spacing | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ enable_line_spacing= │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Altera a propriedade de @enable_line_spacing para v. │ | |
#│ v precisa ser true ou false. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def enable_line_spacing=(v) | |
@enable_line_spacing = v | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ line_spacing │ Espaço customizado entre as linhas. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def line_spacing | |
@line_spacing | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ line_spacing= │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Altera o espaço customizado entre as linhas para v. │ | |
#│ v precisa ser um número inteiro. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def line_spacing=(v) | |
@line_spacing = v | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_font_property │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Permite alterar as propriedades da fonte. │ | |
#│ → symbol: um símbolo contendo a informação a ser alterada. │ | |
#│ Ex: :name, :size, :out_color... │ | |
#│ → value: o valor que será atribuído. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_font_property(symbol, value) | |
@font[symbol] = value | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ restore_font │ Restaura as configurações de fonte. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def restore_font | |
self.bitmap.font.name = @font[:name] | |
self.bitmap.font.size = @font[:size] | |
self.bitmap.font.bold = @font[:bold] | |
self.bitmap.font.italic = @font[:italic] | |
self.bitmap.font.outline = @font[:outline] | |
self.bitmap.font.shadow = @font[:shadow] | |
self.bitmap.font.color = @font[:color] | |
self.bitmap.font.out_color = @font[:out_color] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_text │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha um texto normal. │ | |
#│ → set_text: o texto a ser desenhado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_text(text) | |
self.bitmap.dispose if self.bitmap | |
w = @rect_bitmap.text_size(text).width | |
h = @rect_bitmap.text_size(text).height | |
if w > 0 || h > 0 | |
self.bitmap = Bitmap.new(w, h) | |
else | |
self.bitmap = Bitmap.new(1, 1) | |
end | |
restore_font | |
self.bitmap.draw_text(0, 0, w, h, text) | |
@text = text | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ write_text │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha um texto com quebra de linha (\n). │ | |
#│ → set_text: o texto a ser desenhado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def write_text(text) | |
lines = [] | |
r = @rect_bitmap | |
w = 0; h = 0 | |
text.scan(/[^\n]*/) { |line| lines.push(line) unless line == "" } | |
h = r.text_size(lines[0]).height | |
for i in 0...lines.size | |
nw = r.text_size(lines[i]).width | |
w = nw if w < nw | |
end | |
self.bitmap.dispose if self.bitmap | |
self.bitmap = Bitmap.new(w, h * lines.size) | |
restore_font | |
for t in 0...lines.size | |
c = t == 0 ? 0 : enable_line_spacing? ? line_spacing * t : h * t | |
self.bitmap.draw_text(0, 0 + c, w + 4, h + 4, lines[t]) | |
@text << lines[t] | |
end | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ dispose │ Se livra do bitmap extra ao realizar o dispose. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def dispose | |
@rect_bitmap.dispose | |
super | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Text_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Gauge_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite que funciona como uma barra. Ou gauge, para ser mais preciso. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Gauge_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: o bitmap, caso for usar um gauge baseado em imagem. │ | |
#│ → mode: :normal ou :image. Use o que achar melhor. Padrão: :normal │ | |
#│ → viewport: o viewport associado ao sprite. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, mode = :normal, viewport = nil) | |
super(viewport) | |
self.bitmap = bitmap if bitmap | |
@mode = mode | |
@rate = 0.0 | |
set_gauge mode | |
end | |
#┌─────────────┬─────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_gauge │ Ajusta o gauge dependendo do modo. │ | |
#└─────────────┴─────────────────────────────────────────────────────────────┘ | |
def set_gauge m | |
if m == :normal | |
set_normal_gauge | |
else | |
set_bitmap_gauge | |
end | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ set_normal_gauge │ Ajusta o gauge normal, sem imagem. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def set_normal_gauge(w = gauge_width, h = gauge_height) | |
c = gauge_back_color | |
c2 = gauge_fill_color | |
fw = (gauge_width * @rate).to_i | |
self.bitmap.dispose if self.bitmap | |
self.bitmap = Bitmap.new(w, h) | |
self.bitmap.fill_rect(0, 0, w, h, c) | |
self.bitmap.gradient_fill_rect(1, 1, fw - 2, h - 2, c2[0], c2[1]) | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ set_bitmap_gauge │ Ajusta o gauge com imagem. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def set_bitmap_gauge | |
fw = (self.bitmap.width * @rate).to_i | |
self.src_rect.width = fw | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ gauge_width │ É aqui que é definido a largura do gauge. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def gauge_width | |
return @mode == :normal ? 100 : self.bitmap.width | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ gauge_height │ É aqui que é definido a altura do gauge. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def gauge_height | |
return @mode == :normal ? 4 : self.bitmap.height | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ gauge_back_color │ A cor de fundo do gauge. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def gauge_back_color | |
return Color.new(50, 0, 0, 255) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ gauge_fill_color │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Retorna uma array de duas cores. A primeira é a cor inicial, e a segunda │ | |
#│ é a cor final. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def gauge_fill_color | |
start_color = Color.new(100, 0, 0, 255) | |
finish_color = Color.new(255, 0, 0, 255) | |
return [start_color, finish_color] | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_rate │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Configura a taxa de preenchimento do gauge externamente. │ | |
#│ → rate: a taxa. De 0.0 a 1.0 │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_rate(rate) | |
@rate = rate | |
set_gauge(@mode) | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Gauge_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Animated_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite com animação de frames. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Animated_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → framesx: o número de frames na horizontal. │ | |
#│ → framesy: o número de frames na vertical. │ | |
#│ → max_frames: o número máximo de frames. │ | |
#│ → bitmap: o bitmap necessário para animar. │ | |
#│ → viewport: o viewport associado ao sprite. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(framesx, framesy, max_frames, bitmap, viewport = nil) | |
super(viewport) | |
self.bitmap = bitmap | |
@framesx = framesx | |
@framesy = framesy | |
@max_frames = max_frames | |
@animate = false | |
@count = 0 | |
@index = 0 | |
@sizex = self.bitmap.width / @framesx | |
@sizey = self.bitmap.height / @framesy | |
setup_rect | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ setup_rect │ Configura o retângulo para desenhar o frame. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def setup_rect | |
x = @index % @framesx * @sizex | |
y = @index / @framesx * @sizex | |
rect = Rect.new(x, y, @sizex, @sizey) | |
self.src_rect.set(rect) | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ start_animation │ Usado para iniciar a animação. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def start_animation | |
@animate = true | |
end | |
#┌──────────────────┬────────────────────────────────────────────────────────┐ | |
#│ ♦ stop_animation │ Usado para parar a animação. │ | |
#└──────────────────┴────────────────────────────────────────────────────────┘ | |
def stop_animation | |
@animate = false | |
end | |
#┌───────────────────┬───────────────────────────────────────────────────────┐ | |
#│ ♦ reset_animation │ Usado para reiniciar a animação. │ | |
#└───────────────────┴───────────────────────────────────────────────────────┘ | |
def reset_animation | |
@index = 0 | |
setup_rect | |
end | |
#┌─────────────┬─────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_index │ Para manupular externamente o index do sprite. │ | |
#└─────────────┴─────────────────────────────────────────────────────────────┘ | |
def set_index(num) | |
@index = num | |
setup_rect | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
update_animation if @animate | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ update_animation │ Atualiza a animação. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def update_animation | |
@count + 1 > animate_wait ? @count = 0 : @count += 1 | |
if @count == animate_wait | |
@index == @max_frames - 1 ? @index = 0 : @index += 1 | |
setup_rect | |
end | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ animate_wait │ Quanto menor esse número, mais rápido é a animação. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def animate_wait | |
return 15 | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Animated_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Aura_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite com um efeito de aura. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Aura_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: o bitmap do sprite. É recomendado usar um. │ | |
#│ → viewport: o viewport associado ao sprite. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, viewport = nil) | |
super | |
@stopped = false | |
@comps = [] | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
for i in 0...@comps.size | |
@comps[i].update | |
if @comps[i].done | |
@comps[i].dispose | |
@comps[i] = nil | |
end | |
end | |
@comps.compact! | |
fixed_update if Prism.run_fixed_update? | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ fixed_update │ Atualização a cada 15 frames. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def fixed_update | |
spawn_new_sprite unless @stopped | |
end | |
#┌────────┬──────────────────────────────────────────────────────────────────┐ | |
#│ ♦ stop │ Usado para parar a animação. │ | |
#└────────┴──────────────────────────────────────────────────────────────────┘ | |
def stop | |
@stopped = true | |
end | |
#┌─────────┬─────────────────────────────────────────────────────────────────┐ | |
#│ ♦ start │ Usado para iniciar a animação. Ela já inicia sozinha por padrão.│ | |
#└─────────┴─────────────────────────────────────────────────────────────────┘ | |
def start | |
@stopped = false | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ spawn_new_sprite │ Cria um novo sprite, que será deletado depois. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def spawn_new_sprite | |
@comps.push(Prism::Aura_Sprite_Comp.new(self.bitmap.clone, self.viewport)) | |
@comps[-1].x = self.x | |
@comps[-1].x += @comps[-1].ox | |
@comps[-1].y = self.y | |
@comps[-1].y += @comps[-1].oy | |
@comps[-1].z = self.z - 1 | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Aura_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Aura_Sprite_Comp ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Aura_Sprite_Comp < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_reader :done | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: o bitmap do sprite. │ | |
#│ → viewport: o viewport associado ao sprite. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, viewport = nil) | |
super | |
self.ox = self.bitmap.width * 0.5 | |
self.oy = self.bitmap.height * 0.5 | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
update_animation | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ update_animation │ Atualização da animação. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def update_animation | |
self.opacity -= 8 | |
self.zoom_x += 0.005 | |
self.zoom_y += 0.005 | |
if self.zoom_x >= 1.2 && self.zoom_y >= 1.2 | |
@done = true | |
end | |
end | |
#┌───────────┬───────────────────────────────────────────────────────────────┐ | |
#│ ♦ dispose │ Se livra do bitmap antes de efetuar o dispose. │ | |
#└───────────┴───────────────────────────────────────────────────────────────┘ | |
def dispose | |
self.bitmap.dispose | |
super | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Aura_Sprite_Comp ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Circular_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite que se move de maneira circular. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Circular_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :clockwise | |
attr_accessor :auto | |
attr_accessor :range | |
attr_accessor :speed | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: o bitmap do sprite. Padrão: nil. │ | |
#│ → viewport: o viewport associado ao sprite. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, viewport = nil) | |
super | |
@clockwise = false | |
@auto = true | |
@angle = 0 | |
@range = 48 | |
@speed = 0.05 | |
@origin_ox = self.ox | |
@origin_oy = self.oy | |
adjust_pos | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
adjust_count if @auto | |
adjust_pos | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ rotate_right │ Rotaciona o sprite para a direita. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def rotate_right | |
@angle -= @speed | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ rotate_left │ Rotaciona o sprite para a esquerda. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def rotate_left | |
@angle += @speed | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_count │ Ajusta a contagem para a rotação. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def adjust_count | |
@clockwise ? @angle -= @speed : @angle += @speed | |
end | |
#┌──────────────┬────────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_pos │ Ajusta o ponto de origem para a rotação do sprite. │ | |
#└──────────────┴────────────────────────────────────────────────────────────┘ | |
def adjust_pos | |
self.ox = (@origin_ox + Math.sin(@angle) * @range) | |
self.oy = (@origin_oy + @range * Math.cos(@angle)) | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Circular_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Numeric_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite que desenha números usando um bitmap como base. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Numeric_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :dimension | |
attr_accessor :source_bitmap | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: o bitmap do sprite. Padrão: nil. │ | |
#│ → dimension: o tamanho de um caractere em pixels. │ | |
#│ → bytes: a quantidade de caracteres na horizontal. Padrão: 10 │ | |
#│ → viewport: o viewport associado ao sprite. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, dimension = 7, bytes = 10, viewport = nil) | |
super(nil, viewport) | |
@dimension = dimension | |
@align = 0 | |
@value = 0 | |
@bytes = bytes | |
@source_bitmap = bitmap | |
setup_base_bitmap | |
set_value(@value) | |
end | |
#┌─────────┬─────────────────────────────────────────────────────────────────┐ | |
#│ ♦ align │ Usado para obter o alinhamento. │ | |
#└─────────┴─────────────────────────────────────────────────────────────────┘ | |
def align | |
@align | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ align= │ Usado para alterar o alinhamento. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def align=(num) | |
@align = num | |
set_value(@value) | |
end | |
#┌─────────────────────┬─────────────────────────────────────────────────────┐ | |
#│ ♦ setup_base_bitmap │ Configura o bitmap de base. │ | |
#└─────────────────────┴─────────────────────────────────────────────────────┘ | |
def setup_base_bitmap | |
self.bitmap.dispose if self.bitmap | |
self.bitmap = Bitmap.new(@bytes * @dimension, @dimension) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_value │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta o novo valor de desenho do sprite. │ | |
#│ → integer: um número que será o novo valor do sprite. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_value(integer) | |
@value = integer | |
return false unless @source_bitmap | |
self.bitmap.clear | |
char = integer.to_s | |
px = x_for_align(@align, char) | |
dsrc = Rect.new(px, 0, @dimension, @dimension) | |
for i in 0...char.size | |
dsrc.x = char[i].to_i * @dimension | |
self.bitmap.blt(px + (@dimension * i), 0, @source_bitmap, dsrc) | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ x_for_align │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém a posição de desenho do sprite dependendo do alinhamento. │ | |
#│ → a: o número do alinhamento. │ | |
#│ → c: o número completo convertido em string. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def x_for_align(a, c) | |
res = 0 | |
if a == 1 | |
res += self.bitmap.width * 0.5 - (c.size * @dimension) * 0.5 | |
elsif a == 2 | |
res += self.bitmap.width - (c.size * @dimension) | |
end | |
return res | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Numeric_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Jump_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite com propriedades de pulo. Ele também inclui propriedades de ║ | |
#║ movimento, usando add_force_left ou add_force_right. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Jump_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :auto | |
attr_accessor :range | |
attr_accessor :speed | |
attr_accessor :x_force_max | |
attr_accessor :bounciness | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: o bitmap do sprite. Padrão: nil. │ | |
#│ → viewport: o viewport associado ao sprite. Padrão: nil │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Abaixo há algumas explicações das instâncias usadas no sprite para melhor │ | |
#│ entendimento. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap, viewport = nil) | |
super | |
@auto = true # Indica se o sprite irá pular constantemente. | |
@angle = 0 # O contador do ângulo de pulo. | |
@range = 98 # A distância do pulo. | |
@speed = 0.1 # A velocidade de pulo. | |
@bounciness = 0.3 # Esse valor pode aplicar "bounce" no pulo. | |
@jump_times = 0 # Número de vezes que o sprite irá pular. | |
@default_speed = 0.1 # É recomendado ser o mesmo que speed. | |
@default_range = 98 # É recomendado ser o mesmo que range. | |
@x_force = 0 # A força de velocidade em X. | |
@x_force_max = 4 # A força máxima de velocidade em X. | |
@jumping = false # Indica se o sprite está pulando. | |
@landed = false # Indica se o sprite aterrissou. | |
@source_y = self.y # O ponto de origem do pulo. | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
adjust_count if @auto | |
adjust_jump | |
adjust_force | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_count │ Ajuste da incrementação do ângulo. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def adjust_count | |
@angle += @speed | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_jump │ Ajuste do pulo. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def adjust_jump | |
adjust_auto_jump if @auto | |
adjust_normal_jump if !@auto | |
end | |
#┌────────────────────┬──────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_auto_jump │ Ajuste do pulo automático. │ | |
#└────────────────────┴──────────────────────────────────────────────────────┘ | |
def adjust_auto_jump | |
self.y = -(Math.sin(@angle) * @range).abs + @source_y | |
end | |
#┌──────────────────────┬────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_normal_jump │ Ajuste do pulo normal. │ | |
#└──────────────────────┴────────────────────────────────────────────────────┘ | |
def adjust_normal_jump | |
if @range != @default_range && !@jumping | |
@speed = @default_speed | |
@range = @default_range | |
@angle = 0 | |
end | |
if !@jumping && self.y != @source_y | |
self.y = @source_y | |
end | |
return unless @jumping | |
self.y = -(Math.sin(@angle) * @range).abs + @source_y | |
@range = Prism.decrease(@range, @bounciness, 0) | |
if self.y.between?(@source_y - 2, @source_y) | |
@landed = true | |
else | |
@landed = false | |
end | |
if @range == 0 && @jump_times <= 0 | |
@jumping = false | |
end | |
if @landed && @jump_times > 0 | |
@jump_times -= 1 | |
@angle = 0 | |
@speed = @default_speed | |
@range = @default_range | |
end | |
@speed += 0.001 | |
adjust_count | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ refresh_position │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualiza o novo ponto de origem da posição Y. É recomendado chamar este │ | |
#│ método quando quiser gravar o novo ponto onde o sprite deve "cair". │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def refresh_position | |
@source_y = self.y | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ jump │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Faz o sprite pular o número de vezes desejados. Começando por 0. │ | |
#│ → times: o número de vezes que ele irá pular. Padrão: 0 │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def jump(times = 0) | |
@jumping = true | |
@jump_times = times | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_force │ Ajusta a força de velocidade X. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def adjust_force | |
self.x += @x_force | |
if @x_force > 0 | |
@x_force - 0.1 < 0 ? @x_force = 0 : @x_force -= 0.1 | |
elsif @x_force < 0 | |
@x_force + 0.1 > 0 ? @x_force = 0 : @x_force += 0.1 | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ add_force_right │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Adiciona uma certa quantidade de força de movimento X para a direita. │ | |
#│ → force: a força desejada, em float. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def add_force_right(force) | |
if @x_force + force > @x_force_max | |
@x_force = @x_force_max | |
else | |
@x_force += force | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ add_force_left │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Adiciona uma certa quantidade de força de movimento X para a esquerda. │ | |
#│ → force: a força desejada, em float. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def add_force_left(force) | |
if @x_force - force < -@x_force_max | |
@x_force = -@x_force_max | |
else | |
@x_force -= force | |
end | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Jump_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Flashing_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite que pisca. Você pode ajustar o tom, velocidade e etc... ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Flashing_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :auto | |
attr_accessor :speed | |
attr_accessor :source_tone | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: o bitmap do sprite. Padrão: nil. │ | |
#│ → viewport: o viewport associado ao sprite. Padrão: nil │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, viewport = nil) | |
super | |
@auto = true | |
@phase = 0 | |
@speed = 15 | |
@flash_times = 0 | |
@manual_flashing = false | |
@source_tone = Tone.new(255, 255, 255, 255) | |
end | |
#┌──────────┬────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ Atualização de frames. │ | |
#└──────────┴────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
adjust_tone if @auto || @manual_flashing | |
adjust_flash if @auto || @manual_flashing | |
end | |
#┌───────────────┬───────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_tone │ Ajuste de tonalidade. │ | |
#└───────────────┴───────────────────────────────────────────────────────────┘ | |
def adjust_tone | |
tr = self.tone.red | |
tg = self.tone.green | |
tb = self.tone.blue | |
ta = self.tone.gray | |
sr = @source_tone.red | |
sg = @source_tone.green | |
sb = @source_tone.blue | |
sa = @source_tone.gray | |
c1 = tr >= sr && tg >= sg && tb >= sb && ta >= sa | |
c2 = tr <= 0 && tg <= 0 && tb <= 0 && ta <= 0 | |
if c1 && @phase == 0 | |
@phase = 1 | |
@flash_times - 1 < 0 ? @flash_times = 0 : @flash_times -= 1 | |
elsif c2 && @phase == 1 | |
@phase = 0 | |
end | |
@manual_flashing = !(@flash_times <= 0 && c2 && @phase == 0) | |
end | |
#┌────────────────┬──────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_flash │ Ajuste de flash. │ | |
#└────────────────┴──────────────────────────────────────────────────────────┘ | |
def adjust_flash | |
if @phase == 0 | |
self.tone.red = Prism.increase(self.tone.red, @speed, @source_tone.red) | |
self.tone.green = Prism.increase(self.tone.green, @speed, @source_tone.green) | |
self.tone.blue = Prism.increase(self.tone.blue, @speed, @source_tone.blue) | |
self.tone.gray = Prism.increase(self.tone.gray, @speed, @source_tone.gray) | |
elsif @phase == 1 | |
self.tone.red = Prism.decrease(self.tone.red, @speed, 0) | |
self.tone.green = Prism.decrease(self.tone.green, @speed, 0) | |
self.tone.blue = Prism.decrease(self.tone.blue, @speed, 0) | |
self.tone.gray = Prism.decrease(self.tone.gray, @speed, 0) | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ flash │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Faz o sprite piscar o número de vezes desejado. Começando por 1. │ | |
#│ → times: o número de vezes que ele irá piscar. Padrão: 1 │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def flash(times = 1) | |
@flash_times = times | |
@manual_flashing = true | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Flashing_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Touch_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite com métodos de toque. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Touch_Sprite < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: automaticamente configura o bitmap se for especificado. │ | |
#│ → viewport: o viewport associado ao sprite, se for especificado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, viewport = nil) | |
super | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_pressed? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se o sprite está sendo tocado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_pressed? | |
return Prism::Touch_Input.is_pressed? && is_hovered? | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_triggered? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se o sprite foi tocado uma vez. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_triggered? | |
return Prism::Touch_Input.is_triggered?(self) && is_hovered? | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_repeated? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se o sprite está sendo pressionado repetidamente. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_repeated? | |
return Prism::Touch_Input.is_repeated?(self) && is_hovered? | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_cancelling? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se o sprite está sendo cancelado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_cancelling? | |
return Prism::Touch_Input.is_cancelling? && is_hovered? | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_cancelled? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se o sprite foi cancelado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_cancelled? | |
return Prism::Touch_Input.is_cancelled?(self) && is_hovered? | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_hovered? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se o cursor está sobre o sprite. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_hovered? | |
x = self.x | |
y = self.y | |
w = self.bitmap.width | |
h = self.bitmap.height | |
return Prism::Touch_Input.hovering?(x, y, w, h) | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Touch_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::Drag_Sprite ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um sprite que você pode arrastar por aí com o toque. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::Drag_Sprite < Prism::Touch_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → bitmap: automaticamente configura o bitmap se for especificado. │ | |
#│ → viewport: o viewport associado ao sprite, se for especificado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(bitmap = nil, viewport = nil) | |
super | |
@mouse_coords = Prism::Point.new | |
@new_points = Prism::Point.new | |
@dragging = false | |
@block_to_screen = true | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualização de frames. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
update_mouse_coords | |
check_if_dragging | |
on_drag if @dragging | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update_mouse_coords │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualiza as coordenadas do cursor. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update_mouse_coords | |
@mouse_coords.x = Prism::Touch_Input.x - self.x | |
@mouse_coords.y = Prism::Touch_Input.y - self.y | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ check_if_dragging │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Checa se o sprite está sendo arrastado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def check_if_dragging | |
if is_pressed? | |
@dragging = true | |
@new_points.x = Prism::Touch.last_pos[0] - self.x | |
@new_points.y = Prism::Touch.last_pos[1] - self.y | |
else | |
@dragging = false | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ on_drag │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Processa o arrastamento do sprite. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def on_drag | |
if @mouse_coords.x < @new_points.x | |
if !getting_off_screen(:lb) && @block_to_screen | |
self.x -= @new_points.x - @mouse_coords.x | |
@new_points.x = Prism::Touch.last_pos[0] - self.x | |
elsif !@block_to_screen | |
self.x -= @new_points.x - @mouse_coords.x | |
@new_points.x = Prism::Touch.last_pos[0] - self.x | |
else | |
self.x = 0 | |
end | |
elsif @mouse_coords.x > @new_points.x | |
if !getting_off_screen(:rb) && @block_to_screen | |
self.x += @mouse_coords.x - @new_points.x | |
@new_points.x = Prism::Touch.last_pos[0] - self.x | |
elsif !@block_to_screen | |
self.x += @mouse_coords.x - @new_points.x | |
@new_points.x = Prism::Touch.last_pos[0] - self.x | |
else | |
self.x = Graphics.width - self.bitmap.width | |
end | |
end | |
if @mouse_coords.y < @new_points.y | |
if !getting_off_screen(:ub) && @block_to_screen | |
self.y -= @new_points.y - @mouse_coords.y | |
@new_points.y = Prism::Touch.last_pos[1] - self.y | |
elsif !@block_to_screen | |
self.y -= @new_points.y - @mouse_coords.y | |
@new_points.y = Prism::Touch.last_pos[1] - self.y | |
else | |
self.y = 0 | |
end | |
elsif @mouse_coords.y > @new_points.y | |
if !getting_off_screen(:db) && @block_to_screen | |
self.y += @mouse_coords.y - @new_points.y | |
@new_points.y = Prism::Touch.last_pos[1] - self.y | |
elsif !@block_to_screen | |
self.y += @mouse_coords.y - @new_points.y | |
@new_points.y = Prism::Touch.last_pos[1] - self.y | |
else | |
self.y = Graphics.height - self.bitmap.height | |
end | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ getting_off_screen │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se o sprite está prestes a sair da tela. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def getting_off_screen(type) | |
lb = self.x - (@new_points.x - @mouse_coords.x) < 0 | |
rb = self.x + (@mouse_coords.x - @new_points.x + self.bitmap.width) > Graphics.width | |
ub = self.y - (@new_points.y - @mouse_coords.y) < 0 | |
db = self.y + (@mouse_coords.y - @new_points.y + self.bitmap.height) > Graphics.height | |
return lb if type == :lb | |
return rb if type == :rb | |
return ub if type == :ub | |
return db if type == :db | |
return true | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::Drag_Sprite ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::GUI ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um módulo contendo sprites para a criação de GUIs simples. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
module Prism::GUI; end | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::GUI::Button ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um botão que pode ser clicado. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::GUI::Button < Prism::Touch_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :on_click | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal do botão. │ | |
#│ → y: posição vertical do botão. │ | |
#│ → width: largura do botão. │ | |
#│ → height: altura do botão. │ | |
#│ → text: o texto que será mostrado no botão. │ | |
#│ → viewport: o viewport associado ao botão. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height, text = "", viewport = nil) | |
@normal_bmp = main_bitmap(width, height, text) | |
@highlight_bmp = main_bitmap(width, height, text, true) | |
@on_click = nil | |
super(@normal_bmp, viewport) | |
self.x = x | |
self.y = y | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ main_bitmap │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o bitmap do botão. │ | |
#│ → w: largura do bitmap. │ | |
#│ → h: altura do bitmap. │ | |
#│ → t: texto que será desenhado no bitmap. │ | |
#│ → highlight: bitmap caso o cursor esteja acima do botão. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def main_bitmap(w, h, t, highlight = false) | |
bmp = Bitmap.new(w, h) | |
c1 = highlight ? Prism.color_convert("e5f1fb") : Prism.color_convert("e1e1e1") | |
c2 = highlight ? Prism.color_convert("0179d7") : Prism.color_convert("adadad") | |
bmp.fill_rect(0, 0, w, h, c1) | |
bmp.fill_rect(0, 0, w, 1, c2) | |
bmp.fill_rect(0, h - 1, w, 1, c2) | |
bmp.fill_rect(0, 0, 1, h, c2) | |
bmp.fill_rect(w - 1, 0, 1, h, c2) | |
bmp.font.name = "Segoe UI" | |
bmp.font.size = 14 | |
bmp.font.outline = false | |
bmp.font.color = Prism.color_convert("010101") | |
bmp.draw_text(0, 0, w, h, t, 1) | |
return bmp | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualização de frames. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
if is_hovered? | |
self.bitmap = @highlight_bmp | |
else | |
self.bitmap = @normal_bmp | |
end | |
if is_triggered? && @on_click | |
@on_click.call | |
end | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::GUI::Button ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::GUI::Background ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um background padrão para servir de modelo na criação de GUIs. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::GUI::Background < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → viewport: o viewport associado ao background. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(viewport = nil) | |
rect = Rect.new(0, 0, Graphics.width, Graphics.height) | |
color = Prism.color_convert("efefef") | |
super(Bitmap.new(rect.width, rect.height), viewport) | |
self.bitmap.fill_rect(0, 0, rect.width, rect.height, color) | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::GUI::Background ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::GUI::Panel ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um painel com uma cor um tanto mais clara que o background do GUI. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::GUI::Panel < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal do painel. │ | |
#│ → y: posição vertical do painel. │ | |
#│ → width: largura do painel. │ | |
#│ → height: altura do painel. │ | |
#│ → viewport: o viewport associado ao painel. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height, viewport = nil) | |
bmp = main_bitmap(width, height) | |
super(bmp, viewport) | |
self.x = x | |
self.y = y | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ main_bitmap │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha o bitmap principal do painel. │ | |
#│ → w: largura do bitmap do painel. │ | |
#│ → h: altura do bitmap do painel. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def main_bitmap(w, h) | |
bmp = Bitmap.new(w, h) | |
c1 = Prism.color_convert("ffffff") | |
c2 = Prism.color_convert("d8d8d8") | |
bmp.fill_rect(0, 0, w, h, c1) | |
bmp.fill_rect(0, 0, w, 1, c2) | |
bmp.fill_rect(0, h - 1, w, 1, c2) | |
bmp.fill_rect(0, 0, 1, h, c2) | |
bmp.fill_rect(w - 1, 0, 1, h, c2) | |
return bmp | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::GUI::Panel ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::GUI::Text_Input ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Uma caixa onde o usuário pode inserir texto. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::GUI::Text_Input < Prism::Input_Window | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :text | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal do campo de texto. │ | |
#│ → y: posição vertical do campo de texto. │ | |
#│ → width: largura do campo de texto. │ | |
#│ → height: altura do campo de texto. │ | |
#│ → viewport: o viewport associado ao campo de texto. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height, viewport = nil) | |
@box_input_bmp_n = get_box_input_bmp(width, height) | |
@box_input_bmp_h = get_box_input_bmp(width, height, true) | |
create_box_input(viewport) | |
super(x, y, width, height + 8) | |
self.opacity = 0 | |
self.viewport = viewport | |
@box_input.x = self.x | |
@box_input.y = self.y + (window_padding * 2) + 1 | |
adjust_font | |
self.deactivate | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Obtém o sprite da caixa de texto para associação de um tooltip. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_associative_tooltip | |
return @box_input | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ adjust_font │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta as configurações de fonte principais. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def adjust_font | |
self.contents.font.name = "Segoe UI" | |
self.contents.font.size = 14 | |
self.contents.font.outline = false | |
self.contents.font.color = Prism.color_convert("010101") | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ create_input_sprite │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Configuração do sprite de cursor. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def create_input_sprite | |
super | |
@input_sprite.bitmap.clear | |
@input_sprite.bitmap.font.name = "Segoe UI" | |
@input_sprite.bitmap.font.size = 14 | |
@input_sprite.bitmap.font.outline = false | |
@input_sprite.bitmap.font.color = Prism.color_convert("010101") | |
@input_sprite.bitmap.draw_text(0, 0, 24, 24, "|") | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ process_character │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajuste no processamento de caracteres. │ | |
#│ → ch: o caractere que está prestes a ser inserido. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def process_character(ch) | |
if self.contents.text_size(@text + ch).width > contents_width | |
Sound.play_buzzer | |
return | |
else | |
@text << ch | |
refresh_text | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualização de frames. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update | |
if @box_input && @box_input.bitmap && @box_input_bmp_h && @box_input_bmp_n | |
if @box_input.is_hovered? | |
@box_input.bitmap = @box_input_bmp_h | |
else | |
@box_input.bitmap = @box_input_bmp_n | |
end | |
if @box_input.is_triggered? | |
self.activate unless self.active | |
elsif Prism::Touch_Input.is_triggered? && !@box_input.is_hovered? | |
self.deactivate unless !self.active | |
end | |
end | |
if @input_sprite && @count | |
@input_sprite.opacity = 0 if !self.active | |
@count = 0 if !self.active | |
end | |
super | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ process_confirmation │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Processamento de confirmação. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def process_confirmation; end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ activate │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ativação. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def activate | |
self.active = true | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ window_padding │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Distância entre o texto e as bordas. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def window_padding | |
return 4 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ z= │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajuste na posição z dos componentes. │ | |
#│ → v: o novo valor z. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def z=(v) | |
@box_input.z = v - 1 | |
@input_sprite.z = v + 1 | |
super | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ viewport= │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajuste no viewport dos componentes. │ | |
#│ → vp: o novo viewport. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def viewport=(vp) | |
@box_input.viewport = vp | |
@input_sprite.viewport = vp | |
super | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ create_box_input │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Cria a caixa de digitação. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def create_box_input(vp) | |
@box_input = Prism::Touch_Sprite.new(@box_input_bmp_n, vp) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_box_input_bmp │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o bitmap para a caixa de digitação. │ | |
#│ → width: a largura do bitmap. │ | |
#│ → height: a altura do bitmap. │ | |
#│ → highlight: bitmap caso o cursor esteja acima da caixa. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_box_input_bmp(width, height, highlight = false) | |
bmp = Bitmap.new(width, height) | |
c1 = Prism.color_convert("ffffff") | |
c2 = highlight ? Prism.color_convert("0078d6") : Prism.color_convert("646464") | |
bmp.fill_rect(0, 0, width, height, c1) | |
bmp.fill_rect(0, 0, width, 1, c2) | |
bmp.fill_rect(0, height - 1, width, 1, c2) | |
bmp.fill_rect(0, 0, 1, height, c2) | |
bmp.fill_rect(width - 1, 0, 1, height, c2) | |
return bmp | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ dispose │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Efetua o dispose do @box_input. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def dispose | |
@box_input.dispose if @box_input | |
super | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::GUI::Text_Input ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::GUI::Label ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um texto normal para ser mostrado em GUIs. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::GUI::Label < Prism::Text_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal do texto. │ | |
#│ → y: posição vertical do texto. │ | |
#│ → text: o texto a ser desenhado. │ | |
#│ → viewport: o viewport associado ao botão. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, text = "", viewport = nil) | |
super(viewport) | |
self.x = x | |
self.y = y | |
set_font_property(:name, "Segoe UI") | |
set_font_property(:size, 14) | |
set_font_property(:outline, false) | |
set_font_property(:color, Prism.color_convert("010101")) | |
set_text(text) | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::GUI::Label ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::GUI::Explorer ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Sistema de explorador de arquivos. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::GUI::Explorer < Prism::Window_Command | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ Variáveis de Instância Públicas │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
attr_accessor :selected # Se a janela terminou de selecionar. | |
attr_accessor :directory # O diretório onde o explorer está. | |
attr_accessor :selected_file # O nome do arquivo selecionado. | |
attr_accessor :selected_file_type # O tipo do arquivo selecionado. | |
# :file, :image ou :text. | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal do explorador. │ | |
#│ → y: posição vertical do explorador. │ | |
#│ → width: largura do explorador. │ | |
#│ → height: altura do explorador. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height) | |
@directory = Dir.getwd | |
@selected = false | |
@selected_file = nil | |
@selected_file_type = nil | |
@viewer = nil | |
super | |
self.windowskin = explorer_windowskin | |
self.back_opacity = 255 | |
update_viewer | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ make_command_list │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Criação da lista de comandos. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def make_command_list | |
@list = {} | |
list = [] | |
@back = [] | |
@folders = [] | |
@files = [] | |
@images = [] | |
@texts = [] | |
d = @directory.unpack("U*").pack("C*") | |
Dir.entries(d, {encoding: "UTF-8"}).each {|dir| | |
ext = File.extname(dir) | |
next if dir == "." | |
list.push(dir) | |
@back.push(dir) if dir == ".." | |
@folders.push(dir) if ext.empty? && (dir != "." && dir != "..") | |
@files.push(dir) if !ext.empty? && !is_image?(ext) && !is_text?(ext) | |
@images.push(dir) if is_image?(ext) | |
@texts.push(dir) if is_text?(ext) | |
} | |
@back.each {|item| add_command(item, item.to_sym, true, get_handler(item))} | |
@folders.each {|item| add_command(item, item.to_sym, true, get_handler(item))} | |
@files.each {|item| add_command(item, item.to_sym, true, get_handler(item))} | |
@images.each {|item| add_command(item, item.to_sym, true, get_handler(item))} | |
@texts.each {|item| add_command(item, item.to_sym, true, get_handler(item))} | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_image? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se a extensão é reconhecida como uma imagem. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_image?(extension) | |
return true if extension =~ /jpg/i | |
return true if extension =~ /jpeg/i | |
return true if extension =~ /png/i | |
return false | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ is_text? │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Indica se a extensão é reconhecida como um arquivo de texto. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def is_text?(extension) | |
return true if extension =~ /txt/i | |
return false | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ get_handler │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o método que será chamado dependendo do item passado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def get_handler(item) | |
return method(:on_back) if item == ".." | |
return method(:on_folder_select) if @folders.include?(item) | |
return method(:on_file_select) if @files.include?(item) | |
return method(:on_image_select) if @images.include?(item) | |
return method(:on_text_select) if @texts.include?(item) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ on_back │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Faz o explorer voltar um diretório acima. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def on_back | |
path = "" | |
folders = @directory.split("/") | |
return if folders.size < 3 | |
for i in 0...folders.size - 1 | |
path += folders[i] + "/" | |
end | |
@directory = path.slice(0, path.size - 1) | |
redraw_command_list | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ on_folder_select │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Faz o explorer ir para a pasta selecionada. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def on_folder_select | |
path = @directory + "/#{selected_item[1][:type]}" | |
if File.directory?(path) | |
@directory = path | |
redraw_command_list | |
else | |
Sound.play_buzzer | |
if @viewer | |
alert_message = "Ocorreu um erro ao abrir o diretório.\nTalvez ele não seja um diretório." | |
@viewer.receive_information(alert_message, :alert) | |
end | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ on_file_select │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Processamento de seleção de um arquivo. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def on_file_select | |
@selected_file = selected_item[1][:type] | |
@selected_file_type = :file | |
@selected = true | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ on_text_select │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Processamento de seleção de um arquivo de texto. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def on_text_select | |
@selected_file = selected_item[1][:type] | |
@selected_file_type = :text | |
@selected = true | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ on_image_select │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Processamento de seleção de um arquivo de imagem. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def on_image_select | |
@selected_file = selected_item[1][:type] | |
@selected_file_type = :image | |
path = @directory + "/" + @selected_file | |
name = File.basename(@selected_file, ".*") | |
dir = File.dirname(path) + "/" | |
begin | |
bmp = Bitmap.new(dir + name) | |
rescue | |
if @viewer | |
alert_message = "Ocorreu um erro ao carregar a imagem." | |
@viewer.receive_information(alert_message, :alert) | |
end | |
return | |
end | |
@selected = true | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ folder_icon │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o bitmap desenhado com o ícone de uma pasta. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def folder_icon | |
bmp = Bitmap.new(16, 16) | |
c = Prism.color_convert("e7c147") | |
c2 = Prism.color_convert("ffe486") | |
bmp.fill_rect(4, 4, 8, 1, c) | |
bmp.fill_rect(4, 4, 1, 9, c) | |
bmp.fill_rect(4, 12, 8, 1, c) | |
bmp.fill_rect(11, 4, 1, 9, c) | |
bmp.fill_rect(9, 4, 1, 9, c) | |
bmp.fill_rect(5, 5, 4, 7, c2) | |
bmp.fill_rect(10, 5, 1, 7, c2) | |
return bmp | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ file_icon │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o bitmap desenhado com o ícone de um arquivo. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def file_icon | |
bmp = Bitmap.new(16, 16) | |
c = Prism.color_convert("0a0a0a") | |
c2_1 = Prism.color_convert("75daed") | |
c2_2 = Prism.color_convert("e5f8fc") | |
bmp.fill_rect(4, 4, 5, 1, c) | |
bmp.fill_rect(4, 4, 1, 9, c) | |
bmp.fill_rect(4, 12, 8, 1, c) | |
bmp.fill_rect(11, 5, 1, 8, c) | |
bmp.fill_rect(8, 5, 4, 1, c) | |
bmp.gradient_fill_rect(6, 7, 4, 4, c2_1, c2_2, true) | |
return bmp | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ text_icon │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o bitmap desenhado com o ícone de um texto. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def text_icon | |
bmp = Bitmap.new(16, 16) | |
c = Prism.color_convert("808283") | |
bmp.fill_rect(4, 4, 8, 1, c) | |
bmp.fill_rect(4, 4, 1, 9, c) | |
bmp.fill_rect(11, 4, 1, 9, c) | |
bmp.fill_rect(4, 12, 8, 1, c) | |
bmp.fill_rect(6, 6, 2, 1, c) | |
bmp.fill_rect(9, 6, 1, 1, c) | |
bmp.fill_rect(6, 8, 1, 1, c) | |
bmp.fill_rect(8, 8, 1, 1, c) | |
bmp.fill_rect(7, 10, 3, 1, c) | |
return bmp | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ image_icon │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o bitmap desenhado com o ícone de uma imagem. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def image_icon | |
bmp = Bitmap.new(16, 16) | |
c = Prism.color_convert("0179d7") | |
bmp.fill_rect(4, 4, 8, 1, c) | |
bmp.fill_rect(11, 4, 1, 9, c) | |
bmp.fill_rect(4, 12, 8, 1, c) | |
bmp.fill_rect(4, 4, 1, 9, c) | |
bmp.fill_rect(5, 8, 2, 1, c) | |
bmp.fill_rect(7, 7, 2, 1, c) | |
bmp.fill_rect(9, 8, 1, 1, c) | |
bmp.fill_rect(10, 9, 1, 1, c) | |
bmp.fill_rect(5, 9, 5, 3, c) | |
bmp.fill_rect(7, 8, 2, 1, c) | |
bmp.fill_rect(10, 10, 1, 2, c) | |
return bmp | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualização de frames. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update | |
old_index = @index | |
super | |
self.active = !@selected | |
update_viewer if @viewer && old_index != @index | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ cursor_speed │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Velocidade do cursor. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def cursor_speed | |
return 12 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ scroll_speed │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Velocidade de rolamento. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def scroll_speed | |
return 12 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_font_settings │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Configura a fonte para desenhar as opções. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_font_settings | |
self.contents.font.name = "Segoe UI" | |
self.contents.font.size = 14 | |
self.contents.font.outline = false | |
self.contents.font.color = Prism.color_convert("010101") | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ process_string │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha os comandos. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def process_string(cmd, i) | |
if @folders.include?(cmd[:type]) | |
process_bitmap(folder_icon, i) | |
elsif @files.include?(cmd[:type]) | |
process_bitmap(file_icon, i) | |
elsif @texts.include?(cmd[:type]) | |
process_bitmap(text_icon, i) | |
elsif @images.include?(cmd[:type]) | |
process_bitmap(image_icon, i) | |
end | |
old_alpha = self.contents.font.color.alpha | |
enabled = cmd[:enabled] | |
!enabled ? self.contents.font.color.alpha = 160 : nil | |
rect = item_rect(i) | |
draw_text(rect.x + 20, rect.y - 4, cmd[:type].to_s) | |
self.contents.font.color.alpha = old_alpha | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ process_bitmap │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Desenha os ícones dos comandos. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def process_bitmap(bmp, i) | |
rect = item_rect(i) | |
bit_rect = Rect.new(0, 0, bmp.width, bmp.height) | |
self.contents.blt(rect.x, rect.y + 2, bmp, bit_rect) | |
bmp.dispose | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ selection_height │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Altura de cada item. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def selection_height | |
return 18 | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ explorer_windowskin │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o bitmap para ser usado como windowskin do explorer. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def explorer_windowskin | |
bmp = Bitmap.new(128, 128) | |
c1 = Prism.color_convert("ffffff"); c2 = Prism.color_convert("e5f3ff") | |
c3 = Prism.color_convert("d8d8d8"); c4 = Prism.color_convert("999999") | |
# Desenho principal. | |
bmp.fill_rect(0, 0, 64, 128, c1) | |
bmp.fill_rect(64, 96, 64, 32, c1) | |
bmp.fill_rect(96, 64, 32, 32, c1) | |
bmp.fill_rect(64, 64, 32, 32, c2) | |
bmp.fill_rect(64, 0, 64, 1, c3) | |
bmp.fill_rect(127, 0, 1, 64, c3) | |
bmp.fill_rect(64, 63, 64, 1, c3) | |
bmp.fill_rect(64, 0, 1, 64, c3) | |
# Seta superior | |
bmp.fill_rect(92, 20, 5, 1, c4) | |
bmp.fill_rect(93, 19, 3, 1, c4) | |
bmp.fill_rect(94, 18, 1, 1, c4) | |
# Seta esquerda | |
bmp.fill_rect(84, 28, 1, 5, c4) | |
bmp.fill_rect(83, 29, 1, 3, c4) | |
bmp.fill_rect(82, 30, 1, 1, c4) | |
# Seta direita | |
bmp.fill_rect(105, 28, 1, 5, c4) | |
bmp.fill_rect(106, 29, 1, 3, c4) | |
bmp.fill_rect(107, 30, 1, 1, c4) | |
# Seta inferior | |
bmp.fill_rect(92, 41, 5, 1, c4) | |
bmp.fill_rect(93, 42, 3, 1, c4) | |
bmp.fill_rect(94, 43, 1, 1, c4) | |
return bmp | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update_tone │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta a tonalidade do explorer. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update_tone | |
self.tone.set(Tone.new(0, 0, 0)) | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_viewer │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Configura o visualizador de informações do explorer. │ | |
#│ → viewer: o visualizador. Precisa ser um Prism::Base_Sprite ou um │ | |
#│ Prism::GUI::Viewer. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_viewer(viewer) | |
@viewer = viewer | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ redraw_command_list │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta o visualizador ao redesenhar comandos. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def redraw_command_list(*args) | |
super(*args) | |
update_viewer | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update_viewer │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualiza o conteúdo do visualizador. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update_viewer | |
return unless @viewer | |
item = selected_item[1][:type] | |
info = "#{@directory}/#{item}" | |
if @texts.include?(item) | |
@viewer.receive_information(info, :text) | |
elsif @files.include?(item) | |
@viewer.receive_information(info, :file) | |
elsif @images.include?(item) | |
@viewer.receive_information(info, :image) | |
else | |
@viewer.receive_information(nil, nil) | |
end | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::GUI::Explorer ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::GUI::Viewer ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um visualizador de imagens ou texto para o Prism::GUI::Explorer. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::GUI::Viewer < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → x: posição horizontal do visualizador. │ | |
#│ → y: posição vertical do visualizador. │ | |
#│ → width: largura do visualizador. │ | |
#│ → height: altura do visualizador. │ | |
#│ → viewport: o viewport associado ao visualizador. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(x, y, width, height, viewport = nil) | |
super(main_bmp(width, height), viewport) | |
@main_rect = [width, height] | |
@main_sprite = Prism::Base_Sprite.new(nil, viewport) | |
self.x = x | |
self.y = y | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ z= │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta a posição z do @main_sprite de acordo. │ | |
#│ → v: a nova posição z. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def z=(v) | |
@main_sprite.z = v + 1 if @main_sprite | |
super | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ x= │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta a posição x do @main_sprite de acordo. │ | |
#│ → v: a nova posição x. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def x=(v) | |
@main_sprite.x = v + 1 if @main_sprite | |
super | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ y= │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta a posição y do @main_sprite de acordo. │ | |
#│ → v: a nova posição y. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def y=(v) | |
@main_sprite.y = v + 1 if @main_sprite | |
super | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ viewport= │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta o viewport do @main_sprite de acordo. │ | |
#│ → vp: o novo viewport. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def viewport=(vp) | |
@main_sprite.viewport = vp if @main_sprite | |
super | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ set_font_settings │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Ajusta as configurações de fonte do bitmap principal. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def set_font_settings | |
self.bitmap.font.name = "Segoe UI" | |
self.bitmap.font.size = 14 | |
self.bitmap.font.outline = false | |
self.bitmap.font.color = Prism.color_convert("000000") | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ main_bmp │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o bitmap original do visualizador. │ | |
#│ → w: a largura do bitmap. │ | |
#│ → h: a altura do bitmap. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def main_bmp(w, h) | |
bmp = Bitmap.new(w, h) | |
c1 = Prism.color_convert("ffffff") | |
c2 = Prism.color_convert("d8d8d8") | |
bmp.fill_rect(0, 0, w, h, c1) | |
bmp.fill_rect(0, 0, w, 1, c2) | |
bmp.fill_rect(0, h - 1, w, 1, c2) | |
bmp.fill_rect(0, 0, 1, h, c2) | |
bmp.fill_rect(w - 1, 0, 1, h, c2) | |
return bmp | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ receive_information │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Recebe uma informação que será passada ao visualizador. │ | |
#│ Caso type seja :text, info será desenhado no bitmap do visualizador. │ | |
#│ → info: a informação a ser passada ao visualizador. │ | |
#│ → type: o tipo de informação a ser passada. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def receive_information(info, type) | |
self.bitmap = main_bmp(@main_rect[0], @main_rect[1]) | |
@main_sprite.bitmap.dispose if @main_sprite.bitmap | |
if type == :text | |
if File.size(info) > 500 | |
text = "Este arquivo de texto é muito grande para ser lido pelo visualizador." | |
else | |
text = load_data(info).unpack("C*").pack("U*") | |
end | |
write_text(4, 4, text.to_s, 0, true) | |
elsif type == :file | |
text = "Este arquivo não pode ser lido pelo visualizador." | |
write_text(4, 4, text, 0, true) | |
elsif type == :alert | |
write_text(4, 4, info, 0, true) | |
elsif type == :image | |
name = File.basename(info, ".*") | |
dir = File.dirname(info) + "/" | |
begin | |
@main_sprite.bitmap = Bitmap.new(dir + name) | |
rescue | |
return | |
end | |
if @main_sprite.bitmap.width > self.bitmap.width | |
@main_sprite.zoom_x = (self.bitmap.width - 2).to_f / @main_sprite.bitmap.width | |
elsif @main_sprite.bitmap.width < self.bitmap.width | |
@main_sprite.zoom_x = 1 | |
end | |
if @main_sprite.bitmap.height > self.bitmap.height | |
@main_sprite.zoom_y = (self.bitmap.height - 2).to_f / @main_sprite.bitmap.height | |
elsif @main_sprite.bitmap.height < self.bitmap.height | |
@main_sprite.zoom_y = 1 | |
end | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ dispose │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Efetua o dispose do @main_sprite. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def dispose | |
@main_sprite.dispose if @main_sprite | |
super | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::GUI::Viewer ◄ | |
#╔═════════════════════════════════════════════════════════════════════════════╗ | |
#║ ҉ Prism::GUI::Tooltip ║ | |
#╠═════════════════════════════════════════════════════════════════════════════╣ | |
#║ Um pequeno sprite que serve como tooltip para algumas opções. ║ | |
#╚═════════════════════════════════════════════════════════════════════════════╝ | |
class Prism::GUI::Tooltip < Prism::Base_Sprite | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ initialize │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ → width: largura do tooltip. │ | |
#│ → height: altura do tooltip. │ | |
#│ → viewport: o viewport associado ao tooltip. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def initialize(width, height, text = "", viewport = nil) | |
super(main_bitmap(width, height, text), viewport) | |
@fixed_pos = [nil, nil] | |
@associated_object = nil | |
@wait_count = 0 | |
self.visible = false | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ associate │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Associa um objeto ao tooltip. O objeto precisa ser um Prism::Touch_Sprite │ | |
#│ ou um Prism::GUI::Text_Input. │ | |
#│ → obj: o objeto a ser associado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def associate(obj) | |
if obj.is_a?(Prism::Touch_Sprite) | |
@associated_object = obj | |
elsif obj.is_a?(Prism::GUI::Text_Input) | |
@associated_object = obj.get_associative_tooltip | |
end | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ main_bitmap │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Obtém o bitmap do tooltip. │ | |
#│ → w: largura do bitmap. │ | |
#│ → h: altura do bitmap. │ | |
#│ → text: o texto a ser desenhado no bitmap. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def main_bitmap(w, h, text) | |
lines = [] | |
text.split("\n").each {|line| lines.push(line) unless line == ""} | |
bmp = Bitmap.new(w, h) | |
c1 = Prism.color_convert("feffe1") | |
c2 = Prism.color_convert("646464") | |
bmp.fill_rect(0, 0, w, h, c1) | |
bmp.fill_rect(0, 0, w, 1, c2) | |
bmp.fill_rect(0, 0, 1, h, c2) | |
bmp.fill_rect(w - 1, 0, 1, h, c2) | |
bmp.fill_rect(0, h - 1, w, 1, c2) | |
bmp.font.name = "Segoe UI" | |
bmp.font.size = 14 | |
bmp.font.outline = false | |
bmp.font.color = Prism.color_convert("010101") | |
for i in 0...lines.size | |
bmp.draw_text(4, 4 + (14 * i), w, 14, lines[i]) | |
end | |
return bmp | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualização de frames. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update | |
super | |
update_associated_object if @associated_object | |
end | |
#┌───────────────────────────────────────────────────────────────────────────┐ | |
#│ ♦ update_associated_object │ | |
#├───────────────────────────────────────────────────────────────────────────┤ | |
#│ Atualização do objeto associado. │ | |
#└───────────────────────────────────────────────────────────────────────────┘ | |
def update_associated_object | |
@associated_object.is_hovered? ? @wait_count += 0.01 : @wait_count = 0 | |
self.visible = @wait_count.between?(1, 5) | |
self.z = @associated_object.z + 1 | |
@wait_count = 5 if @wait_count > 5 | |
@wait_count = 0 if Prism::Touch_Input.is_triggered? | |
if self.visible && @fixed_pos[0].nil? && @fixed_pos[1].nil? | |
@fixed_pos[0] = Prism::Touch_Input.x | |
@fixed_pos[1] = Prism::Touch_Input.y | |
elsif !self.visible | |
@fixed_pos[0] = nil | |
@fixed_pos[1] = nil | |
end | |
self.x = @fixed_pos[0] || 0 | |
self.y = @fixed_pos[1] || 0 | |
end | |
end # ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ ▫ Prism::GUI::Tooltip ◄ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment