支援RMXP的Tilemap
終於將RMXP的Tilemap研究出來了跟原版的差不多
但在使用flash_data的部份有點卡
希望能討論下
畢竟RUBY不能贏VC
以下是腳本class TilemapWIN_W = 640WIN_H = 480AREA_W = 32AREA_H = 32AREA_X = WIN_W / AREA_WAREA_Y = WIN_H / AREA_HANI_T = 20#動畫等待時間(單位:畫格)FLA_T = 4 #閃爍等待時間(單位:畫格)FLA_O= #畫面閃爍變化#畫自動元件用AUTO_XY = [ , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ]#--------------------------------------------------------------------------# ● 定義外部變數#--------------------------------------------------------------------------attr_accessor :autotilesattr_accessor :tilesetattr_reader :viewport#--------------------------------------------------------------------------# ● 初始化物件# 內部使用以 @@ 開頭#--------------------------------------------------------------------------def initialize(viewport = Viewport.new(0,0,WIN_W,WIN_H)) @autotiles = [] @tileset = nil @map_data = nil @flash_data = nil @priorities = nil @visible = true @ox = 0 @oy = 0 @viewport = viewport @@sprite = {} #元件Sprite @@cache = {} #元件Cache @@ani_switch = {} #動畫開關 @@count = 0 #當前顯示動畫 @@counting = 0 #動畫等待畫格 @@flash_layer = nil #畫面閃爍用 @@flash_count = 0 #當前閃爍動畫 @@flash_counting = 0 #閃爍等待畫格 @@last_ox = 0 @@last_oy = 0 @@disposed = falseend#--------------------------------------------------------------------------# ● 釋放#--------------------------------------------------------------------------def dispose return if @@disposed for i in @@cache.values if i.is_a?(Bitmap) i.dispose else for j in i.values j.dispose end end end for i in @@sprite.values i.dispose end @@flash_layer.dispose if @@flash_layer != nil @@flash_layer.bitmap.dispose if @@flash_layer != nil @@disposed = trueenddef dispose? return @@disposedend#--------------------------------------------------------------------------# ● 載入地圖資訊# 載入後繪製地圖#--------------------------------------------------------------------------def map_data return @map_dataenddef map_data=(data) @map_data = data return if @map_data.nil? # 建立地圖元件Cache(方法一) BEGIN # 地圖較大時不適用 #for x in 0...@map_data.xsize #for y in 0...@map_data.ysize # for l in 0..2 # cache_bitmap(@map_data) # end #end #end # 建立地圖元件Cache(方法一) END # 建立地圖元件Cache(方法二) BEGIN # 元件圖較大時不適用 for auto in 0..6 next if @autotiles.nil? for i in 0...48 cache_bitmap(auto * 48 + i) end end if @tileset != nil for y in / AREA_H yy = y * 8 for x in 0...8 cache_bitmap(yy + x + 384) end end end # 建立地圖元件Cache(方法二) END # 描繪地圖元件 BEGIN range_x = (@ox + WIN_W) / AREA_W range_y = (@oy + WIN_H) / AREA_H range_x = .min if @map_data.xsize * AREA_W = @map_data.xsize x += @map_data.xsize if x < 0 y -= @map_data.ysize if y >= @map_data.ysize y += @map_data.ysize if y < 0 id = @map_data return if id == 0 unless @@sprite[].nil? @@sprite[].x = x0 * AREA_W - @ox @@sprite[].y = y0 * AREA_H - @oy return if @priorities.nil? z = @priorities == 0 ? 0 : 32 * (1 + @@sprite[].y / AREA_H + @priorities) z = 0 if z < 0 @@sprite[].z = z return end @@sprite[] = Sprite.new(@viewport) @@sprite[].x = x0 * AREA_W - @ox @@sprite[].y = y0 * AREA_H - @oy @@sprite[].z = l @@sprite[].bitmap = cache_bitmap(id) if id < 384 if @@cache.length > 1 #動畫 @@ani_switch[] = true @@sprite[].bitmap = @@cache[@@count % @@cache.length] end end return if @priorities.nil? z = @priorities == 0 ? 0 : 32 * (1 + @@sprite[].y / AREA_H + @priorities) z = 0 if z < 0 @@sprite[].z = zend#--------------------------------------------------------------------------# ● 繪製地圖元件閃爍#--------------------------------------------------------------------------def draw_flash return if @flash_data.nil? return if @flash_data.xsize 0,'b'=>0} tmpcolor.set(rgb['r']*16,rgb['g']*16,rgb['b']*16) @@flash_layer.bitmap.fill_rect(x*AREA_W,y*AREA_H,AREA_W,AREA_H,tmpcolor) end end @@flash_layer.opacity=FLA_O[@@flash_count]end#--------------------------------------------------------------------------# ● 設定地圖座標#--------------------------------------------------------------------------def ox return @oxenddef oy return @oyenddef ox=(ox) return if @ox == ox @@last_ox = @ox if @@last_ox == @ox @ox = ox @@flash_layer.ox = ox % WIN_W if @@flash_layer != nil return @oxenddef oy=(oy) return if @oy == oy @@last_oy = @oy if @@last_oy == @oy @oy = oy @@flash_layer.oy = oy % WIN_H if @@flash_layer != nil return @oyend#--------------------------------------------------------------------------# ● 設定地圖顯示#--------------------------------------------------------------------------def visible return @visibleenddef visible=(value) @visible = value for i in @@sprite.values i.visible = @visible end @@flash_layer.visible = @visible return @visibleend#--------------------------------------------------------------------------# ● 更新地圖元件閃爍#--------------------------------------------------------------------------def flash_data return @flash_dataenddef flash_data=(data) return @flash_data if @flash_data == data @flash_data = data draw_flash return @flash_dataend#--------------------------------------------------------------------------# ● 更新地圖元件#--------------------------------------------------------------------------def update # 更新動畫等待畫格 if @@counting >= ANI_T @@counting = 0 @@count += 1 for i in @@ani_switch.keys id = @map_data, i, i] @@sprite.bitmap = @@cache[@@count % @@cache.length] end else @@counting += 1 end # 更新閃爍等待畫格 @@flash_counting += 1 if @@flash_counting >= FLA_T @@flash_counting = 0 @@flash_count = (@@flash_count + 1) % FLA_O.size @@flash_layer.opacity=FLA_O[@@flash_count] if @@flash_layer != nil end if @ox != @@last_ox #人物走路時候 if @ox % (AREA_W / 2) != 0 for i in @@sprite.values i.ox = @ox - @@last_ox end else refreshox @@last_ox = @ox end end if @oy != @@last_oy #人物走路時候 if @oy % AREA_H != 0 for i in @@sprite.values i.oy = @oy - @@last_oy end else refreshoy @@last_oy = @oy end end for i in @@sprite.keys id = @map_data,i,i] if @priorities != 0 @@sprite.z = @priorities == 0 ? 0 : 32 * (1 + @@sprite.y / AREA_H + @priorities) @@sprite.update end endend#--------------------------------------------------------------------------def refreshox #需要釋放的元件範圍 del_range_y = [(@@last_oy / AREA_H - 1), ((@@last_oy + WIN_H) / AREA_H)] if @ox > @@last_ox del_range_x = [(@@last_ox / AREA_W - 1), (@ox / AREA_W - 2)] else del_range_x = [((@ox + WIN_W) / AREA_W + 1), ((@@last_ox + WIN_W) / AREA_W)] end #需要繪製的元件範圍 draw_range_y = [(@oy / AREA_H - 1), ((@oy + WIN_H) / AREA_H)] if @ox > @@last_ox draw_range_x = [[((@@last_ox + WIN_W) / AREA_W + 1), (@ox / AREA_W - 1)].max, ((@ox + WIN_W) / AREA_W)] else draw_range_x = [(@ox / AREA_W - 1), ([(@@last_ox / AREA_W - 1),(@ox + WIN_W) / AREA_W + 1].min - 1)] end #釋放元件 BEGIN for x in del_range_x..del_range_x next if draw_range_x > x && x < draw_range_x for y in del_range_y..del_range_y next if draw_range_y > y && y < draw_range_y for l in 0..2 next if @@sprite[].nil? @@sprite[].dispose @@sprite.delete() @@ani_switch.delete() end end end #釋放元件 END #恢復走路時候的偏移 BEGIN if @ox >= (@map_data.xsize * AREA_W - WIN_W) for i in @@sprite.keys @@sprite.ox = 0 @@sprite.x = i * AREA_W - @ox if i < (@ox / 32 - 1) @@sprite.x += @map_data.xsize * AREA_W elsif i == -1 @@sprite.x = 0 end end else for i in @@sprite.keys @@sprite.ox = 0 @@sprite.x = i * AREA_W - @ox end end #恢復走路時候的偏移 END #繪製元件 BEGIN for x in draw_range_x..draw_range_x for y in draw_range_y..draw_range_y for l in 0..2 draw(x, y, l) end end end #繪製元件 ENDend#--------------------------------------------------------------------------def refreshoy #需要釋放的元件範圍 del_range_x = [(@@last_ox / AREA_W - 1), ((@@last_ox + WIN_W) / AREA_W)] if @oy > @@last_oy del_range_y = [(@@last_oy / AREA_H - 1), (@oy / AREA_H - 2)] else del_range_y = [((@oy + WIN_H) / AREA_H + 1), ((@@last_oy + WIN_H) / AREA_H)] end #需要繪製的元件範圍 draw_range_x = [(@ox / AREA_W - 1), ((@ox + WIN_W) / AREA_W)] if @oy > @@last_oy draw_range_y = [[((@@last_oy + WIN_H) / AREA_H + 1), (@oy / AREA_H - 1)].max, ((@oy + WIN_H) / AREA_H)] else draw_range_y = [(@oy / AREA_H - 1), ([(@@last_oy / AREA_H - 1),(@oy + WIN_H) / AREA_H + 1].min - 1)] end #釋放元件 BEGIN for x in del_range_x..del_range_x next if draw_range_x > x && x < draw_range_x for y in del_range_y..del_range_y next if draw_range_y > y && y < draw_range_y for l in 0..2 next if @@sprite[].nil? @@sprite[].dispose @@sprite.delete() @@ani_switch.delete() end end end #釋放元件 END #恢復走路時候的偏移 BEGIN if @oy >= (@map_data.ysize * AREA_H - WIN_H) for i in @@sprite.keys @@sprite.oy = 0 @@sprite.y = i * AREA_H - @oy if i < (@oy / 32 - 1) @@sprite.y += @map_data.ysize * AREA_H elsif i == -1 @@sprite.y = 0 end end else for i in @@sprite.keys @@sprite.oy = 0 @@sprite.y = i * AREA_H - @oy end end #恢復走路時候的偏移 END #繪製元件 BEGIN for x in draw_range_x..draw_range_x for y in draw_range_y..draw_range_y for l in 0..2 draw(x, y, l) end end end #繪製元件 ENDendend复制代码ps:
640*480 fps 在38左右
800*600 fps 在35左右
本帖来自P1论坛作者david50407,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=127629若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页:
[1]