#==============================================================================
#******************************************************************************
#
# RGSS Extensions: Bitmap
# ----------------------------------------------------------------------------
# This script is an extension of the Bitmap class provided with RGSS. It
# allows to execute more vectorial and geometric operations, such as drawing
# lines, circles, rectangles, etc...
#
# Note that all those operations are coded in Ruby, so if you heavily depend on
# those operations (if you redraw them on every frame, etc...), it might
# slowdown your game. The best, as always, is to draw only when necessary.
#
# by exseiken
#
#******************************************************************************
#==============================================================================
class Bitmap
#----------------------------------------------------------------------------
# draw_line: Draw a line between points (x1;y1) and (x2;y2) on the bitmap.
# x1: X-coordinate of an extremity of the line.
# y1: Y-coordinate of an extremity of the line.
# x2: X-coordinate of another extremity of the line.
# y2: Y-coordinate of another extremity of the line.
# color: The color of the line. It can support transparency.
# line_width: The width of the line in pixels. Set to 1 by default.
#----------------------------------------------------------------------------
def draw_line(x1, y1, x2, y2, color, line_width = 1)
# calculate the dimensions vertically and horizontally
cx = x2 - x1
cy = y2 - y1
# if the line is larger horizontally, draw it on an horizontal basis
if cx.abs > cy.abs
# if cx is 0, don't draw
return if cx == 0
# reorder the coordinates so that x1 is left of x2
if x2 < x1
temp = x2
x2 = x1
x1 = temp
temp = y2
y2 = y1
y1 = temp
end
# draw the line
for i in 0..cx.abs
# calculate the position vertically
y = y1 + cy * i / cx
# draw the pixel
set_pixel(x1 + i, y, color)
# enlarge the line if the width is not 1
if line_width != 1
for j in 2..line_width
# on even counter, draw higher; on odd draw below
if (j & 1) == 0
set_pixel(x1 + i, y - j / 2, color)
else
set_pixel(x1 + i, y + j / 2, color)
end
end
end
end
else
# if cy is 0, don't draw
return if cy == 0
# reorder the coordinates so that y1 is above y2
if y2 < y1
temp = x2
x2 = x1
x1 = temp
temp = y2
y2 = y1
y1 = temp
end
# draw the line
for i in 0..cy.abs
# calculate the position horizontally
x = x1 + cx * i / cy
# draw the pixel
set_pixel(x, y1 + i, color)
# enlarge the line if the width is not 1
if line_width != 1
for j in 2..line_width
# on even counter, draw left; on odd draw right
if j & 1
set_pixel(x - j / 2, y1 + i, color)
else
set_pixel(x + j / 2, y1 + i, color)
end
end
end
end
end
end
#----------------------------------------------------------------------------
# draw_square: Draw an unfilled square.
# rect: Rectangle corresponding to the square to draw.
# color: Color of the border.
# line_width: Width of the border. Set to 1 by default.
#----------------------------------------------------------------------------
def draw_square(rect, color, line_width = 1)
draw_square(rect.x, rect.y, rect.cx, rect.cy, color, line_width)
end
#----------------------------------------------------------------------------
# draw_square: Draw an unfilled square.
# x: X-coordinate of the top-left corner of the square.
# y: Y-coordinate of the top-left corner of the square.
# width: Width of the square.
# height: Height of the square.
# color: Color of the border.
# line_width: Width of the border. Set to 1 by default.
#----------------------------------------------------------------------------
def draw_square(x, y, width, height, color, line_width = 1)
# draw the left side
fill_rect(x, y, line_width, height, color)
# draw the top side
fill_rect(x, y, width, line_width, color)
# draw the right side
fill_rect(x + width - line_width + 1, y, line_width, height, color)
# draw the bottom side
fill_rect(x, y + height - line_width + 1, width, line_width, color)
end
#----------------------------------------------------------------------------
# draw_ellipse: Draw an unfilled ellipse. (oval)
# ox: X-coordinate of the center of the ellipse.
# oy: Y-coordinate of the center of the ellipse.
# vradius: The vertical radius.
# ratio: Ratio between the vertical radius and the horizontal radius.
# (horizontal / vertical) Set it to 1.0 to draw a circle.
# color: Color of the border.
# line_width: Width of the border. Set to 1 by default.
# sides: The ellipse is in fact an elliptic polygon with a given amount of
# faces. For example, set it to 6 to have an hexagon. This is set
# to 32 by default, which is plenty to make it look like a curved
# form.
#----------------------------------------------------------------------------
def draw_ellipse(ox, oy, vradius, ratio, color, line_width = 1, sides = 32)
# calculate the horizontal radius
hradius = (vradius * ratio).to_i
# set the initial coordinate
x1 = ox
y1 = oy - vradius
# draw each side of the polygon except the last
for i in 1...sides
# calculate the position of the new point
x2 = ox - (hradius * Math.sin(i * Math::PI * 2 / sides)).round
y2 = oy - (vradius * Math.cos(i * Math::PI * 2 / sides)).round
# draw a the line
draw_line(x1, y1, x2, y2, color, line_width)
# store the old position
x1 = x2
y1 = y2
end
# draw the last side
draw_line(x1, y1, ox, oy - vradius, color, line_width)
end
end