Project1
标题:
咱也来研究下那啥万恶的TILEMAP-_-0
[打印本页]
作者:
orochi2k
时间:
2009-5-13 22:09
标题:
咱也来研究下那啥万恶的TILEMAP-_-0
class Tilemap
FBLX = (640/32.0).ceil*32#x方向解析度
FBLY = (480/32.0).ceil*32#y方向解析度
SIZEX = 32
SIZEY = 32
ANI = 15#動畫等待楨數
#以下畫元件用
AUTO_XY = [
[8, 8, 8, 8], [3, 8, 8, 8], [8, 3, 8, 8], [3, 3, 8, 8],
[8, 8, 8, 3], [3, 8, 8, 3], [8, 3, 8, 3], [3, 3, 8, 3],
[8, 8, 3, 8], [3, 8, 3, 8], [8, 3, 3, 8], [3, 3, 3, 8],
[8, 8, 3, 3], [3, 8, 3, 3], [8, 8, 3, 3], [3, 3, 3, 3],
[7, 7, 7, 7], [7, 3, 7, 7], [7, 7, 7, 3], [7, 3, 7, 3],
[5, 5, 5, 5], [5, 5, 5, 3], [5, 5, 3, 5], [5, 5, 3, 3],
[9, 9, 9, 9], [9, 9, 3, 9], [3, 9, 9, 9], [3, 9, 3, 9],
[11, 11, 11, 11], [3, 11, 11, 11], [11, 3, 11, 11], [3, 3, 11, 11],
[7, 9, 7, 9], [5, 5, 11, 11], [4, 4, 4, 4], [4, 4, 4, 3],
[6, 6, 6, 6], [6, 6, 3, 6], [12, 12, 12, 12], [3, 12, 12, 12],
[10, 10, 10, 10], [10, 3, 10, 10], [4, 6, 4, 6], [4, 4, 10, 10],
[10, 12, 10, 12], [6, 6, 12, 12], [4, 6, 10, 12], [1, 1, 1, 1]
]
#--------------------------------------------------------------------------
# ● 定義外部變數
#--------------------------------------------------------------------------
attr_accessor :autotiles
attr_accessor :tileset
attr_reader :ox
attr_reader :oy
attr_accessor :priorities
#--------------------------------------------------------------------------
# ● 初始化物件
#--------------------------------------------------------------------------
def initialize(viewport = nil)
@shadow = Bitmap.new(SIZEX, SIZEY)
@shadow.fill_rect(0, 0, 17, SIZEY, Color.new(0, 0, 0, 120))#陰影
@viewport = viewport
@bitmaps = []
@tileset = nil
@autotiles= []
@backs = {}#元件精靈
@backbitmap = {}#元件圖塊
@switches = {}#動畫開關
@count = 0#當前顯示動畫
@count1 = 0#等待楨數
@visible = true
@ox = $game_map.display_x / 4
@oy = $game_map.display_y / 4
@lastox = $game_map.display_x / 4
@lastoy = $game_map.display_y / 4
end
#--------------------------------------------------------------------------
# ● 釋放
#--------------------------------------------------------------------------
def dispose
for i in @backbitmap.values
i.dispose
end
for i in @backs.values
i.dispose
end
@shadow.dispose
end
#--------------------------------------------------------------------------
# ● 是否已釋放
#--------------------------------------------------------------------------
def disposed?
return @shadow.disposed?
end
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
def map_data=(value)
@map_data = value
#如果地圖太大,按ESC打開功能表後返回地圖太慢,下面這段迴圈可以不要
# for i in 0...value.xsize
# for j in 0...value.ysize
# for k in 0..2
# cachebitmap(value[i, j, k])
# end
# end
# end
#如果地圖太大,按ESC打開功能表後返回地圖太慢,上面這段迴圈可以不要
redrawmap
end
def redrawmap()
#需要重新描繪的圖快
if @map_data.xsize * SIZEX <= FBLX
rangei = ([@ox / SIZEX - 1,0].max)..[[((@ox + FBLX) / SIZEX), FBLX / SIZEX - 1].min,@map_data.xsize-1].min
else
rangei = ([@ox / SIZEX - 1,0].max)..([(@ox + FBLX) / SIZEX, @map_data.xsize-1].min)
end
if @map_data.ysize * SIZEY <= FBLY
rangej = ([@oy / SIZEY - 1,0].max)..[[((@oy + FBLY) / SIZEY), FBLY / SIZEY - 1].min,@map_data.ysize-1].min
else
rangej = ([@oy / SIZEY - 1,0].max)..([(@oy + FBLY) / SIZEY, @map_data.ysize-1].min)
end
for i in rangei
for j in rangej
for k in 0..2
draw(i, j, k)
end
end
end
end
#--------------------------------------------------------------------------
def refreshox
#需要釋放掉的圖塊
rangej = ([@lastoy / SIZEY - 1,0].max)..([(@lastoy + FBLY) / SIZEY, @map_data.ysize-1].min)
if @ox > @lastox
rangei = (([@lastox / SIZEX - 1,0].max)...[(@ox / SIZEX - 1), @map_data.xsize-1].min)
elsif @ox <= @lastox
rangei = (([(@ox + FBLX) / SIZEX + 1,0].max)..[((@lastox + FBLX) / SIZEX),@map_data.xsize-1].min)
end
#p rangej,rangei,1
if (rangei != nil and rangej != nil)
for i in rangei
for j in rangej
for k in 0..2
next if @backs[[i, j, k]].nil?
@backs[[i, j, k]].dispose
@backs.delete([i, j, k])
@switches.delete([i, j, k])
end
end
end
end
#恢復走路時候的偏移
if @ox >= (@map_data.xsize * SIZEX - FBLX)
for i in @backs.keys
@backs[i].ox = 0
@backs[i].x = i[0] * SIZEX - @ox
if i[0] < (@ox / 32 - 1)
@backs[i].x += @map_data.xsize * SIZEX
elsif i[0] == -1
@backs[i].x = 0
end
end
else
for i in @backs.keys
@backs[i].ox = 0
@backs[i].x = i[0] * SIZEX - @ox
end
end
#需要重新描繪的圖快
rangej = ([@oy / SIZEY - 1,0].max)..([(@oy + FBLY) / SIZEY,@map_data.ysize-1].min)
if @ox > @lastox
rangei = ([[((@lastox + FBLX) / SIZEX + 1), (@ox / SIZEX - 1)].max,0].max..[((@ox + FBLX) / SIZEX + 1),@map_data.xsize-1].min)
elsif @ox < @lastox
rangei = ([(@ox / SIZEX - 1),0].max...[[(@lastox / SIZEX - 1), (@ox + FBLX) / SIZEX + 1].min,@map_data.xsize-1].min)
end
#p rangej,rangei,2
if (rangei != nil and rangej != nil)
for i in rangei
for j in rangej
for k in 0..2
draw(i, j, k,true)
end
end
end
end
#redrawmap
#p @backs.size
#p @backs
end
#--------------------------------------------------------------------------
def refreshoy
#需要釋放掉的圖塊
rangei = ([@lastox / SIZEX - 1,0].max)..([(@lastox + FBLX) / SIZEX, @map_data.xsize-1].min)
if @oy > @lastoy
rangej = ([(@lastoy / SIZEY - 1),0].max...[(@oy / SIZEY - 1), @map_data.ysize-1].min)
elsif @oy <= @lastoy
rangej = ([((@oy + FBLY) / SIZEY + 1),0].max..[((@lastoy + FBLY) / SIZEY), @map_data.ysize-1].min)
end
for i in rangei
for j in rangej
for k in 0..2
next if @backs[[i, j, k]].nil?
@backs[[i, j, k]].dispose
@backs.delete([i, j, k])
@switches.delete([i, j, k])
end
end
end
#恢復走路時候的偏移
if @oy >= (@map_data.ysize * SIZEY - FBLY)
for i in @backs.keys
@backs[i].oy = 0
@backs[i].y = i[1] * SIZEY - @oy
if i[1] < (@oy / 32 - 1)
@backs[i].y += @map_data.ysize * SIZEY
elsif i[1] == -1
@backs[i].y = 0
end
end
else
for i in @backs.keys
@backs[i].oy = 0
@backs[i].y = i[1] * SIZEY - @oy
end
end
#需要重新描繪的圖快
rangei = ([@ox / SIZEX - 1,0].max)..([(@ox + FBLX) / SIZEX, @map_data.xsize-1].min)
if @oy > @lastoy
rangej = ([[((@lastoy + FBLY) / SIZEY + 1), @oy / SIZEY - 1].max,0].max..[((@oy + FBLY) / SIZEY), @map_data.ysize-1].min)
elsif @oy < @lastoy
rangej = ([(@oy / SIZEY - 1),0].max...[[(@lastoy / SIZEY - 1), ((@oy + FBLY) / SIZEY + 1)].min, @map_data.ysize-1].min)
end
for i in rangei
for j in rangej
for k in 0..2
draw(i, j, k)
end
end
end
############
#for i in @backs.keys
# id = @map_data[i[0],i[1],i[2]]
# if @priorities[id] != 0
# @backs[i].z = 32 + (i[1] * SIZEY - @oy ) + 32 * @priorities[id]
#@backs[i].bitmap.clear
#@backs[i].bitmap.draw_text(0,0,32,32,"#{@backs[i].z}")
# end
#end
##############
# redrawmap
end
#--------------------------------------------------------------------------
def resetp(i,j,k)
return if @passages.nil?
return if @priorities.nil?
#return unless @passages[id] == 22
#@backs[[i, j, k]].z = 200
id = @map_data[i, j, k]
if @priorities[id] == 0 #or @priorities[id] == 22
@backs[[i, j, k]].z = 0
else
tt = 32 + (j * SIZEY - @oy ) + 32 * @priorities[id]
if tt < 0
tt = 0
end
@backs[[i, j, k]].z = tt
end
end
#i為x座標,j為y座標,k為圖層
def draw(i, j, k,old = false)
i0 = i
j0 = j
i -= @map_data.xsize if i >= @map_data.xsize
i += @map_data.xsize if i < 0
j -= @map_data.ysize if j >= @map_data.ysize
j += @map_data.ysize if j < 0
id = @map_data[i, j, k]
if old
ttx = @lastox
tty = @lastoy
else
ttx = @ox
tty = @oy
end
return if id == 0
unless @backs[[i, j, k]].nil?
unless @backs[[i, j, 3]].nil?
@backs[[i, j, 3]].x = i0 * SIZEX - ttx
@backs[[i, j, 3]].y = j0 * SIZEY - tty
end
@backs[[i, j, k]].x = i0 * SIZEX - ttx
@backs[[i, j, k]].y = j0 * SIZEY - tty
return
end
@backs[[i, j, k]] = Sprite.new(@viewport)
@backs[[i, j, k]].x = i0 * SIZEX - ttx
@backs[[i, j, k]].y = j0 * SIZEY - tty
@backs[[i, j, k]].z = 0
@backs[[i, j, k]].bitmap = cachebitmap(id)
if id < 384
if @backbitmap[id + 10000] != nil
#動畫
@switches[[i, j, k]] = true
@backs[[i, j, k]].bitmap = @backbitmap[id + @count * 10000]
end
end
return if @passages.nil?
return if @priorities.nil?
#return unless @passages[id] == 22
#@backs[[i, j, k]].z = 200
resetp(i,j,k)
end
#---------------------------------------------------------------------------
def cachebitmap(id)
if @backbitmap[id].nil?
if id < 384#自動元件的情況
bitmapid = (id - (id % 48)) / 48 - 1
@backbitmap[id] = drawbitmap1(id, bitmapid)
if @autotiles[bitmapid].width > 96
@backbitmap[id + 10000] = drawbitmap1(id, bitmapid, 1)
@backbitmap[id + 20000] = drawbitmap1(id, bitmapid, 2)
@backbitmap[id + 30000] = drawbitmap1(id, bitmapid, 3)
end
else
rect = Rect.new((id - 384) % 8 * SIZEX, (id - 384) / 8 * SIZEY, 32, 32)
@backbitmap[id] = Bitmap.new(32, 32)
@backbitmap[id].blt(0, 0, @tileset, rect)
end
end
return @backbitmap[id]
end
#---------------------------------------------------------------------------
#此處的x,y指圖片上的xy位置,id範圍為48-383,bitmapid為圖片編號
def drawbitmap1(id, bitmapid, ani = 0)
bitmap = Bitmap.new(32, 32)
pic_id = id % 48
for i in 0..3
rect_x = (AUTO_XY[pic_id][i] - 1) % 3
rect_y = (AUTO_XY[pic_id][i] - 1 - rect_x) / 3
x = (i % 2) * 16
y = (i - (x / 16)) / 2 * 16
bitmap.blt(x, y, @autotiles[bitmapid], Rect.new(rect_x * 32 + x + ani * 96, rect_y * 32 + y, 16, 16))
end
return bitmap
end
#---------------------------------------------------------------------------
def priorities=(value)
@priorities = value
@passages = value
# resetppp()
# redrawmap
# for i in ([@ox / SIZEX - 1, 0].max)..((@ox + FBLX) / SIZEX)
# for j in ([@oy / SIZEY - 1, 0].max)..((@oy + FBLY) / SIZEY)
# for kk in 0..2
# id = @map_data[i, j, 3-kk]
# if id.nil?
# next
# end
#unless value[id] == 22
# next
#end
# if value[id] == 0
# @backs[[i, j, 3-kk]].z = 0
# else
# @backs[[i, j, 3-kk]].z = 32 + @backs[[i, j, 3]].y * 32 + 32 * value[id]
# end
# break
# end
# end
# end
end
#--------------------------------------------------------------------------
def ox=(value)
if @ox != value
@ox = value
if value >= (@map_data.xsize * SIZEX - FBLX)
@lastox += @map_data.xsize * SIZEX if @lastox < (@ox - FBLX)
end
#人物走路時候
if @ox % (SIZEX/2) != 0
for i in @backs.values
i.ox = @ox - @lastox
end
else
refreshox
@lastox = @ox
end
end
end
#--------------------------------------------------------------------------
def oy=(value)
if @oy != value
@oy = value
if value >= (@map_data.ysize * SIZEY - FBLY)
@lastoy += @map_data.ysize * SIZEY if @lastoy < (@oy - FBLY)
end
#人物走路時候
if @oy % SIZEY != 0
for i in @backs.values
i.oy = @oy - @lastoy
end
else
refreshoy
@lastoy = @oy
end
end
end
#---------------------------------------------------------------------------
def count=(value)
value = 0 if value >= 4
@count = value
for i in @switches.keys
id = @map_data[i[0], i[1], i[2]]
@backs[i].bitmap = @backbitmap[id + value * 10000]
end
end
#---------------------------------------------------------------------------
def update
if @count1 == ANI
@count1 = 0
self.count = @count+1
else
@count1 += 1
end
for i in @backs.keys
id = @map_data[i[0],i[1],i[2]]
if @priorities[id] != 0
@backs[i].z = 32 + (i[1] * SIZEY - @oy ) + 32 * @priorities[id]
end
end
end
end
复制代码
不是完全原创脚本,是从某一脚本的基础上改的(嗯,今天翻硬盘时翻到的),请原作者认领一下-_-0
我的修改部分:
1,修正了原作者对RMXP说明文件中无视的一条东西:
优先级为 0 的地图元件的 Z 座标必定是 0。
2,加入了地图元件优先级的正确显示(呃...原来脚本好像啥东西Z坐标都一样-_-0)
3,原作者的脚本中DRAW函数(现在已经被我拆成2个了) 有一处X和Y写错的地方,会导致Y轴移动和场景转换时的一些问题
4,呃...好像没了....
具体用途,纯粹做技术参考....
实用性方面,貌似除了丢去某邪恶的RMXP套RMVX库的诡异开发框架作为TILEMAP的替换外没啥别的功能(嗯...而对这方面比较关注的也就搞笑艺人团体了...在这里貌似不会有多少人干这么诡异的事-_-0,实际上,我非常怀疑这是一个唯一符合那种技术框架下要求的国产TILEMAP类-_-0)
总结,我是来打酱油的...大家爱怎么办怎么办吧-_-0
由于是新鲜出炉,过完测试直接丢出来的东西,一堆测试用代码变注释没删-_-0
还有UPDATA里那个Z轴刷新,不知道谁有办法把那东西丢到别的地方去判断么...
作者:
tommay
时间:
2009-5-13 22:49
太深奥,不懂的人飘过~
作者:
hitlerson
时间:
2009-5-14 04:33
能否请改善下能在1024*768的地图下人物速度6时不卡
作者:
orochi2k
时间:
2009-5-14 23:01
以下引用
hitlerson于2009-5-13 20:33:30
的发言:
能否请改善下能在1024*768的地图下人物速度6时不卡
呃...那个....RMXP的地图大小限制不是最大只能500*500么-_-0
分辨率默认最大也只有640*480
如果用其它脚本改了分辨率的话,可能还要考虑一下其它因素...这个暂时没什么改进思路{/gg}
作者:
bububinghe
时间:
2009-5-16 17:22
楼主是高手,鉴定完毕
作者:
longhun9958
时间:
2009-5-16 17:37
提示:
作者被禁止或删除 内容自动屏蔽
作者:
david50407
时间:
2009-7-3 17:55
抱歉,
那是我根據kissye的VX版tilemap做修改的
有些小細節沒注意到
謝謝
作者:
david50407
时间:
2009-7-5 14:34
感謝閣下的協助
我又寫出新的腳本
把多餘部分刪除
優化
加上flash_data的功能
http://rpg.blue/viewthread.php?tid=127629
作者:
君少
时间:
2009-7-5 15:29
什么都不懂的人路过
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1