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();
}


  
  
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值