А за чем переменной события десятичная дробь? я лично не вижу как это можно использовать.
Касаемо меня, я пока что ничего не думаю. Судя по постам на некоторых сайтах, в VX этот класс сильно изменился. Кроме того, на VX я не нашёл ни одной пользовательской реализации, а на XP сразу несколько. Пока надо спокойно изучить и посмотреть что к чему. Всё-таки надо его не просто переписать, а переписать так, чтобы он заработал на обоих мэйкерах.Господа, так что вы думаете касательно Tilemap?
Там же и приступим к тесту на практике.
Ну и нормально. Разве где-то они могут понадобиться?Кстати, вы замечали, что Maker на дух не переносит числа с плавающей точкой?
Естественно! Вот выдвигаешь ты окошко из-за границы экрана. Размер окошка произвольный, размер экрана произвольный, высчитываешь шаг и... окошко остается за границами экрана. А все потому, что при попытке сдвинуть его на 0.4 пикселя влево, вместо того чтобы запомнить 0.4 для следующих операций, мейкер его просто отбрасывает! Я когда писал скрипт системы диалогов специально под такие вычисления хэш заводил, для хранения дробной части.
Хм, мне казалось, что я спер этот скрипт именно с VX:
Впрочем, может, и ошибаюсь. Поскольку он закрыт и нам остаются лишь методы метапрограммирования для его изучения, то о том, что внутри самих методов остается лишь гадать. Следовательно, извлекаем интерфейсы, объединяем, пишем на основе получившегося интерфейса класс. И что там будет внутри - мейкеров не касается. Разная обработка тайлсета. Вероятно, будут различатсья ID автотайлов. По сути всё.Код:#=============================================================================== # Custom Tilemap v1.2 # Автор оригинала: poccil # Над скриптом измывались: Equilibrium Keeper [ICQ: 470355387] #=============================================================================== class CustomTilemapAutotiles #----------------------------------------------------------------------------- attr_accessor :changed #----------------------------------------------------------------------------- # Инициализация #----------------------------------------------------------------------------- def initialize @changed = true @tiles = [nil, nil, nil, nil, nil, nil, nil] end #----------------------------------------------------------------------------- # Задает новый тайл #----------------------------------------------------------------------------- def []=(i, value) @tiles[i] = value @changed = true end #----------------------------------------------------------------------------- # Возвращаем тайл #----------------------------------------------------------------------------- def [](i) return @tiles[i] end #----------------------------------------------------------------------------- end #=============================================================================== # Класс, управляющий картами тайла. Карты тайла - специализированное понятие в # отображении карт 2D игр, созданный внутренне от множества спрайтов. #=============================================================================== class Tilemap #----------------------------------------------------------------------------- # Константы #----------------------------------------------------------------------------- Resize_Factor = 1.0 Animated_Autotiles_Frames = 15 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] ] ] FlashOpacity = [100, 90, 80, 70, 80, 90] #----------------------------------------------------------------------------- # Аттрибуты #----------------------------------------------------------------------------- attr_reader :tileset attr_reader :autotiles attr_reader :map_data attr_reader :visible attr_reader :viewport attr_accessor :flash_data attr_accessor :priorities attr_accessor :ox attr_accessor :oy #----------------------------------------------------------------------------- # Инициализация # viewport :viewport - область просмотра #----------------------------------------------------------------------------- def initialize(viewport = nil) @viewport = viewport ? viewport : Viewport.new(0, 0, Graphics.width, Graphics.height) @autotiles = CustomTilemapAutotiles.new @visible = true # Refers to Tileset Visibleness @ox = 0 # Bitmap Offsets @oy = 0 # bitmap Offsets @tiles = [] @autotileInfo = [] @regularTileInfo = [] @oldOx = 0 @oldOy = 0 @layer0 = Sprite.new(viewport) @layer0.visible = true @layer0.bitmap = Bitmap.new(@viewport.rect.width * 2, @viewport.rect.height * 2) @layer0.ox = 0 @layer0.oy = 0 @oxLayer0 = 0 @oyLayer0 = 0 @oxFlash = 0 @oyFlash = 0 @layer0.z = 0 @priotiles = [] @prioautotiles = [] @autosprites = [] @framecount = [] @tileset_changed = true @firsttime = true @layer0clip = true @firsttimeflash = true end #----------------------------------------------------------------------------- # Возвращает TRUE, если карта тайлов была освобождёна. #----------------------------------------------------------------------------- def disposed? return @disposed end #----------------------------------------------------------------------------- # Освобождает карту тайлов. Если карта тайлов уже была освобождёна, не делает # ничего. #----------------------------------------------------------------------------- def dispose return if disposed? @help.free @autotileInfo.free @regularTileInfo.free @tiles.free @autosprites.free @layer0.free @flash.free self.autotiles.free @priorities.free @disposed = true end #----------------------------------------------------------------------------- # Задает новое значение вспышки #----------------------------------------------------------------------------- def flash_data=(value) @flash_data = value @flash_changed = true end #----------------------------------------------------------------------------- # Обновляет анимацию динамических тайлов и др. Как правило, этот метод # вызывается один раз за кадр. #----------------------------------------------------------------------------- def update if @autotiles.changed refresh_autotiles repaint_autotiles end if @flash_changed refresh_flash end if @tileset_changed refresh_tileset end if @flash.exists? @flash.opacity = FlashOpacity[(Graphics.frame_count / 2) % 6] end unless (@oldOx == @ox && @oldOy == @oy && !@tileset_changed && !@autotiles.changed) refresh end if (Graphics.frame_count % Animated_Autotiles_Frames == 0) && shown? repaint_autotiles refresh(false) end @nowshown = false @autotiles.changed = false @tileset_changed = false end #----------------------------------------------------------------------------- # Задает новую таблицу приоритетов #----------------------------------------------------------------------------- def priorities=(value) @priorities = value @tileset_changed = true end #----------------------------------------------------------------------------- # Задает новый тайлсет #----------------------------------------------------------------------------- def tileset=(value) @tileset = value @tileset_changed = true end #----------------------------------------------------------------------------- # Отображено #----------------------------------------------------------------------------- def shown? return false unless @visible start_x = ((@ox / 32) - 1).limit(0, @map_data.xsize - 1) start_y = ((@oy / 32) - 1).limit(0, @map_data.ysize - 1) end_x = (((@ox + @viewport.rect.width) / 32) + 1).limit(0, @map_data.xsize - 1) end_y = (((@oy + @viewport.rect.height) / 32) + 1).limit(0, @map_data.ysize - 1) return (start_x < end_x && start_y < end_y) end #----------------------------------------------------------------------------- # Рисует автотайлы #----------------------------------------------------------------------------- def bltAutotile(bitmap, x, y, id, frame) return if frame < 0 autotile = @autotiles[id / 48 - 1] return unless autotile if autotile.height == 32 anim=frame*32 src_rect=Rect.new(anim,0,32,32) bitmap.blt(x,y,autotile,src_rect) else anim=frame*96 id%=48 tiles = Autotiles[id>>3][id&7] src=Rect.new(0,0,0,0) for i in 0...4 tile_position = tiles[i] - 1 src.set(tile_position % 6 * 16 + anim, tile_position / 6 * 16, 16, 16) bitmap.blt(i%2*16+x,i/2*16+y, autotile, src) end end end #----------------------------------------------------------------------------- # ??? #----------------------------------------------------------------------------- def autotileNumFrames(id) autotile = @autotiles[id / 48 - 1] return 0 unless autotile.exists? frames = 1 if autotile.height == 32 frames = autotile.width / 32 else frames = autotile.width / 96 end return frames end #----------------------------------------------------------------------------- # ??? #----------------------------------------------------------------------------- def autotileFrame(id) autotile = @autotiles[id / 48 - 1] return -1 unless autotile.exists? frames = 1 if autotile.height == 32 frames = autotile.width / 32 else frames = autotile.width / 96 end return (Graphics.frame_count / Animated_Autotiles_Frames) % frames end #----------------------------------------------------------------------------- # Перерисовка автотайлов #----------------------------------------------------------------------------- def repaint_autotiles for i in 0...@autotileInfo.length next if !@autotileInfo[i] frame=autotileFrame(i) bltAutotile(@autotileInfo[i],0,0,i,frame) end end #----------------------------------------------------------------------------- # Возвращает автотайл #----------------------------------------------------------------------------- def getAutotile(sprite, id) anim = autotileFrame(id) return if anim < 0 bitmap = @autotileInfo[id] unless bitmap bitmap = Bitmap.new(32, 32) bltAutotile(bitmap, 0, 0, id, anim) @autotileInfo[id] = bitmap end sprite.bitmap = bitmap if !sprite.equal?(bitmap) || sprite.bitmap != bitmap end #----------------------------------------------------------------------------- # Добавляем тайл #----------------------------------------------------------------------------- def addTile(tiles, count, xpos, ypos, id) if id >= 384 if count >= tiles.length sprite = Sprite.new(@viewport) tiles.push(sprite, 0) else sprite = tiles[count] tiles[count + 1] = 0 end sprite.visible = @visible sprite.x = xpos sprite.y = ypos sprite.bitmap = RPG::Cache.tile(@tileset, id, 0) spriteZ = (@priorities[id] == 0 || !@priorities[id]) ? 0 : ypos + @priorities[id] * 32 + 32 sprite.z = spriteZ count += 2 else if count >= tiles.length sprite = Sprite.new(@viewport) tiles.push(sprite, 1) else sprite = tiles[count] tiles[count + 1] = 1 end sprite.visible = @visible sprite.x = xpos sprite.y = ypos getAutotile(sprite, id) spriteZ = (@priorities[id] == 0 || !@priorities[id]) ? 0 : ypos + @priorities[id] * 32 + 32 sprite.z = spriteZ count += 2 end return count end #----------------------------------------------------------------------------- # Освежаем тайлсет #----------------------------------------------------------------------------- def refresh_tileset @regularTileInfo.free @priotiles.free if @map_data.xsize > 100 || @map_data.ysize > 100 @fullyrefreshed = false else for z in 0...@map_data.zsize for y in 0...@map_data.ysize for x in 0...@map_data.xsize id = @map_data[x, y, z] next if id == 0 || !@priorities[id] next if @priorities[id] == 0 @priotiles.push([x, y, z, id]) end end end @fullyrefreshed = true end end #----------------------------------------------------------------------------- # Освежаем вспышку #----------------------------------------------------------------------------- def refresh_flash if @flash_data && !@flash.exists? @flash = Sprite.new(viewport) @flash.visible = true @flash.z = 1 @flash.blend_type = 1 @flash.bitmap = Bitmap.new(@viewport.rect.width * 2, @viewport.rect.height * 2) @firsttimeflash = true elsif !@flash_data && @flash.exists? @flash.free @firsttimeflash = false end end #----------------------------------------------------------------------------- # Освежаем автотайлы #----------------------------------------------------------------------------- def refresh_autotiles @autotileInfo.free @autosprites.free @prioautotiles.free hasanimated = false for i in 0...7 numframes = autotileNumFrames(48 * (i + 1)) hasanimated = true if numframes >= 2 @framecount[i] = numframes end if hasanimated if @map_data.xsize > 100 || @map_data.ysize > 100 @fullyrefreshedautos = false else for y in 0...@map_data.ysize for x in 0...@map_data.xsize haveautotile = false for z in 0...@map_data.zsize id = @map_data[x, y, z] next if id == 0 || id >= 384 || @priorities[id] != 0 || !@priorities[id] next if @framecount[id / 48 - 1] < 2 haveautotile = true break end @prioautotiles.push([x, y]) if haveautotile end end @fullyrefreshedautos = true end else @fullyrefreshedautos = true end end #----------------------------------------------------------------------------- # Задаем новую map_data #----------------------------------------------------------------------------- def map_data=(value) @map_data = value @tileset_changed = true end #----------------------------------------------------------------------------- # Освежаем спрайт вспышки #----------------------------------------------------------------------------- def refreshFlashSprite return if !@flash.exists? || @flash_data.nil? ptX = @ox - @oxFlash ptY = @oy - @oyFlash if !@firsttimeflash && !@usedsprites && ptX >= 0 && ptX + @viewport.rect.width <= @flash.bitmap.width && ptY >= 0 && ptY + @viewport.rect.height <= @flash.bitmap.height @flash.ox = 0 @flash.oy = 0 @flash.src_rect.set(ptX.round, ptY.round, @viewport.rect.width,@viewport.rect.height) return end width = @flash.bitmap.width height = @flash.bitmap.height bitmap = @flash.bitmap ysize = @map_data.ysize xsize = @map_data.xsize zsize = @map_data.zsize @firsttimeflash = false @oxFlash = @ox - (width >> 2) @oyFlash = @oy - (height >> 2) @flash.ox = 0 @flash.oy = 0 @flash.src_rect.set(width >> 2, height >> 2, @viewport.rect.width, @viewport.rect.height) @flash.bitmap.clear @oxFlash = @oxFlash.floor @oyFlash = @oyFlash.floor start_x = (@oxFlash >> 5).correct(0, nil) start_y = (@oyFlash >> 5).correct(0, nil) end_x = (start_x + (width >> 5) + 1).correct(nil, xsize) end_y = (start_y + (height >> 5) + 1).correct(nil, ysize) if start_x < end_x && start_y < end_y yrange = start_y...end_y xrange = start_x...end_x tmpcolor = Color.new(0, 0, 0, 0) for y in yrange ypos = (y << 5) - @oyFlash for x in xrange xpos = (x << 5) - @oxFlash id = @flash_data[x, y, 0] r = (id >> 8) & 15 g = (id >> 4) & 15 b = (id) & 15 tmpcolor.set(r * 16, g * 16, b * 16) bitmap.fill_rect(xpos, ypos, 32, 32, tmpcolor) end end end end #----------------------------------------------------------------------------- # Обновляем слой спрайтов #----------------------------------------------------------------------------- def refreshLayer0(autotiles = false) ptX = @ox - @oxLayer0 ptY = @oy - @oyLayer0 if !autotiles && !@firsttime && !@usedsprites && ptX >= 0 && ptX+@viewport.rect.width <= @layer0.bitmap.width && ptY >= 0 && ptY+@viewport.rect.height <= @layer0.bitmap.height if @layer0clip @layer0.ox = 0 @layer0.oy = 0 @layer0.src_rect.set(ptX.round, ptY.round, @viewport.rect.width,@viewport.rect.height) else @layer0.ox = ptX.round @layer0.oy = ptY.round @layer0.src_rect.set(0, 0, @layer0.bitmap.width, @layer0.bitmap.height) end return true end width = @layer0.bitmap.width height = @layer0.bitmap.height bitmap = @layer0.bitmap ysize = @map_data.ysize xsize = @map_data.xsize zsize = @map_data.zsize if autotiles return true if @fullyrefreshedautos && @prioautotiles.length == 0 return true if !shown? start_x = (@oxLayer0 >> 5) start_x = 0 if start_x < 0 start_y = (@oyLayer0 >> 5) start_y = 0 if start_y < 0 end_x = start_x + (width >> 5) + 1 end_y = start_y + (height >> 5) + 1 end_x = xsize if end_x > xsize end_y = ysize if end_y > ysize return true if start_x >= end_x || start_y >= end_y trans = Color.new(0, 0, 0, 0) temprect = Rect.new(0, 0, 0, 0) tilerect = Rect.new(0, 0, 32, 32) range = 0...zsize overallcount = 0 count = 0 unless @fullyrefreshedautos for y in start_y..end_y for x in start_x..end_x haveautotile = false for z in range id = @map_data[x, y, z] break unless id next if id < 48 || id >= 384 || @priorities[id] != 0 || !@priorities[id] next if id == 0 || id >= 384 || @priorities[id] != 0 || !@priorities[id] next if @framecount[id / 48 - 1] < 2 haveautotile = true break end next unless haveautotile overallcount += 1 xpos = (x << 5) - @oxLayer0 ypos = (y << 5) - @oyLayer0 bitmap.fill_rect(xpos, ypos, 0, 0, trans) if overallcount <= 2000 for z in range id = @map_data[x, y, z] next if id < 48 || @priorities[id] != 0 || !@priorities[id] if overallcount > 2000 count = addTile(@autosprites, count, xpos, ypos, id) next elsif id >= 384 temprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32, 32, 32) bitmap.blt(xpos, ypos, RPG::Cache.tileset(@tileset), temprect) else tilebitmap = @autotileInfo[id] unless tilebitmap anim = autotileFrame(id) next if anim < 0 tilebitmap = Bitmap.new(32, 32) bltAutotile(tilebitmap, 0, 0, id, anim) @autotileInfo[id] = tilebitmap end bitmap.blt(xpos, ypos, tilebitmap, tilerect) end end end end else for tile in @prioautotiles x = tile[0] y = tile[1] next if x < start_x || x > end_x next if y < start_y || y > end_y overallcount += 1 xpos = (x << 5) - @oxLayer0 ypos = (y << 5) - @oyLayer0 bitmap.fill_rect(xpos, ypos, 0, 0, trans) if overallcount <= 2000 for z in range id = @map_data[x, y, z] next if id < 48 || @priorities[id] != 0 || !@priorities[id] if overallcount > 2000 count = addTile(@autosprites, count, xpos, ypos, id) next elsif id >= 384 temprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32, 32, 32) bitmap.blt(xpos, ypos, RPG::Cache.tileset(@tileset), temprect) else tilebitmap = @autotileInfo[id] unless tilebitmap anim = autotileFrame(id) next if anim < 0 tilebitmap = Bitmap.new(32, 32) bltAutotile(tilebitmap, 0, 0, id, anim) @autotileInfo[id] = tilebitmap end bitmap.blt(xpos, ypos, tilebitmap, tilerect) end end end end Graphics.frame_reset if overallcount > 2000 @usedsprites = false return true end return false if @usedsprites @firsttime = false @oxLayer0 = @ox - (width >> 2) @oyLayer0 = @oy - (height >> 2) if @layer0clip @layer0.ox = 0 @layer0.oy = 0 @layer0.src_rect.set(width >> 2, height >> 2, @viewport.rect.width, @viewport.rect.height) else @layer0.ox = (width >> 2) @layer0.oy = (height >> 2) end @layer0.bitmap.clear @oxLayer0 = @oxLayer0.floor @oyLayer0 = @oyLayer0.floor start_x = (@oxLayer0 >> 5) start_x = 0 if start_x < 0 start_y = (@oyLayer0 >> 5) start_y = 0 if start_y < 0 end_x = start_x + (width >> 5) + 1 end_y = start_y + (height >> 5) + 1 end_x = xsize if end_x >= xsize end_y = ysize if end_y >= ysize if start_x < end_x && start_y < end_y tmprect = Rect.new(0, 0, 0, 0) yrange = start_y...end_y xrange = start_x...end_x for z in 0...zsize for y in yrange ypos = (y << 5) - @oyLayer0 for x in xrange xpos = (x << 5) - @oxLayer0 id = @map_data[x, y, z] next if id == 0 || @priorities[id] != 0 || !@priorities[id] if id >= 384 tmprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32, 32, 32) bitmap.blt(xpos, ypos, RPG::Cache.tileset(@tileset), tmprect) else frame = autotileFrame(id) bltAutotile(bitmap, xpos, ypos, id, frame) end end end end Graphics.frame_reset end return true end #----------------------------------------------------------------------------- # Задаем новое значение координате ox #----------------------------------------------------------------------------- def ox=(val) val = (val * Resize_Factor).to_i val = (val / Resize_Factor).to_i wasshown = self.shown? @ox = val.floor @nowshown = (!wasshown && self.shown?) end #----------------------------------------------------------------------------- # Задаем новое значение координате oy #----------------------------------------------------------------------------- def oy=(val) val = (val * Resize_Factor).to_i val = (val / Resize_Factor).to_i wasshown = self.shown? @oy = val.floor @nowshown = (!wasshown && self.shown?) end #----------------------------------------------------------------------------- # Задаем новое значение показателю видимости #----------------------------------------------------------------------------- def visible=(val) wasshown = @visible @visible = val @nowshown = (!wasshown && val) end #----------------------------------------------------------------------------- # Освежаем #----------------------------------------------------------------------------- def refresh(autotiles = false) @oldOx = @ox @oldOy = @oy usesprites = false if @layer0 @layer0.visible = @visible usesprites = !refreshLayer0(autotiles) if autotiles && !usesprites return end else usesprites = true end refreshFlashSprite vpx = @viewport.rect.x vpy = @viewport.rect.y vpr = @viewport.rect.width + vpx vpb = @viewport.rect.height + vpy xsize = @map_data.xsize ysize = @map_data.ysize min_x = ((@ox / 32) - 1).limit(0, xsize - 1) min_y = ((@oy / 32) - 1).limit(0, ysize - 1) max_x = (((@ox + @viewport.rect.width) / 32) + 1).limit(0, xsize - 1) max_Y = (((@oy + @viewport.rect.height) / 32) + 1).limit(0, ysize - 1) count = 0 if min_x < max_x && min_y < max_Y @usedsprites = usesprites || @usedsprites if @layer0 @layer0.visible = false if usesprites end if @fullyrefreshed for prio in @priotiles next if prio[0] < min_x || prio[0] > max_x next if prio[1] < min_y || prio[1] > max_Y id = prio[3] xpos = (prio[0] << 5) - @ox ypos = (prio[1] << 5) - @oy count = addTile(@tiles, count, xpos, ypos, id) end else for z in 0...@map_data.zsize for y in min_y..max_Y for x in min_x..max_x id = @map_data[x, y, z] next if id == 0 || !@priorities[id] next if @priorities[id] == 0 xpos = (x << 5) - @ox ypos = (y << 5) - @oy count = addTile(@tiles, count, xpos, ypos, id) end end end end end if count < @tiles.length bigchange = (count <= (@tiles.length * 2 / 3)) && (@tiles.length * 2 / 3) > 25 j = count; len = @tiles.length; while j < len sprite = @tiles[j] @tiles[j + 1] = -1 if bigchange sprite.dispose @tiles[j] = nil @tiles[j + 1] = nil elsif !@tiles[j].disposed? sprite.visible = false if sprite.visible end j += 2 end @tiles.compact! if bigchange end end #----------------------------------------------------------------------------- end
Кстати да, с легкописностью общих слоев я погорячился. Все немножко сложнее - слоев будет не 3, а 3 * N, где N - количество возможных приоритетов. Но, в любом случае, лучше 18 спрайтов, чем 40000.
Последний раз редактировалось Equilibrium Keeper; 04.09.2011 в 20:47.
Как я понял ты имеешь в виду сделать неограниченное количество слоёв, используя много карт и как бы накладывая их друг на друга. Это можно сделать небольшим редактированием Spriteset_Map без всяких этих Rpg::Tilemap. Кстати это позволит использовать несколько тайлов одновременно. (но как это сделать для обоих мэйкеров мне неизвестно)
Насчёт десятичных дробей. Может в Window есть какой то скрытый round.
Последний раз редактировалось Andrew; 11.09.2011 в 18:21.
Andrew
Ты немного неверно понимаешь ситуацию. Тут идет переписывание базовых классов, включая Tilemap, и возможность наложения карт - не цель, а плюшка. (=
А хочу я оптимизировать тайловую систему мейкера, чтобы вместо сотен спрайтов с крошечными картинками, было несколько спрайтов с огромными картинками. Такой набор легче обрабатывать, как программисту, так и программе (тем более однопоточной). Это, конечно, в нормальном языке программирования. Мейкер может подложить свинью, если, к примеру, работа с большими изображениями изначально кривая. Тогда это наоборот выйдет боком. Надо тестить.
Код:module RPG ## # Класс с данными игровой локации. ## class Map #========================================================================== # Атрибуты #========================================================================== # ID набора тайлов, используемого в локации. # @note Используется в XP. # @return [Integer] attr_accessor :tileset_id # Ширина (в тайлах). # @return [Integer] attr_accessor :width # Высота (в тайлах). # @return [Integer] attr_accessor :height # Зацикливание (0: нет, 1: вертикальное, 2: горизонтальное, 3: оба) # @note Используется в VX. # @return [Integer] attr_accessor :scroll_type # Определяет, будет ли изменена фоновая музыка при переходе на локацию. # @return [Boolean] attr_accessor :autoplay_bgm # Фоновая музыка. # @return [RPG::AudioFile] attr_accessor :bgm # Определяет, будут ли изменены фоновые звуки при переходе на локацию. # @return [Boolean] attr_accessor :autoplay_bgs # Фоновые звуки. # @return [RPG::AudioFile] attr_accessor :bgs # Флаг активности опции "Бегать запрещено" # @note Используется в VX. # @return [Boolean] attr_accessor :disable_dashing # Список ID встречающихся на карте групп врагов. # @return [Array<Integer>] attr_accessor :encounter_list # Количество шагов между встречами с врагами. # @return [Integer] attr_accessor :encounter_step # Название файла, использующегося в качестве панорамы (графики фона) локации. # @note Используется в VX. # @return [String] attr_accessor :parallax_name # Определяет, зациклена ли панорама по горизонтале. # @note Используется в VX. # @return [Boolean] attr_accessor :parallax_loop_x # Определяет, зациклена ли панорама по вертикале. # @note Используется в VX. # @return [Boolean] attr_accessor :parallax_loop_y # Скорость движения панорамы по горизонтале. Знак определяет направление. # @note Используется в VX. # @return [Boolean] attr_accessor :parallax_sx # Скорость движения панорамы по вертикале. Знак определяет направление. # @note Используется в VX. # @return [Boolean] attr_accessor :parallax_sy # Определяет, следует ли отображать панораму в редакторе. # @note Используется в VX. # @return [Boolean] attr_accessor :parallax_show # Данные карты. 3-мерный массив ID тайлов. # @return [Table] attr_accessor :data # События карты. # @note Хэш, в котором ключ - ID события, значение - его экземпляр. # @return [Hash<Integer, RPG::Event>] attr_accessor :events #========================================================================== # Методы #========================================================================== ## # Инициализирует переменные экземпляра, присваивает им значения по умолчанию # # @param [Integer] width Ширина новой игровой локации (в тайлах). # @param [Integer] height Высота новой игровой локации (в тайлах). # # @note Вызывается автоматически при создании нового экземпляра # # @return [NilClass] ## def initialize(width, height) @tileset_id = 1 @width = width @height = height @scroll_type = 0 @autoplay_bgm = false @bgm = RPG::AudioFile.new @autoplay_bgs = false @bgs = RPG::AudioFile.new("", 80) @disable_dashing = false @encounter_list = [] @encounter_step = 30 @parallax_name = "" @parallax_loop_x = false @parallax_loop_y = false @parallax_sx = 0 @parallax_sy = 0 @parallax_show = false @data = Table.new(width, height, 3) @events = {} end # ------------------------------------------------------------------------- end # --------------------------------------------------------------------------- endКод:module RPG ## # Класс с данными информации об игровой локации. ## class MapInfo #========================================================================== # Атрибуты #========================================================================== # Название карты. # @return [String] attr_accessor :name # ID родительской карты. # @return [Integer] attr_accessor :parent_id # Индекс узла в дереве карт. # @note Используется в редакторе. # @return [Integer] attr_accessor :order # Определяет развернуто ли древо карт. # @note Используется в редакторе. # @return [Boolean] attr_accessor :expanded # Положение горизонтального ползунка прокрутки карты. # @note Используется в редакторе. # @return [Integer] attr_accessor :scroll_x # Положение вертикального ползунка прокрутки карты. # @note Используется в редакторе. # @return [Integer] attr_accessor :scroll_y #========================================================================== # Методы #========================================================================== ## # Инициализирует переменные экземпляра, присваивает им значения по умолчанию # # @note Вызывается автоматически при создании нового экземпляра # # @return [NilClass] ## def initialize @name = "" @parent_id = 0 @order = 0 @expanded = false @scroll_x = 0 @scroll_y = 0 end # ------------------------------------------------------------------------- end # --------------------------------------------------------------------------- endКод:module RPG ## # Класс с данными команды [Move] ("Переместить"). ## class MoveCommand(code = 0, parameters = []) #========================================================================== # Атрибуты #========================================================================== # Код комманды. # @return [Integer] attr_accessor :code # Массив, содержащий аргументы команды [Move] ("Переместить"). # @note Содержание массива изменяется в зависимости от команды. # @return [Array<Object>] attr_accessor :parameters #========================================================================== # Методы #========================================================================== ## # Инициализирует переменные экземпляра, присваивает им значения по умолчанию # # @note Вызывается автоматически при создании нового экземпляра # # @return [NilClass] ## def initialize @code = code @parameters = parameters end # ------------------------------------------------------------------------- end # --------------------------------------------------------------------------- endБеру RPG::StateКод:module RPG ## # Класс с данными маршрута движения. ## class MoveRoute #========================================================================== # Атрибуты #========================================================================== # Флаг активности опции "Повторять действия". # @return [Boolean] attr_accessor :repeat # Флаг активности опции "Перейти к следующему шагу, если движение невозможно", # @return [Boolean] attr_accessor :skippable # Флаг активности опции "Ждать окончания движения". # @note Используется в VX. # @return [Boolean] attr_accessor :wait # Список комманд движения, определяющих маршрут следования. # @return [Array<RPG::MoveCommand>] attr_accessor :list #========================================================================== # Методы #========================================================================== ## # Инициализирует переменные экземпляра, присваивает им значения по умолчанию # # @note Вызывается автоматически при создании нового экземпляра # # @return [NilClass] ## def initialize @repeat = true @skippable = false @wait = false @list = [RPG::MoveCommand.new] end # ------------------------------------------------------------------------- end # --------------------------------------------------------------------------- end
Господа, кто-нибудь, берите RPG::System и его подклассы. У меня времени не будет его сводить расписывать.
Ну-с? Что за затишье? Жду ответа.
Кип, я сейчас в раздумьях насчёт того, что нам может предложить VXAce. Если в нём будут исправления слоёв и тайлсетов — можно с гарантией утверждать, что XP и VX уйдут в прошлое.
Скорее всего в нём будут три разных RTP, а это позволяет с высокой степенью вероятности предположить возврат к тайлсетам XP. Надеюсь дебилизма с переключением между RTP не будет. Хотя и в этом случае можно придумать неплохое решение.
Переход на RGSS3 (а не 2.5) также говорит о том, что базовые классы подверглись суровой переписке под новый редактор. Тут есть два хороших момента.
Первый. Вполне возможно, что классы переписали более эффективно и они имеют больше возможностей (в VX такое было).
Второй. Очень вероятно, что в VXAce будет использоваться Ruby 1.9, который в разы быстрее 1.8.1 из VX и XP. Известно, что Ruby 1.9 вышел на несколько дней позже релиза VX, поэтому была использована старая версия. Но для VXAce, думаю, переход к новой ветке должен состояться. Надеюсь, по крайней мере.
И ещё один, последний тезис. В середине 2004-го вышел XP, затем спустя 3.5 года VX и ещё спустя 4 года готовится VXAce. Логично предположить выход следующего за ним мэйкера аж в конце 2015-го года.
Суммируя всё вышесказанное, предлагаю пару месяцев обождать, пока выйдет VXAce и посмотреть на его возможности. Хоть и верится с трудом, но он может стать довольно серьёзной вещью. И поскольку следующий мэйкер будет только через 4 года, то лучше всего продолжать наш проект с обязательной оглядкой на VXAce и только после его выхода. Не исключено, что концепция OpenRGSS3 может полностью измениться.
Разумеется, это всё я выдвинул в качестве предложения. Если решишь продолжить, то продолжим.
Последний раз редактировалось mephis; 02.10.2011 в 08:05.
Не слышал о VXAce, так что полностью поддерживаю. Если он ничем не будет уступать XP (или это можно будет компенсировать), то за основу нужно будет брать его. Уйдут сотни килобайт кода ориентированного на совместимость. В общем, мы - ждем, а я - гуглю, это чудо.
Ну, а после выхода нужно будет в темпе вальса распотрошить сие чудо. Кстати, можно связаться с разрабами? Я, черт возьми, хочу поддержку высоких разрешений!
По причине выхода VXAce разработка OpenRGSS3 заморожена. Если она будет возобновлена, то уже в совсем ином ключе. Всем участникам - спасибо.
Эту тему просматривают: 2 (пользователей: 0 , гостей: 2)
Социальные закладки