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

前面实现了地图的显示但是地图很单一,这回实现地图的编辑、保存和载入。
我们给地图类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(QMouseEvent *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;
  • 13
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值