2010年1月5日 星期二

利用Qt 4.6強大的QPropertyAnimation功能,來自製2D遊戲開發框架

我又對qgame_move這個類,寫了幾個功能
1.能指定要移動幾次
2.或是重複一直移動
3.目前移動完成會消失(當然我想移動完成不消失會在寫進去,現在還沒寫)

我是用QPropertyAnimation的finished()信號來完成,這是當完成移動後會發出finished()信號
move_obj->start(QAbstractAnimation:: KeepWhenStopped );
move_obj->start(QAbstractAnimation::DeleteWhenStopped);
這2個差別就是當QPropertyAnimation完成移動後,是否保留或是刪除,若是要寫能重複移動就要用
move_obj->start(QAbstractAnimation:: KeepWhenStopped );

來看看下面簡單幾行使用qgame_move這個類,幾行程式,就讓圖片產生不同移動狀態,是不是傻眼了.

mainwindow.cpp
====================================================
QPixmap birdimg=QPixmap(":/new/prefix1/Star.bmp").scaled(40,40);
//move1 移動一次,移動物消失
QPoint p1(0, 360);
QPoint p2(310, 180);
QGame_move *a1=new QGame_move(p1,p2,1,"DELETE",birdimg,ui->graphicsView);
//move2 移動5次,移動物消失
QPoint p3(620, 360);
QPoint p4(310, 180);
QGame_move *a2=new QGame_move(p3,p4,5,"DELETE",birdimg,ui->graphicsView);
//move3 重複移動
QPoint p5(0, 0);
QPoint p6(310, 180);
QGame_move *a3=new QGame_move(p5,p6,1,"LOOP",birdimg,ui->graphicsView);

qgame_move.h
=====================================================
#ifndef QGAME_MOVE_H
#define QGAME_MOVE_H
#include <QWidget>
#include <QObject>
#include <QLabel>
#include <QPixmap>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>
#include <QParallelAnimationGroup>
#include <QTimer>
#include <QAbstractAnimation>

class QGame_move : public QWidget {
Q_OBJECT
public:
QGame_move(QPoint startp,QPoint endp,int loop_count,QString end_style,QPixmap image,QWidget *parent = 0);
private:
QPropertyAnimation *move_obj;
QLabel *move_obj_label;
public slots:
void clear_move_obj();
void loop_move_obj();
};

#endif // QGAME_MOVE_H


qgame_move.cpp
=====================================================
#include "qgame_move.h"

QGame_move::QGame_move(QPoint startp,QPoint endp,int loop_count,QString end_style,QPixmap image,QWidget *parent) :
QWidget(parent)
{
int i=0;
if(end_style=="DELETE")i=1;
if(end_style=="LOOP")i=2;

move_obj_label=new QLabel(parent);
move_obj_label->setPixmap(image);
move_obj=new QPropertyAnimation(move_obj_label, "pos");
move_obj->setDuration(2000);
move_obj->setStartValue(startp); //起始點
move_obj->setEndValue(endp); //結束點
move_obj->start(QAbstractAnimation:: KeepWhenStopped ); //動畫開始
//move_obj->start(QAbstractAnimation::DeleteWhenStopped);//動畫開始
move_obj->setDirection( QAbstractAnimation::Forward); //向前
//anim1->setDirection( QAbstractAnimation::Backward); //這各用移動完成信號能造成來回移動
move_obj->setLoopCount(loop_count); //重複幾次
switch(i)
{
case 1:connect(move_obj,SIGNAL(finished()),this,SLOT(clear_move_obj()));break;//當物件移動完成信號連結到信號曹清除
case 2:connect(move_obj,SIGNAL(finished()),this,SLOT(loop_move_obj()));break; //當物件移動完成信號連結到信號曹再一次開始移動
}
//anim1->setDirection(QAbstractAnimation::DeleteWhenStopped);

}
void QGame_move::clear_move_obj() //清除移動物件
{
this->move_obj_label->clear();
} //再一次開始移動
void QGame_move::loop_move_obj()
{
this->move_obj->start(QAbstractAnimation:: KeepWhenStopped );
}


這4個例子畫面都從qgame_move類就造出不同動畫,當然還可變化出更多動畫(qgame_move類我又寫進了一些功能,才有下面變化)
類似青蛙過街的畫面:

類似賽車畫面:




類似俄羅斯方塊





(射擊遊戲)