QT(C++)游戏之坦克大战(三)

6 篇文章 3 订阅

前言

这篇说一下玩家类,子弹类的实现

实现

玩家类,敌人类都继承于坦克类,所以我们先来了解一下坦克类,坦克类继承于Base。

坦克类(Tank)

坦克类简单来说,就是实现了坦克基本属性,移动速度,碰撞检测,更新地图位置等等。
Tank.h

class Tank : public Base
{
    Q_OBJECT
public:
    Tank();
    ~Tank();

    void setMoveFlag(bool flag);
    bool getMoveFlag() const;

    void setRole(char role);
    char getRole() const;

    void setSpeedX(int speedX);
    char getSpeedX() const;
    void setSpeedY(int speedY);
    char getSpeedY() const;

    int getAngle();        //获取图片旋转的角度

    bool isTouchWall(int x, int y);
    bool isTouchObjectPart(int x, int y);   //是否检测到一部分障碍物
    bool isTouchObject();   //是否检测到障碍物
    bool isTouchBorder();   //是否碰到边界
    void updateBullte();    //更新子弹位置

    void updateTankMap(char value);

    Bullet m_bullet;    //子对象子弹
    bool m_moveFlag;    //是否可移动

    QPoint m_saveLoca[2];


private:
    void swapDirec();
    void swapPoint();

    char m_role;

    int m_speedX;
    int m_speedY;
};

玩家类(Player)

  • Player继承于Tank,它自身包括生命值等一些属性。
class Player : public Tank
{
    Q_OBJECT
public:
    Player();
    ~Player();

    //初始化
    void playerInit(int xx, int yy, Direction ddirec, char role);
    void playerReInit();	//死亡后重新初始化

    void setAlive(int alive);	//生命值
    int getAlive() const;

    void updateLoca();

private:
    int m_alive;	//生命值

    int initX;  //保留初始位置
    int initY;  //保留初始位置
    Direction initDir;//保留初始位置
};

  • 绘制坦克
    用到的知识是Qt的绘图事件,简单示例:
void BattleCity::paintEvent(QPaintEvent *ev)
{
	...
    QImage imgP1(":/player/image/player/p1tankNormal_U1.png");
    p.drawImage(p1.x, p1.y, imgP1);
    ...
}
  • 坦克移动

用到的知识是Qt的键盘事件
刚开始的时候想着是按下按键,让坦克的xy改变,但是实验过后,发现按键检测的速度太慢,导致坦克移动的慢。后来改进了方法,设置一个标志,按下按键,标志设为true,坦克移动;松开按键,标志设为false,坦克停止。用QTimer进行速度控制。

子弹类(Bullet)

首先还是来看Bullet.h
Bullet算是游戏中最核心的类了,它是所有坦克的子对象。它继承于Base,自身属性包括速度,等级,打击墙壁,打击钢铁,打击敌人等等。

class Bullet : public Base
{
    Q_OBJECT
public:
    Bullet();
    virtual ~Bullet();

    void bulletInit(int xx, int yy, Direction ddirec, int grade);

    void setSpeed(int speed);
    int getSpeed() const;

    void setGrade(int grade);
    int setGrade() const;

    void setMoveFlag(int flag);
    bool getMoveFlag() const;

    bool updateLoca(); //更新子弹位置
    void updateGrade();//更新子弹等级

    void getBulletStatus(QMatrix &matrixBullet, QImage &imgBullet);

    bool isWall(int xx, int yy);
    bool attackWall();
    bool attackIron();
    bool attackEnemy(char role);
    bool attackBase();

private:
    int m_speed;
    int m_grade;
    bool m_moveFlag;
};

检测原理

打击检测的思路其实都一样,判断子弹的位置是否为障碍物,注意,将实际地图转化为逻辑地图时,注意地图的存放方式,比如墙壁是每隔一个放一个,钢铁是每隔两个放一个,基地是每隔四个放一个,这里要十分小心。
比如,墙壁的转换方式为:

	int xx = (cenX)/CELL_WIDTH/2*2;
	int yy = (cenY)/CELL_HEIGHT/2*2;

钢铁的转换方式为:

	int xx = (cenX)/CELL_WIDTH/4*4;
	int yy = (cenY)/CELL_HEIGHT/4*4;

下篇我们实现敌人的移动。

坦克大战系列博客:
QT(C++)游戏之坦克大战(四):https://blog.csdn.net/qq_36327203/article/details/86509381
QT(C++)游戏之坦克大战(二):https://blog.csdn.net/qq_36327203/article/details/86499661

  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
游戏分里外两个部分组成,里部分(用户不可见) 通过里部分执行判断,地图数组更改,和各种值的改变。更改完里部分再根据相应变化更改表部分。(用户可视部分)表部分的打印通过gotoxy去到相应坐标再printf打印出字符,通过文本函数改变文字字体颜色与文字背景颜色与字符组合实现图形界面。 程序通过 计数器+循环判断 的思想,类似单核cpu的多线程实现(单线程在不同程序/函数间来回执行)省去了多线程。(具体过程在功能设计与描述有详细描述) 另AI实现与加强依赖于rand随机函数的运用,进一步强化AI,增加游戏乐趣 功能方面,游戏参考于80年代任天堂红白机(FC/FamilyComputer)上的游戏坦克大战(Battle City),包括地图,游戏模式等等(当时的游戏直接烧在电路板上)。所以游戏平衡方面已经有了很好的参考,无需再花大量时间测试平衡性。 但诸如地图中的树林元素,随机道具等没有实现。但较之原版,该游戏由C/C++编写PC运行,由字符界面实现游戏画面。原版一辆坦克的子弹未消失之前不能发射第二颗。导致子弹打击远处CD长,近处CD短。该游戏每个子弹都有相同CD,子弹未消失只要CD达到即可发射第二颗,第颗…增加了真实性,相较于原版是个改进。且考虑到PC性能不一内置了游戏速度调整。玩家可根据PC性能调整至合适的速度。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chasentech

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

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

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

打赏作者

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

抵扣说明:

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

余额充值