QT 图形视图框架之角色移动

来源:互联网 发布:大纲软件 编辑:程序博客网 时间:2024/05/18 03:40

继续学习图形视图框架~

唔,因为要做游戏,游戏对象很多都需要持续的播放,所以把之前做的Blast类抽出动画来。。。

Object.h

#ifndef OBJECT_H#define OBJECT_H#include <QGraphicsItem>#include <QBasicTimer>class Object:public QObject,public QGraphicsItem{    Q_OBJECTpublic:    Object();    Object(const QString &FileName,const QPoint &Count,const bool &Direction=true);    void setAnimationPixmap(const QList<QList<QPixmap>> Pixmap){m_Pixmap = Pixmap;}    bool setAnimationPixmap(const QString &FileName, const QPoint &Count, const bool &Direction=true);    bool addAnimationMovieFile(const QString &FileName);    void start(const int &msec=150);    void stop();    void setState(const int &State){m_State = State;}    bool isStop()const{return m_Timer->isActive();}    bool isDestructible()const{return m_Destruction;}    QRectF boundingRect() const;    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR);private:    int m_State;    int m_Index;    bool m_Destruction;    QBasicTimer *m_Timer;    QList<QList<QPixmap>> m_Pixmap;protected:    void timerEvent(QTimerEvent *event);};#endif // OBJECT_H


Object.cpp

#include "object.h"#include <QTimerEvent>#include <QPainter>#include <QMessageBox>#include <QMovie>Object::Object()    :m_Index(0)    ,m_State(0)    ,m_Destruction(false){    m_Timer = new QBasicTimer;}Object::Object(const QString &FileName, const QPoint &Count, const bool &Direction)    :m_Index(0)    ,m_State(0)    ,m_Destruction(false){        m_Timer = new QBasicTimer;    if(setAnimationPixmap(FileName,Count,Direction))    {        QMessageBox::warning(NULL,u8"警告!",u8"加载图片失败",QMessageBox::Yes,QMessageBox::Yes);        return;    }}bool Object::setAnimationPixmap(const QString &FileName, const QPoint &Count, const bool &Direction){    QPixmap *Pixmap = new QPixmap;    if(!Pixmap->load(FileName))        return true;    const int &WidthCount = Count.x();    const int &HeightCount = Count.y();    int Width = Pixmap->width() / WidthCount;    int Height = Pixmap->height() / HeightCount;    if(Direction)    {        for(int y=0; y<HeightCount; y++)//从左向右拆分        {            m_Pixmap << QList<QPixmap>();            for(int x=0; x<WidthCount; x++)                m_Pixmap[y] << Pixmap->copy(x*Width,y*Height,Width, Height);        }    }    else    {        for(int x=0; x<WidthCount; x++)//从上到下拆分        {            m_Pixmap << QList<QPixmap>();            for(int y=0; y<HeightCount; y++)                m_Pixmap[x] << Pixmap->copy(x*Width,y*Height,Width, Height);        }    }    return false;}bool Object::addAnimationMovieFile(const QString &FileName)//抽出gif的帧{    QMovie *Movie = new QMovie(FileName);    if(!Movie->frameCount())        return true;    m_Pixmap << QList<QPixmap>();    const int Count = m_Pixmap.count()-1;    do    {        m_Pixmap[Count] << Movie->currentPixmap();    }while(Movie->jumpToNextFrame());    return false;}void Object::start(const int &msec){    m_Timer->start(msec,this);}void Object::stop(){    m_Index = 0;    m_Timer->stop();}QRectF Object::boundingRect() const{    if(!m_Pixmap.count() )        return QRectF();    qreal penWidth = 1;         return QRectF(-m_Pixmap[0][0].width()/2- penWidth / 2, -m_Pixmap[0][0].height()/2- penWidth / 2,                       m_Pixmap[0][0].width() + penWidth, m_Pixmap[0][0].height() + penWidth);}void Object::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){    Q_UNUSED(widget);    Q_UNUSED(option);    if(!m_Pixmap.count() || m_State > m_Pixmap.count()-1)        return;    if(!m_Pixmap[m_State].count() || m_Index > m_Pixmap[m_State].count()-1)        return;    painter->drawPixmap(boundingRect().x()                        ,boundingRect().y()                        ,boundingRect().width()                        ,boundingRect().height()                        ,m_Pixmap[m_State][m_Index]);    this->update();}void Object::timerEvent(QTimerEvent *event){    if(!m_Pixmap.count() || m_State > m_Pixmap.count()-1)        return;    if(!m_Pixmap[m_State].count() || m_Index > m_Pixmap[m_State].count()-1)        return;    if(event->timerId() == m_Timer->timerId())    {        m_Index = ++m_Index % m_Pixmap[m_State].count();    }}



现在就来做一下移动类,首先继承上面的类

GameCharacter.h

#ifndef GAMECHARACTER_H#define GAMECHARACTER_H#include "object.h"#include <QTimer>class GameCharacter:public Object{public:    GameCharacter();    void moveLeft(const int &Index);    void moveRight(const int &Index);    void moveUp(const int &Index);    void moveDown(const int &Index);    void addBubble(){m_Bubble++;}    void delBubble(){if(m_Bubble)m_Bubble--;}    int getBubbleNumber()const{return m_Bubble;}    void setMsec(const int &Mesc){m_Msec = Mesc;}    void stopMove(){stop();m_MoveTimer->stop();}private slots:    void timeOut();private:    int m_Msec;    int m_Speed;    int m_xSpeed;    int m_ySpeed;    int m_Bubble;    QTimer *m_MoveTimer;    void startMove(const int &Index);};#endif // GAMECHARACTER_H


GameCharacter.cpp

#include "gamecharacter.h"#include <QGraphicsScene>GameCharacter::GameCharacter()    :m_Speed(5)    ,m_Msec(10)    ,m_Bubble(1){    m_MoveTimer = new QTimer(this);    connect( m_MoveTimer, &QTimer::timeout,this,&GameCharacter::timeOut);}void GameCharacter::moveLeft(const int &Index){    m_xSpeed = -m_Speed;    m_ySpeed = 0;    startMove(Index);}void GameCharacter::moveRight(const int &Index){    m_xSpeed = m_Speed;    m_ySpeed = 0;    startMove(Index);}void GameCharacter::moveUp(const int &Index){    m_xSpeed = 0;    m_ySpeed = -m_Speed;    startMove(Index);}void GameCharacter::moveDown(const int &Index){    m_xSpeed = 0;    m_ySpeed = m_Speed;    startMove(Index);}void GameCharacter::startMove(const int &Index){    if(!m_MoveTimer->isActive())        m_MoveTimer->start(m_Msec);    if(!isStop())        start();    setState(Index);}void GameCharacter::timeOut(){     moveBy(m_xSpeed,m_ySpeed);}

唔相信这个类非常易于理解,其实就是利用时间上下左右移动而已,来试试

role = new GameCharacter;    role->setAnimationPixmap(u8"E:/code/QThang/QQT素材/走图/Done_body13001_walk.png",QPoint(4,4));    role->setMsec(10);    scene->addItem(role);

void QThang::keyPressEvent(QKeyEvent *event){    keyEvent(event);    QGraphicsView::keyPressEvent(event);}void QThang::keyReleaseEvent(QKeyEvent *event){    switch(event->key())    {    case Qt::Key_Space:        putDown();    }     keyEvent(event);    if(!event->isAutoRepeat())    {        role->stopMove();    }    QGraphicsView::keyReleaseEvent(event);}void QThang::keyEvent(QKeyEvent *event){    switch(event->key())    {    case Qt::Key_Left:        role->moveLeft(1);        break;    case Qt::Key_Right:        role->moveRight(2);        break;    case Qt::Key_Up:        role->moveUp(3);        break;    case Qt::Key_Down:        role->moveDown(0);    }}

至于role->moveLeft(1);这个0-3是什么

请结合http://blog.csdn.net/qq_17813937/article/details/51291216的图自己猜


相信到这里运行后肯定会发现有时候移动有时候很流畅,有时候会卡着在哪里,至于怎么解决。。。。抱歉我还没找到,如果你找到了方法,并且愿意公开,期待你的评论


大笑原谅我表达能力差~

0 0
原创粉丝点击