扫描二维码关注官方公众号
返回列表
+ 发新帖
查看: 100|回复: 0

[转载发布] 支援RMXP的Tilemap

[复制链接]
累计送礼:
0 个
累计收礼:
0 个
  • TA的每日心情
    开心
    5 小时前
  • 签到天数: 114 天

    连续签到: 4 天

    [LV.6]常住居民II

    2338

    主题

    403

    回帖

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    6
    卡币
    10607
    OK点
    16
    推广点
    0
    同能卷
    0
    积分
    13376

    灌水之王

    发表于 2024-4-19 16:39:22 | 显示全部楼层 |阅读模式
    終於將RMXP的Tilemap研究出來了
    跟原版的差不多
    但在使用flash_data的部份有點卡
    希望能討論下
    畢竟RUBY不能贏VC
    以下是腳本
    1. class Tilemap  WIN_W = 640  WIN_H = 480  AREA_W = 32  AREA_H = 32  AREA_X = WIN_W / AREA_W  AREA_Y = WIN_H / AREA_H  ANI_T = 20  #動畫等待時間(單位:畫格)  FLA_T = 4   #閃爍等待時間(單位:畫格)  FLA_O=[110,100,90,80,70,80,90,100] #畫面閃爍變化  #畫自動元件用  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 :viewport  #--------------------------------------------------------------------------  # ● 初始化物件  # 內部使用以 @@ 開頭  #--------------------------------------------------------------------------  def initialize(viewport = Viewport.new(0,0,WIN_W,WIN_H))    @autotiles = []    @tileset = nil    @map_data = nil    @flash_data = nil    @priorities = nil    @visible = true    @ox = 0    @oy = 0    @viewport = viewport        @@sprite = {} #元件Sprite    @@cache = {} #元件Cache    @@ani_switch = {} #動畫開關    @@count = 0 #當前顯示動畫    @@counting = 0 #動畫等待畫格    @@flash_layer = nil #畫面閃爍用    @@flash_count = 0 #當前閃爍動畫    @@flash_counting = 0 #閃爍等待畫格    @@last_ox = 0    @@last_oy = 0    @@disposed = false  end  #--------------------------------------------------------------------------  # ● 釋放  #--------------------------------------------------------------------------  def dispose    return if @@disposed    for i in @@cache.values      if i.is_a?(Bitmap)        i.dispose      else        for j in i.values          j.dispose        end      end    end    for i in @@sprite.values      i.dispose    end    @@flash_layer.dispose if @@flash_layer != nil    @@flash_layer.bitmap.dispose if @@flash_layer != nil    @@disposed = true  end  def dispose?    return @@disposed  end  #--------------------------------------------------------------------------  # ● 載入地圖資訊  # 載入後繪製地圖  #--------------------------------------------------------------------------  def map_data    return @map_data  end  def map_data=(data)    @map_data = data    return if @map_data.nil?    # 建立地圖元件Cache(方法一) BEGIN    # 地圖較大時不適用    #for x in 0...@map_data.xsize    #  for y in 0...@map_data.ysize    #    for l in 0..2    #      cache_bitmap(@map_data[x, y, l])    #    end    #  end    #end    # 建立地圖元件Cache(方法一) END    # 建立地圖元件Cache(方法二) BEGIN    # 元件圖較大時不適用    for auto in 0..6      next if @autotiles[auto].nil?      for i in 0...48        cache_bitmap(auto * 48 + i)      end    end    if @tileset != nil      for y in [email protected] / AREA_H        yy = y * 8        for x in 0...8          cache_bitmap(yy + x + 384)        end      end    end    # 建立地圖元件Cache(方法二) END    # 描繪地圖元件 BEGIN    range_x = (@ox + WIN_W) / AREA_W    range_y = (@oy + WIN_H) / AREA_H    range_x = [range_x, WIN_W / AREA_W - 1].min if @map_data.xsize * AREA_W = @map_data.xsize    x += @map_data.xsize if x < 0    y -= @map_data.ysize if y >= @map_data.ysize    y += @map_data.ysize if y < 0    id = @map_data[x, y, l]    return if id == 0    unless @@sprite[[x, y, l]].nil?      @@sprite[[x, y, l]].x = x0 * AREA_W - @ox      @@sprite[[x, y, l]].y = y0 * AREA_H - @oy      return if @priorities.nil?      z = @priorities[id] == 0 ? 0 : 32 * (1 + @@sprite[[x, y, l]].y / AREA_H + @priorities[id])      z = 0 if z < 0       @@sprite[[x, y, l]].z = z      return    end    @@sprite[[x, y, l]] = Sprite.new(@viewport)    @@sprite[[x, y, l]].x = x0 * AREA_W - @ox    @@sprite[[x, y, l]].y = y0 * AREA_H - @oy    @@sprite[[x, y, l]].z = l    @@sprite[[x, y, l]].bitmap = cache_bitmap(id)    if id < 384      if @@cache[id].length > 1        #動畫        @@ani_switch[[x, y, l]] = true        @@sprite[[x, y, l]].bitmap = @@cache[id][@@count % @@cache[id].length]      end    end    return if @priorities.nil?    z = @priorities[id] == 0 ? 0 : 32 * (1 + @@sprite[[x, y, l]].y / AREA_H + @priorities[id])    z = 0 if z < 0     @@sprite[[x, y, l]].z = z  end  #--------------------------------------------------------------------------  # ● 繪製地圖元件閃爍  #--------------------------------------------------------------------------  def draw_flash    return if @flash_data.nil?    return if @flash_data.xsize 0,'b'=>0}        tmpcolor.set(rgb['r']*16,rgb['g']*16,rgb['b']*16)        @@flash_layer.bitmap.fill_rect(x*AREA_W,y*AREA_H,AREA_W,AREA_H,tmpcolor)      end    end    @@flash_layer.opacity=FLA_O[@@flash_count]  end  #--------------------------------------------------------------------------  # ● 設定地圖座標  #--------------------------------------------------------------------------  def ox    return @ox  end  def oy    return @oy  end  def ox=(ox)    return if @ox == ox    @@last_ox = @ox if @@last_ox == @ox    @ox = ox    @@flash_layer.ox = ox % WIN_W if @@flash_layer != nil    return @ox  end  def oy=(oy)    return if @oy == oy    @@last_oy = @oy if @@last_oy == @oy    @oy = oy    @@flash_layer.oy = oy % WIN_H if @@flash_layer != nil    return @oy  end  #--------------------------------------------------------------------------  # ● 設定地圖顯示  #--------------------------------------------------------------------------  def visible    return @visible  end  def visible=(value)    @visible = value    for i in @@sprite.values      i.visible = @visible    end    @@flash_layer.visible = @visible    return @visible  end  #--------------------------------------------------------------------------  # ● 更新地圖元件閃爍  #--------------------------------------------------------------------------  def flash_data    return @flash_data  end  def flash_data=(data)    return @flash_data if @flash_data == data    @flash_data = data    draw_flash    return @flash_data  end  #--------------------------------------------------------------------------  # ● 更新地圖元件  #--------------------------------------------------------------------------  def update    # 更新動畫等待畫格    if @@counting >= ANI_T      @@counting = 0      @@count += 1      for i in @@ani_switch.keys        id = @map_data[i[0], i[1], i[2]]        @@sprite[i].bitmap = @@cache[id][@@count % @@cache[id].length]      end    else      @@counting += 1    end    # 更新閃爍等待畫格    @@flash_counting += 1    if @@flash_counting >= FLA_T      @@flash_counting = 0      @@flash_count = (@@flash_count + 1) % FLA_O.size      @@flash_layer.opacity=FLA_O[@@flash_count] if @@flash_layer != nil    end    if @ox != @@last_ox      #人物走路時候      if @ox % (AREA_W / 2) != 0        for i in @@sprite.values          i.ox = @ox - @@last_ox        end      else        refreshox        @@last_ox = @ox      end    end    if @oy != @@last_oy      #人物走路時候      if @oy % AREA_H != 0        for i in @@sprite.values          i.oy = @oy - @@last_oy        end      else        refreshoy        @@last_oy = @oy      end    end    for i in @@sprite.keys     id = @map_data[i[0],i[1],i[2]]     if @priorities[id] != 0       @@sprite[i].z = @priorities[id] == 0 ? 0 : 32 * (1 + @@sprite[i].y / AREA_H + @priorities[id])       @@sprite[i].update     end    end  end  #--------------------------------------------------------------------------  def refreshox    #需要釋放的元件範圍    del_range_y = [(@@last_oy / AREA_H - 1), ((@@last_oy + WIN_H) / AREA_H)]    if @ox > @@last_ox      del_range_x = [(@@last_ox / AREA_W - 1), (@ox / AREA_W - 2)]    else      del_range_x = [((@ox + WIN_W) / AREA_W + 1), ((@@last_ox + WIN_W) / AREA_W)]    end    #需要繪製的元件範圍    draw_range_y = [(@oy / AREA_H - 1), ((@oy + WIN_H) / AREA_H)]    if @ox > @@last_ox      draw_range_x = [[((@@last_ox + WIN_W) / AREA_W + 1), (@ox / AREA_W - 1)].max, ((@ox + WIN_W) / AREA_W)]    else      draw_range_x = [(@ox / AREA_W - 1), ([(@@last_ox / AREA_W - 1),(@ox + WIN_W) / AREA_W + 1].min - 1)]    end    #釋放元件 BEGIN    for x in del_range_x[0]..del_range_x[1]      next if draw_range_x[0] > x && x < draw_range_x[1]      for y in del_range_y[0]..del_range_y[1]        next if draw_range_y[0] > y && y < draw_range_y[1]        for l in 0..2          next if @@sprite[[x, y, l]].nil?          @@sprite[[x, y, l]].dispose          @@sprite.delete([x, y, l])          @@ani_switch.delete([x, y, l])        end      end    end    #釋放元件 END    #恢復走路時候的偏移 BEGIN    if @ox >= (@map_data.xsize * AREA_W - WIN_W)      for i in @@sprite.keys        @@sprite[i].ox = 0        @@sprite[i].x = i[0] * AREA_W - @ox        if i[0] < (@ox / 32 - 1)          @@sprite[i].x += @map_data.xsize * AREA_W        elsif i[0] == -1          @@sprite[i].x = 0        end      end    else      for i in @@sprite.keys        @@sprite[i].ox = 0        @@sprite[i].x = i[0] * AREA_W - @ox      end    end    #恢復走路時候的偏移 END    #繪製元件 BEGIN    for x in draw_range_x[0]..draw_range_x[1]      for y in draw_range_y[0]..draw_range_y[1]        for l in 0..2          draw(x, y, l)        end      end    end    #繪製元件 END  end  #--------------------------------------------------------------------------  def refreshoy    #需要釋放的元件範圍    del_range_x = [(@@last_ox / AREA_W - 1), ((@@last_ox + WIN_W) / AREA_W)]    if @oy > @@last_oy      del_range_y = [(@@last_oy / AREA_H - 1), (@oy / AREA_H - 2)]    else      del_range_y = [((@oy + WIN_H) / AREA_H + 1), ((@@last_oy + WIN_H) / AREA_H)]    end    #需要繪製的元件範圍    draw_range_x = [(@ox / AREA_W - 1), ((@ox + WIN_W) / AREA_W)]    if @oy > @@last_oy      draw_range_y = [[((@@last_oy + WIN_H) / AREA_H + 1), (@oy / AREA_H - 1)].max, ((@oy + WIN_H) / AREA_H)]    else      draw_range_y = [(@oy / AREA_H - 1), ([(@@last_oy / AREA_H - 1),(@oy + WIN_H) / AREA_H + 1].min - 1)]    end    #釋放元件 BEGIN    for x in del_range_x[0]..del_range_x[1]      next if draw_range_x[0] > x && x < draw_range_x[1]      for y in del_range_y[0]..del_range_y[1]        next if draw_range_y[0] > y && y < draw_range_y[1]        for l in 0..2          next if @@sprite[[x, y, l]].nil?          @@sprite[[x, y, l]].dispose          @@sprite.delete([x, y, l])          @@ani_switch.delete([x, y, l])        end      end    end    #釋放元件 END    #恢復走路時候的偏移 BEGIN    if @oy >= (@map_data.ysize * AREA_H - WIN_H)      for i in @@sprite.keys        @@sprite[i].oy = 0        @@sprite[i].y = i[1] * AREA_H - @oy        if i[1] < (@oy / 32 - 1)          @@sprite[i].y += @map_data.ysize * AREA_H        elsif i[1] == -1          @@sprite[i].y = 0        end      end    else      for i in @@sprite.keys        @@sprite[i].oy = 0        @@sprite[i].y = i[1] * AREA_H - @oy      end    end    #恢復走路時候的偏移 END    #繪製元件 BEGIN    for x in draw_range_x[0]..draw_range_x[1]      for y in draw_range_y[0]..draw_range_y[1]        for l in 0..2          draw(x, y, l)        end      end    end    #繪製元件 END  endend复制代码
    复制代码
    ps:
    640*480 fps 在38左右
    800*600 fps 在35左右
                 本帖来自P1论坛作者david50407,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=127629  若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2025-3-14 23:14 , Processed in 0.061100 second(s), 53 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表