I just wrote something up for you:
[rgss]
class Viewport
def set_alpha_mask(matrix)
@mask = Sprite.new(self)
@mask.bitmap = Bitmap.new(self.rect.width,self.rect.height)
@mask.opacity = 160
@mask.z = 999
for i in 0..matrix.size
if !matrix.nil?
com = matrix[0]
case com.downcase
when 'line'
x1 = matrix[1][0]
y1 = matrix[1][1]
x2 = matrix[1][2]
y2 = matrix[1][3]
cl = matrix[1][4]
wd = matrix[1][5]
@mask.bitmap.draw_line(x1, y1, x2, y2, cl, wd)
when 'rect_filled'
x = matrix[1][0]
y = matrix[1][1]
w = matrix[1][2]
h = matrix[1][3]
c = matrix[1][4]
@mask.bitmap.fill_rect(x, y, w, h, c)
when 'ellipse_unfilled'
ox = matrix[1][0]
oy = matrix[1][1]
vr = matrix[1][2]
rt = 1.0
cl = matrix[1][3]
lw = matrix[1][4]
@mask.bitmap.draw_ellipse(ox, oy, vr, rt, cl, lw)
end
end
end
end
end
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
[/rgss]
It takes a 3 dimensional array.
Usage:
[rgss]
black = Color.new(0,0,0,255)
matrix = []
matrix[0] = ['line']
matrix[0][1] = [0,0,320,240,black,5]
matrix[1] = ['rect_filled']
matrix[1][1] = [320, 240, 200, 200, black]
matrix[2] = ['ellipse_unfilled']
matrix[2][1] = [128, 128, 64, black, 5]
@viewport1 = Viewport.new(0, 0, 640, 480)
@viewport1.set_alpha_mask(matrix)
[/rgss]
You can add more shapes(right now there's only line, filled rect, and unfilled circle)by adding more drawing functions to the Bitmap class.