2009年8月21日 星期五

在QT設計多載建構子和介面

A.

要處理不同body(機體),想了好久,才想出要用介面來當成溝通不同機體的橋樑,滿妙的窩,當按一下按鈕就能更換body和同時更換子彈,bullet1是繼承bullet而來,body1是繼承了body而來,並改寫部份程序.
只要我想在增加body2,bullet2,
繼承body,bullet,改寫部份程序,又是另一個機體和武器,並在介面加一些溝通body程式既可
介面是放在bodylist class

下面是呼叫不同body程序,
new bodylist(new body(500,10,4))是產生一個新機體
void Frame::change_body(int i)
{
switch (i)
{
case 0 : this->thisbody=new bodylist(new body(500,10,4));thread->set_bodylist(thisbody);break ;
case 1 : this->thisbody=new bodylist(new body1(500,10,4));thread->set_bodylist(thisbody);break ;
}
}
目前換機體只換子彈大小,後續會改寫子彈路徑,威力和機體形狀

B.多載建構子宣告,注意
body* b和body1* b是不同body,來達成多載

bodylist(body* b,QWidget *parent=0); //多載,利用多載來設定不同機體,注意*parent=0和*parent不同
bodylist(body1* b1,QWidget *parent=0);//多載,利用多載來設定不同機體

C.介面

////增加body,此處介面要記得加上去

#include "bodylist.h"

bodylist::bodylist(body* b ,QWidget *parent)
{
body_0=b; //body初始化
body_id=0; //id
}
bodylist::bodylist(body1* b1 ,QWidget *parent)
{
body_1=b1; //body初始化
body_id=1; //id
}

void bodylist::set_x(int i)
{
switch(body_id)
{
case 0:this->body_0->set_x(i);break;
case 1:this->body_1->set_x(i);break;
}

}
void bodylist::set_y(int i)
{
switch(body_id)
{
case 0:this->body_0->set_y(i);break;
case 1:this->body_1->set_y(i);break;
}

}
.................

body ,bullet 和bodylist介面程式碼

bullet.h
-------------------------------------------------------------------------------
#ifndef BULLET_H
#define BULLET_H

#include <QWidget>

class bullet : public QWidget
{
Q_OBJECT
public:
bullet(int v,int x,int y,int m,QWidget *parent = 0);//建構子,目的初始化物件

//private:
public:
int b_m;
int xx;
int yy;
int bullet_v;

public:
void set_bullet_x(int x1);
void set_bullet_y(int y1);
int get_bullet_x();
int get_bullet_y();
QRectF path();
};

#endif // BULLET_H

bullet.cpp
----------------------------------------------------------------------------------
//用這個class來放bullet的x,y座標
#include "bullet.h"

bullet::bullet(int v,int x,int y,int m,QWidget *parent)
: QWidget(parent)
{
bullet_v=v; //這設bulle速度,不能太快(不要超過目標y軸),擊中目標判斷會錯
xx=x; //初始化子彈x
yy=y; //初始化子彈y
b_m=m; //斜率

}
//設x
void bullet::set_bullet_x(int x1)//一次只能一個
{
this->xx=x1;
}
//設y
void bullet::set_bullet_y(int y1)
{
this->yy=y1;
}
//取得x
int bullet::get_bullet_x()
{
return this->xx;
}
//取得y
int bullet::get_bullet_y()
{
return this->yy;
}
QRectF bullet::path()//enemy路徑運算
{

if(b_m!=0&&b_m!=999&&b_m!=-999)
{
yy=-bullet_v+yy;
xx=-bullet_v/b_m+xx;
}
if(b_m==-999) //這來代表斜率-0
{
yy=yy;
xx=xx-bullet_v;
}
if(b_m==999) //這來代表斜率+0
{
yy=yy;
xx=xx+bullet_v;
}
QRectF r(xx, yy,5.0, 10.0);

return r;//橢圓

}

bullet1.h
---------------------------------------------------------------------------------
#ifndef BULLET1_H
#define BULLET1_H
#include "bullet.h"
#include <QObject>

class bullet1 :public bullet //繼承bullet
{
Q_OBJECT

public:

bullet1(int v,int x,int y,int m );
virtual QRectF path(); //覆寫

};

#endif // BULLET1_H

bullet1.cpp
--------------------------------------------------------------------------------
#include "bullet1.h"
#include "bullet.h"
bullet1::bullet1(int v,int x,int y,int m):bullet(v,x,y,m)//用call 叫bullet建構子
{


}


QRectF bullet1::path()//enemy路徑運算
{

if(b_m!=0&&b_m!=999&&b_m!=-999)
{
yy=-bullet_v+yy;
xx=-bullet_v/b_m+xx;
}
if(b_m==-999) //這來代表斜率-0
{
yy=yy;
xx=xx-bullet_v;
}
if(b_m==999) //這來代表斜率+0
{
yy=yy;
xx=xx+bullet_v;
}
QRectF r(xx, yy,10.0, 10.0);

return r;//橢圓

}

body.h
-------------------------------------------------------------------------
#ifndef BODY_H
#define BODY_H
#include <QWidget>
#include <bullet.h>

class body :public QWidget
{
Q_OBJECT
public:
body(int life ,int v,int no,QWidget *parent = 0);


QPainterPath body_paint1(int move_x,int move_y);

void set_life(int i);
int get_life();
void get_body_fly(int i);
void add_bullet(int i);
void set_x(int i);
void set_y(int i);
QVector<bullet*> *get_bullet_list();
void remove_bullet(int i);
//private:
public:


int body_life;
int xx;
int yy;
int bullet_number;
int x_int;
int y_int;
int bv;
int body_fly;
private:
QVector<bullet*> *bullet_list_Painter;
};

#endif // BODY_H

body.cpp
----------------------------------------------------------------------------------
//一種機體放不同武器,更換機體子彈就會跟著變換武器,要產生機體只要繼承body,改寫方法既可,好棒的想法
#include "body.h"

body::body(int life,int v,int no,QWidget *parent)//機體生命,子彈速度,子彈數


{
//可變初始化,譬如機體升級,life加大,發射數變大,加快
body_life=life; //機體生命
body_fly=0; //bullet1* p1=new bullet1(bv,x_int-12,y_int,999999);
bullet_number=no;//子彈數
bv=v; //子彈速度
bullet_list_Painter=new QVector<bullet*>;

}




QPainterPath body::body_paint1(int move_x,int move_y)
{
xx=move_x;
yy=move_y;

QPainterPath* body;
body=new QPainterPath;
body->moveTo(move_x-2,move_y);

body->lineTo(move_x,move_y-5);
body->lineTo(move_x+2,move_y);
body->lineTo(move_x+2,move_y+5);
body->lineTo(move_x+12,move_y+5);
body->lineTo(move_x+12,move_y+10);
body->lineTo(move_x-12,move_y+10);
body->lineTo(move_x-12,move_y+5);
body->lineTo(move_x-2,move_y+5);

body->lineTo(move_x-2,move_y);



if(body_fly==1)
{
QRectF r0(move_x-14, move_y+2, 2, 10 );
QRectF r1(move_x+12, move_y+2, 2, 10 );
body->addRect(r0);
body->addRect(r1);
}

if(body_fly==2)
{
QRectF r0(move_x-14, move_y+2, 2, 10 );
QRectF r1(move_x+12, move_y+2, 2, 10 );
QRectF r2(move_x-1, move_y+2, 2, 10 );
body->addRect(r0);
body->addRect(r1);
body->addRect(r2);

}

if(body_fly==3)
{
QRectF r0(move_x-24, move_y+2, 10, 10 );
QRectF r1(move_x+12, move_y+2, 10, 10 );
body->addEllipse(r0);;
body->addEllipse(r1);;

}


return *body;
}
void body::get_body_fly(int i)
{
body_fly=i;
}







void body::set_life(int i)
{
this->body_life=i;
}
int body::get_life()
{
return this->body_life;
}
///////////////////////////////
void body::set_x(int i)
{
this->x_int=i;
}
void body::set_y(int i)
{
this->y_int=i;
}

void body::add_bullet(int i)
{
if(i==0)//單一
{
if(bullet_list_Painter->size()<bullet_number)//最多bullet_number顆子彈
{
bullet* p=new bullet(bv,x_int,y_int,999999);//速度10斜率無限大的子彈


bullet_list_Painter->append(p);
}

}
if(i==1)//2列
{
if(bullet_list_Painter->size()<bullet_number*2)//最多bullet_number顆子彈
{
bullet* p=new bullet(bv,x_int-12,y_int,999999);//速度10斜率無限大的子彈
bullet_list_Painter->append(p);
bullet* p1=new bullet(bv,x_int+12,y_int,999999);//速度10斜率無限大的子彈
bullet_list_Painter->append(p1);
}

}
if(i==2)//3列
{
if(bullet_list_Painter->size()<bullet_number*3)//最多bullet_number顆子彈
{
bullet* p=new bullet(bv,x_int,y_int,-2); //速度10,斜率-2的子彈
bullet_list_Painter->append(p);
bullet* p1=new bullet(bv,x_int,y_int,+2); //速度10,斜率2的子彈
bullet_list_Painter->append(p1);
bullet* p2=new bullet(bv,x_int,y_int,999999);//速度10,斜率無限大的子彈
bullet_list_Painter->append(p2);

}

}
if(i==3)//5列
{
if(bullet_list_Painter->size()<bullet_number*5)//最多bullet_number顆子彈
{
bullet* p1=new bullet(bv,x_int,y_int,-999); //速度10,斜率-2的子彈
bullet* p2=new bullet(bv,x_int,y_int,-2);
bullet* p3=new bullet(bv,x_int,y_int,+999); //速度10,斜率2的子彈
bullet* p4=new bullet(bv,x_int,y_int,+2);
bullet* p5=new bullet(bv,x_int,y_int,999999);//速度10,斜率無限大的子彈
bullet_list_Painter->append(p1);
bullet_list_Painter->append(p2);
bullet_list_Painter->append(p3);
bullet_list_Painter->append(p4);
bullet_list_Painter->append(p5);
}
}

}
void body::remove_bullet(int i)
{
if(!bullet_list_Painter->isEmpty())
{
this->bullet_list_Painter->remove(i);
}
}


QVector<bullet*> *body::get_bullet_list()
{
return bullet_list_Painter;
}

body1.h
-----------------------------------------------------------------------------------
#ifndef BODY1_H
#define BODY1_H
#include "body.h"
#include <bullet1.h>
class body1:public body
{
public:
body1(int life ,int v,int no);

virtual void add_bullet(int i); //覆寫
virtual void remove_bullet(int i); //覆寫
virtual QVector<bullet1*> *get_bullet_list();//覆寫

private:
QVector<bullet1*> *bullet1_list_Painter;
};

#endif // BODY1_H

body1.cpp
-----------------------------------------------------------------------------
#include "body1.h"
#include <iostream>


using namespace std;

body1::body1(int life ,int v,int no):body(life ,v,no)
{
bullet1_list_Painter=new QVector<bullet1*>;

}
void body1::add_bullet(int i)
{
if(i==0)//單一
{

if(bullet1_list_Painter->size()<bullet_number)//最多bullet_number顆子彈
{
bullet1* p=new bullet1(bv,x_int,y_int,999999);//速度10斜率無限大的子彈
bullet1_list_Painter->append(p);
}

}
if(i==1)//2列
{
if(bullet1_list_Painter->size()<bullet_number*2)//最多bullet_number顆子彈
{
bullet1* p=new bullet1(bv,x_int-12,y_int,999999);//速度10斜率無限大的子彈
bullet1_list_Painter->append(p);
bullet1* p1=new bullet1(bv,x_int+12,y_int,999999);//速度10斜率無限大的子彈
bullet1_list_Painter->append(p1);
}

}
if(i==2)//3列
{
if(bullet1_list_Painter->size()<bullet_number*3)//最多bullet_number顆子彈
{
bullet1* p=new bullet1(bv,x_int,y_int,-2); //速度10,斜率-2的子彈
bullet1_list_Painter->append(p);
bullet1* p1=new bullet1(bv,x_int,y_int,+2); //速度10,斜率2的子彈
bullet1_list_Painter->append(p1);
bullet1* p2=new bullet1(bv,x_int,y_int,999999);//速度10,斜率無限大的子彈
bullet1_list_Painter->append(p2);

}

}
if(i==3)//5列
{
if(bullet1_list_Painter->size()<bullet_number*5)//最多bullet_number顆子彈
{
bullet1* p1=new bullet1(bv,x_int,y_int,-999); //速度10,斜率-2的子彈
bullet1* p2=new bullet1(bv,x_int,y_int,-2);
bullet1* p3=new bullet1(bv,x_int,y_int,+999); //速度10,斜率2的子彈
bullet1* p4=new bullet1(bv,x_int,y_int,+2);
bullet1* p5=new bullet1(bv,x_int,y_int,999999);//速度10,斜率無限大的子彈
bullet1_list_Painter->append(p1);
bullet1_list_Painter->append(p2);
bullet1_list_Painter->append(p3);
bullet1_list_Painter->append(p4);
bullet1_list_Painter->append(p5);
}
}

}
void body1::remove_bullet(int i)
{
if(!bullet1_list_Painter->isEmpty())
{
this->bullet1_list_Painter->remove(i);
}
}


QVector<bullet1*> *body1::get_bullet_list()
{

return bullet1_list_Painter;

}

bodylist.h
-----------------------------------------------------------------
//////////body介面,用這個來放不同body//////////////////////////////////////////////////////////////

#ifndef BODYLIST_H
#define BODYLIST_H

#include <QWidget>
#include <body.h>
#include <body1.h>

class bodylist:public QWidget
{

public:
body* body_0;
body1* body_1;
bodylist(body* b,QWidget *parent=0); //多載,利用多載來設定不同機體,注意*parent=0和*parent不同
bodylist(body1* b1,QWidget *parent=0);//多載,利用多載來設定不同機體
int get_body_life();
void set_x(int i);
void set_y(int y);
void add_bullet(int i);
void get_body_fly(int i);
QVector<QRectF> *bullet_path();
void remove_bullet(int i);
QPainterPath body_paint(int move_x,int move_y);
int get_bullet_number();
private:
int body_id; //識別id

};

#endif // BODYLIST_H

bodylist.cpp
--------------------------------------------------------------------------------
////增加body,此處介面要記得加上去

#include "bodylist.h"

bodylist::bodylist(body* b ,QWidget *parent)
{
body_0=b; //body初始化
body_id=0; //id
}
bodylist::bodylist(body1* b1 ,QWidget *parent)
{
body_1=b1; //body初始化
body_id=1; //id
}

void bodylist::set_x(int i)
{
switch(body_id)
{
case 0:this->body_0->set_x(i);break;
case 1:this->body_1->set_x(i);break;
}

}
void bodylist::set_y(int i)
{
switch(body_id)
{
case 0:this->body_0->set_y(i);break;
case 1:this->body_1->set_y(i);break;
}

}

//取得body life
int bodylist::get_body_life() //取得body life
{
int life;

switch(body_id)
{
case 0:life=this->body_0->get_life();break;
case 1:life=this->body_1->get_life();break;
}
return life;
}
//獲得機體翅膀
void bodylist::get_body_fly(int i)
{
switch(body_id)
{
case 0:this->body_0->get_body_fly(i);break;
case 1:this->body_1->get_body_fly(i);break;
}
}
//加子彈
void bodylist::add_bullet(int i)
{
switch(body_id)
{
case 0:this->body_0->add_bullet(i);break;
case 1:this->body_1->add_bullet(i);break;
}
}
//子彈數
int bodylist::get_bullet_number()
{
int size;
switch(body_id)
{
case 0:size=this->body_0->get_bullet_list()->size();break;
case 1:size=this->body_1->get_bullet_list()->size();break;
}
return size;
}
//移走子彈
void bodylist::remove_bullet(int i)
{
switch(body_id)
{

case 0:
{
this->body_0->remove_bullet(i);
;break;
}

case 1:
{
this->body_1->remove_bullet(i);
;break;
}
}
}
//取得子彈path list,是QRectF list
QVector<QRectF> *bodylist::bullet_path()
{
QVector<QRectF> *list;
list=new QVector<QRectF>;
switch(body_id)
{

case 0:
{
for(int i=0;i<this->body_0->get_bullet_list()->size();i++)
{
list->append(body_0->get_bullet_list()->at(i)->path());
}
;break;
}

case 1:
{
for(int i=0;i<this->body_1->get_bullet_list()->size();i++)
{
list->append(body_1->get_bullet_list()->at(i)->path());
}
;break;
}
}
return list; //回傳子彈的QRectF list
}
QPainterPath bodylist::body_paint(int move_x,int move_y)
{

QPainterPath b;
//b=new QPainterPath;
switch(body_id)
{

case 0:
{
b= this->body_0->body_paint1(move_x,move_y);
;break;
}

case 1:
{
b= this->body_1->body_paint1(move_x,move_y);
;break;
}
}
return b;

}







video

沒有留言: