2009年8月29日 星期六

ubuntu9.04美化GRUB2開機畫面

用synaptic安裝grub2,再把grub解除安裝,重開機可能會grub開機錯誤,拿出live cd重建grub後,grub2就會正常了,參考來源:http://www.xxlinux.com/linux/article/accidence/install/20081231/14759.html

grub2支援背景圖片,中文開機選單,如下:


sudo chmod u+w
/boot/grub/grub.cfg
sudo vi
/boot/grub/grub.cfg
改完
sudo chmod u-w /boot/grub/grub.cfg

#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by /usr/sbin/update-grub using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
set default=0
set timeout=5
set root=(hd0,4)
search --fs-uuid --set 391ed808-6c1e-4617-9a4e-7efbdb0eb3de
if font /usr/share/grub/unicode.pff ; then
set gfxmode=640x480
insmod gfxterm
insmod vbe

insmod jpeg

terminal gfxterm
background_image /boot/grub/xxxx.jpeg
fi
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/05_debian_theme ###
##set menu_color_normal=cyan/blue
##set menu_color_highlight=white/blue
### END /etc/grub.d/05_debian_theme ###

### BEGIN /etc/grub.d/10_hurd ###
### END /etc/grub.d/10_hurd ###

### BEGIN /etc/grub.d/10_linux ###
set root=(hd0,4)
search --fs-uuid --set 391ed808-6c1e-4617-9a4e-7efbdb0eb3de
....................

read more...

追蹤子彈

原理很簡單
把敵人座標一直傳給子彈class做計算
寫這個遊戲會一段滿長得時間(有空閒在寫),我想寫出來一個RPG的射擊遊戲,能讓機體升級,購買武器,購買機體,可能的話加上劇情
下面是測試畫面(把附機體子彈一直發射,觀看路徑)

read more...

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;

}








read more...

2009年8月17日 星期一

Qt的繼承

Qt的繼承,觀念和java是一樣的.
之前機體發射子彈,子彈class是由thread來加,這樣變換機體,還要考慮變換子彈,寫起來程式將會變的很複雜.
我發現應該
子彈class應該是由body class來加,這樣我只要一變換body,子彈會隨著body變換,好處thread class幾乎程式碼不動,我要在寫另一種子彈只要繼承原來子彈class,覆寫裡面程序,就可形成另一個子彈class(body class亦是)

下面bullet1.cpp是繼承bullet.cpp而來,我還沒
覆寫裡面程序,所以bullet1和bullet是一樣的class,注意bullet1幾乎沒程式碼窩

body.h
=============================================================
#ifndef BODY_H
#define BODY_H
#include <QWidget>
#include <bullet.h>
#include <bullet1.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:
QVector<bullet*> *bullet_list_Painter;
int body_life;
int xx;
int yy;
int bullet_number;
int x_int;
int y_int;
int bv;
int body_fly;


};

#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;
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;
}

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:
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
{
Q_OBJECT
public:

bullet1(int v,int x,int y,int m );
};

#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)
{


}


read more...

2009年8月15日 星期六

建構子

class用建構子比較好,目的在初始化物件

bullet* p1=new bullet(10,x_int,y_int,+2);產生斜率+2,速度10,開始位置(
x_int,y_int)
這class可產生不同方向的子彈,用斜率運算來達成

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:
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();
void 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;
}
void bullet::path()//enemy路徑運算
{
if(b_m!=0)
{
yy=-bullet_v+yy;
xx=-bullet_v/b_m+xx;
}


}

read more...

2009年8月11日 星期二

在加上一個laser_bullet class(雷射子彈)

原理就是取2點(enemy_king和body這2點),算出斜率

m=(yn-y)/(xn-x);
l*l=
(yn-y)*(yn-y)+(xn-x)*(xn-x); //畢士定理

取得xn和yn,詳細運算在下面程式,最後回傳成QLine



laser_bullet.h

------------------------------------------------------------------------------
#ifndef LASER_BULLET_H
#define LASER_BULLET_H

#include <QWidget>

class laser_bullet : public QWidget
{
public:
laser_bullet(QWidget *parent = 0);
void set_laser_x(int x1);
void set_laser_y(int y1);
void set_laser_x1(int x1);
void set_laser_y1(int y1);
int get_laser_x();
int get_laser_y();
QLine* path();
void set_laser_m();
int get_m();
private:
int xx;
int yy;
int xx1;
int yy1;
int laser_v;
int m;
int laser_length;

};

#endif // LASER_BULLET_H



laser_bullet.cpp
----------------------------------------------------------------------------
#include "laser_bullet.h"
#include <iostream>
#include <math.h>
#include <QLine>
using namespace std;
laser_bullet::laser_bullet(QWidget *parent)
{
laser_v=8;//laser速度
laser_length=50;
xx=0;
yy=0;

m=1;

}
void laser_bullet::set_laser_x(int x1)//一次只能一個
{
this->xx=x1;
}
//設y
void laser_bullet::set_laser_y(int y1)
{
this->yy=y1;
}
//取得x
void laser_bullet::set_laser_x1(int x1)//一次只能一個
{this->xx1=x1;}
void laser_bullet::set_laser_y1(int y1)//一次只能一個
{this->yy1=y1;}

int laser_bullet::get_laser_x()
{
return this->xx;
}
//取得y
int laser_bullet::get_laser_y()
{
return this->yy;
}


void laser_bullet::set_laser_m() //斜率
{
if( xx1-xx!=0 ){ //避免斜率無限大error
this->m=(yy1-yy)/(xx1-xx);
}

//cout << "m=" << m ;
}
int laser_bullet::get_m(){
return this->m;
}
QLine* laser_bullet::path()//enemy路徑運算
{
int xn;
int yn;

if(m<0 && sqrt(1+m*m)!=0) //斜率負時,y增加,x減少
{
yy = yy+laser_v; //y位移量,一定要在yn之前
xx = -laser_v/sqrt(m*m)+xx; //x位移量,一定要在xn之前
yn=yy-m*laser_length/sqrt(1+m*m); //laser長度的y點
xn=xx-laser_length/sqrt(1+m*m); //laser長度的x點

} //斜率正時,y增加,x增加
else
{
yy = yy+laser_v; //y位移量,一定要在yn之前
xx = laser_v/sqrt(m*m)+xx; //x位移量,一定要在xn之前
yn=yy+m*laser_length/sqrt(1+m*m); //laser長度的y點
xn=xx+laser_length/sqrt(1+m*m); //laser長度的x點

}


QLine *p;
p=new QLine; //一定要先初始化否則ERROR
*p=QLine (xx,yy,xn,yn);
return p; //回傳QLine

}

read more...

2009年8月9日 星期日

Qt更換視窗的背景

使用setStyleSheet可輕易更換背景
/new/prefix1/ICON/back-134.gif
這是qrc的路徑,前幾篇文章有教怎樣建立qrc
void Frame::skin1()
{
setStyleSheet("background-image: url(:/new/prefix1/ICON/back-134.gif);");
}

read more...

2009年8月1日 星期六

程式碼

blog不能顯示尖括號,只好寫個sed小程式來取代,要放上程式就要先轉換

目前加上enemy的畫面,enmy是利用qrand()造成亂動畫面,產生一隻enemy就加入QVector,enemy.cpp放著座標

用這個public來設enemy座標
void enemy::set_enemy_x(int x1)//一次只能一個
{
this->enemy_xx=x1;
}
用這個public來取得enemy座標
int enemy::getx()
{
return this->enemy_xx;
}

這個是滿有用的技巧,是當初在玩java時看人用的,套用在C++也通用.

stage.cpp這個是放障礙物的class
bullet.cpp這個是放子彈座標的class
enemy.cpp這個是放敵人的class
whread.cpp這是執行續class
frame.cpp視窗體class


stage.cpp
------------------------------------------------------------------------------------
#include "stage1.h"
#include <QList>
#include <iostream>
#include <QRectF>

using namespace std;
/////////放障礙物mask_lis存著QRectF/////////////////////////////
stage1::stage1()
{
for(int i=0 ; i< 450 ; i += 10)
{
for (int j =0.0 ; j < 40 ; j += 10)
{
QRectF r(i, j, 10.0, 10.0);
mask_list<<r;
}
}
}

QList<QRectF> stage1::get_mask() //回傳mask_list
{
return this->mask_list;
}

void stage1::remove_mask(int i)
{
this->mask_list.removeAt(i);
}


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

bullet::bullet(QWidget *parent)
: QWidget(parent)
{
}
//設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;
}
enemy.cpp
----------------------------------------------------------------------------
#include "enemy.h"
#include "wthread.h"
#include <QThread>
#include <QPainterPath>
#include <QPainter>
#include <QtGui/QFrame>
#include <math.h>
using namespace std;
enemy::enemy(QWidget *parent) //使用parent回傳才能用this
: QWidget(parent)
{
angle=0;
enemy_yy=0;
}

void enemy::set_enemy_x(int x1)//一次只能一個
{
this->enemy_xx=x1;
}
void enemy::set_enemy_y(int y1)
{
this->enemy_yy=y1;
}
void enemy::set_enemy_v(int a1)//一次只能一個
{
this->enemy_v=a1;
}
void enemy::set_enemy_b(int r1)
{
this->enemy_b=r1;
}

int enemy::getx()
{
return this->enemy_xx;
}
int enemy::gety()
{
return this->enemy_yy;
}
int enemy::getv()
{
return this->enemy_v;
}
int enemy::getb()
{
return this->enemy_b;
}

void enemy::path(int x,int y,int b,int v)//enemy路徑運算
{

enemy_yy = enemy_yy + enemy_v ; //目前enemy的y座標+移動值(速度)
enemy_xx = enemy_xx + enemy_v*enemy_b; //目前enemy的x座標+移動值(速度*方向)
//超出frame範圍後座標
if (enemy_xx >450 ){enemy_xx= 0;}
if (enemy_xx <0 ){enemy_xx=450;}
if (enemy_xx >450 ){enemy_xx= 0;}
if (enemy_xx <0 ){enemy_xx=450;}
if (enemy_yy >360 ){enemy_yy= 0;}
if (enemy_yy <0 ){enemy_yy=360;}
if (enemy_yy >360 ){enemy_yy= 0;}
if (enemy_yy <0 ){enemy_yy=360;}
//rand()%10/6/



}
whread.cpp
------------------------------------------------------------------------
#include "wthread.h"
#include <QThread>
#include <QPainterPath>
#include <QPainter>
#include <QtGui/QFrame>
#include <enemy.h>
#include <math.h>
using namespace std;
Wthread::Wthread(QWidget *parent )
: QThread(parent)
{
//可變動變數
bullet_v =10 ;//bullet速度,不能超過enemy高度
enemy_max_v=2 ;//enemy最大速度
thread_s =50;//執行續秒數


//一定要先初始化否則ERROR
bullet_list_Painter=new QVector<bullet*>;
enemy_list_Painter=new QList<enemy*>;

enemy_y=0;
this->set_enemy(new enemy,100,100,1,-1);//產生enemy
this->set_enemy(new enemy,200,300,1,1);//產生enemy
this->set_enemy(new enemy,340,150,1,1);//產生enemy
this->set_enemy(new enemy,170,250,1,-1);//產生enemy

}
//執行續要處裡的事,每100毫秒,做一次信號
void Wthread::run() {

while(true) {
//處裡bullet
int y;
int x;
bullet_p=new QPainterPath;//100ms存一次QpainterPath,更新path
if(bullet_list_Painter->size()==0){ bullet_list_Painter->clear();}
for( int i= 0 ; i < bullet_list_Painter->size(); i++)//處裡QList的子彈
{
y=bullet_list_Painter->at(i)->get_bullet_y()-bullet_v;
x=bullet_list_Painter->at(i)->get_bullet_x()-0;
if( y < -20 ){this->remove_bullet(i);} //超出畫面就移走
else
{
QPainterPath* p=new QPainterPath;
p->addRoundRect(x,y,5.0,5.0,10);
bullet_list_Painter->at(i)->set_bullet_x(x); //新的取代掉,多判斷是避免例外
bullet_list_Painter->at(i)->set_bullet_y(y);
emit bullet_xy(x,y,i);
this->bullet_path(x,y); //子彈
}
}

//處裡enemy
enemy_p=new QPainterPath;

for( int i= 0 ; i < enemy_list_Painter->length(); i++)//處裡QList的enemy
{
int x=enemy_list_Painter->at(i)->getx();//y
int y=enemy_list_Painter->at(i)->gety();//y
int v=enemy_list_Painter->at(i)->getv();//y
int b=enemy_list_Painter->at(i)->getb();//y
enemy_p->addRect(x,y,20,20);
emit e_path(x,y,v,b); //目前信號參數x,y,v,b沒用到
enemy_list_Painter->at(i)->disconnect();
//讓enemy能亂動
if (qrand()%1000000>900000)
{
if (qrand()%1000000>500000)
{
enemy_list_Painter->at(i)->set_enemy_b(-1);//設往負x方向
}
else
{
enemy_list_Painter->at(i)->set_enemy_b(1);//設往正x方向
}
}
//讓enemy速度發生變化
if (qrand()%1000000>900000)
{
if (qrand()%1000000>500000)
{
enemy_list_Painter->at(i)->set_enemy_v(qrand()%enemy_max_v+1);//設往負x方向
}
else
{
enemy_list_Painter->at(i)->set_enemy_v(qrand()%enemy_max_v+1);//設往正x方向
}
}


}
emit setxy(1,1,1,enemy_p, bullet_p);

msleep(thread_s);
}
}
Wthread::~Wthread()
{

}
void Wthread::set_x(int i) //設定子彈x座標,按一下滑鼠
{
this->x_int=i;
}

void Wthread::add_bullet() //加一個子彈QPainterPath
{
if(bullet_list_Painter->size()<4)//最多4顆子彈
{
bullet* p=new bullet;
p->set_bullet_x(x_int);
p->set_bullet_y(300);
bullet_list_Painter->append(p);
}
}
void Wthread::bullet_path(int x,int y)//子彈形狀,從這可改子彈形狀
{
QRectF r(x, y,5.0, 10.0);//橢圓
bullet_p->addEllipse(r);
//bullet_p->addRoundRect(x,y,5.0,5.0,100);
}
void Wthread::remove_bullet(int i) //從QList移走子彈
{
if(!bullet_list_Painter->isEmpty())
{
bullet_list_Painter->remove(i);
}
}

//這是產生enemy的函式
void Wthread::set_enemy(enemy* e,int x,int y,int v,int b)
{
e->set_enemy_x(x); //enemy一定要在之前就宣告否則呼叫2次會error
e->set_enemy_y(y);
e->set_enemy_v(v);
e->set_enemy_b(b);
connect(this, SIGNAL(e_path(int,int,int,int)),e,SLOT(path(int,int,int,int)));
enemy_list_Painter->append(e);//加一隻enemy
}
frame.cpp
--------------------------------------------------------------------------------
#include "frame.h"
#include "ui_frame.h"
#include <QPainter>
#include <math.h>
#include <QMouseEvent>
#include <stage1.h>
#include <QVector>
#include "wthread.h"
using namespace std;

//static const QSize resultSize(5, 5);

Frame::Frame(QWidget *parent) :
QFrame(parent),
m_ui(new Ui::Frame)
{
//初始化設定
m_ui->setupUi(this);
step_value=0;
move_x=0;
move_y=300;
//setMouseTracking(true);//設一開始追蹤mouse
bullet_path=new QPainterPath; //一定要先初始化否則ERROR
enemy_path=new QPainterPath;
thread=new Wthread; //thread 物件化
connect(thread, SIGNAL(setxy(int , int ,int ,QPainterPath*,QPainterPath*)),this, SLOT(setShape(int ,int ,int ,QPainterPath*,QPainterPath*)));
connect(thread, SIGNAL(bullet_xy(int,int,int)),this,SLOT(hit_mask(int ,int, int)));
thread->start();
}

Frame::~Frame()
{
delete m_ui;
}

void Frame::changeEvent(QEvent *e)
{
QFrame::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:
break;
}
}
//SLOT,更新繪圖的值(子彈)
void Frame::setShape(int id,int y,int w,QPainterPath *enemy_path1,QPainterPath *bullet_path1)
{
bullet_path=bullet_path1;
enemy_path=enemy_path1;
update();
}
//繪圖宣告
void Frame::paintEvent(QPaintEvent *event)
{

QPainter painter(this);

///////////////////////////////////機台///////////////////////////
//設定筆刷
painter.setBrush(QColor(112, 186, 39));
//畫出機台
painter.drawPath(this->body_paint(new QPainterPath));
//////////////畫出
//設定筆刷
// painter.setBrush(QColor(112, 186, 39));
painter.drawPath(this->mask_pain(new QPainterPath));
///////////////////////////////////子彈////////////////////////////

painter.setBrush(QColor(212, 16, 39));
painter.drawPath(*bullet_path);
////////////////////////enemy//////////////////////////////////////

painter.setBrush(QColor(12, 16, 139));
painter.drawPath(*enemy_path);

}

//畫出機台
QPainterPath Frame::body_paint(QPainterPath* body)
{

body->addRect(move_x, move_y, 10, 20);
return *body;
}
//畫出障礙
QPainterPath Frame::mask_pain(QPainterPath* mask)
{
//stage1 stage;//放障礙物的class
for (int i = 0; i < stage.get_mask().length(); i++)
{
stage.get_mask().at(i);
mask->addRect(stage.get_mask().at(i));
}
return *mask;
}
//移動機台,繪圖

void Frame::move_body_paint(int x,int y)
{
move_x=x;
move_y=y;
update();
}
//回傳目前body的x,y值
int Frame::get_body_x()
{
return this->move_x;
}
int Frame::get_body_y()
{
return this->move_y;
}

void Frame::mouseMoveEvent(QMouseEvent *e)//滑鼠事件move
{
//move_x=e-> globalX();
//update();
int xx=e->x();
//int xx=e-> globalX(); //x
int yy=e->y(); //y
this->move_body_paint(xx,move_y);

}
void Frame::mousePressEvent(QMouseEvent *event)//滑鼠事件press
{
//按下按鈕,就產生一個子彈QPainterPath加入thread的bullet_list
thread->set_x(this->get_body_x());
thread->add_bullet();

}

void Frame::hit_mask(int bx,int by,int id) //打中障礙物移走障礙
{
for (int i = 0; i < stage.get_mask().length(); i++)
{
int x = stage.get_mask().at(i).x();
int y = stage.get_mask().at(i).y();
if ( x-4 < bx && bx <= x+6 && y-5 < by && by <= y+5 )
{
thread->wait(10);//否則有例外,可能有需要根據情形設定,例外是因為移走QList元素,thread正在處裡QList元素,有可能同步,先讓thread等一下
thread->remove_bullet(id);

stage.remove_mask(i);


}
}


}
--------------------------------------------------end-----------------------


read more...