使用WINDOWS的GDI开发游戏(5)

第五篇

前面的框架已经构建出了一个雏形了,只是没有加入游戏控制逻辑而已,所以不能说是有意义的游戏,但相信同学们已经有所收获了。

这篇我们就来给游戏加上灵魂,赋予游戏生命,形形色色的游戏都是依靠这部分的精彩编写,

这里面涉及的知识也是最多的,什么AI、粒子系统、碰撞检测、物理系统、行走系统等等。不同的游戏也主要体现在这部分的不同。

当然我们这个游戏不需要应用这些了,我们只需要作简单的碰撞检测和行走动画就可以了。这里面只是应用了简单的碰撞检测。

前面的版本我们已经构建起了画面,并做了简单的碰撞检测,例如我们看到坦克不会进入障碍物里去,但那只是粗略的检测,并不能使用,

我们现在就来改进它。

正如我们看到前一版本,这里面有两个地方需要注意,一是碰撞检测和坦克行进方向有关,另外是坦克在转弯时会涉及到轨道的切合问题。

我们这样检测,在坦克前进的方向,判断坦克前面的两个端点是否可通过前面的道路,即可判断是否碰撞了。但有时细微的像素,玩家是不可能注意到的,

所以有时可能会出现看起来能通过,却出现坦克无法通过的情形,特别是在单个轨道通道口的情况下,这就是细微的像素导致了碰撞。

所以我们有必要对这种情况加以修正,以使坦克紧贴轨道运行,这样在做坦克之间的碰撞时也有利。

我们先来按坦克前进方向来做碰撞检测。

坦克前进方向分四个方向,所以只需要针对具体的方向,做对应的是否重叠的判断就可以知道前面是否碰撞上。

这里碰撞分为对地图障碍物的碰撞和跟移动物体的碰撞。对地图的障碍物判断很简单。直接针对地图座标判断是否可通行物体就可以了。

代码如下

// 障碍物判断

bool CGameMap::IsCanWalk( int nX, int nY, const CSpirit &spirit )

{

    int nBoxX = nX / C_TILE_W;

    int nBoxY = nY / C_TILE_H;

    if( ENUM_WALL == m_pMap[nBoxY][nBoxX] )

    {

        return TestWall( nX, nY, spirit );

    }

    else if( ENUM_IRON == m_pMap[nBoxY][nBoxX] || ENUM_WATER == m_pMap[nBoxY][nBoxX] || ENUM_EAGER == m_pMap[nBoxY][nBoxX] )

        return false;

    return true;

}

只需要判断障碍物是否可通行,但这里需要对砖墙做特殊处理,因为砖墙是可击打物件,对于击打的状态做分别的处理。

首先将坦克的位置坐标转换为地图座标,

int nBoxX = nX / C_TILE_W;

int nBoxY = nY / C_TILE_H;

这样nBoxX,nBoxY就是地图格子的坐标了,然后找出该位置所放的障碍物,再进行判断。

我们在游戏逻辑函数里,只需要移动玩家坦克,如果遇到障碍物就做退回处理,使坦克不能逾越障碍物。

代码也很简单

POINT ptOldPlayer;

    ptOldPlayer = m_oPlayer.GetPos();

    POINT ptNew = m_oPlayer.Move( dwTime );

    if( !m_oGameMap.TestCanWalk( ptNew.x, ptNew.y, m_oPlayer ) )

    {

        m_oPlayer.SetPos( ptOldPlayer.x, ptOldPlayer.y );

    }

游戏逻辑是最复杂的部分,游戏创意也大都体现在这里,需要制作者有很高的技巧或经验。大家平时可以多留意别人的游戏制作,多玩玩游戏,

并在生活中积累,也许灵感就在不经意间诞生。

在坦克大战游戏中,逻辑基本上是围绕碰撞检测来展开的。例如子弹碰到了砖墙,要对砖墙做处理,子弹碰到了对方坦克,要产生爆炸并使对方消失的处理。

在这个游戏中,我们把逻辑列一下,主要有:

1、坦克遇到地图障碍物。

2、坦克遇到对方坦克。

3、子弹遇到对方坦克。

4、子弹遇到子弹(这个可选,就是子弹是否可消耗对方子弹,为了好玩点,还是需要加上,我在游戏中并没处理)

5、子弹遇到鹰(玩家大本营)

6、坦克遇到随机奖品。

7、子弹遇到地图障碍物,子弹和坦克的障碍物不同,体现在对河流的处理上。子弹应该是可以越过河流的。

8、移动物体的移动。

9、对键盘输出的反应处理。

所以我们必须在每一帧里,对以上所有的逻辑做一个判断,并据此修改画面的显示并展现给玩家。

例如,坦克遇到障碍物我们已经在前面用代码说明了处理办法。

子弹遇到对方坦克,则需要展示一幅爆炸的画面,然后让对方坦克死亡。

我们输入方向键,则修改玩家坦克的行进方向。

    switch( wKey )

    {

        case VK_UP:

            m_oPlayer.SetDirection( ENUM_UP );

            break;

    }

对于这些逻辑的处理,大家可以参考随附的源代码,对照着来看。代码里都有注释,应该很容易看的明白。

在这篇章节里,我们已经完成了大部分的游戏处理了。一个基本可操作的游戏已经将近完成。但还不是可玩的作品。

因为我们还缺乏关卡的设计、游戏分数的处理已经过关等逻辑做处理。我们只是完成了技术上的逻辑实现。

游戏故事逻辑还需要我们去完成,那么下一篇我们就介绍游戏分数、通过流程、游戏失败的处理。

但我们已经距离成功不远了,下一篇,将诞生一个真正意义上的游戏,至少让你可以让你哄哄你的表弟或侄子了。

配套代码下载

https://download.csdn.net/download/b2b160/1794657

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

b2b160

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值