#===
#¤Classe Tilemap
#---
#%Création de Map avec les une taille de Tile choisie.
#%/!\ Le centrage n'est pas fonction des Characters donc veillez
# à bien positionner les characters dans leur positions virtuelles.
#---
#© 09/11/2010 - Nuri Yuri (塗 ゆり) Version Projet Communautaire
#© 10/10/2011 - Nuri Yuri (塗 ゆり) Amélioration, correction de bugs.
#© 25/10/2011 - Nuri Yuri (塗 ゆり) Correction du problème avec les tiles en supériorité 1.
#===
class Tilemap
#===
#%Déclaration des attributs.
#===
attr_accessor :viewport, :ox, :oy, :tileset, :autotiles, :update_count
attr_accessor :map_data, :priorities, :visible
#===
#%Déclaration des constantes
#===
M=10**3
MM=10**6
MMM=10**9
Autotiles = [
[ [27, 28, 33, 34], [ 5, 28, 33, 34], [27, 6, 33, 34], [ 5, 6, 33, 34],
[27, 28, 33, 12], [ 5, 28, 33, 12], [27, 6, 33, 12], [ 5, 6, 33, 12] ],
[ [27, 28, 11, 34], [ 5, 28, 11, 34], [27, 6, 11, 34], [ 5, 6, 11, 34],
[27, 28, 11, 12], [ 5, 28, 11, 12], [27, 6, 11, 12], [ 5, 6, 11, 12] ],
[ [25, 26, 31, 32], [25, 6, 31, 32], [25, 26, 31, 12], [25, 6, 31, 12],
[15, 16, 21, 22], [15, 16, 21, 12], [15, 16, 11, 22], [15, 16, 11, 12] ],
[ [29, 30, 35, 36], [29, 30, 11, 36], [ 5, 30, 35, 36], [ 5, 30, 11, 36],
[39, 40, 45, 46], [ 5, 40, 45, 46], [39, 6, 45, 46], [ 5, 6, 45, 46] ],
[ [25, 30, 31, 36], [15, 16, 45, 46], [13, 14, 19, 20], [13, 14, 19, 12],
[17, 18, 23, 24], [17, 18, 11, 24], [41, 42, 47, 48], [ 5, 42, 47, 48] ],
[ [37, 38, 43, 44], [37, 6, 43, 44], [13, 18, 19, 24], [13, 14, 43, 44],
[37, 42, 43, 48], [17, 18, 47, 48], [13, 18, 43, 48], [ 1, 2, 7, 8] ] ]
#===
#§Initialisation du Tilemap
#---
#%Aupdate_count est l'écart entre les mise à jour d'autotiles en frames.
#===
def initialize(viewport=false, update_count=10, tile_size_x=16, tile_size_y=16, visible=true)
@viewport=viewport
@visible=visible
@tiled=false
@dispose=false
@update_count=update_count.to_i
set_tile_zoom(tile_size_x,tile_size_y)
@tiles={}
@atiles={}
@bitmap_tiles={}
@autotile_update_ids=[] # tableau des id tiles(autotiles) a mettre a jour
@autotile_max_count=[] # tableau contenant le nombre de frammes par autotiles
@autotiles=[]
@rect=Rect.new(0, 0, 32, 32)
@dest_rect = Rect.new(0, 0, @tile_size_x, @tile_size_y)
end
#===
#§Mise à jour du Tilemap
#===
def update(forced=false)
@ox /= @tile_zoom_x
@oy /= @tile_zoom_y
if not @tiled
@tiled=true
create_map
end
update_autotiles if forced or (Graphics.frame_count % @update_count == 0)
update_pos
end
#===
#§Dessin de la Map et detection du nombre max de frammes.
#===
def create_map
for i in 0..6
@autotile_max_count[i] = @autotiles[i].width / 96
end
for z in 0... @map_data.zsize
for x in
0...@map_data.xsize for y in
0...@map_data.ysize id = @map_data[x, y, z]
next if id == 0
c = @priorities[id]
next unless c
id < 384 ? sprite_at2(x, y, c, z, id) : sprite_t(x, y, c, z, id)
end
end
end
end
#===
#§Sprite_t
#---
#%Création d'un sprite de tiles/collage de tiles sur ce sprite.
#===
def sprite_t(x,y,z,c,id)
if z==1
sprite_t!(x,y,z,c,id)
return
end
name=-(z*MMM+c)
if @bitmap_tiles[id]
if @tiles[name]
@tiles[name].bitmap.blt(x*@tile_size_x,y*@tile_size_y,@bitmap_tiles[id],@dest_rect)
else
@tiles[name] = Sprite.new(@viewport)
@tiles[name].ox=@ox
@tiles[name].oy=@oy
@tiles[name].z = z*150 + c
@tiles[name].bitmap=Bitmap.new(@map_data.xsize*@tile_size_x,@map_data.ysize*@tile_size_y)
@tiles[name].bitmap.blt(x*@tile_size_x,y*@tile_size_y,@bitmap_tiles[id],@dest_rect)
@tiles[name].visible=@visible
end
else
@rect.x=(id - 384) % 8 * 32
@rect.y=(id - 384) / 8 * 32
x *= @tile_size_x
y *= @tile_size_y
@bitmap_tiles[id]=Bitmap.new(@tile_size_x, @tile_size_y)
@bitmap_tiles[id].stretch_blt(@dest_rect, @tileset, @rect)
@rect.x=0
@rect.y=0
if @tiles[name]
@tiles[name].bitmap.blt(x,y,@bitmap_tiles[id],@dest_rect)
else
@tiles[name] = Sprite.new(@viewport)
@tiles[name].ox=@ox
@tiles[name].oy=@oy
@tiles[name].z = z*150 + c
@tiles[name].bitmap=Bitmap.new(@map_data.xsize*@tile_size_x,@map_data.ysize*@tile_size_y)
@tiles[name].bitmap.blt(x,y,@bitmap_tiles[id],@dest_rect)
@tiles[name].visible=@visible
end
end
end
#===
#§Dessin des tiles en *1
#===
def sprite_t!(x,y,z,c,id)
name=y.to_f
if @bitmap_tiles[id]
if @tiles[name]
@tiles[name].bitmap.blt(x*@tile_size_x,0,@bitmap_tiles[id],@dest_rect)
else
@tiles[name] = Sprite.new(@viewport)
@tiles[name].ox=@ox
@tiles[name].oy=@oy
@tiles[name].y = @tile_size_y*y
@tiles[name].bitmap=Bitmap.new(@map_data.xsize*@tile_size_x,@tile_size_y)
@tiles[name].bitmap.blt(x*@tile_size_x,0,@bitmap_tiles[id],@dest_rect)
@tiles[name].visible=@visible
end
else
@rect.x=(id - 384) % 8 * 32
@rect.y=(id - 384) / 8 * 32
x *= @tile_size_x
#y *= @tile_size_y
@bitmap_tiles[id]=Bitmap.new(@tile_size_x, @tile_size_y)
@bitmap_tiles[id].stretch_blt(@dest_rect, @tileset, @rect)
@rect.x=0
@rect.y=0
if @tiles[name]
@tiles[name].bitmap.blt(x,0,@bitmap_tiles[id],@dest_rect)
else
@tiles[name] = Sprite.new(@viewport)
@tiles[name].ox=@ox
@tiles[name].oy=@oy
@tiles[name].y = @tile_size_y*y
@tiles[name].bitmap=Bitmap.new(@map_data.xsize*@tile_size_x,@tile_size_y)
@tiles[name].bitmap.blt(x,0,@bitmap_tiles[id],@dest_rect)
@tiles[name].visible=@visible
end
end
end
#===
#§Detection du type d'autotile à dessiner.
#---
#Si c'est un autotile à une frame ça le considère comme un tile
#===
def sprite_at2(x,y,z,c,id)
if @autotile_max_count[id / 48 - 1]==1
name=-(z*MMM+c)
if @bitmap_tiles[id]
if @tiles[name]
@tiles[name].bitmap.blt(x*@tile_size_x,y*@tile_size_y,@bitmap_tiles[id],@dest_rect)
else
@tiles[name] = Sprite.new(@viewport)
@tiles[name].ox=@ox
@tiles[name].oy=@oy
@tiles[name].z = z*150 + c
@tiles[name].bitmap=Bitmap.new(@map_data.xsize*@tile_size_x,@map_data.ysize*@tile_size_y)
@tiles[name].bitmap.blt(x*@tile_size_x,y*@tile_size_y,@bitmap_tiles[id],@dest_rect)
@tiles[name].visible=@visible
end
else
bitmap=get_autotile_bmp(id)
x *= @tile_size_x
y *= @tile_size_y
@bitmap_tiles[id]=Bitmap.new(@tile_size_x, @tile_size_y)
@bitmap_tiles[id].stretch_blt(@dest_rect, bitmap, @rect)
if @tiles[name]
@tiles[name].bitmap.blt(x,y,@bitmap_tiles[id],@dest_rect)
else
@tiles[name] = Sprite.new(@viewport)
@tiles[name].ox=@ox
@tiles[name].oy=@oy
@tiles[name].z = z*150 + c
@tiles[name].bitmap=Bitmap.new(@map_data.xsize*@tile_size_x,@map_data.ysize*@tile_size_y)
@tiles[name].bitmap.blt(x,y,@bitmap_tiles[id],@dest_rect)
@tiles[name].visible=@visible
end
end
else
sprite_at(x,y,z,c,id)
end
end
#===
#§Dessin d'autotile
#===
def sprite_at(x,y,z,c,id)
name=id*MMM+x*MM+y*M+z
@atiles[name]=id
if @bitmap_tiles[id]
if @tiles[name]
@tiles[name].bitmap=@bitmap_tiles[id]
else
@tiles[name] = Sprite.new(@viewport)
@tiles[name].x = x*@tile_size_x
@tiles[name].y = y*@tile_size_y
@tiles[name].ox=@ox
@tiles[name].oy=@oy
@tiles[name].z = z*150 + c
@tiles[name].bitmap=@bitmap_tiles[id]
@tiles[name].visible=@visible
end
else
bitmap=get_autotile_bmp(id)
x *= @tile_size_x
y *= @tile_size_y
@bitmap_tiles[id]=Bitmap.new(@tile_size_x, @tile_size_y)
@bitmap_tiles[id].stretch_blt(@dest_rect, bitmap, @rect)
@tiles[name] = Sprite.new(@viewport)
@tiles[name].x = x
@tiles[name].y = y
@tiles[name].z= z*150 + c
@tiles[name].ox=@ox
@tiles[name].oy=@oy
@tiles[name].bitmap=@bitmap_tiles[id]
@tiles[name].visible=@visible
if not @autotile_update_ids.include?(id)
@autotile_update_ids.push(id) if @autotile_max_count[id / 48 - 1] > 1
end
end
end
#===
#§Capture du Bitmap d'un Autotile.
#===
def get_autotile_bmp(id)
autotile = @autotiles[id / 48 - 1]
return autotile if autotile.width < 96
id %= 48
bitmap=Bitmap.new(32,32)
tiles = Autotiles[id / 8][id % 8]
frames = autotile.width / 96
anim = (Graphics.frame_count / @update_count) % frames * 96
for i in 0...4
tile_position = tiles[i] - 1
src_rect = Rect.new(tile_position % 6 * 16 + anim, tile_position / 6 * 16, 16, 16)
bitmap.blt(i % 2 * 16, i / 2 * 16, autotile, src_rect)
end
return bitmap
end
#===
#§Mise à jour des autotiles.
#===
def update_autotiles
for i in
0...@autotile_update_ids.length id=@autotile_update_ids[i]
bitmap=get_autotile_bmp(id)
#@bitmap_tiles[id]=Bitmap.new(@tile_size_x, @tile_size_y) #Pas besoins d'en recréer
@bitmap_tiles[id].stretch_blt(@dest_rect, bitmap, @rect)
end
end
#===
#§Mise à jour des positions des Sprites du Tilemap
#===
def update_pos
for i in @tiles.keys
@tiles[i].ox=@ox
@tiles[i].oy=@oy
@tiles[i].visible=@visible
if @atiles[i]
@tiles[i].bitmap=@bitmap_tiles[@atiles[i]]
end
if i.class==Float
@tiles[i].z=(i.to_i*128 - $game_map.display_y + 3) / 4 + 32 +32
end
end
end
#===
#§Effacement du Tilemap
#===
def dispose
for i in @tiles
i[1].bitmap.clear
i[1].bitmap=nil
i[1].dispose
@tiles.delete(i[0])
end
for i in @bitmap_tiles
i[1].clear
@bitmap_tiles.delete(i[0])
end
GC.start
@dispose=true
end
#===
#§Disposed?
#===
def disposed?
return @dispose
end
#===
#§Changement de dimentions du Tilemap
#===
def resize_tiles(x=16,y=16)
dispose
set_tile_zoom(x,y)
@dest_rect = Rect.new(0, 0, @tile_size_x, @tile_size_y)
create_map
@dispose=false
end
#===
#§Modification des varables size et zoom
#===
def set_tile_zoom(tile_size_x,tile_size_y)
@tile_size_x=tile_size_x
@tile_size_y=tile_size_y
@tile_zoom_x=32/tile_size_x
@tile_zoom_y=32/tile_size_y
end
end
#===
#¤Ajout de l'attribut Tilemap dans Spriteset_Map pour un acces plus simple.
#===
class Spriteset_Map
attr_accessor :tilemap
end
#===
#¤Ajout de l'attribut Spriteset dans Scene_Map,
# cet attribut n'existe pas sur les versions d'RMXP
#===
class Scene_Map
attr_accessor :spriteset
end