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

来源:互联网 发布:真正的绝望是什么知乎 编辑:程序博客网 时间:2024/06/09 16:13

前面实现了地图的显示但是地图很单一,这回实现地图的编辑、保存和载入。
我们给地图类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_OBJECTpublic:    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) endupdate();}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) endupdate();}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;