Код:
#==============================================================================
# EK Lib v2.1b
#------------------------------------------------------------------------------
# Created by: Equilibrium Keeper [equilibriumkeeper@inbox.com]
# Created on: 05.01.2009 22:02:54
# Отдельное спасибо: insider, Snaiper, Рольф, Dr. Nick To, Steck
# А так же: rpgmaker.sk6.ru, rpg-maker.info, gdsa.rpgmaker.ru,
# otvety.google.ru
# За основу метода draw_rout был взят метод draw_line неизвестного автора
#==============================================================================
# Описание: Библиотека содержит несколько наиболее часто используемых мной
# методов. При желании вы можете воспользоваться ими, но делайте
# это на свой страх и риск.
#------------------------------------------------------------------------------
# Установка: В редакторе скриптов создайте чистую страницу над "Main" и
# скопируйте туда данный скрипт.
#------------------------------------------------------------------------------
# Примечание: В описании скриптов используются следующие сокращения:
# [](array) - массив; i(integer) - целое число; f(float) - дробное число
# b(boolean) - true/false; s(string) - строка
# В круглых () скобках указаны рекомедуемые значения параметров
# В фигурных {} скобках указаны допустимые значения параметров
#==============================================================================
class Test
def initialize
# Класс для тестирования методов и отлова ошибок.
# Вызывается через команду "Script..." события: Test.new
end
end
#==============================================================================
module Math
#----------------------------------------------------------------------------
# Метод возвращает массив координат точек, лежащих на отрезке AB
# Возвращает :[[i, i],..,[i, i]]
# start_coords :[i, i] - координаты x, y начала отрезка
# end_coords :[i, i] - координаты x, y конца отрезка
#----------------------------------------------------------------------------
def self.calculate_line(start_coords, end_coords)
distance = (start_coords[0] - end_coords[0]).abs + (start_coords[1] - end_coords[1]).abs
array = []
for i in 1..distance
x = (start_coords[0] + 1.0 * (end_coords[0] - start_coords[0]) * i / distance).to_i
y = (start_coords[1] + 1.0 * (end_coords[1] - start_coords[1]) * i / distance).to_i
array.push([x, y])
end
return array
end
#----------------------------------------------------------------------------
# Метод возвращает массив координат точек, лежащих на окружности
# Возвращает :[[i, i],..,[i, i]]
# center :[i, i] - координаты x, y центра окружности
# radius :[i, i] - координаты x, y точки лежащей на окружности
# -radius :integer - радиус окружности
# accuracy :integer {1~5) - точность вычислений; nil - автоматически
# чем больше значение accuracy, тем дольше расчеты
#----------------------------------------------------------------------------
def self.calculate_circle (center, radius, accuracy = nil)
if radius.is_a?(Array)
catet_x = (radius[0] - center[0]).abs
catet_y = (radius[1] - center[1]).abs
radius = hypot(catet_x, catet_y)
end
if accuracy == nil then accuracy = 1 + radius/100 end
angle = 0
array = []
while angle > -360 * accuracy && angle < 360 * accuracy
x = center[0] + radius * cos(PI * angle.to_f / (180 * accuracy))
y = center[1] + radius * sin(PI * angle.to_f / (180 * accuracy))
angle += 1
unless array.include?([x.round, y.round])
array.push([x.round, y.round])
end
end
return array
end
#----------------------------------------------------------------------------
# Метод возвращает массив координат точек, лежащих на дуге окружности
# Возвращает :[[i, i],..,[i, i]]
# center :[i, i] - координаты x, y центра окружности
# start_coords :[i, i] - координаты x, y начала дуги
# end_coords :[i, i] - координаты x, y конца дуги
# обе точки должны лежать на одной окружности, иначе метод вернет false
# -end_coords :float (-359.0~+359.0) - угол,
# на который конец дуги отстоит от ее начала
# accuracy :integer {1~5) - точность вычислений; nil - автоматически
# чем больше значение accuracy, тем дольше расчеты
#----------------------------------------------------------------------------
def self.calculate_arc (center, start_coords, end_coords, clockwise = true, accuracy = nil)
catet_x = (start_coords[0] - center[0]).abs
catet_y = (start_coords[1] - center[1]).abs
radius = hypot(catet_x, catet_y)
if end_coords.is_a?(Array)
catet_x2 = (end_coords[0] - center[0]).abs
catet_y2 = (end_coords[1] - center[1]).abs
radius2 = hypot(catet_x2, catet_y2)
return false if radius != radius2
end
circle = calculate_circle(center, radius, accuracy)
index = circle.index([start_coords[0], start_coords[1]])
unless end_coords.is_a?(Array)
if end_coords < 0
end_coords = -end_coords
clockwise = !clockwise
end
while end_coords > 360.0
end_coords -= 360.0
end
rate = circle.size.to_f / 360.0
end_index = (end_coords * rate).round
if clockwise
end_index += index
if end_index > circle.size - 1 then end_index -= circle.size end
else
end_index = index - end_index
if end_index < 0 then end_index += circle.size end
end
end
array = []
loop do
array.push(circle[index])
if end_coords.is_a?(Array)
break if circle[index] == [end_coords[0], end_coords[1]]
else
break if index == end_index
end
if clockwise
if index + 1 == circle.size then index = 0 else index += 1 end
else
if index == 0 then index = circle.size - 1 else index -= 1 end
end
end
return array
end
#----------------------------------------------------------------------------
end
#==============================================================================
class Array
#----------------------------------------------------------------------------
# Метод записывает в массив фрагменты изображения
# filename : string - имя файла, относительно папки проекта
# index_t : integer / [integer] [0~...) - порядковый номер(а) фрагмента(ов)
# - index_t[0] == true - будут возвращены все фрагменты с index[1] по index[2]
# - index_t[0] == false - будет возвращено index[2] фрагментов начиная с index[1]
# width : integer [1 ~ bitmap.width] - ширина каждого фрагмента
# height : integer [1 ~ bitmap.height] - высота каждого фрагмента
# Примечание: Счет ведется слева направо, сверху вниз.
#----------------------------------------------------------------------------
def push_image_fragments (filename, index_t, width, height)
index = []
if index_t.is_a?(Integer)
return false if index_t < 0
index.push(index_t)
@interval = index
elsif index_t.is_a?(Array)
index = index_t
return false if index[1] < 0
if index[0] == true
return false if index[2] < index[1]
@interval = index[1]..index[2]
elsif index[0] == false
return false if index[2] < 1
@interval = index[1]...index[1] + index[2]
end
else
return false
end
for index_t in @interval
bitmap = Bitmap.new (filename)
bitmap_result = Bitmap.new (width, height)
n = bitmap.width / width
x = index_t % n * width
y = index_t / n * height
rect = Rect.new(x, y, width, height)
bitmap_result.blt(0, 0, bitmap, rect)
self.push(bitmap_result)
end
end
#----------------------------------------------------------------------------
end
#==============================================================================
class Numeric
#----------------------------------------------------------------------------
# Метод преобразует число в строку с заданным количеством знаков
# digits : integer - количество знаков в возвращаемой строке
# filling_symbol : string - символ, заполняющий не достающие знаки
#----------------------------------------------------------------------------
def to_string(digits = 3, filling_symbol = "0")
counter = self.to_s
for i in self.to_s.size...digits
counter = filling_symbol + counter
i += 1
end
return counter
end
#----------------------------------------------------------------------------
end
#==============================================================================
class Bitmap
#----------------------------------------------------------------------------
# Метод возвращает отраженное изображение
# horizontal :boolean - изображение будет отражено по горизонтали
# vertical :boolean - изображение будет отражено по вертикали
#----------------------------------------------------------------------------
def mirror(horizontal = true, vertical = false)
source = self
if horizontal
bitmap = Bitmap.new(source.width, source.height)
for i in 0...source.width
bitmap.blt(i, 0, source, Rect.new(source.width - 1 - i, 0, 1, source.height))
end
source = bitmap
end
if vertical
bitmap = Bitmap.new(source.width, source.height)
for i in 0...source.height
bitmap.blt(0, i, source, Rect.new(0, source.height - 1 - i, source.width, 1))
end
source = bitmap
end
return source
end
#----------------------------------------------------------------------------
# Метод возвращает изображение с измененным размером
# width :integer {1~+x) - итоговая ширина изображения
# height :integer {1~+x) - итоговая высота изображения
# background :color - цвет фона
# interpolation :boolean {false} (НЕ РАБОТАЕТ) - будет ли исходное изображение растянуто или сжато
#----------------------------------------------------------------------------
def resize(width, height, interpolation = false, background = nil)
unless interpolation
bitmap = Bitmap.new(width, height)
bitmap.fill_rect(0, 0, width, height, background) if background
bitmap.blt(0, 0, self, Rect.new(0, 0, self.width, self.height))
return bitmap
end
end
#----------------------------------------------------------------------------
# Метод рисует точки заданной величины в координатах, взятых из массива
# points :[[i, i],..,[i, i]] - двумерный массив координат x, y точек
# start_color :color - цвет, которым будет изображена первая точка
# width :integer {1~5) - размер точек
# end_color :color - цвет, которым будет изображена последняя точка
# если начальный цвет и конечный совподают, то все точки будут нарисованы
# начальным цветом, в противном случае будет осуществлен плавный переход цвета
#----------------------------------------------------------------------------
def draw_rout (points, start_color, width = 1, end_color = start_color)
if end_color == start_color
for i in 0...points.size
if width == 1
self.set_pixel(points[i][0], points[i][1], start_color)
else
self.fill_rect(points[i][0], points[i][1], width, width, start_color)
end
end
else
for i in 0...points.size
# Graphics.update # Следить за линией
r = start_color.red * (points.size-1-i)/(points.size-1) + end_color.red * i/(points.size-1)
g = start_color.green * (points.size-1-i)/(points.size-1) + end_color.green * i/(points.size-1)
b = start_color.blue * (points.size-1-i)/(points.size-1) + end_color.blue * i/(points.size-1)
a = start_color.alpha * (points.size-1-i)/(points.size-1) + end_color.alpha * i/(points.size-1)
if width == 1
self.set_pixel(points[i][0], points[i][1], Color.new(r, g, b, a))
else
self.fill_rect(points[i][0], points[i][1], width, width, Color.new(r, g, b, a))
end
end
end
end
#----------------------------------------------------------------------------
# Метод рисует прямоугольник
# rect : rect - прямоугольник
# -rect : [i, i, i, i] - массив с координатами x, y, ширина, высота
# color : color - цвет прямоугольника
# gauge : integer - толщина линии, не имеет значения при заливке
# filling : boolean - флаг заливки
#----------------------------------------------------------------------------
def draw_rectangle (rect, color, gauge = 2, filling = false)
if rect.is_a?(Rect)
x = rect.x
y = rect.y
width = rect.width
height = rect.height
else
x = rect[0]
y = rect[1]
width = rect[2]
height = rect[3]
end
if filling
fill_rect(x, y, width, height, color)
else
fill_rect(x, y, width, gauge, color)
fill_rect(x, y, gauge, height, color)
fill_rect(x, y + height - gauge, width, gauge, color)
fill_rect(x + width - gauge, y, gauge, height, color)
end
end
#----------------------------------------------------------------------------
# Метод рисует строку text в контейнере рисунка, перенося не помещающиеся слова
# text : string - строка (длина не важна), которую требуется записать
# width : integer - максимальная длина строк
# x : integer - координата x начала первой строки
# y : integer - координата y начала первой строки
# height : integer - высота строки
# calc : boolean - если true, то рисование производиться не будет
# при некорректном значении, будет высчитана автоматически
#----------------------------------------------------------------------------
def hyphen_draw_text (text, width, x = 20, y = 20, height = -1, calc = false)
n = 0
index = 0
strings = []
if height < (font.size.to_f / 1.2).to_f then height = text_size("1рВысотаHeight0").height end
if text == "" then strings.push("") end
while n < text.size
length = text.size
while text_size(text[n, length]).width > width
length /= (text_size(text[n, length]).width.to_f / width.to_f).to_f
end
strings[index] = text[n, length]
if (n + length) < text.size
while (strings[index][length - 1, 1] != " " && strings[index][length - 1, 1] != "")
length -= 1
strings[index] = strings[index][0, length]
end
n += length - 1
else
n += length
end
index += 1
end
for i in 0...strings.size
if strings[i] == "" && i == strings.size - 1
break
elsif strings[i] == "" then i += 1 end
if strings[i][0, 1] == " " then strings[i] = strings[i][1, strings[i].size] end
unless calc then draw_text(x, y + height * i, width, height, strings[i]) end
end
return [strings, y + height * i, height]
end
#----------------------------------------------------------------------------
end
#==============================================================================
class Font
#----------------------------------------------------------------------------
# Метод изменяет все параметры шрифта изображения, если они не указаны,
# возвращает их к значению по умолчанию
# size : integer - размер шрифта
# bold : boolean - флаг утолщенности
# italic : boolean - флаг курсива
# color : color - цвет шрифта
# name : string / [string] - имя шрифта или массив имен
#----------------------------------------------------------------------------
def change (size = 24 , bold = false, italic = false,
color = Color.new(255,255,255,255),
name = ["Arial", "Courier New", "Times New Roman"])
self.size = size
self.bold = bold
self.italic = italic
self.color = color
self.name = name
end
#----------------------------------------------------------------------------
end
#==============================================================================
Социальные закладки