=begin
==============================================================================
SCRIPT CREADO POR NEWOLD
DE USO LIBRE PARA JUEGOS NO COMERCIALES
Título: Star Wars Letters
Para qué Sirve: Simula el efecto de letras volando por el espacio de star wars.
Fecha de Creación: 12-09-2014
Versión: 1.0
SI QUIERES USARLO EN UN PROYECTO COMERCIAL PONTE EN CONTACTO CONMIGO
todobasura31@hotmail.es
Instalación: Colocarlo encima del main (Compatible con RPG Maker XP, VX y ACE)
Para inicializar el script poner esto:
scene = StarWarsLetters.new
Para configurar los diferentes apartados del script usad estos comandos:
-----------------------------------------------------------------------------
* Tipografía del texto:
scene.fontName = 'Nombre de la fuente'
* Color del texto:
scene.fontColor= color # color = Color.new(r,g,b,a)
# r,g,b,a = número entre 0-255
* Tamaño del texto:
scene.fontSize = número
* Altura máxima que alcanza el texto:
scene.top = número
* Tiempo en segundos en alcanzar el máximo alto:
scene.time = número
* Sesgado del texto
scene.angled = número
* Máximo zoom:
scene.maxZoom = número
* Espacio en píxels entre un texto y otro:
scene.margin = número
* Resolución del maker horizontal:
scene.w = número
* Resolución del maker vertical:
scene.h = número
* Añadir un fondo con o sin movimiento:
scene.set_background('Dirección imagen',velocidad X, Velocidad Y)
* Añadir música de fondo:
scene.set_music('Dirección música',volumen)
* Añadir el texto que vuela por la pantalla:
scene.data = ['Texto1', 'Texto2', '...', 'textoN']
* Añadir Título/s inical/es antes de que vuele el texto:
scene.set_title(title,fontName,fontSize,fontColor, align, zoom, time,timeout)
title = ['Texto para ese título'] # ['line1','line2','...','lineN']
fontName = 'Nombre de la tipografía'
fontSize = número # Tamaño del texto
fontColor = color
# color = Color.new(r,g,b,a) || r,g,b,a = número entre 0-255
align = número # Alineación del texto || 0 = Izquierda, 1 = Centro, 2 = Derecha
zoom = número # Zoom para el texto.
# Si pones un zoom diferente de 1 se producirá un efecto
# de zoom-out. Si lo pones en 1 el efecto será opacity-out.
time = número # Tiempo en segundos que tarda en aparecer el texto
timeout = número # Tiempo en segundos que tarda en desaparecer el texto
-----------------------------------------------------------------------------
Una vez configurado el script usa el comando
scene.preload
para realizar una precarga de datos y usa el comando
scene.start para mostrar el resultado.
(Nota: El script termina cuando el texto volador se pierde en el horizonte
o cuando se pulsa B y ya no se está mostrando ningún título inicial.
Si se pulsa B mientras se muestra un título éste termina y se muestra el
siguiente si ubiera o se empieza a mostrar el texto volador)
==============================================================================
=end
# ==============================================================================
class Point # by Newold
#--------------------------------------------------------------------------
attr_accessor :x
attr_accessor :y
#--------------------------------------------------------------------------
def initialize(x=0,y=0)
@x = x; @y = y
end
#--------------------------------------------------------------------------
def ==(point)
return (self.x == point.x and self.y == point.y)
end
#--------------------------------------------------------------------------
def ===(point)
return (self.x.eql?(point.x) and self.y.eql?(point.y))
end
#--------------------------------------------------------------------------
def to_a
return [self.x.floor,self.y.floor]
end
#--------------------------------------------------------------------------
def to_s
return "[#{self.x.to_i}x, #{self.y.to_i}y]"
end
#--------------------------------------------------------------------------
def dup
return Point.new(@x,@y)
end
#--------------------------------------------------------------------------
def _dump(d=0)
s = [3].pack('L')
s = [@x].pack("F")
s << [@y].pack("F")
s
end
#--------------------------------------------------------------------------
def self._load(s)
x = s[0,4].unpack("F")[0]
y = s[4,4].unpack("F")[0]
point = Point.new(x,y)
return point
end
end
# ==============================================================================
#===============================================================================
class Bitmap # << by NEWOLD
#--------------------------------------------------------------------------
# transferPoint:
# Transfiere un punto de una imagen a otra deformada tomando en cuenta las
# 4 esquinas de la imagen normal y las 4 esquinas de la imagen deformada
# Parámetetros:
# xI = Coordenada x en la imagen original
# yI = Coordenada y en la imagen original
# source = Array de esquinas de la imagen original
# (siguiendo el sentido de las agujas del reloj
# desde esquina superior izquierda a esquina inferior izquierda)
# Ejemplo:
# source = [];
# source[0] = Point.new(0, 0);
# source[2] = Point.new(200,100);
# destination = Array de esquinas de la imagen distorsionada (perspectiva)
# (siguiendo el sentido de las agujas del reloj
# desde esquina superior izquierda a esquina inferior izquierda)
# Ejemplo:
# destination = [];
# destination[n] = Point.new(0, 0); # n= 0...4
#--------------------------------------------------------------------------
def transferPoint (xI, yI, source, destination)
adding = 0.001; # (para evitar dividir por 0)
xA = source[0].x.to_f;
yA = source[0].y.to_f;
xC = source[2].x.to_f;
yC = source[2].y.to_f;
xAu = destination[0].x.to_f;
yAu = destination[0].y.to_f;
xBu = destination[1].x.to_f;
yBu = destination[1].y.to_f;
xCu = destination[2].x.to_f;
yCu = destination[2].y.to_f;
xDu = destination[3].x.to_f;
yDu = destination[3].y.to_f;
# Cálculos
# (si los puntos son iguales hay que añadir 'adding' para evitar división 0)
if (xBu==xCu); xCu+=adding; end;
if (xAu==xDu); xDu+=adding; end;
if (xAu==xBu); xBu+=adding; end;
if (xDu==xCu); xCu+=adding; end;
kBC = (yBu-yCu)/(xBu-xCu);
kAD = (yAu-yDu)/(xAu-xDu);
kAB = (yAu-yBu)/(xAu-xBu);
kDC = (yDu-yCu)/(xDu-xCu);
if (kBC==kAD); kAD+=adding; end;
xE = (kBC*xBu - kAD*xAu + yAu - yBu) / (kBC-kAD);
yE = kBC*(xE - xBu) + yBu;
if (kAB==kDC); kDC+=adding; end;
xF = (kAB*xBu - kDC*xCu + yCu - yBu) / (kAB-kDC);
yF = kAB*(xF - xBu) + yBu;
if (xE==xF); xF+=adding; end;
kEF = (yE-yF) / (xE-xF);
if (kEF==kAB); kAB+=adding; end;
xG = (kEF*xDu - kAB*xAu + yAu - yDu) / (kEF-kAB);
yG = kEF*(xG - xDu) + yDu;
if (kEF==kBC); kBC+=adding; end;
xH = (kEF*xDu - kBC*xBu + yBu - yDu) / (kEF-kBC);
yH = kEF*(xH - xDu) + yDu;
rG = (yC-yI)/(yC-yA);
rH = (xI-xA)/(xC-xA);
xJ = (xG-xDu)*rG + xDu;
yJ = (yG-yDu)*rG + yDu;
xK = (xH-xDu)*rH + xDu;
yK = (yH-yDu)*rH + yDu;
if (xF==xJ); xJ+=adding; end;
if (xE==xK); xK+=adding; end;
kJF = (yF-yJ) / (xF-xJ);
kKE = (yE-yK) / (xE-xK);
if (kJF==kKE); kKE+=adding; end;
xIu = (kJF*xF - kKE*xE + yE - yF) / (kJF-kKE);
yIu = kJF * (xIu - xJ) + yJ;
b=Point.new(xIu.floor,yIu.floor);
return b;
end
#--------------------------------------------------------------------------
end
#===============================================================================
# ==============================================================================
class StarWarsLetters
#--------------------------------------------------------------------------
attr_accessor :fontName, :fontSize, :fontColor, :data, :top, :time, :angled,
:maxZoom, :margin, :w, :h
#--------------------------------------------------------------------------
def initialize(*args)
@fontName = args[0].nil? ? ['Verdana','Times New Roman','Arial'] : args[0]
@fontSize = args[1].nil? ? 46 : [args[1].to_i,6].max
@fontColor = args[2].nil? ? Color.new(255,255,0) : args[2]
@data = args[3].nil? ? [] : args[3]
@top = args[4].nil? ? 270 : args[4].to_i
@time = args[5].nil? ? 35 : [args[5].to_i,1].max
@angled = args[6].nil? ? 85.0 : ([args[6].to_i,0].max).to_f
@maxZoom = args[7].nil? ? 2.5 : ([args[7].to_i,0.1].max).to_f
@margin = args[8].nil? ? -30 : args[8].to_i
@background = nil
@vx = 0
@vy = 0
@ox = @oy = 0
@music = nil
@maxVol = 100
@vol = 0
@sprites = []
@points = {}
@w = 640
@h = 480
@title = []
end
#--------------------------------------------------------------------------
def set_title(title,fontName='Verdana',fontSize=36,
fontColor=Color.new(0,0,160), align=0, zoom=1.0, time=3,timeout=4)
timer = time * Graphics.frame_rate * 1.0
timer2 = timeout * Graphics.frame_rate * 1.0
b = Bitmap.new(1,1)
b.font.name = fontName
b.font.size = fontSize
w = h = 1
for i in 0...title.size
size = b.text_size(title[i].to_s)
w = size.width if w < size.width
h = size.height if h < size.height
end
s = Sprite.new
s.bitmap = Bitmap.new(w,h*(title.size > 0 ? title.size : 1))
s.bitmap.font.name = fontName
s.bitmap.font.size = fontSize
s.bitmap.font.color = fontColor
for i in 0...title.size
s.bitmap.draw_text(0,h*i,w,h,title[i],align)
end
s.zoom_x = s.zoom_y = zoom
s.opacity = 0
s.x = (@w/2) - (s.bitmap.width * s.zoom_x / 2)
s.y = (@h/2) - (s.bitmap.height * s.zoom_y / 2)
@title << [s,timer,timer2,true,zoom,zoom/(timer+timer2)]
end
#--------------------------------------------------------------------------
def set_background(dir,vx=0,vy=0)
@background = Plane.new
@background.bitmap = Bitmap.new(dir)
@background.visible = false
@vx = vx.to_f
@vy = vy.to_f
end
#--------------------------------------------------------------------------
def set_music(dir,vol=100)
@music = dir
@maxVol = vol
end
#--------------------------------------------------------------------------
def find_zoom(text)
b = Bitmap.new(1,1)
b.font.name = @fontName
b.font.size = @fontSize
zoom = 1
size = b.text_size(text)
if size.width == 0 or size.height == 0
p "Font <#{@fontName}> incompatible with this RPG MAKER"
p "Using font... ['Verdana','Times New Roman','Arial']"
@fontName = ['Verdana','Times New Roman','Arial']
find_zoom(text)
return
end
while size.height * zoom < 115
zoom += 0.1
end
while size.width * zoom > @w + 384
zoom -= 0.1
end
@maxZoom = zoom
end
#--------------------------------------------------------------------------
def start
b = Bitmap.new(1,1)
b.font.name = @fontName
b.font.size = @fontSize
size = b.text_size(' ')
if size.width == 0 or size.height == 0
p "Font <#{@fontName}> incompatible with this RPG MAKER"
p "Using font... ['Verdana','Times New Roman','Arial']"
@fontName = ['Verdana','Times New Roman','Arial']
end
Graphics.freeze
unless @background.nil?
@background.visible = true
end
Graphics.transition(20)
while @data.size > 0 or @sprites.size > 0
Input.update
update
update_background
update_music
Graphics.update
if Input.trigger?(Input::B)
if @title.size > 0
obj = @title.shift
obj[0].dispose
else
break
end
end
end
Graphics.freeze
dispose
Graphics.transition(20)
end
#--------------------------------------------------------------------------
def update
if @title.size > 0
obj = @title[0]
if obj[3]
obj[1] -= 1
obj[3] = false if obj[1] <= 0
obj[0].opacity += 1
else
obj[2] -= 1
if obj[2] < 22
obj[0].opacity -= 12
end
if obj[2] <= 0
@title.delete(obj)
return
end
end
if obj[4] != 1.0
obj[0].zoom_x -= obj[5]
obj[0].zoom_y = obj[0].zoom_x
obj[0].x = (@w/2) - (obj[0].bitmap.width * obj[0].zoom_x / 2)
obj[0].y = (@h/2) - (obj[0].bitmap.height * obj[0].zoom_y / 2)
end
return
end
if (@sprites.size == 0) or
(@sprites[-1][0].y + @margin +
@sprites[-1][0].bitmap.height * @sprites[-1][0].zoom_y <= @h)
draw
end
timer = @time * Graphics.frame_rate * 1.0
ratioZoom = @maxZoom / timer
@sprites.each {|obj|
obj[2] = obj[2] + ((@top - obj[2]) / timer)
obj[0].y = [obj[2],@top].max - (obj[0].bitmap.height * obj[0].zoom_y / 2)
if obj[0].y <= @top or obj[0].zoom_x < 0.4
obj[0].opacity -= 2
if obj[0].opacity == 0
@sprites.delete(obj)
end
else
obj[0].opacity += 2
end
obj[0].x = @w/2 - (obj[0].bitmap.width * obj[0].zoom_x / 2)
ratioZoom = obj[0].zoom_x / timer
obj[0].zoom_x -= ratioZoom
obj[0].zoom_y = obj[0].zoom_x
}
end
#--------------------------------------------------------------------------
def update_background
return if @background.nil?
@ox += @vx
@oy += @vy
@background.ox = @ox
@background.oy = @oy
end
#--------------------------------------------------------------------------
def update_music
return if @music.nil?
Audio.bgm_play(@music,@vol)
@vol = [@vol+5,@maxVol].max
end
#--------------------------------------------------------------------------
def preload
data = @data.dup
while @data.size > 0
draw(true)
end
@data = data
end
#--------------------------------------------------------------------------
def draw(pl = false)
text = @data.shift
return if text.nil?
b = Bitmap.new(10,10)
b.font.name = @fontName
b.font.size = @fontSize
size = b.text_size(' ')
s = Sprite.new
s.bitmap = Bitmap.new(@w,size.height)
s.bitmap.font.name = @fontName
s.bitmap.font.size = @fontSize
s.bitmap.font.color = @fontColor
while s.bitmap.text_size(text).width > @w
s.bitmap.font.size -= 1
end
s.bitmap.draw_text(0,0,@w,size.height,text,1)
if @points.size == 0
sz = s.bitmap.text_size(' ')
source = [Point.new(0.0,0.0),nil,
Point.new(s.bitmap.width.to_f+sz.width,s.bitmap.height.to_f+sz.height),nil]
point1 = Point.new(@angled,0.0)
point2 = Point.new(s.bitmap.width-@angled,0.0)
point3 = Point.new(s.bitmap.width.to_f,s.bitmap.height.to_f)
point4 = Point.new(0.0,s.bitmap.height.to_f)
destination = [point1,point2,point3,point4]
for y in 0...s.bitmap.height
for x in 0...s.bitmap.width
point = b.transferPoint(x.to_f, y.to_f, source, destination)
@points[[x,y]] = [point.x,point.y]
end
end
end
if pl
s.dispose
return
end
b = s.bitmap.dup
s.bitmap.clear
for y in 0...s.bitmap.height
for x in 0...s.bitmap.width
color = b.get_pixel(x,y)
s.bitmap.set_pixel(@points[[x,y]][0],@points[[x,y]][1],color)
end
end
s.zoom_x = s.zoom_y = @maxZoom
s.x = @w/2 - (s.bitmap.width * s.zoom_x / 2)
s.y = @h + (s.bitmap.height * s.zoom_x / 2)
s.opacity = 0
@sprites << [s,s.x,s.y]
end
#--------------------------------------------------------------------------
def dispose
@sprites.each {|obj| obj[0].dispose}
@sprites = []
@title.each {|obj| obj[0].dispose}
@title = []
end
#--------------------------------------------------------------------------
end
# ==============================================================================