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