您的位置:首页 > 编程语言 > C语言/C++

C++(qt)游戏实战项目:坦克大战(三)

2017-05-29 20:02 896 查看
前面实现了地图的显示但是地图很单一,这回实现地图的编辑、保存和载入。

我们给地图类Gamemap添加下面几个成员函数

gamemap.h

int switchstyle(int i,int j);//改变cells[i][j]地图块的样式
void setstyle(int i,int j,int style);//设置cells[i][j]地图块的样式
void deletecell(int i,int j);//删除cells[i][j]处地图块
//save map
void savemap(const char *str);//保存地图
//load map
void loadmap(const char *str);//载入地图
void cal(int x,int y,int &i,int &j);//根据鼠标点击位置计算出地图块的二维编号地址


gamemap.cpp

#include "gamemap.h"

GameMap::GameMap()
{
for(int i=0;i<INUM;i++)
for(int j=0;j<JNUM;j++)
cells[i][j]=NULL;
//for(int i=0;i<INUM;i++)
// for(int j=0;j<JNUM;j++)
//cells[i][j]=new Mapcell(i,j,0);
loadmap("1.dat");
}
GameMap::~GameMap(){
for(int i=0;i<INUM;i++)
for(int j=0;j<JNUM;j++)
if(cells[i][j])
{delete cells[i][j] ;cells[i][j]=NULL;}
}

void GameMap::Display(QPainter &paint){

paint.drawImage(QRect(0,0,WIDTH,HEIGHT),QImage(":/images/background.bmp"));
for(int i=0;i<INUM;i++)
for(int j=0;j<JNUM;j++)
{
if(cells[i][j]!=NULL)
cells[i][j]->Display(paint);

}

}

int GameMap::switchstyle(int i,int j){
int tmpstyle=0;
if(i>=INUM||j>=JNUM)
{qDebug("数组越界");return 0;}
if(cells[i][j])
tmpstyle=cells[i][j]->switchstyle();
else{
cells[i][j]=new Mapcell(i,j,0);
tmpstyle=0;
}
return tmpstyle;
}
void GameMap::cal(int x,int y,int &i,int &j){//根据鼠标点击位置计算出地图块的二维编号地址
j=x/CELLWIDTH;
i=y/CELLHEIGHT;
}

void GameMap::setstyle(int i, int j, int style){
if(i>=INUM||j>=JNUM)
{qDebug("数组越界");return ;}
if(cells[i][j])
cells[i][j]->setstyle(style);
else{
cells[i][j]=new Mapcell(i,j,style);

}
}

void GameMap::deletecell(int i, int j){
if(i>=INUM||j>=JNUM)
{qDebug("数组越界");return;}
delete cells[i][j];
cells[i][j]=NULL;

}

void GameMap::savemap(const char *str){
//erjinzhi
std::ofstream ou(str);
for(int i=0;i<INUM;i++)
for(int j=0;j<JNUM;j++)
if(cells[i][j])
ou.write((char*)cells[i][j],sizeof(Mapcell));
ou.close();
}

void GameMap::loadmap(const char *str){
for(int i=0;i<INUM;i++)
for(int j=0;j<JNUM;j++)
if(cells[i][j])
{delete cells[i][j] ;cells[i][j]=NULL;}
//
Mapcell cellst;
std::ifstream in(str);
int i=0,j=0;
while(in.read((char*)&cellst,sizeof(Mapcell)))
{ j=cellst.getpos().x()/CELLWIDTH;
i=cellst.getpos().y()/CELLHEIGHT;
if(cells[i][j])
*cells[i][j]=cellst;
else
{
cells[i][j]=new Mapcell(i,j);
*cells[i][j]=cellst;//moren de 赋值 gou zao hanshu
}

}
in.close();
}


函数准备好了,我们来完成交互。

mainwindow.h

//游戏类
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QKeyEvent>
#include<QMouseEvent>
#include<QPainter>
#include<QTimer>
#include"main.h"
#include "gamemap.h"
class MainWindow : public QMainWindow
{
Q_OBJECT

public:
enum Gamestatus{mapedit=520,gameing,pause};//
MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
void timefun();
private:
int leftorright;//左右
int laststyle;//上一次方块样式
void setgame(Gamestatus status){gamestatus=status;}//设置游戏状态
Gamestatus gamestatus;
QPainter paint;
};

#endif // MAINWINDOW_H


mainwindow.cpp

#include "mainwindow.h"
#include"QRect"
#include<QFont>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{   //
setWindowTitle("by phoenix");
//初始发全局结构体
glo.framei=0;
glo.blockimage=new QImage(":/images/map_block.png");
gamestatus=gameing;
laststyle=0;
leftorright=1;
}

MainWindow::~MainWindow()
{

}
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);

setFixedSize(WIDTH,HEIGHT);

paint.begin(this);
glo.gamemap->Display(paint);
paint.end();
}

void MainWindow::keyPressEvent(QKeyEvent *event){
qDebug("key:--------------------------%d ",event->key());
//当按键为M时设置游戏状态为mapedit
if(event->key()==Qt::Key_M)
{
gamestatus=mapedit;
}else if(event->key()==Qt::Key_G){
gamestatus=gameing;
}

if(gamestatus==mapedit){
if(event->key()==Qt::Key_S)
{

glo.gamemap->savemap("1.dat");
}
else if(event->key()==Qt::Key_L)
{

glo.gamemap->loadmap("1.dat");
}

}else if(gamestatus==gameing){

}
update();
}

void MainWindow::keyReleaseEvent(QKeyEvent *event){

}

// 鼠标移动事件       默认情况下,触发事件需要按下鼠标,才能触发。可设置为自动触发:setMouseTracking(true);
void MainWindow::mouseMoveEvent(QMouseEvent *event){
if(gamestatus==mapedit){
int i,j;//地图块的二维编号地址
glo.gamemap->cal(event->x(),event->y(),i,j);
if(leftorright==1){//如果移动时候按下左键
glo.gamemap->setstyle(i,j,laststyle);
}
else{
glo.gamemap->deletecell(i,j);

}

}//if(gamestatus==mapedit) end

update();
}

void MainWindow::mousePressEvent(QMouseEvent *event){
int i,j;//地图块的二维编号地址
if(gamestatus==mapedit){
glo.gamemap->cal(event->x(),event->y(),i,j);

if(event->button()==Qt::LeftButton){

//qDebug("i %d",i);
//qDebug("j %d",j);
leftorright=1;
laststyle=glo.gamemap->switchstyle(i,j);
}
else{
glo.gamemap->deletecell(i,j);
leftorright=2;
}
}//if(gamestatus==mapedit) end
update();

}
void MainWindow::mouseReleaseEvent(QMouseEven
acff
t *event){

//update();

}


为了方便管理全局变量,我们在main.h里添加

class QImage;
class GameMap;
typedef struct{
unsigned int framei;
QImage *blockimage;
GameMap *gamemap;
}Glo;//实列化Glo类型变量,能实列化出来,所有的指针变量所占空间daxiao一样。
extern Glo glo;//声明变量


在main.cpp里添加

Glo glo;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: