本程序借鉴学习了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中对库函数进行修改