実験 800x450 公開中

マップエディタの実験1 - 単純なエディタ

投稿者:akasata 投稿日時: 2013/09/13 20:31:44
マップエディタのテストです。
左側のチップを選んで右側のマップエリアに書き込むことができます。

以下、制限事項です。

  • スクロールは存在しません → 2013/9/15実装しました!
  • 塗りつぶし、矩形描画は存在しません → 2013/9/16実装しました!
  • レイヤー機能は存在しません → 2013/9/17実装しました!
  • 消しゴム(配置したマップチップを消去)機能はありません → 2013/9/19実装しました!
  • 海岸線補間も存在しません → 2013/10/03実装しました!
  • ミニマップはありません
  • セーブ・ロードは存在しません
  • マップチップセットは一つしかありません
閲覧: 466 評価: 0
  • Starwhite
  • Starwhite
  • Starwhite
  • Starwhite
  • Starwhite
  • Starwhite
  • Starwhite
  • Starwhite
  • Starwhite
  • Starwhite
あなたはまだ評価していません。
#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
コード一覧
  • start.rb

コメントするには、ログインする必要があります。

コメント一覧
お知らせ

2014/03/04 ver. 0.1.39 を公開しました!
・0.1.36でWindowsで起動しない問題を修正しました
(Android版はバージョン番号のみの変更です。)

2014/03/04 ver. 0.1.36 を公開しました!
・アプリケーションアイコンを変更しました
・セーブ・ロードを繰り返すとアプリが強制終了する問題を修正しました
・他、重大なバグを修正しました

ダウンロードはこちらから。

2013/07/17 Code on Rmakeをα公開しました!