【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 5831|回复: 3

RPG游戏引擎制作——地图篇:斜45度

[复制链接]
发表于 2007-12-12 15:12:55 | 显示全部楼层 |阅读模式
RPG游戏地图占很重要的一部份。它是游戏展开的平台。所以我对使用地图的接口简化的很简单,必然太过复杂带来使用上的不便。
    地图的接口:设置地图大小、设置地图块的大小、地图切换到指定ID的场景、根据指定的图片和地图块的大小生成地图
    RPG地图一般都是多层的:背景层、遮挡物,还有事件。背景层主要根据地图块进行地图场景的绘制。遮挡物则主要是可能发生事件、产生遮挡和阻挡关系的物体。事件是和地图区域绑定的,实际上也是地图块绑定的。因为角色在不动时或在前进时所有相关的检测都是和地图块相关的。
    这里难点可能还是地图的拼接,地图的绘制都是很简单的事件。而拼接的难点导致了地图遮挡的难点。这里对这几个难点做一介绍:
   
1 地图的拼接:在斜45度地图的行和一般意义上的行不同,它的行是锯齿形的,先对行上的块进行编号,偶数处于正常意义上的顺序位置,而奇数的则是在偶数的斜45度方向上进行绘制。
   startCol = g.getClipX()/20;endCol = (g.getClipX() +g.getClipWidth())/20 + 2;
    startRow = g.getClipY()/20;endRow = (g.getClipY() +(tmp = g.getClipHeight()))/20 + 2;
    for (int row = startRow - 1; row < endRow; row++) {
      //y = row*tileHeight;
      i = 0;
      if(row < 0 || row >= this.grid[0].length)continue;
      for (int col = ((startCol - 1)<<1); col < (endCol<<1); col++) {
        if(col < 0||col >= this.grid.length)continue;
        x = (col>>1) * this.tileWidth ;
        y = row * this.tileHeight;
       // this.drawCell(g, x, y, col, row);
          this.drawImage(this.tiles,g,x,y,20);
         //绘制奇数列
          col++;
          x = x + halfW;
          y = y+ halfH;
         this.drawImage(this.tiles,g,x,y,20);
      }
    }

2 遮挡的判断:因为是斜45度视角,所以遮挡的判断不能依据90度的判断,单纯的x或y不能比较出谁在前,谁在后。如果我们在自己的视角前画切面,那么与地图的交面出会出现一条与地图坐标成45度的直线,那么这条直线就是我们要进行比较的依据。谁前谁后要看这条线谁离预原点远了。那就是看x+y=b中的b的值大小了。好了,到此因该明白了吧。还有一点就是当b相同时,可能要看谁y大了。OK大家应该明白了吧
 楼主| 发表于 2007-12-12 15:17:31 | 显示全部楼层

有人在新浪网的游戏制作论坛问这个,那我随便说说这个问题的解法,先看看地图元素:

可以看出来是个扁的菱形。这个地图元素的大小是64X32,你可以随意决定元素长宽,在设计程序时,地图元素大小并不重要,只要把尺寸扔进绘图方程,程序就能正确地绘制地图。在这个例子中,我们就先用64X32来演示。

那么这个公式是怎么样的呢?先看看Staggered地图

<-- Staggered

这个地图有5行,看着这个地图你会想,怎么拼图才能将地图拼出来。再画张图来演示:

从这张图可以看出,拼图时从左到右,从上到下,跟正规的矩形拼图一样,唯一同的是,地图元素与元素之间有重叠,看看第一行和第二行之间,第二行的地图元素会压在第一行的元素上,而第三行的的地图元素则压在第二行的元素上。所以,只要找到正确的公式,你就能正确地设计程序,再来一张图:

图上绿点(是高亮度绿色,不是暗绿色)是每块地图元素的起点,第一行的座标是0,第二行的座标是1,第三行的座标是2,......由这些行位座标决定你的地图元素的起点,从这个规律中看出行位座标0,和行位座标2的横向座标X的起点是一样的是0,行位座标1的起点是向右移半块地图元素。

再从纵向座标找规律,看行位座标0和行位座标2,两块地图元素之间的距离刚好是一块地图元素的高。再看看行位座标0和行位座标1,两块地图元素之间的距离刚好是半块地图元素的高。所以,计算每块地图元素的位置,你的公式刚好是:

void CalculateMapTilePos(int n_map_pos_x,
int n_map_pos_y,
int & n_scrn_pos_x,
int & n_scrn_pos_y)
{
n_scrn_pos_x = n_map_pos_x * iso_tile_size_x
+
(n_map_pos_y & 1) * (iso_tile_size_x / 2);
n_scrn_pos_y = (n_map_pos_y) * iso_tile_size_y / 2;
}

在这个公式中,n_map_pos_x是地图纵横的横向座标,n_map_pos_y是地图纵横的纵向座标,n_scrn_pos_x和n_scrn_pos_y是地图元素在屏幕上的纵横座标。

重要:

首先以上的公式只适用于Staggered斜45度地图,而slide,和Diamond形地图,这个公式要稍加修改才能用。

Slide:

Diamond:

 楼主| 发表于 2007-12-12 15:19:44 | 显示全部楼层
别人写的两篇文章~看着容易明白~
发表于 2007-12-12 17:45:34 | 显示全部楼层

呵呵 不错

顶!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2025-2-6 06:41

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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