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

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

查看: 2225|回复: 1

斜45度游戏开发(一)

[复制链接]
发表于 2005-12-27 13:30:34 | 显示全部楼层 |阅读模式
作者:Flysky 2005

注:写的十分粗糙,如果看不懂请对照KgameV1.0源代码浏览。

  最好的游戏末过于RPG游戏了,但如果赢得大众的好评,那么必须要采用(甚至说现在是一种标准)斜45度地图、人物游戏引擎,下面我们分别展开分析。

一.地图数据结构

Soft的《圣剑英雄传二》定义的就不错,可以参考它的。
定义地图结构以前,我们要先定义Tile结构,分两种情况。

(1).物品、景物等按NPC处理(不规则处理,如“魔力宝贝”):
typedef struct{
bool IsGround;//是否显示地表
short GroundPicNum; //地表图片页面编号(0~59),,,(0-55)页为静态,(56~59)页为动态
short GroundPicX; //地表材料在地表图片上的横坐标(以格子为坐标)
short GroundPicY; //地表材料在地表图片上的纵坐标(以格子为坐标)
short Block; //阻碍标志(ID_BLOCK_T,ID_BLOCK_F)
short Hook; //陷阱标志(ID_HOOK_F,ID_HOOK_T …………)
char HookScriptName[28];
char Reserve; //保留位,(我估计我们肯定还有想不到的一些信息,以后可以在这里添加,以免地图编辑完成之后,再修改cell结构时可避免重新编辑地图文件)
}stCell;

具体我也不说什么了,注释都很清楚!

(2).物品、景物也按Tile处理但NPC按不规则处理(如:“仙剑奇侠转”,强烈不推荐!)
typedef struct{
bool IsGround;//是否显示地表
short GroundPicNum; //地表图片页面编号(0~59),,,(0-55)页为静态,(56~59)页为动态
short GroundPicX; //地表材料在地表图片上的横坐标(以格子为坐标)
short GroundPicY; //地表材料在地表图片上的纵坐标(以格子为坐标)
bool IsObject1;//是否显示物品1
short Object1PicNum; //地表图片页面编号(0~59),,,(0-55)页为静态,(56~59)页为动态
short Object1PicX; //物体材料1在物体图片上的横坐标(以格子为坐标)
short Object1PicY; //物体材料1在物体图片上的纵坐标(以格子为坐标)
bool IsObject2; //是否显示物品2
short Object2PicNum; //地表图片页面编号(0~59),,,(0-55)页为静态,(56~59)页为动态
short Object2PicX; //物体材料2在物体图片上的横坐标(以格子为坐标)
short Object2PicY; //物体材料2在物体图片上的纵坐标(以格子为坐标)
short Block; //阻碍标志(ID_BLOCK_T,ID_BLOCK_F)
short Hook; //陷阱标志(ID_HOOK_F,ID_HOOK_T …………)
char HookScriptName[28];
char Reserve; //保留位,(我估计我们肯定还有想不到的一些信息,以后可以在这里添加,以免地图编辑完成之后,再修改cell结构时可避免重新编辑地图文件)
}stCell;

太清楚了,我也不解释了!

下一步就是地图了,地图的处理不管是什么方法大同小异.
int ID; //地图编号
char Name[32]; //地图名称(地图文件名)
int Width; //宽度(以格子为坐标) 斜
int Height; //高度(以格子为坐标) 斜
int MapStartX,MapStartY; //左上角坐标
stCell **Cell; //动态格子
char FileName[32]; //当前地图文件名
char ScrFName[32]; //地图初始化脚本文件名
char Reserve[4]; //保留位,(我估计我们肯定还有想不到的一些信息,以后可以在这里添加,以免地图编辑完成之后,再修改Map_struct格式,破坏原先编好的地图文件)

//这里先不用看,到了那里再说。
LPDIRECTDRAWSURFACE7 lpDDS_MapBack; //地图临时保存点
LPDIRECTDRAWSURFACE7 lpDDS_TMouse; //Tile鼠标
int MapBx,MapBy; //用来优化机器

  这样不就介绍完了吗?简单吧,不过后面的越来越难,做好心理准备。

二.坐标转换

各大文章在这里都快讲疯了,我不想说推理方法了,你记住以下函数就可以:

//斜45度的坐标转换成屏幕坐标
inline void MIToMD(int Dx,int Dy,int &Ix,int &Iy)
{
Ix=(TileWidth>>1)*(Dx-Dy);//转换为绝对坐标x
Iy=(TileHeight>>1)*(Dx+Dy);//转换为绝对坐标y 大菱形
}

//屏幕坐标转换成斜45度的坐标
inline void MDToMI(int Ix,int Iy,int &Dx,int &Dy)
{
Dx=int(0.5*((Iy<<1)+Ix)/(TileWidth>>1));
Dy=int(0.5*((Iy<<1)-Ix)/(TileWidth>>1));
}

其中
#define TileWidth 32 //每个Tile的宽
#define TileHeight 16 //每个Tile的高


三.绘制地图

  绘制地图有什么难的,错!地图绘制好了FPS能提高数倍。

传统的地图绘制方法:

for(int i=0;i<height;i++)
{
for(int t=0;t<width;t++)
{
绘制。。。。。
}
}

经过改进我这样做

if (MapBx!=x&&MaxBy!=y)
{
for(int i=0;i<height;i++)
{
for(int t=0;t<width;t++)
{
绘制。。。。。
更新MaxBx和MaxBy
备份地图(存成图片)
}
}
}
else
{
还原地图(取出图片)
}

这样空闲状态的FPS就会提升,什么?还想提升,这样办吧!

推理方法从略(其实我也不记得的,春天写的):

#define MapDMX int(0.5*((ScreenHeight<<1)+ScreenWidth)/(TileWidth>>1))+1 //最大画出点X
#define MapDMY int(0.5*(ScreenHeight<<1)/(TileWidth>>1))+1 //最大画出点Y
#define MapDSY int(0.5*(-ScreenWidth)/(TileWidth>>1))-1 //最小画出点Y(特殊)

然后
if (MapBx!=x&&MaxBy!=y)
{
for (int Y=IntSizeL(MapStartY+MapDSY,0); Y<IntSizeS(MapStartY+MapDMY,Height); Y++)
{
for (int X=IntSizeL(MapStartX-1,0); X<IntSizeS(MapStartX+MapDMX,Width); X++)
{
绘制。。。。。
更新MaxBx和MaxBy
备份地图(存成图片)
}
}
else
{
还原地图(取出图片)
}

其中IntSizeL取两个数大的,IntSizeS取两个数小的!

速度优化到极限了,好了,先写到着,下一次我再说遮挡。


资讯仅供参考,不代表本站(GameRes.com)观点,此信息由sea_bug提交。 

发布日期:2005-12-21 12:16:00
 楼主| 发表于 2005-12-27 13:31:05 | 显示全部楼层
作者:Flysky 2005

  上一篇我们讲了地图的结构和地图的基本的绘制,这个属于较简单的步骤,我做这些也不是特别的麻烦,如果你是老手,那么1天对你来说已经足够,我们这一组文章也没有讲任何的优化技巧,如果你想优化,还是需要在实际中摸索,当然,我有时间也会写的。

  这一篇我们主要研讨地图的物品、景物、NPC建立,并说一下遮挡的简单实现方法。

NPC\主角结构:
  主角和NPC在一起比较好,也便于管理(再次声明:作者已经不使用这些方法,这些方法只适用于初学者!),结构如下:

struct stRoleC
{
//判断
bool IsNPC; //是不是NPC

//----------Role基本--------------
char *Name; //NPC名字
bool VS; //是否有这个人物(是否可见)
int x,y; //人物的XY坐标值
RECT roler; //人物矩形
int face; //NPC面向的方向 0. 下 1. 上 2.左 3.右
char *facePic;

//----------属性值-------------
int HP,MP; //目前的HP,MP
int MaxHP,MaxMP; //满HP和MP
int Level; //目前的等级
int Exp; //目前的经验
int MaxExp; //满血的经验

//----------寻路相关--------------
bool move;
int movex,movey; //移动目标点

//----------NPC相关---------------
char *EScrFName; //当触发人民的脚本文件名
};

struct stRole
{
//判断
bool IsNPC; //是不是NPC

//----------Role基本--------------
char Name[32]; //NPC名字
bool VS; //是否有这个人物(是否可见)
int x,y; //人物的XY坐标值
int oldx,oldy; //人物上一步的XY值
RECT roler; //人物矩形
POINT PicS; //距像素坐标的偏移
int face; //NPC面向的方向 0. 下 1. 上 2.左 3.右
bool facejd; //上一步的站向
char facePic[64];
int facej; //NPC方向的脚步 0 1 2 3
vector<OINT> zd; //遮挡列表

//----------属性值-------------
int HP,MP; //目前的HP,MP
int MaxHP,MaxMP; //满HP和MP
int Level; //目前的等级
int Exp; //目前的经验
int MaxExp; //满血的经验

//----------寻路相关--------------
bool move;
vector<OINT> Path; //各个步数
int PathSteps; //步数
int PathCSteps; //已经走过步数
int movex,movey; //移动目标点

//----------NPC相关---------------
char *EScrFName; //当触发人民的脚本文件名
bool WalkLoop; //是向前走还是倒退

//----------Surface--------------
LPDIRECTDRAWSURFACE7 lpDDS_ROLEP; //Role的图片
LPDIRECTDRAWSURFACE7 lpDDS_ROLEL; //Role的logo
};

  这两个结构其中stRole是内部储存的结构,而stRoleC是对外的接口,其实你完全不必那样,用一个也可以,具体的完全随你便。

  注意:以下的代码和KGameSrc一点关系也没有。

景物的建立:

struct st_scene
{
int x,y; //房子等东西右下角的坐标
int Width,Height; //物品的大小,利用这个可以选出房子等左上角的坐标
LPDIRECTDRAWSURFACE7 lpDDS_SCENEPIC; //房子等的图片
unsigned short b_isablock; //0: 不阻碍 1: 全部阻碍 2:使用阻碍表
struct {unsigned int data;}**v_block; //阻碍表,比如房子,门那里是不遮挡的
//注意:因为我们构件的是<<魔力宝贝>>式,所以陷阱并不是归这里
};

  我也注释了,应该很好看吧。

  遮挡问题:

  这个确实比较棘手,如果是单格遮挡,可以看云风的遮挡算法,可我们是多个格的,怎么办呢?

  根据几位前辈的讨论,他们想出了使用X+Y算法(画家算法),但当时不是很成功,我就做一下补充。

  首先,把地图上的一切东西(不管是物品还是主角)串成一个链表(遮挡链表),然后根据X+Y的值有小到大(左上到右下)排列,最后绘制,这样就完成了,很简单吧(哪位可以帮我画一下图,感激不尽.)

  优化方法也有:那就是这个景物的排列让地图编辑器排列,然后这个不动了,光人物在链表中的位置移动,这样就完成了快速遮挡。


  好了,基本的东西我也写完了,由于现在我在做操作系统,语言说的太急,下一次我会把更好的优化代码和例子程序给大家,谢谢大家观看!

资讯仅供参考,不代表本站(GameRes.com)观点,此信息由sea_bug提交。 

发布日期:2005-12-22 13:08:00
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-5-19 02:15

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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