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-----------------------

沒有留言: