openrgss 0.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/openrgss.rb +19 -0
- data/lib/openrgss/audio.rb +109 -0
- data/lib/openrgss/bitmap.rb +255 -0
- data/lib/openrgss/color.rb +106 -0
- data/lib/openrgss/font.rb +106 -0
- data/lib/openrgss/graphics.rb +150 -0
- data/lib/openrgss/input.rb +141 -0
- data/lib/openrgss/plane.rb +102 -0
- data/lib/openrgss/rect.rb +78 -0
- data/lib/openrgss/rgss.rb +302 -0
- data/lib/openrgss/rgsserror.rb +7 -0
- data/lib/openrgss/rgssreset.rb +7 -0
- data/lib/openrgss/sprite.rb +135 -0
- data/lib/openrgss/table.rb +51 -0
- data/lib/openrgss/tilemap.rb +686 -0
- data/lib/openrgss/tone.rb +95 -0
- data/lib/openrgss/viewport.rb +82 -0
- data/lib/openrgss/window.rb +303 -0
- data/lib/rgss.rb +1 -0
- metadata +21 -2
@@ -0,0 +1,106 @@
|
|
1
|
+
# The font class. Font is a property of the Bitmap class.
|
2
|
+
#
|
3
|
+
# If there is a "Fonts" folder directly under the game folder, the font files in it can be used even if they are not installed on the system.
|
4
|
+
#
|
5
|
+
# You can change the default values set for each component when a new Font object is created.
|
6
|
+
#
|
7
|
+
# Font.default_name = ["Myriad", "Verdana"]
|
8
|
+
# Font.default_size = 22
|
9
|
+
# Font.default_bold = true
|
10
|
+
|
11
|
+
class Font
|
12
|
+
@@cache = {}
|
13
|
+
# Creates a Font object.
|
14
|
+
|
15
|
+
def initialize(arg_name=@@default_name, arg_size=@@default_size)
|
16
|
+
@name = arg_name
|
17
|
+
@size = arg_size
|
18
|
+
@bold = @@default_bold
|
19
|
+
@italic= @@default_italic
|
20
|
+
@color = @@default_color
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns true if the specified font exists on the system.
|
24
|
+
|
25
|
+
def Font.exist?(arg_font_name)
|
26
|
+
font_key = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts'
|
27
|
+
reg_open_keyex = Win32API.new('Advapi32', 'RegOpenKeyEx', 'lpllp', 'l')
|
28
|
+
reg_enum_value = Win32API.new('Advapi32', 'RegEnumValue', 'llppiiii', 'l')
|
29
|
+
reg_close_key = Win32API.new('Advapi32', 'RegCloseKey', 'l', 'l')
|
30
|
+
open_key = [0].pack('V')
|
31
|
+
# get key
|
32
|
+
reg_open_keyex.call(0x80000002, font_key, 0, 0x20019, open_key)
|
33
|
+
open_key = (open_key + [0].pack('V')).unpack('V').first
|
34
|
+
# enumerate
|
35
|
+
buffer = "\0"*256
|
36
|
+
buff_size = [255].pack('l')
|
37
|
+
key_i = 0
|
38
|
+
font_names= []
|
39
|
+
while (reg_enum_value.call(open_key, key_i, buffer, buff_size, 0, 0, 0, 0).zero?)
|
40
|
+
# get name
|
41
|
+
font_names << buffer[0, buff_size.unpack('l').first].sub(/\s\(.*\)/, '')
|
42
|
+
# reset
|
43
|
+
buff_size = [255].pack('l')
|
44
|
+
# increment
|
45
|
+
key_i += 1
|
46
|
+
end
|
47
|
+
reg_close_key.call(open_key)
|
48
|
+
# test
|
49
|
+
return font_names.include?(arg_font_name)
|
50
|
+
end
|
51
|
+
|
52
|
+
# SDL::TTF对象
|
53
|
+
|
54
|
+
def entity
|
55
|
+
result = @@cache[[@name, @size]] ||= SDL::TTF.open('wqy-microhei.ttc', @size)
|
56
|
+
result.style = (@bold ? SDL::TTF::STYLE_BOLD : 0) | (@italic ? SDL::TTF::STYLE_ITALIC : 0)
|
57
|
+
result
|
58
|
+
end
|
59
|
+
|
60
|
+
# The font name. Include an array of strings to specify multiple fonts to be used in a desired order.
|
61
|
+
#
|
62
|
+
# font.name = ["Myriad", "Verdana"]
|
63
|
+
# In this example, if the higher priority font Myriad does not exist on the system, the second choice Verdana will be used instead.
|
64
|
+
#
|
65
|
+
# The default is ["Verdana", "Arial", "Courier New"].
|
66
|
+
attr_accessor :name
|
67
|
+
|
68
|
+
# The font size. The default is 24.
|
69
|
+
attr_accessor :size
|
70
|
+
|
71
|
+
# The bold flag. The default is FALSE.
|
72
|
+
attr_accessor :bold
|
73
|
+
|
74
|
+
# The italic flag. The default is FALSE.
|
75
|
+
attr_accessor :italic
|
76
|
+
|
77
|
+
# The flag for outline text. The default is TRUE.
|
78
|
+
attr_accessor :outline
|
79
|
+
|
80
|
+
# The flag for shadow text. The default is false (RGSS3). When enabled, a black shadow will be drawn to the bottom right of the character.
|
81
|
+
attr_accessor :shadow
|
82
|
+
|
83
|
+
# The font color (Color). Alpha values may also be used. The default is (255,255,255,255).
|
84
|
+
#
|
85
|
+
# Alpha values are also used when drawing outline (RGSS3) and shadow text.
|
86
|
+
attr_accessor :color
|
87
|
+
|
88
|
+
# The outline color (Color). The default is (0,0,0,128).
|
89
|
+
attr_accessor :out_color
|
90
|
+
|
91
|
+
class <<self
|
92
|
+
[:name, :size, :bold, :italic, :color, :outline, :shadow, :out_color].each { |attribute|
|
93
|
+
name = 'default_' + attribute.to_s
|
94
|
+
define_method(name) { class_variable_get('@@'+name) }
|
95
|
+
define_method(name+'=') { |value| class_variable_set('@@'+name, value) }
|
96
|
+
}
|
97
|
+
end
|
98
|
+
#------------------------------------------------------------------------
|
99
|
+
# * Standard Einstellungen aus der RGSS102E.dll.
|
100
|
+
#------------------------------------------------------------------------
|
101
|
+
@@default_name = "Arial"
|
102
|
+
@@default_size = 22
|
103
|
+
@@default_bold = false
|
104
|
+
@@default_italic= false
|
105
|
+
@@default_color = Color.new(255, 255, 255, 255)
|
106
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
module Graphics
|
2
|
+
FPS_COUNT = 30
|
3
|
+
@frame_rate = 60
|
4
|
+
@frame_count = 0
|
5
|
+
@frame_count_recent = 0
|
6
|
+
@skip = 0
|
7
|
+
@ticks = 0
|
8
|
+
@fps_ticks = 0
|
9
|
+
@brightness = 255
|
10
|
+
@width = 640
|
11
|
+
@height = 480
|
12
|
+
@graphics_render_target = Bitmap.new(544, 416) # need rebuild when resize.
|
13
|
+
@freeze = false # or true?
|
14
|
+
class <<self
|
15
|
+
attr_reader :width, :height
|
16
|
+
attr_accessor :entity
|
17
|
+
attr_accessor :frame_rate, :frame_count, :brightness
|
18
|
+
|
19
|
+
attr_reader :real_fps
|
20
|
+
|
21
|
+
def resize_screen(width, height)
|
22
|
+
@width = width
|
23
|
+
@height = height
|
24
|
+
end
|
25
|
+
|
26
|
+
def update
|
27
|
+
RGSS.update
|
28
|
+
@frame_count += 1
|
29
|
+
if @skip >= 10 or SDL.get_ticks < @ticks + 1000 / frame_rate
|
30
|
+
@entity.fill_rect(0, 0, @width, @height, 0x000000)
|
31
|
+
if (@old_resources!=RGSS.resources) # Maybe here can make a dirty mark
|
32
|
+
RGSS.resources.sort!
|
33
|
+
@old_resources=RGSS.resources.clone
|
34
|
+
end
|
35
|
+
|
36
|
+
unless @freezed # redraw only when !freezed
|
37
|
+
@graphics_render_target.entity.fill_rect(0, 0, @width, @height, @graphics_render_target.entity.map_rgba(0, 0, 0, 255))
|
38
|
+
@graphics_render_target.entity.set_alpha(SDL::RLEACCEL, 0)
|
39
|
+
RGSS.resources.each { |resource| resource.draw(@graphics_render_target) }
|
40
|
+
end
|
41
|
+
@entity.put @graphics_render_target.entity, 0, 0
|
42
|
+
@entity.drawRect(0, 0, @width, @height, @entity.map_rgb(0, 0, 0), true, 255-@brightness) # draw gray layout
|
43
|
+
@entity.update_rect(0, 0, 0, 0)
|
44
|
+
sleeptime = @ticks + 1000.0 / frame_rate - SDL.get_ticks
|
45
|
+
sleep sleeptime.to_f / 1000 if sleeptime > 0
|
46
|
+
|
47
|
+
@skip = 0
|
48
|
+
@ticks = SDL.get_ticks
|
49
|
+
else
|
50
|
+
@skip += 1
|
51
|
+
end
|
52
|
+
|
53
|
+
@frame_count_recent += 1
|
54
|
+
if @frame_count_recent >= FPS_COUNT
|
55
|
+
@frame_count_recent = 0
|
56
|
+
now = SDL.get_ticks
|
57
|
+
@real_fps = FPS_COUNT * 1000 / (now - @fps_ticks)
|
58
|
+
@fps_ticks = now
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def wait(duration)
|
63
|
+
duration.times { update }
|
64
|
+
end
|
65
|
+
|
66
|
+
def fadeout(duration)
|
67
|
+
step=255/duration
|
68
|
+
duration.times { |i| @brightness=255-i*step; update }
|
69
|
+
@brightness=0
|
70
|
+
end
|
71
|
+
|
72
|
+
def fadein(duration)
|
73
|
+
step=255/duration
|
74
|
+
duration.times { |i| @brightness=i*step; update }
|
75
|
+
@brightness=255
|
76
|
+
end
|
77
|
+
|
78
|
+
def freeze
|
79
|
+
@freezed=true
|
80
|
+
end
|
81
|
+
|
82
|
+
def transition(duration=10, filename=nil, vague=40)
|
83
|
+
if (duration==0)
|
84
|
+
@freezed=false; return;
|
85
|
+
end
|
86
|
+
if (filename.nil?) #
|
87
|
+
imgmap=Array.new(@width) { Array.new(@height) { 255 } }
|
88
|
+
else #
|
89
|
+
b =Bitmap.new(filename); pfb = b.entity.format
|
90
|
+
imgmap=Array.new(@width) { |x| Array.new(@height) { |y| [pfb.get_rgb(b.entity[x, y])[0], 1].max } }
|
91
|
+
#TODO : free
|
92
|
+
end
|
93
|
+
step =255/duration
|
94
|
+
new_frame = Bitmap.new(@width, @height)
|
95
|
+
RGSS.resources.sort!
|
96
|
+
@old_resources=RGSS.resources.clone
|
97
|
+
new_frame.entity.fill_rect(0, 0, @width, @height, new_frame.entity.map_rgba(0, 0, 0, 255))
|
98
|
+
new_frame.entity.set_alpha(SDL::SRCALPHA, 255)
|
99
|
+
RGSS.resources.each { |resource| resource.draw(new_frame) }
|
100
|
+
# draw frame to bitmap
|
101
|
+
|
102
|
+
pf = new_frame.entity.format
|
103
|
+
new_frame.entity.lock
|
104
|
+
picmap=Array.new(@width) { |x| Array.new(@height) { |y| pf.getRGBA(new_frame.entity[x, y]) } } # better to use bit calculate
|
105
|
+
new_frame.entity.unlock
|
106
|
+
maker = Bitmap.new(@width, @height)
|
107
|
+
# create pre-render layoyt
|
108
|
+
maker.entity.fill_rect(0, 0, @width, @height, new_frame.entity.map_rgba(0, 0, 0, 255))
|
109
|
+
maker.entity.put @graphics_render_target.entity, 0, 0
|
110
|
+
# transition layout
|
111
|
+
new_frame.entity.lock
|
112
|
+
@width.times { |x| @height.times { |y|
|
113
|
+
if (imgmap[x][y]!=0)
|
114
|
+
new_frame.entity[x, y]=pf.map_rgba(picmap[x][y][0], picmap[x][y][1], picmap[x][y][2], [255/(duration/(255.0/imgmap[x][y])), 255].min)
|
115
|
+
#TODO : alpha will be 255 after many render.it's different fron RPG Maker
|
116
|
+
else
|
117
|
+
new_frame.entity[x, y]=pf.map_rgba(picmap[x][y][0], picmap[x][y][1], picmap[x][y][2], 255)
|
118
|
+
end
|
119
|
+
} }
|
120
|
+
new_frame.entity.unlock
|
121
|
+
duration.times { |i|
|
122
|
+
@entity.fill_rect(0, 0, @width, @height, 0x000000)
|
123
|
+
maker.entity.put new_frame.entity, 0, 0 # alpha
|
124
|
+
@entity.put maker.entity, 0, 0
|
125
|
+
@entity.update_rect(0, 0, 0, 0)
|
126
|
+
}
|
127
|
+
# TODO: free
|
128
|
+
@graphics_render_target.entity.set_alpha(0, 255); @freezed=false; @brightness=255; update
|
129
|
+
end
|
130
|
+
|
131
|
+
def snap_to_bitmap
|
132
|
+
return @graphics_render_target.clone # free
|
133
|
+
end
|
134
|
+
|
135
|
+
def frame_reset
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
def play_movie(filename)
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
def brightness=(brightness)
|
144
|
+
@brightness = brightness < 0 ? 0 : brightness > 255 ? 255 : brightness
|
145
|
+
#gamma = @brightness.to_f / 255
|
146
|
+
#SDL::Screen.set_gamma(5,1,1)
|
147
|
+
#seems SDL::Screen.set_gamma and SDL::Screen.set_gamma_rmap doesn't work
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# A module that handles input data from a gamepad or keyboard.
|
2
|
+
#
|
3
|
+
# Managed by symbols rather than button numbers in RGSS3. (RGSS3)
|
4
|
+
module Input
|
5
|
+
Keys = {
|
6
|
+
DOWN: [SDL::Key::DOWN, SDL::Key::S],
|
7
|
+
LEFT: [SDL::Key::LEFT, SDL::Key::A],
|
8
|
+
RIGHT: [SDL::Key::RIGHT, SDL::Key::D],
|
9
|
+
UP: [SDL::Key::UP, SDL::Key::W],
|
10
|
+
A: [SDL::Key::LSHIFT],
|
11
|
+
B: [SDL::Key::X, SDL::Key::ESCAPE],
|
12
|
+
C: [SDL::Key::Z, SDL::Key::RETURN],
|
13
|
+
L: [SDL::Key::PAGEUP],
|
14
|
+
R: [SDL::Key::PAGEDOWN],
|
15
|
+
SHIFT: [SDL::Key::LSHIFT, SDL::Key::RSHIFT],
|
16
|
+
CTRL: [SDL::Key::LSHIFT, SDL::Key::RSHIFT],
|
17
|
+
ALT: [SDL::Key::LSHIFT, SDL::Key::RSHIFT],
|
18
|
+
F5: [SDL::Key::F5],
|
19
|
+
F6: [SDL::Key::F6],
|
20
|
+
F7: [SDL::Key::F7],
|
21
|
+
F8: [SDL::Key::F8],
|
22
|
+
F9: [SDL::Key::F9],
|
23
|
+
SHOW_FPS: [SDL::Key::F2],
|
24
|
+
RESET: [SDL::Key::F12]
|
25
|
+
}
|
26
|
+
|
27
|
+
Entities = {}
|
28
|
+
|
29
|
+
Keys.each { |key, value|
|
30
|
+
const_set(key, key)
|
31
|
+
value.each { |entity| Entities[entity] = key }
|
32
|
+
|
33
|
+
}
|
34
|
+
@status = {}
|
35
|
+
@events = []
|
36
|
+
class <<self
|
37
|
+
attr_accessor :events
|
38
|
+
|
39
|
+
# Updates input data. As a general rule, this method is called once per frame.
|
40
|
+
|
41
|
+
def update
|
42
|
+
RGSS.update
|
43
|
+
@status.each { |key, value| @status[key] = value.next }
|
44
|
+
while event = events.shift
|
45
|
+
key = Entities[event.sym]
|
46
|
+
Log.debug('key') { event }
|
47
|
+
if event.press
|
48
|
+
case key
|
49
|
+
when :SHOW_FPS
|
50
|
+
RGSS.show_fps = !RGSS.show_fps
|
51
|
+
when :RESET
|
52
|
+
raise RGSSReset
|
53
|
+
else
|
54
|
+
@status[key] = 0
|
55
|
+
end
|
56
|
+
else
|
57
|
+
@status.delete key
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Determines whether the button corresponding to the symbol sym is currently being pressed.
|
63
|
+
#
|
64
|
+
# If the button is being pressed, returns TRUE. If not, returns FALSE.
|
65
|
+
#
|
66
|
+
# if Input.press?(:C)
|
67
|
+
# do_something
|
68
|
+
# end
|
69
|
+
|
70
|
+
def press?(sym)
|
71
|
+
@status[sym]
|
72
|
+
end
|
73
|
+
|
74
|
+
# Determines whether the button corresponding to the symbol sym is currently being pressed again.
|
75
|
+
#
|
76
|
+
# "Pressed again" is seen as time having passed between the button being not pressed and being pressed.
|
77
|
+
#
|
78
|
+
# If the button is being pressed, returns TRUE. If not, returns FALSE.
|
79
|
+
|
80
|
+
def trigger?(sym)
|
81
|
+
@status[sym] and @status[sym].zero?
|
82
|
+
end
|
83
|
+
|
84
|
+
# Determines whether the button corresponding to the symbol sym is currently being pressed again.
|
85
|
+
#
|
86
|
+
# Unlike trigger?, takes into account the repeated input of a button being held down continuously.
|
87
|
+
#
|
88
|
+
# If the button is being pressed, returns TRUE. If not, returns FALSE.
|
89
|
+
|
90
|
+
def repeat?(sym)
|
91
|
+
@status[sym] and (@status[sym].zero? or (@status[sym] > 10 and (@status[sym] % 4).zero?))
|
92
|
+
end
|
93
|
+
|
94
|
+
# Checks the status of the directional buttons, translates the data into a specialized 4-direction input format, and returns the number pad equivalent (2, 4, 6, 8).
|
95
|
+
#
|
96
|
+
# If no directional buttons are being pressed (or the equivalent), returns 0.
|
97
|
+
|
98
|
+
def dir4
|
99
|
+
case
|
100
|
+
when @status[:DOWN]
|
101
|
+
2
|
102
|
+
when @status[:LEFT]
|
103
|
+
4
|
104
|
+
when @status[:RIGHT]
|
105
|
+
6
|
106
|
+
when @status[:UP]
|
107
|
+
8
|
108
|
+
else
|
109
|
+
0
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Checks the status of the directional buttons, translates the data into a specialized 8-direction input format, and returns the number pad equivalent (1, 2, 3, 4, 6, 7, 8, 9).
|
114
|
+
#
|
115
|
+
# If no directional buttons are being pressed (or the equivalent), returns 0.
|
116
|
+
|
117
|
+
def dir8
|
118
|
+
case
|
119
|
+
when @status[:DOWN] && @status[:LEFT]
|
120
|
+
1
|
121
|
+
when @status[:DOWN] && @status[:RIGHT]
|
122
|
+
3
|
123
|
+
when @status[:DOWN]
|
124
|
+
2
|
125
|
+
when @status[:UP] && @status[:LEFT]
|
126
|
+
7
|
127
|
+
when @status[:UP] && @status[:RIGHT]
|
128
|
+
9
|
129
|
+
when @status[:UP]
|
130
|
+
8
|
131
|
+
when @status[:LEFT]
|
132
|
+
4
|
133
|
+
when @status[:RIGHT]
|
134
|
+
6
|
135
|
+
else
|
136
|
+
0
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# The Plane class. Planes are special sprites that tile bitmap patterns across the entire screen and are used to display parallax backgrounds and so on.
|
2
|
+
class Plane
|
3
|
+
|
4
|
+
# Refers to the bitmap (Bitmap) used in the plane.
|
5
|
+
#attr_accessor :bitmap
|
6
|
+
|
7
|
+
# Refers to the viewport (Viewport) associated with the plane.
|
8
|
+
#attr_accessor :viewport
|
9
|
+
|
10
|
+
# The plane's visibility. If TRUE, the plane is visible. The default value is TRUE.
|
11
|
+
#attr_accessor :visible
|
12
|
+
|
13
|
+
# The plane's z-coordinate. The larger the value, the closer to the player the plane will be displayed.
|
14
|
+
#
|
15
|
+
# If multiple objects share the same z-coordinate, the more recently created object will be displayed closest to the player.
|
16
|
+
#attr_accessor :z
|
17
|
+
|
18
|
+
# The x-coordinate of the plane's starting point. Change this value to scroll the plane.
|
19
|
+
attr_accessor :ox
|
20
|
+
|
21
|
+
# The y-coordinate of the plane's starting point. Change this value to scroll the plane.
|
22
|
+
attr_accessor :oy
|
23
|
+
|
24
|
+
# The plane's x-axis zoom level. 1.0 denotes actual pixel size.
|
25
|
+
#attr_accessor :zoom_x
|
26
|
+
|
27
|
+
# The plane's y-axis zoom level. 1.0 denotes actual pixel size.
|
28
|
+
#attr_accessor :zoom_y
|
29
|
+
|
30
|
+
# The plane's opacity (0-255). Out-of-range values are automatically corrected.
|
31
|
+
#attr_accessor :opacity
|
32
|
+
|
33
|
+
# The plane's blending mode (0: normal, 1: addition, 2: subtraction).
|
34
|
+
#attr_accessor :blend_type
|
35
|
+
|
36
|
+
# The color (Color) to be blended with the plane. Alpha values are used in the blending ratio.
|
37
|
+
#attr_accessor :color
|
38
|
+
|
39
|
+
# The plane's color tone (Tone).
|
40
|
+
#attr_accessor :tone
|
41
|
+
|
42
|
+
# Creates a Plane object. Specifies a viewport (Viewport) when necessary.
|
43
|
+
def initialize(arg_viewport=nil)
|
44
|
+
@sprite = Sprite.new(arg_viewport)
|
45
|
+
@src_bitmap = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
# Frees the plane. If the plane has already been freed, does nothing.
|
49
|
+
|
50
|
+
def dispose
|
51
|
+
@sprite.bitmap.dispose unless @sprite.bitmap.nil? or @sprite.bitmap.disposed?
|
52
|
+
@sprite.dispose unless @sprite.nil? or @sprite.disposed?
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns TRUE if the plane has been freed.
|
56
|
+
|
57
|
+
def disposed?
|
58
|
+
@sprite.nil? or @sprite.disposed?
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def ox=(val)
|
63
|
+
@sprite.ox= (val % (@src_bitmap.nil? ? 1 : @src_bitmap.width))
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def oy=(val)
|
68
|
+
@sprite.oy= (val % (@src_bitmap.nil? ? 1 : @src_bitmap.height))
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def bitmap
|
73
|
+
@src_bitmap
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def bitmap=(arg_bmp)
|
78
|
+
vp_width = @sprite.viewport.nil? ? \
|
79
|
+
Graphics.width : @sprite.viewport.rect.width
|
80
|
+
vp_height = @sprite.viewport.nil? ? \
|
81
|
+
Graphics.height : @sprite.viewport.rect.height
|
82
|
+
x_steps = [(vp_width / arg_bmp.width).ceil, 1].max * 2
|
83
|
+
y_steps = [(vp_height / arg_bmp.height).ceil, 1].max * 2
|
84
|
+
|
85
|
+
bmp_width = x_steps * arg_bmp.width
|
86
|
+
bmp_height = y_steps * arg_bmp.height
|
87
|
+
|
88
|
+
@src_bitmap = arg_bmp
|
89
|
+
@sprite.bitmap.dispose unless @sprite.bitmap.nil? or @sprite.bitmap.disposed?
|
90
|
+
@sprite.bitmap = Bitmap.new(bmp_width, bmp_height)
|
91
|
+
|
92
|
+
x_steps.times { |ix| y_steps.times { |iy|
|
93
|
+
@sprite.bitmap.blt(ix * arg_bmp.width, iy * arg_bmp.height,
|
94
|
+
@src_bitmap, @src_bitmap.rect)
|
95
|
+
} }
|
96
|
+
end
|
97
|
+
|
98
|
+
def method_missing(symbol, *args)
|
99
|
+
@sprite.method(symbol).call(*args)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|