Qt 游戏之路(一) 场景搭建 和 战车移动、地图拉伸


场景信息

//info.cpp文件 存储场景信息
int MAPWIDTH = 1200;
int MAPHEIGHT = 650;
//info.h文件 存储全局变量
#ifndef INFO_H    //全局变量
#define INFO_H

#define SCENEWIDTH 1920
#define SCENEHEIGHT 1200

extern int MAPWIDTH;
extern int MAPHEIGHT;

#endif // INFO_H

游戏客户区 ,由QGraphicsItem、QGraphicsScene、QGraphicsView 图形视图框架搭建

//gamewindow.h
#ifndef GAMEWINDOW_H
#define GAMEWINDOW_H

#include 
#include 
#include 
#include 
#include 
#include 
#include "info.h"
#include "player.h"

class Player;

class GameWindow : public QGraphicsView
{
    Q_OBJECT
    friend class Player;
public:
    GameWindow(QWidget *parent = 0);
    void mousePressEvent(QMouseEvent *event);
public:
    QGraphicsScene *scene; //场景
    Player *player;
    bool canArrive(qreal x, qreal y);
    bool canArrive(QPointF pos);
    void moveto(qreal x, qreal y);
    void moveto(QPointF pos);
    QTimer *timer;  //用于移动
protected:
    void fixClientFor(qreal x, qreal y, bool right, bool down);

private slots:
    void move_use_timer();
};

#endif// GAMEWINDOW_H

实现文件

#include 
#include 
#include "gamewindow.h"

GameWindow::GameWindow(QWidget *parent)
    :QGraphicsView(parent)
{
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //关闭显示
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    horizontalScrollBar()->setRange(0, SCENEWIDTH); //设置滚动条
    verticalScrollBar()->setRange(0, SCENEHEIGHT);
    horizontalScrollBar()->setValue(0);
    verticalScrollBar()->setValue(0);

    player = new Player;

    timer = 0;

}
void GameWindow::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::RightButton)
    {
        moveto(mapToScene(event->pos()));
    }
}

bool GameWindow::canArrive(qreal x, qreal y)
{
    return !(x > SCENEWIDTH || x < 0 || y > SCENEHEIGHT || y < 0);
}
bool GameWindow::canArrive(QPointF pos)
{
    return canArrive(pos.x(), pos.y());
}

void GameWindow::fixClientFor(qreal x, qreal y, bool right, bool down)
{
    qreal cx = horizontalScrollBar()->value();
    qreal cy = verticalScrollBar()->value();

    qreal x = sx - cx;
    qreal y = sy - cy;
    //横向
    if (x > MAPWIDTH * 2/3 && right)
    {
        horizontalScrollBar()->setValue(x - MAPWIDTH * 2/3);
    }
    if (x < MAPWIDTH /3 && !right)
    {
        horizontalScrollBar()->setValue(x - MAPWIDTH /3);
    }
    //纵向
    if (y > MAPHEIGHT * 2/3 && down)
    {
        verticalScrollBar()->setValue(y - MAPHEIGHT * 2/3 );
    }
    if (y < MAPHEIGHT / 3 && !down)
    {
        verticalScrollBar()->setValue(y - MAPHEIGHT /3 );
    }
}


void GameWindow::move_use_timer()
{
    qreal partx = player->arrivepos.x() - player->cpos.x(); //x,y分量
    qreal party = player->arrivepos.y() - player->cpos.y();
    qreal s = sqrt(partx*partx + party*party);  //直线路程
    if (s < 5)
    {
        if (timer->isActive())
        {
            timer->stop();
            delete timer;
            timer = 0;
        }
    }
    else
    {
        qreal movex = partx/s* 5; //每次计时移动距离
        qreal movey = party/s* 5;

        if (canArrive(player->cpos.x() + movex, player->cpos.y() + movey))
        {
            player->cpos.setX(player->cpos.x() + movex);
            player->cpos.setY(player->cpos.y() + movey);
            player->itempix->setPos(player->cpos);
        }
        else
        {
            if (timer->isActive())
            {
                timer->stop();
                delete timer;
                timer = 0;
            }
        }
    }
    fixClientFor(player->cpos.x(), player->cpos.y(), partx > 0, party > 0);
}

void GameWindow::moveto(qreal x, qreal y)
{
    player->arrivepos.setX(x);
    player->arrivepos.setY(y);
    if (!timer)
    {
        timer = new QTimer;
        timer->start(50);
        connect(timer, SIGNAL(timeout()), this, SLOT(move_use_timer()));
    }
}
void GameWindow::moveto(QPointF pos)
{
    moveto(pos.x(), pos.y());
}

主窗口

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include "gamewindow.h"
#include "info.h"

class GameWindow;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void paintEvent(QPaintEvent *);

    Ui::MainWindow *ui;
    GameWindow *client; //视窗
    QGraphicsScene *scene; //场景

};

#endif // MAINWINDOW_H

主窗口实现文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    scene = new QGraphicsScene(this);
    client =  new GameWindow(this);
    client->scene = scene;
    client->setScene(scene);
    client->setFixedHeight(MAPHEIGHT);  //视口
    client->setFixedWidth(MAPWIDTH);

    scene->setSceneRect(0, 0, SCENEWIDTH, SCENEHEIGHT); //场景
    scene->addPixmap(QPixmap(":/pic/back"));
    client->show();

    client->player->itempix = scene->addPixmap(*client->player->pix);
    client->player->setPos(MAPWIDTH/2, MAPHEIGHT/2);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::paintEvent(QPaintEvent *)
{
    client->setFixedHeight(this->height()); // 重绘时重置大小(窗口大小可能被改变)
    client->setFixedWidth(this->width());
    MAPWIDTH = this->width();
    MAPHEIGHT = this->height();
}


资源   :/pic/1.png    

资源   :/pic/back.jpg  由于上传大小问题,建议把这个图片改成png格式



玩家类

#ifndef PLAYER_H
#define PLAYER_H

#include 
#include 
#include "info.h"
#include "mainwindow.h"

class Player : public QWidget
{
    Q_OBJECT

public:
    Player(QWidget * parent = 0);
    ~Player() {}

    void setPos(qreal x, qreal y);
    QPixmap * pix; //角色图组指针
    QGraphicsPixmapItem *itempix;

    QPointF cpos, arrivepos;  //角色坐标,到达目标坐标
    QTimer *timer;  //用于移动
    qreal speed; //速度

};

#endif // PLAYER_H

玩家类实现

#include "player.h"

//Player
Player::Player(QWidget * parent) : QWidget(parent)
{
    timer = 0;
    speed = 5;
    pix = new QPixmap(":/pic/1");
}
void Player::setPos(qreal x, qreal y)
{
    cpos.setX(x);
    cpos.setY(y);
    itempix->setPos(cpos);
}

主函数

#include "info.h"
#include "mainwindow.h"
#include 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow mainw;
    mainw.setMinimumSize(MAPWIDTH, MAPHEIGHT);
    mainw.show();

    return a.exec();
}

posted @ 2014-03-13 23:03  闲云阁  阅读(893)  评论(0编辑  收藏  举报