Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class ISS::TMX_Tilemap
- A1SID = 1
- A2SID = 769
- A3SID = 1537
- A4SID = 2049
- A5SID = 3009
- BSID = 3521
- CSID = 4545
- DSID = 5569
- ESID = 6593
- PARENT_IDS = []
- TILESET = []
- PARENT_IDS[0] = 0
- TILESET[0] = 5
- (A1SID...A2SID).to_a.each { |i|
- PARENT_IDS[i] = A1SID
- TILESET[i] = 0#:a1
- }
- (A2SID...A3SID).to_a.each { |i|
- PARENT_IDS[i] = A2SID
- TILESET[i] = 1#:a2
- }
- (A3SID...A4SID).to_a.each { |i|
- PARENT_IDS[i] = A3SID
- TILESET[i] = 2#:a3
- }
- (A4SID...A5SID).to_a.each { |i|
- PARENT_IDS[i] = A4SID
- TILESET[i] = 3#:a4
- }
- (A5SID...BSID).to_a.each { |i|
- PARENT_IDS[i] = A5SID
- TILESET[i] = 4#:a5
- }
- (BSID...CSID).to_a.each { |i|
- PARENT_IDS[i] = BSID
- TILESET[i] = 5#:b
- }
- (CSID...DSID).to_a.each { |i|
- PARENT_IDS[i] = CSID
- TILESET[i] = 6#:c
- }
- (DSID...ESID).to_a.each { |i|
- PARENT_IDS[i] = DSID
- TILESET[i] = 7#:d
- }
- (ESID...(ESID+2024)).to_a.each { |i|
- PARENT_IDS[i] = ESID
- TILESET[i] = 8#:e
- }
- TILESIZE = 16
- BoxStruct = Struct.new( :width, :height )
- class MapStruct
- class LayerStruct
- attr_accessor :group, :type, :map_zs, :parameters
- end
- attr_accessor :map_data, :layer_props, :bitmaps
- attr_accessor :layer_structs
- attr_accessor :total_layers
- def width() ; return self.map_data.xsize ; end
- def height() ; return self.map_data.ysize ; end
- def setup_layers()
- @layer_structs = [] # // Each key is the layer group
- @total_layers = 0
- for i in 0...(self.layer_props.size)
- a = self.layer_props[i] # // a subarray
- @__lg = nil
- # // First check is to setup the struct
- a.each { |e|
- case e[0]
- when :layergroup
- @layer_structs[e[1]] ||= LayerStruct.new()
- (@layer_structs[e[1]].map_zs ||= []) << i
- @__lg = e[1]
- @layer_structs[@__lg].parameters ||= []
- @layer_structs[@__lg].group ||= @__lg
- @layer_structs[@__lg].type ||= :normal
- end
- }
- # // Second check is for sub properties
- a.each { |e|
- case e[0]
- when :animlayer
- @layer_structs[@__lg].parameters << [i, e[1]]
- @layer_structs[@__lg].type = :anim
- end
- }
- end
- @total_layers = ((@layer_structs.inject([]) { |r, i| r << i.group }).max) + 1
- @layer_structs.each { |e|
- e.parameters.sort! { |a, b| a[1] <=> b[1] } if e.type == :anim
- }
- end
- def layer_type( l ) ; return @layer_structs[l].type ; end
- def layer_bmp_count( l )
- return 1 unless layer_type( l ) == :anim
- return (@layer_structs[l].parameters.inject(0) { |r, pz|
- r = pz[1] if pz[1] > r ; r }) + 1
- end
- end
- def self.get_tilebit( index, sbitmap )
- bitmap = Bitmap.new( TILESIZE, TILESIZE )
- bitmap.blt( 0, 0,
- sbitmap, Rect.new(
- TILESIZE * (index % (sbitmap.width/TILESIZE)),
- TILESIZE * (index / (sbitmap.width/TILESIZE)),
- TILESIZE, TILESIZE )
- )
- return bitmap
- end
- def self.read_tileset_tmx( filename )
- File.open( filename ) { |f|
- f.each_line { |l|
- case l
- when /<image source="(.*)" width="(\d+)" height="(\d+)"\/>/i
- return $1
- end
- }
- }
- end
- def self.read_tmx( filename )
- @__layer_id = -1
- @__read_layer = 0
- @__tcount = 0
- @__x_count = 0
- @__y_count = 0
- @__layers = []
- @__bitmaps = []
- @__layerprops = []
- @__readprops = 0
- File.open( filename ) { |f|
- f.each_line { |l|
- #puts l
- case l
- when /<map version="(.*)" orientation="(\w+)" width="(\d+)" height="(\d+)" tilewidth="(\d+)" tileheight="(\d+)">/i
- @__map = Table.new( $3.to_i, $4.to_i, 1 ) { 0 }
- @__box = BoxStruct.new( $3.to_i, $4.to_i )
- when /<layer name="(.*)" width="(\d+)" height="(\d+)"/i # >
- @__layer_id += 1
- @__layerprops[@__layer_id] ||= []
- @__layers[@__layer_id] = Table.new( @__map.xsize, @__map.ysize )
- @__tcount = 0
- when /<properties>/i
- @__readprops = 1
- when /<\/properties>/i
- @__readprops = 0
- when /<property name="(.*)" value="(.*)"\/>/i
- next unless @__readprops == 1
- pr, vl = $1, $2
- case pr.upcase
- when "LAYERGROUP"
- @__layerprops[@__layer_id] << [:layergroup, vl.to_i]
- when "ANIMLAYER"
- @__layerprops[@__layer_id] << [:animlayer, vl.to_i]
- end
- when /<tileset firstgid="(\d+)" source="(.*)"\/>/i
- @__bitmaps << read_tileset_tmx("Graphics/System/extra_tiles/"+$2)
- when /<data>/i
- @__read_layer = 1
- when /<\/data>/i
- @__read_layer = 0
- when /<tile gid="(\d+)"\/>/i
- tid = $1.to_i
- next unless @__read_layer == 1
- @__x_count = (@__tcount % @__box.width)
- @__y_count = (@__tcount / @__box.width)
- @__layers[@__layer_id][@__x_count, @__y_count] = tid
- @__tcount += 1
- end
- }
- }
- @__map.resize( @__box.width, @__box.height, @__layers.size )
- for x in 0...@__map.xsize
- for y in 0...@__map.ysize
- for z in 0...@__map.zsize
- @__map[x, y, z] = @__layers[z][x, y]
- end
- end
- end
- ms = MapStruct.new()
- ms.map_data = @__map
- ms.layer_props = @__layerprops
- ms.bitmaps = @__bitmaps
- ms.setup_layers()
- return ms
- end
- attr_accessor :ox
- attr_accessor :oy
- attr_accessor :z
- attr_reader :viewport
- def initialize( viewport )
- @viewport = viewport
- @disposed = false
- @layers = []
- @layer_bitmaps = []
- @bitmaps = []
- @ox, @oy = 0, 0
- @z = 0
- @map_struct = nil
- @anim_rate = 12
- @anim_index = Graphics.frame_count / @anim_rate
- @last_anim_index = -1
- end
- def viewport=( newview )
- @viewport = newview
- @layers.each { |l| l.viewport = @viewport }
- end
- def create_layer_bitmap()
- return Bitmap.new(@map_data.xsize*TILESIZE, @map_data.ysize*TILESIZE)
- end
- # // MapStruct
- def setup( map_struct )
- @map_struct = map_struct
- @map_data = map_struct.map_data
- bitmaps = map_struct.bitmaps
- @layers.each { |l| l.dispose() } ; @layers.clear()
- @layer_bitmaps.each { |a| a.each { |b| b.dispose() } } ; @layer_bitmaps.clear()
- ans = @map_struct.total_layers
- ans.times { |i|
- @layers[i] = Plane.new()
- @layer_bitmaps[i] = []
- case @map_struct.layer_type(i)
- when :anim
- @map_struct.layer_bmp_count(i).times { @layer_bitmaps[i] << create_layer_bitmap() }
- when :normal
- @layer_bitmaps[i] = [create_layer_bitmap()]
- end
- }
- @layers.each { |l| l.viewport = @viewport }
- @bitmaps = bitmaps.inject([]) { |r, e| r << Cache.system("extra_tiles/"+e) }
- refresh_layer_bitmaps()
- refresh()
- end
- def layer_z( i )
- @map_struct.layer_structs[i].group * 50
- end
- def refresh_layer_bitmaps
- for i in 0...@layers.size ; refresh_layer_bitmap( i ) ; end
- end
- def refresh_layer_bitmap( i )
- @layers[i].bitmap = @layer_bitmaps[i][@anim_index%@layer_bitmaps[i].size]
- end
- def draw_tile( x, y, tile_id, bitmap )
- b = self.class.get_tilebit( tile_id-PARENT_IDS[tile_id], @bitmaps[TILESET[tile_id]] )
- bitmap.blt( x*TILESIZE, y*TILESIZE, b, b.rect ) ; b.dispose()
- end
- def get_layer_id( z )
- return @map_struct.layer_props[z].inject( 0 ) { |r,a|
- r = a[1] if a[0] == :layergroup ; r
- }
- end
- def refresh()
- for x in 0...@map_data.xsize
- for y in 0...@map_data.ysize
- for ly in 0...@map_struct.total_layers
- case @map_struct.layer_type(ly)
- when :anim
- for ma in @map_struct.layer_structs[ly].parameters
- z = ma[0]
- next unless @map_data[x, y, z] > 0
- draw_tile( x, y,
- @map_data[x, y, z], @layer_bitmaps[get_layer_id(z)][ma[1]] )
- end
- when :normal
- for mz in @map_struct.layer_structs[ly].map_zs
- next unless @map_data[x, y, mz] > 0
- draw_tile( x, y,
- @map_data[x, y, mz], @layer_bitmaps[get_layer_id(mz)][0] )
- end
- end
- end
- end
- end
- end
- def disposed?() ; return @disposed ; end
- def dispose()
- @layers.each { |l| l.bitmap.dispose() ; l.dispose() }
- @disposed = true
- end
- def update()
- @anim_index = Graphics.frame_count / @anim_rate
- for i in 0...@layers.size
- refresh_layer_bitmap( i ) if @last_anim_index != @anim_index
- @layers[i].ox, @layers[i].oy, @layers[i].z = self.ox, self.oy, self.z + layer_z(i)
- end
- @last_anim_index = @anim_index
- end
- end
- mp = ISS::TMX_Tilemap.read_tmx( "testmap.tmx" )
- tilemap = ISS::TMX_Tilemap.new( Viewport.new( 0, 0, mp.width*16, mp.height*16 ) )
- tilemap.setup( mp ) # // MapStruct
- tilemap.z = 100
- loop do
- Graphics.update()
- tilemap.update
- #tilemap.ox += 1
- #tilemap.oy += 1
- end
Advertisement
Add Comment
Please, Sign In to add comment