#encoding:utf-8
=begin
#==============================================================================
# ■ 多层地图脚本 by dukesward
#-----------------------------------------------------------------------------
使用方法:
基本的使用方法是在哈希表中输入:
id => { layer1 => [ [第一个图块组], [第二个图块组]... ], layer2 =>
[ [第一个图块组], [第二个图块组]... ], ... }
举例: MAP_LAYER = { 1 => { 1 => [ [ "B", [0, 0], [1, 1], [2, 2], true]] } }
意思是你要在id为1的地图里,添加一层,在该层中绘制一个图块,图块起始位置对应地图坐标
[0, 0], 起始图块来源为B图块组坐标[1, 1]的那张,图块大小为64*64。
#==============================================================================
=end
NORMAL_SET = ["B", "C", "D", "E"]
MAP_LAYER = {
1 => { 1 => [["B", [6, 0], [0, 16], [3, 2], false]],
2 => [["A2", [0, 0], [3, 4], [3, 3], true]],
3 => [["C", [0, 0], [0, 23], [3, 2], false]]
}
}
class Game_Map
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_accessor :layers # 地图图层表
#--------------------------------------------------------------------------
# ● 设置
#--------------------------------------------------------------------------
alias setup_old setup
def setup(map_id)
setup_old(map_id)
create_layer_table
clear_layer_table
end
#--------------------------------------------------------------------------
# ● 生成图层数据表
#--------------------------------------------------------------------------
def create_layer_table
@layers = Table.new(@map.data.xsize, @map.data.ysize,
MAP_LAYER.keys.include?(@map_id) ? MAP_LAYER[@map_id].keys.size : 1)
end
#--------------------------------------------------------------------------
# ● 清空图层数据表
#--------------------------------------------------------------------------
def clear_layer_table
for x in [email]0...@layers.xsize[/email]
for y in [email]0...@layers.ysize[/email]
for z in [email]0...@layers.zsize[/email]
@layers[x, y, z] = 1
end
end
end
end
#--------------------------------------------------------------------------
# ● 通行检查
# bit : 判断通行禁止与否的字节(请参照二进制运算)
#--------------------------------------------------------------------------
def check_passage(x, y, bit)
all_tiles(x, y).each do |tile_id|
flag = tileset.flags[tile_id]
return false if !all_layer_pass(x, y)
next if flag & 0x10 != 0 # [☆] : 不影响通行
return true if flag & bit == 0 # [○] : 可以通行
return false if flag & bit == bit # [×] : 不能通行
end
return false # 不能通行
end
#--------------------------------------------------------------------------
# ● 图层检查
#--------------------------------------------------------------------------
def all_layer_pass(x, y)
return true if !MAP_LAYER.keys.include?(@map_id)
MAP_LAYER[@map_id].keys.each do |i|
return false if @layers[x, y, i-1] == 0
end
end
end
class Spriteset_Map
#--------------------------------------------------------------------------
# ● 生成人物精灵
#--------------------------------------------------------------------------
alias create_old_char create_characters
def create_characters
create_old_char
create_map_layer
end
#--------------------------------------------------------------------------
# ● 创建地图层
#--------------------------------------------------------------------------
def create_map_layer
@event_sprites = []
if MAP_LAYER.keys.include?(@map_id)
MAP_LAYER[@map_id].keys.each_with_index do |i|
@event_sprites.push(Spriteset_Tile.new(@viewport1, @map_id, i))
end
end
end
#--------------------------------------------------------------------------
# ● 更新画面
#--------------------------------------------------------------------------
alias update_old update
def update
update_old
update_spriteset_tile
end
#--------------------------------------------------------------------------
# ● 更新图块精灵组
#--------------------------------------------------------------------------
def update_spriteset_tile
@event_sprites.each do |spriteset|
spriteset.update_all_sprites
end
end
#--------------------------------------------------------------------------
# ● 释放
#--------------------------------------------------------------------------
alias dispose_old dispose
def dispose
dispose_old
dispose_spriteset_tile
end
#--------------------------------------------------------------------------
# ● 释放图块精灵组
#--------------------------------------------------------------------------
def dispose_spriteset_tile
@event_sprites.each do |spriteset|
spriteset.dispose_all_sprites
end
end
end
class Spriteset_Tile
#--------------------------------------------------------------------------
# ● 初始化对象
#--------------------------------------------------------------------------
def initialize(viewport, id, layer)
@tile_ary = MAP_LAYER[id][layer]
@layer = layer
@tile_sprites = []
create_sprites(viewport)
end
#--------------------------------------------------------------------------
# ● 生成精灵
#--------------------------------------------------------------------------
def create_sprites(viewport)
@tile_ary.each do |array|
array[0].include?("A") ? create_auto(viewport, array) :
create_normal(viewport, array)
end
end
#--------------------------------------------------------------------------
# ● 生成普通精灵
#--------------------------------------------------------------------------
def create_normal(viewport, array)
for x in 0...array[3][0]
for y in 0...array[3][1]
@tile_sprites.push(Sprite_Tile.new(viewport, array[0],
[array[1][0]+x, array[1][1]+y], [array[2][0]+x, array[2][1]+y],
@layer, 0))
$game_map.layers[x, y, @layer-1] = array[4] ? 1 : 0
end
end
end
#--------------------------------------------------------------------------
# ● 生成自动精灵
#--------------------------------------------------------------------------
def create_auto(viewport, array)
for x in 0...array[3][0]*2
for y in 0...array[3][1]*2
@tile_sprites.push(Sprite_Tile.new(viewport, array[0],
[array[1][0]+x, array[1][1]+y], [array[2][0], array[2][1]], @layer,
[[x+1, y+1], [array[3][0], array[3][1]]]))
$game_map.layers[x, y, @layer-1] = array[4] ? 1 : 0
end
end
end
#--------------------------------------------------------------------------
# ● 更新所有精灵
#--------------------------------------------------------------------------
def update_all_sprites
@tile_sprites.each do |sprite|
sprite.update
end
end
#--------------------------------------------------------------------------
# ● 释放所有精灵
#--------------------------------------------------------------------------
def dispose_all_sprites
@tile_sprites.each do |sprite|
sprite.dispose
end
end
end
class Sprite_Tile < Sprite_Base
#--------------------------------------------------------------------------
# ● 初始化对象
#--------------------------------------------------------------------------
def initialize(viewport, tileset, map_pos, tile_pos, layer, tag)
super(viewport)
@layer = layer
@bitmap = get_tile_id(tileset)
@map_pos = map_pos
@tile_pos = tile_pos
@auto_tile = tileset.include?("A")
@depth = 0
get_tag(tag) if tag != 0
update
end
#--------------------------------------------------------------------------
# ● 获取图块标签
#--------------------------------------------------------------------------
def get_tag(tag)
@tag = tag[0]
@prod = [tag[1][0]*2, tag[1][1]*2]
set_auto_bitmap
end
#--------------------------------------------------------------------------
# ● 更新自动元件
#--------------------------------------------------------------------------
def set_auto_bitmap
@sx = (@tile_pos[0]*2-2)*32; @sy = (@tile_pos[1]*3-2)*32;
self.bitmap = @bitmap
assign_tile(0, 0) if @tag == [1, 1]
assign_tile(48, 48) if @tag == @prod
if @tag[0] == 1 && @tag[1] != 1
assign_tile(0, 48) if @tag[1] == @prod[1]
assign_tile(0, 16) if @tag[1] != @prod[1] && (@tag[1]-@prod[1])%2 == 0
assign_tile(0, 32) if @tag[1] != @prod[1] && (@tag[1]-@prod[1])%2 == 1
elsif @tag[1] == 1 && @tag[0] != 1
assign_tile(48, 0) if @tag[0] == @prod[0]
assign_tile(16, 0) if @tag[0] != @prod[0] && (@tag[0]-@prod[0])%2 == 0
assign_tile(32, 0) if @tag[0] != @prod[0] && (@tag[0]-@prod[0])%2 == 1
end
if (@tag[0] > 1) && (@tag[1] > 1) && @tag != @prod
assign_tile(16, 48) if @tag[1] == @prod[1] && ((@tag[0]-@prod[0])%2 == 0)
assign_tile(32, 48) if @tag[1] == @prod[1] && ((@tag[0]-@prod[0])%2 == 1)
assign_tile(48, 16) if @tag[0] == @prod[0] && ((@tag[0]-@prod[0])%2 == 0)
assign_tile(48, 32) if @tag[0] == @prod[0] && ((@tag[0]-@prod[0])%2 == 1)
if @tag[1] != @prod[1] && @tag[0] != @prod[0]
assign_tile(16, 16) if ((@tag[0]-@prod[0])%2 == 0) &&
((@tag[1]-@prod[1])%2 == 0)
assign_tile(32, 16) if ((@tag[0]-@prod[0])%2 != 0) &&
((@tag[1]-@prod[1])%2 == 0)
assign_tile(16, 32) if ((@tag[0]-@prod[0])%2 == 0) &&
((@tag[1]-@prod[1])%2 != 0)
assign_tile(32, 32) if ((@tag[0]-@prod[0])%2 != 0) &&
((@tag[1]-@prod[1])%2 != 0)
end
end
self.ox = 8
self.oy = 16
end
#--------------------------------------------------------------------------
# ● 更新自动元件
#--------------------------------------------------------------------------
def assign_tile(x, y, depth = 0)
self.src_rect.set(@sx+=x, @sy+=y, 16, 16)
@depth = depth
end
#--------------------------------------------------------------------------
# ● 获取图块id
#--------------------------------------------------------------------------
def get_tile_id(tileset)
return tileset_normal(tileset) if NORMAL_SET.include?(tileset)
return tileset_auto(tileset) if tileset.include?("A")
end
#--------------------------------------------------------------------------
# ● 获取指定图块 ID 的图块组
#--------------------------------------------------------------------------
def tileset_normal(tileset)
case tileset
when "B"
return Cache.tileset($game_map.tileset.tileset_names[5])
when "C"
return Cache.tileset($game_map.tileset.tileset_names[6])
when "D"
return Cache.tileset($game_map.tileset.tileset_names[7])
when "E"
return Cache.tileset($game_map.tileset.tileset_names[8])
end
end
#--------------------------------------------------------------------------
# ● 获取指定自动图块 ID 的图块组
#--------------------------------------------------------------------------
def tileset_auto(tileset)
tile_word = tileset.split("A")[-1].to_i - 1
return Cache.tileset(tileset) if tile_word > 4
return Cache.tileset($game_map.tileset.tileset_names[tile_word])
end
#--------------------------------------------------------------------------
# ● 更新画面
#--------------------------------------------------------------------------
def update
super
update_bitmap
update_position
end
#--------------------------------------------------------------------------
# ● 更新位图
#--------------------------------------------------------------------------
def update_bitmap
@sx = (@tile_pos[0] + @tile_pos[1]/16.to_i * 8) * 32 if !@sx
@sy = @tile_pos[1]%16 * 32 if !@sy
self.bitmap = @bitmap
if !@auto_tile
self.src_rect.set(@sx, @sy, 32, 32)
self.ox = 16
self.oy = 32
end
end
#--------------------------------------------------------------------------
# ● 更新位置
#--------------------------------------------------------------------------
def update_position
if @auto_tile
self.x = (@map_pos[0] - $game_map.display_x) * 16 + 8
self.y = (@map_pos[1] - $game_map.display_y) * 16 + 16
else
self.x = (@map_pos[0] - $game_map.display_x) * 32 + 16
self.y = (@map_pos[1] - $game_map.display_y) * 32 + 32
end
self.z = 5 * (@layer - 1) + @depth
end
#--------------------------------------------------------------------------
# ● 释放
#--------------------------------------------------------------------------
def dispose
self.bitmap.dispose
super
end
end