继续学习图形视图框架~
唔,因为要做游戏,游戏对象很多都需要持续的播放,所以把之前做的Blast类抽出动画来。。。
Object.h
#ifndef OBJECT_H #define OBJECT_H #include <QGraphicsItem> #include <QBasicTimer> class Object:public QObject,public QGraphicsItem { Q_OBJECT public: 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
#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); } }
请结合http://blog.csdn.net/qq_17813937/article/details/51291216的图自己猜
相信到这里运行后肯定会发现有时候移动有时候很流畅,有时候会卡着在哪里,至于怎么解决。。。。抱歉我还没找到,如果你找到了方法,并且愿意公开,期待你的评论
原谅我表达能力差~