QT实现塔防游戏2

本程序借鉴学习了https://blog.csdn.net/m0_47055280/article/details/106918193?spm=1001.2014.3001.5502

 程序到自己手里才发现寸步难行,这一部分实现了,第一关的界面,航点与传奇(即防御塔)的初步建设。

创建了四个新文件,gamescene,waypoint,legend_location,legends

首先在完善了选关系统

//包含头文件
#include <QWidget>
#include<qpushbutton.h>
#include<gamescene.h>
#include<qicon.h>
#include<qpainter.h>
#include<qpixmap.h>
#include<qpushbutton.h>
#include<qevent.h>
类外
//  开始第一关
    connect(ui->firstbtn,&QPushButton::clicked,[=](){
        gamescene *game=new gamescene;
        this->hide();
        game->setpath(":/image/1.jpg");
        game->addwaypoint1();
        game->addlegend_location1();
        game->show();
    });
//具体函数后作演示

接着创建航点

.h文件内:

#ifndef WAY_H
#define WAY_H
#include<qpoint.h>
#include<qpainter.h>
class waypoint
{
private:
    //    航点的位置
    QPoint mypos;
    //    下一个航点指针
    waypoint *mynextpoint;
    
public:
    waypoint();
    waypoint(QPoint pos);
    //    设置下一个航点
    void setnextwaypoint(waypoint * nextwaypoint);
    //    下一个航点的指针,返回值为指针
    waypoint * getnextwaypoint();
    //    本航点的位置
    const QPoint getpos();\
    //    画出本航点
    void draw(QPainter * painter) ;
    
};

#endif // WAY_H

.cpp中

#include <QPoint>
#include <QPainter>
#include "waypoint.h"
//   构造函数
waypoint::waypoint(QPoint pos)
{
    mypos=pos;
    mynextpoint=NULL;
}
//   设置下一个航点
void waypoint::setnextwaypoint(waypoint * nextwaypoint)
{
    this->mynextpoint=nextwaypoint;
}
//   下一个航点的指针
waypoint* waypoint :: getnextwaypoint()
{
    return this->mynextpoint;
}
//返回值为const防止位置被修改
const QPoint waypoint::getpos()
{
    return this->mypos;
}

void waypoint::draw(QPainter * painter)
{
    painter->save();//保存原始的绘画参数
    painter->setPen(Qt::green);//设置画笔的颜色
方便调试,之后为了美观消除
    painter->drawEllipse(mypos,4,4);//画一个半径为4的圆
确定中心点
    painter->drawEllipse(mypos,1,1);//半径为1的圆
    painter->restore();//还原原来的画笔设置
}

然后是传奇坐标

.h文件中:

#ifndef LEGEND_LOCATION_H
#define LEGEND_LOCATION_H

#include<qpainter.h>
#include<qpoint.h>
#include<qpixmap.h>
class legend_location
{
public:
    //    构造函数
    legend_location(QPoint pos);
    //得到防御塔坑的中心点
    QPoint getcenterpos();
    //得到防御塔坑的左上点
    QPoint getpos();
    //判断点是否在传奇格子的范围内
    bool containpos(QPoint pos);
    //  获取私有成员
    bool getexsistence();
    //  设置是否有传奇
    void setexsistence(bool exsist=true);
    //    绘图事件
    void draw(QPainter * painter) const;
    
private:
    //坐标
    QPoint mypos;
    //存在判别
    bool myexsist;
    //传奇格子的固定大小
    static const QSize myfixedsize;
};

#endif // LEGEND_LOCATION_H

.cpp文件中:

#include "legend_location.h"
//设置图片的大小
const QSize legend_location::myfixedsize(120,120);
//初始化列表
legend_location::legend_location(QPoint pos):
    mypos(pos),
   myexsist(false)
{
}
//获取私有成员
bool legend_location::getexsistence()
{
    return myexsist;
}
//获取私有成员
QPoint legend_location::getpos()
{
    return mypos;
}
//  设置是否有传奇
void legend_location::setexsistence(bool exsist)
{
    myexsist=exsist;
}
//获取中心点
QPoint legend_location::getcenterpos()
{
    QPoint tmp;
    tmp.setX(mypos.x()+myfixedsize.width()/2);
    tmp.setY(mypos.y()+myfixedsize.height()/2);
    return tmp;
}
//判断是否在选中区域内
bool legend_location::containpos(QPoint pos)
{
    bool xInHere=pos.x()>mypos.x() && pos.x()<mypos.x()+myfixedsize.width();
    bool yInHere=pos.y()>mypos.y() && pos.y()<mypos.y()+myfixedsize.height();
    return xInHere && yInHere;
}
//画出传奇格子
void legend_location::draw(QPainter *painter) const
{
    painter->drawPixmap(mypos.x(),mypos.y(),100,100,QString(":/cal.ico.png"));
}

接着是传奇类

.h文件中

#ifndef LEGENDS_H
#define LEGENDS_H

#include <QObject>
#include <QObject>
#include <QPoint>
#include <QSize>
#include <QString>
#include<gamescene.h>


class gamescene;
class QPainter;
class legends :  QObject
{
    Q_OBJECT
private:
//    传奇坐标
    QPoint mypos;
//    传奇图片路径
    QString mypath;
//    传奇攻击范围
    int myattackrange;
//    指向地图的指针
     gamescene *mygame=NULL;
//    传奇固定大小
    static const QSize myfixedSize;
public:
    legends(QPoint pos,gamescene *game0,QString path=":/image/gz.png");
    ~legends();
    void draw(QPainter * painter)const;//画出防御塔
};


#endif // LEGENDS_H

.cpp文件中

#include<legends.h>
#include<qpoint.h>
const QSize legends::myfixedSize(120,120);
legends::~legends()
{
}

legends::legends(QPoint pos,gamescene * game,QString path)
{
    mypos=pos;
    myattackrange=250;
    mygame=game;
    mypath=path;
}
void legends::draw(QPainter *painter) const
{
    painter->save();
    painter->drawPixmap(mypos.x()-myfixedSize.width()*2/3,mypos.y()-myfixedSize.height()*3/5,155,155,QString(":/image/gz.png"));//画出防御塔的图片
    painter->setPen(Qt::green);
便于调试
    painter->drawEllipse(mypos,myattackrange,myattackrange);//画出防御塔的攻击范围
}

接着将以上文件整合到gamescene中

#ifndef MAP_H
#define MAP_H

#include <QWidget>
#include<qicon.h>
#include<qlist.h>
#include<qstring.h>
#include<qpainter.h>
#include<qsize.h>
#include<qpixmap.h>
#include<QMouseEvent>
#include<legends.h>
#include<legend_location.h>
#include<waypoint.h>
class legends;
class gamescene : public QWidget
{
    Q_OBJECT
private:
    //    地图路径
    QString mypath;
    //    新航点的列表
    QList<waypoint*>mynextwaypointlist;
    //    传奇坐标链表
    QList<legend_location>mylegend_loclist;
    //    传奇类型坐标
    QList< legends*> mylegendlist;
public:
    explicit gamescene(QWidget *parent = nullptr);
    //    设置地图路径
    void setpath(QString path);
    //    添加新的航点
    void addwaypoint1();
    //    添加传奇坐标
    void addlegend_location1();
    //    点击生成传奇
    void mousePressEvent(QMouseEvent *event) ;
    //    绘图事件
    void paintEvent(QPaintEvent *event) ;

signals:

};

#endif // MAP_H

 .cpp中

#include "gamescene.h"
gamescene::gamescene(QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle("APEX");
    this->setFixedSize(1920,1080);
    this->setWindowIcon(QIcon("://cal.ico.png"));

}
    void gamescene::setpath(const QString path)
    {
        mypath=path;
    }
void gamescene::paintEvent(QPaintEvent *)
{   QPainter painter(this);
    QPixmap pix;
    pix.load(mypath);
    painter.drawPixmap(0,0,1920,1080,pix);
    foreach( waypoint * waypoint0,mynextwaypointlist)
    {
        waypoint0->draw(&painter);
    }
    foreach(const legend_location location0,mylegend_loclist)
        location0.draw(&painter);
    foreach(const legends *legend0,mylegendlist)
    {
        legend0->draw(&painter);
    }
}

void gamescene::mousePressEvent(QMouseEvent *event)
{
    QPoint presspos=event->pos();
    auto legendlist0=mylegend_loclist.begin();
//    遍历所有传奇格子
    while(legendlist0!=mylegend_loclist.end())
       {
//        限制鼠标左键点击
           if(Qt::LeftButton==event->button())
           {
               //如果鼠标点击的位置在格子内,并且没有传奇
               if(legendlist0->containpos(presspos)&&!legendlist0->getexsistence())
               {
                   //创建一个新传奇点
                   legends * legend=new legends(legendlist0->getcenterpos(),this);
                   //把这个防御塔放到储存防御塔的list中
                   mylegendlist.push_back(legend);
                   //设置这个防御塔坑内有防御塔了        
                   legendlist0->setexsistence(true);
                   //更新地图
                   update();
                   break;
               }
           }
           legendlist0++;
       }
}
//   设置怪物移动的航点
void gamescene::addwaypoint1()
{
    waypoint *waypoint1=new waypoint(QPoint(238,225));
    mynextwaypointlist.push_back(waypoint1);
    waypoint *waypoint2=new waypoint(QPoint(238,698));
    mynextwaypointlist.push_back(waypoint2);
    waypoint *waypoint3=new waypoint(QPoint(720,698));
    mynextwaypointlist.push_back(waypoint3);
    waypoint *waypoint4=new waypoint(QPoint(720,548));
    mynextwaypointlist.push_back(waypoint4);
    waypoint *waypoint5=new waypoint(QPoint(1205,548));
    mynextwaypointlist.push_back(waypoint5);
    waypoint *waypoint6=new waypoint(QPoint(1205,698));
    mynextwaypointlist.push_back(waypoint6);
    waypoint *waypoint7=new waypoint(QPoint(1685,698));
    mynextwaypointlist.push_back(waypoint7);
    waypoint *waypoint8=new waypoint(QPoint(1685,265));
    mynextwaypointlist.push_back(waypoint8);

}
void gamescene::addlegend_location1()
{
    //  设置传奇位置,用一维数组实现
    QPoint legend_loc[]=
    {
        QPoint(320,345),QPoint(515,485), QPoint(1480,345),
        QPoint(830,345),QPoint(980,345),QPoint(1295,485),
        QPoint(1295,778),QPoint(515,778),QPoint(320,778)
    };
    //用循环创建传奇列表
    int len=sizeof(legend_loc)/sizeof(legend_loc[0]);
    for(int i=0;i<len;i++)
    {
        mylegend_loclist.push_back(legend_loc[i]);
    }
}

实现效果如下: 

 总结:这部分所花时间较长,主要在熟悉qt的多文件操作上,其中出现了不少问题,折磨许久

1.程序的封装性导致私有程序必须通过函数引出

2.要前置引出类名,不然qt无法设定相关指针

3.可能undefined reference to,要在pro中对库函数进行修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值