#game.draw_collision_mode true
#game.draw_fps_mode true
game.loading do |loader|
loader.add :window, :system => "window"
loader.add :gui_item, :system => "gui_item"
loader.add :mapchip, 200
loader.add :pen_tool, 196
loader.add :fill_tool, 197
loader.add :rect_tool, 199
loader.add :scroll_tool, 198
end
Map_Data = nil
Layer_Number = 3
game.on_init do
set_window_image :window
set_gui_image :gui_item
scene_change :start_scene
end
scene :start_scene do |scene|
scene.on_init do
speak("マップエディタのテストです。マップをお絵かき感覚で書くことができます")
Map_Data = MapView.new
Map_Data.chip_x = 2
Map_Data.chip_y = 1
map_sprite = scene.add :image, :name => :map_sprite, :template => :mapview, :position => [256, 0]
mapchip_view = scene.add :image, :name => :mapchip_sprite, :template => :mapchipview, :position => [0, 32]
selected_tool = scene.sprite :position => [0, 0], :layer_order => 1, :color => [255, 255, 0, 180]
selected_tool.set_dest_size 32, 32
rect_tool_rect = scene.sprite :position => [0, 0]
rect_tool_rect.set_color 255, 255, 255, 180
rect_tool_rect.set_dest_size 0, 0
tools = [[:pen_tool, 0], [:fill_tool, 32], [:rect_tool, 64], [:scroll_tool, 96]]
tools.each do |item|
sprite = scene.add :image, :texture => item[0], :position => [item[1], 0], :layer_order => 0
sprite.event :on_touch_up do |event|
Map_Data.selected_tool = item[0]
selected_tool.set_position item[1], 0
rect_tool_rect.set_position 0, 0
rect_tool_rect.set_dest_size 0, 0
end
end
selected_chip = scene.sprite :position => [Map_Data.chip_x * 32, Map_Data.chip_y * 32 + 32]
selected_chip.set_color 255, 255, 255, 180
selected_chip.set_dest_size 32, 32
layer_buttons = []
Layer_Number.times do |i|
layer_button = scene.text :position => [0, 288 + i * 32]
layer_button.set_text_area_size 128, 32
layer_button.set_font_point_size 28
layer_button.set_text("レイヤー#{i}")
layer_buttons << layer_button
if i == 0
layer_button.set_color 255, 0, 0, 255
end
layer_button.event :on_touch_up do |event|
Map_Data.layer_index = i
layer_buttons.each do |b|
b.set_color 255, 255, 255, 255
end
event.target.set_color 255, 0, 0, 255
end
end
erase_button = scene.text :position => [128, 288]
erase_button.set_text_area_size 128, 32
erase_button.set_font_point_size 28
erase_button.set_text("消しゴム")
erase_button.set_color 255, 255, 255, 255
erase_button.event :on_touch_up do |event|
Map_Data.chip_x = -1
Map_Data.chip_y = -1
erase_button.set_color 255, 0, 0, 255
selected_chip.set_visible false
end
mapchip_view.event :on_touch_up do |event|
x = (event.screen_x / 32).to_i
y = ((event.screen_y - 32) / 32).to_i
Map_Data.chip_x = x
Map_Data.chip_y = y
erase_button.set_color 255, 255, 255, 255
selected_chip.set_visible true
selected_chip.set_position Map_Data.chip_x * 32, Map_Data.chip_y * 32 + 32
end
return_button = scene.text :position => [32, 416]
return_button.set_text_area_size 200, 32
return_button.set_font_point_size 28
return_button.set_text("メニューに戻る")
return_button.event :on_click do |event|
speak("メニューに戻ります")
game.change_project "start_menu"
end
# ******************************************************************************** #
# Map View
# ******************************************************************************** #
drag_start = nil
scroll_start_x = 0
scroll_start_y = 0
map_sprite.event :on_touch_down do |event|
drag_start = true
if Map_Data.selected_tool == :pen_tool
do_pen_tool(event.target, event.screen_x, event.screen_y)
elsif Map_Data.selected_tool == :fill_tool
do_paint_tool(event.target, event.screen_x, event.screen_y)
elsif Map_Data.selected_tool == :scroll_tool
scroll_start_x = event.screen_x
scroll_start_y = event.screen_y
elsif Map_Data.selected_tool == :rect_tool
scroll_start_x = event.screen_x
scroll_start_y = event.screen_y
end
end
map_sprite.event :on_touch_move do |event|
if drag_start && Map_Data.selected_tool == :pen_tool
do_pen_tool(event.target, event.screen_x, event.screen_y)
elsif drag_start && Map_Data.selected_tool == :scroll_tool
dx = ((event.screen_x - scroll_start_x) / 16).to_i
dy = ((event.screen_y - scroll_start_y) / 16).to_i
do_scroll_tool(event.target, dx, dy)
scroll_start_x = event.screen_x if dx != 0
scroll_start_y = event.screen_y if dy != 0
elsif drag_start && Map_Data.selected_tool == :rect_tool
x, y, w, h = rect_tool_rect(scroll_start_x, scroll_start_y, event.screen_x, event.screen_y)
rect_tool_rect.set_position x * 32 + 256, y * 32
rect_tool_rect.set_dest_size w * 32, h * 32
end
end
map_sprite.event :on_touch_up do |event|
if Map_Data.selected_tool == :rect_tool && drag_start
do_rect_tool(event.target, scroll_start_x, scroll_start_y, event.screen_x, event.screen_y)
rect_tool_rect.set_position 0, 0
rect_tool_rect.set_dest_size 0, 0
end
drag_start = false
end
end
end
def do_pen_tool(sprite, screen_x, screen_y)
if Map_Data.selected_tool == :pen_tool
Map_Data.change_chip(((screen_x - 256) / 32).to_i, (screen_y / 32).to_i)
Map_Data.render_tiles(sprite)
end
end
def do_scroll_tool(sprite, dx, dy)
if Map_Data.selected_tool == :scroll_tool
Map_Data.scroll_x = Map_Data.scroll_x - dx
Map_Data.scroll_y = Map_Data.scroll_y - dy
Map_Data.render_tiles(sprite)
end
end
def do_paint_tool(sprite, screen_x, screen_y)
if Map_Data.selected_tool == :fill_tool
Map_Data.paint_chip(((screen_x - 256) / 32).to_i, (screen_y / 32).to_i)
Map_Data.render_tiles(sprite)
end
end
def do_rect_tool(sprite, start_x, start_y, end_x, end_y)
if Map_Data.selected_tool == :rect_tool
x, y, w, h = rect_tool_rect(start_x, start_y, end_x, end_y)
w.times do |i|
h.times do |j|
Map_Data.change_chip(x + i, y + j);
end
end
Map_Data.render_tiles(sprite)
end
end
def rect_tool_rect(start_x, start_y, end_x, end_y)
max_x, min_x = start_x > end_x ? [start_x, end_x] : [end_x, start_x]
max_y, min_y = start_y > end_y ? [start_y, end_y] : [end_y, start_y]
x = ((min_x - 256) / 32).to_i
y = (min_y / 32).to_i
w = ((max_x - 256) / 32).ceil - x
h = (max_y / 32).ceil - y
[x, y, w, h]
end
sprite_template :mapview do |st|
st.texture :mapchip
st.dest_size 800, 448
st.center_offset 400, 224
st.collision :rect, :mode => :left_top, :position => [0, 0],
:width => [800, 448], :group_id => 1
st.animation :default do |commands|
commands.proc_call do |sprite|
Map_Data.render_tiles(sprite)
end
end
end
sprite_template :mapchipview do |st|
st.texture :mapchip
st.src_size 256, 256
st.dest_size 256, 256
st.copy_rect 0, 0
st.collision :rect, :mode => :left_top, :position => [0, 0],
:width => [256, 256], :group_id => 1
end
# ********************************************************************************
# Class
# ********************************************************************************
class MapChipView
end
class MapView
attr_accessor :width, :height, :display_width, :display_height
attr_accessor :tiles, :collision_data, :scroll_x, :scroll_y
attr_accessor :chip_x, :chip_y, :selected_tool
attr_accessor :layer_index, :layers
def initialize(width = 100, height = 100, display_width = 17, display_height = 14)
@width = width
@height = height
@display_width = display_width
@display_height = display_height
@scroll_x = 0
@scroll_y = 0
@layers = []
Layer_Number.times do |i|
if i == 0
cx = 0
cy = 0
else
cx = -1
cy = -1
end
@layers << self.init_src_rects(cx, cy)
end
@chip_x = 0
@chip_y = 0
@layer_index = 0
@selected_tool = :pen_tool
end
def init_src_rects(cx = 0, cy = 0)
src_rects = []
@height.times do |j|
@width.times do |i|
src_rects << [cx, cy]
end
end
src_rects
end
def change_chip(x, y)
sx = @scroll_x + x
sy = @scroll_y + y
if sx > -1 && sy > -1 && sx < @width && sy < @height
tiles_index = (sx + sy * @width)
get_tiles()[tiles_index] = [@chip_x, @chip_y]
end
end
def get_tiles(layer_index = nil)
if layer_index && layer_index > -1 && layer_index < Layer_Number
@layers[layer_index]
else
@layers[self.layer_index]
end
end
def get_chip(sx, sy, layer_index = nil)
if sx > -1 && sy > -1 && sx < @width && sy < @height
get_tiles(layer_index)[sx + sy * @width]
else
nil
end
end
def equal_chip?(c1, c2)
c1 && c2 && c1[0] == c2[0] && c1[1] == c2[1]
end
def can_paint_next?(process_targets, start_chip, sx, sy)
current_chip = self.get_chip(sx, sy)
tiles_index = (sx + sy * @width)
if equal_chip?(current_chip, start_chip)
process_targets << [sx, sy]
end
end
def paint_chip(x, y)
current_sx = @scroll_x + x
current_sy = @scroll_y + y
current_chip = self.get_chip(current_sx, current_sy)
start_chip = [current_chip[0], current_chip[1]]
process_targets = []
process_targets << [current_sx, current_sy]
while process_targets.length > 0 do
current_sx, current_sy = process_targets.pop
current_chip = self.get_chip(current_sx, current_sy)
if equal_chip?(current_chip, start_chip)
get_tiles()[current_sx + current_sy * @width] = [@chip_x, @chip_y]
end
can_paint_next?(process_targets, start_chip, current_sx + 1, current_sy)
can_paint_next?(process_targets, start_chip, current_sx - 1, current_sy)
can_paint_next?(process_targets, start_chip, current_sx, current_sy + 1)
can_paint_next?(process_targets, start_chip, current_sx, current_sy - 1)
end
end
def render_tiles(sprite)
colors = []
dest_rects = []
src_rects = []
Layer_Number.times do |layer_index|
@display_height.times do |j|
@display_width.times do |i|
sx = @scroll_x + i
sy = @scroll_y + j
chip = self.get_chip(sx, sy, layer_index)
if chip[0] > -1 && chip[1] > -1
dest_rects << -400 + 0 + i * 32 # x
dest_rects << -224 + 0 + j * 32 # y
dest_rects << 32 # w
dest_rects << 32 # h
colors << 255 # R
colors << 255 # G
colors << 255 # B
colors << 255 # A
src_rects << 32 * chip[0] # + 0.5
src_rects << 32 * chip[1] # + 0.5
src_rects << 32 # 31
src_rects << 32 # 31
if self.coast_chip?(sx, sy, layer_index)
coast_line_chips = self.check_coast_chip(sx, sy, layer_index)
clpo = self.coast_line_position_offset(sx, sy, layer_index)
index = 0
d_positions = [[0, 0], [16, 0], [16, 16], [0, 16]]
coast_line_chips.each do |chip_id|
if chip_id != -1
position = self.position_by_coast_chip_id(chip_id)
dp = d_positions[index]
dest_rects << -400 + 0 + i * 32 + dp[0] # x
dest_rects << -224 + 0 + j * 32 + dp[1] # y
dest_rects << 16 # w
dest_rects << 16 # h
colors << 255 # R
colors << 255 # G
colors << 255 # B
colors << 255 # A
src_rects << clpo[0] + position[0]
src_rects << clpo[1] + position[1]
src_rects << 16
src_rects << 16
end
index += 1
end
end
end
end
end
end
sprite.set_rects dest_rects, colors, src_rects
end
def coast_chip?(sx, sy, layer_index)
chip = self.get_chip(sx, sy, layer_index)
chip == nil || chip[0] > 3 && chip[1] == 0
end
def coast_line_position_offset(sx, sy, layer_index)
chip = self.get_chip(sx, sy, layer_index)
if chip[0] == 4
[0, 384]
elsif chip[0] == 5
[128, 384]
elsif chip[0] == 6
[0, 448]
elsif chip[0] == 7
[128, 448]
end
end
def position_by_coast_chip_id(chip_id)
case chip_id
when 1..4
[(chip_id - 1) * 16, 0]
when 5..7
[48, (chip_id - 4) * 16]
when 8..10
[(10 - chip_id) * 16, 48]
when 11..12
[0, (13 - chip_id) * 16]
when 103
[80, 16]
when 104
[96, 16]
when 101
[96, 32]
when 102
[80, 32]
when 201
[64, 0]
when 202
[80, 0]
when 203
[112, 0]
when 204
[112, 16]
when 205
[112, 48]
when 206
[96, 48]
when 207
[64, 48]
when 208
[64, 32]
else
[0, 0]
end
end
def check_coast_chip(sx, sy, layer_index)
up = self.coast_chip?(sx, sy - 1, layer_index)
up_right = self.coast_chip?(sx + 1, sy - 1, layer_index)
right = self.coast_chip?(sx + 1, sy, layer_index)
right_down = self.coast_chip?(sx + 1, sy + 1, layer_index)
down = self.coast_chip?(sx, sy + 1, layer_index)
down_left = self.coast_chip?(sx - 1, sy + 1, layer_index)
left = self.coast_chip?(sx - 1, sy, layer_index)
left_up = self.coast_chip?(sx - 1, sy - 1, layer_index)
if !up && !right && !down && !left
[1, 4, 7, 10]
elsif !up && !right && !down && left
[3, 4, 7, 8]
elsif !up && !right && down && !left
[1, 4, 5, 12]
elsif !up && right && !down && !left
[1, 2, 9, 10]
elsif up && !right && !down && !left
[11, 6, 7, 10]
elsif up && !right && down && !left
[208, 203, 204, 207]
elsif !up && right && !down && left
[201, 202, 205, 206]
elsif !up && !right && down && left
if down_left
[3, 4, 5, -1]
else
[3, 4, 5, 104]
end
elsif up && !right && !down && left
if left_up
[-1, 6, 7, 8]
else
[101, 6, 7, 8]
end
elsif up && right && !down && !left
if up_right
[11, -1, 9, 10]
else
[11, 102, 9, 10]
end
elsif !up && right && down && !left
if right_down
[1, 2, -1, 12]
else
[1, 2, 103, 12]
end
elsif !up && right && down && left
if right_down && down_left
[201, 202, -1, -1]
elsif !right_down && down_left
[201, 202, 103, -1]
elsif right_down && !down_left
[201, 202, -1, 104]
else
[201, 202, 103, 104]
end
elsif up && !right && down && left
if left_up && down_left
[-1, 203, 204, -1]
elsif !left_up && down_left
[101, 203, 204, -1]
elsif left_up && !down_left
[-1, 203, 204, 104]
else
[101, 203, 204, 104]
end
elsif up && right && !down && left
if left_up && up_right
[-1, -1, 205, 206]
elsif !left_up && up_right
[101, -1, 205, 206]
elsif left_up && !up_right
[-1, 102, 205, 206]
else
[101, 102, 205, 206]
end
elsif up && right && down && !left
if right_down && up_right
[208, -1, -1, 207]
elsif !right_down && up_right
[208, -1, 103, 207]
elsif right_down && !up_right
[208, 102, -1, 207]
else
[208, 102, 103, 207]
end
elsif up && right && down && left
result = []
result << (left_up ? -1 : 101)
result << (up_right ? -1 : 102)
result << (right_down ? -1 : 103)
result << (down_left ? -1 : 104)
result
end
end
def scroll_x=(v)
if v < 0
@scroll_x = 0
elsif @width - @display_width < v
@scroll_x = @width - @display_width
else
@scroll_x = v
end
end
def scroll_y=(v)
if v < 0
@scroll_y = 0
elsif @height - @display_height < v
@scroll_y = @height - @display_height
else
@scroll_y = v
end
end
end