【四聖龍神錄的程式設計教室】第22章、放炸彈來攻擊吧
這次講炸彈攻擊。
和往常一樣,準備好資訊儲存的地方,然後進行載入,然後讓他自動計算,大概就是這樣的感覺就行了。。。
在之前的章節裡,我們準備了變數來展現特效。
之前敵機消滅時,使用了特效。現在在同一個儲存區裡,載入炸彈的特效看看。
之前也說過了,這個特效變數裡,載入任何特效都是可以的。
以knd作為識別編號的特效,對應的特效被載入後,就那樣一直運算的話,那就可以放在同一個儲存空間裡面了。
龍神錄的炸彈特效是:
“BIU。。。 DON” 這樣的一個特效,(這個的編號為1)
特效的線條上下左右的移動,(這個的編號為2)
從角色身上“咻~”的冒出來的特效,(這個的編號為3)
放炸彈的時候,把這些特效的編號分別進行載入,讓我們來實現一下吧。
首先準備以下的東西。
——————————————————————————————————————————————————————————————————————————
——————————————————————————————————————————————————————————————————————————<span style="font-size:14px;"><span style="font-size:12px;">---- struct.h 新增如下程式碼 ---- //特效 typedef struct{ int flag,cnt,col,knd,img,eff; double x,y,r,ang,spd,mvang,brt; }effect_t; //炸彈的資訊 typedef struct{ int flag,cnt,knd; double x,y; }bom_t; //畫面明暗的資訊 typedef struct{ unsigned char brt; }bright_set_t; //咚!這樣的畫面搖晃的資訊 typedef struct{ int flag,cnt,time,size; int x,y; }dn_t; ---- GV.h 新增如下程式碼 ---- GLOBAL int img_eff_bom[5]; //炸彈的效果的影象 GLOBAL bom_t bom; //炸彈 GLOBAL bright_set_t bright_set; //繪製的亮度 GLOBAL dn_t dn; //咚一下的搖晃 ---- load.cpp load函式裡新增如下程式碼 ---- img_eff_bom[0] = LoadGraph( "../dat/img/effect/bom0.png" ); img_eff_bom[1] = LoadGraph( "../dat/img/effect/bom1.png" ); img_eff_bom[2] = LoadGraph( "../dat/img/char/body.png" ); img_eff_bom[3] = LoadGraph( "../dat/img/bullet/bom_title0.png" ); sound_se[14]=LoadSoundMem("../dat/se/bom0.wav"); sound_se[15]=LoadSoundMem("../dat/se/bom1.wav"); ---- ini.cpp 的 ini函式裡新增如下程式碼 ---- memset(&bom,0,sizeof(bom_t)); memset(&bright_set,0,sizeof(bright_set_t)); memset(&dn,0,sizeof(dn_t)); bright_set.brt=255; ---- out.cpp 的out_main函式改動 ---- //碰撞判定的主函式 void out_main(){ cbom_and_enemy(); cshot_and_enemy(); enemyshot_and_ch(); } ---- out.cpp 的下面任意地方進行改動 ---- //第s個敵人受到炸彈的傷害 void hit_enemy(int s,int power){ enemy[s].hp-=power;//根據炸彈的威力,減去對應的HP enemy_death_judge(s);//判斷敵機是不是掛了 } //炸彈和敵機的處理 void cbom_and_enemy(){ int s; if(bom.flag!=1)return; for(s=0;s<ENEMY_MAX;s++){//敵機總數 if(enemy[s].flag>0) hit_enemy(s,ch.power/20);//第s個敵機扣掉ch.power/20的血 } } //自己子彈和敵機的處理 void cshot_and_enemy(){ int i,s; for(i=0;i<CSHOT_MAX;i++){//自機子彈的總數 if(cshot[i].flag>0){ for(s=0;s<ENEMY_MAX;s++){//敵機總數 if(enemy[s].flag>0){ if(out_judge_cshot(i,s)){//自機子彈和敵機發生碰撞的話 cshot[i].flag=0;//把那個自機子彈消除掉 hit_enemy(s,cshot[i].power);//第s個敵機 扣掉 power那麼多的血 } } } } } } ---- graph.cpp 的 graph_effect 的紅字部分進行追加---- void graph_effect(int knd){ for(int i=0;i<EFFECT_MAX;i++){ if(effect[i].flag>0 && effect[i].knd==knd){ if(effect[i].eff==1)//特效是光的話 SetDrawBlendMode( DX_BLENDMODE_ADD, effect[i].brt) ; if(effect[i].eff==2)//特效是α特效的話 SetDrawBlendMode( DX_BLENDMODE_ALPHA, effect[i].brt) ; DrawRotaGraphF(effect[i].x+FIELD_X+dn.x,effect[i].y+FIELD_Y+dn.y,effect[i].r,effect[i].ang,effect[i].img,TRUE); if(effect[i].eff==1 || effect[i].eff==2) SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ; } } } ---- graph.cpp 的 graph_main 的改動 ---- void graph_main(){ if(bright_set.brt!=255)SetDrawBright(bright_set.brt,bright_set.brt,bright_set.brt); graph_back_main();//繪製背景的主函式 graph_effect(0);//敵機死亡的特效 graph_enemy();//敵機的繪製 graph_cshot();//自機子彈的繪製 if(bright_set.brt!=255)SetDrawBright(255,255,255); graph_ch();//自機的繪製 if(bright_set.brt!=255)SetDrawBright(bright_set.brt,bright_set.brt,bright_set.brt); graph_bullet();//子彈的繪製 if(bright_set.brt!=255)SetDrawBright(255,255,255); graph_effect(1);//炸彈的特效 graph_effect(2);//炸彈線的特效 graph_effect(3);//炸彈人物的特效 graph_board();//板子的繪製 }</span></span>
這次在新的構造體裡,
・儲存炸彈資訊的bom_t,
・儲存畫面明暗資訊的 bright_set_t,
・咚!的搖晃畫面的資訊 dn_t,
準備了這三個東西。
用 bright_set_t 表示的變數,一般都是255,只有當畫面明暗需要變化時才發生變動。
dn_t 這個變數使用方法和以前一樣,載入,計算,在畫面抖動的時候使用。
炸彈的變數的使用方法,都和以前的一樣。
那麼準備工作都做好了。現在就把實際的效果來運算出來看看吧。
————————————————————————————————————————————————————————————————————————
<span style="font-size:14px;"><span style="font-size:12px;">---- effect.cpp 的改動----
#include "../include/GV.h"
//尋找空的特效編號
int search_effect(){
for(int i=0;i<EFFECT_MAX;i++){
if(effect[i].flag==0)
return i;
}
return -1;
}
//對特效進行計算
void calc_effect(){
for(int i=0;i<EFFECT_MAX;i++){
if(effect[i].flag>0){//特效已經載入的話
switch(effect[i].knd){//判斷特效的種類
case 0://敵機消滅的特效
effect[i].cnt++;
effect[i].r+=0.08;//特效的大小逐漸增大
if(effect[i].cnt>10)//計數到10以上的話
effect[i].brt-=25;//明暗度降低
if(effect[i].cnt>20)//計數到20以上的話
effect[i].flag=0;//消失
break;
case 1://炸彈的特效
//座標計算
effect[i].x+=cos(effect[i].mvang)*effect[i].spd;
effect[i].y+=sin(effect[i].mvang)*effect[i].spd;
//速度計算
if(effect[i].cnt<60)
effect[i].spd-=(0.2+effect[i].cnt*effect[i].cnt/3000.0);
if(effect[i].cnt==60){
effect[i].spd=0;
se_flag[15]=1;
dn.flag=1;
dn.cnt=0;
dn.size=11;
dn.time=20;
}
//明暗和大小的計算
effect[i].r+=0.015;
if(effect[i].cnt<51)
effect[i].brt+=5;
if(effect[i].cnt>=60){
effect[i].r+=0.04;
effect[i].brt-=255/30.0;
}
//計數增加,和消除的計算
effect[i].cnt++;
if(effect[i].cnt>=90)
effect[i].flag=0;
break;
case 2://炸彈特效(文字)
//座標計算
effect[i].x+=cos(effect[i].mvang)*effect[i].spd;
effect[i].y+=sin(effect[i].mvang)*effect[i].spd;
//明暗計算
if(effect[i].cnt<51)
effect[i].brt+=4;
if(effect[i].cnt>130-51)
effect[i].brt-=4;
//計數增加,和消除計算
effect[i].cnt++;
if(effect[i].cnt>=130)
effect[i].flag=0;
break;
case 3://炸彈的特效(線條)
//座標計算
effect[i].x+=cos(effect[i].mvang)*effect[i].spd;
effect[i].y+=sin(effect[i].mvang)*effect[i].spd;
//明暗計算
if(effect[i].cnt<51)
effect[i].brt+=2;
if(effect[i].cnt>130-51)
effect[i].brt-=2;
//計數增加,和消除計算
effect[i].cnt++;
if(effect[i].cnt>=130)
effect[i].flag=0;
break;
default:
printfDx("effect設定出錯\n");
break;
}
}
}
}
//尋找消滅特效的空編號
int search_del_effect(){
for(int i=0;i<DEL_EFFECT_MAX;i++){
if(del_effect[i].flag==0)
return i;
}
return -1;
}
//消滅特效的載入
void enter_del_effect(int s){
int k=search_del_effect();
if(k!=-1){
del_effect[k].flag=1;//設定標記
del_effect[k].cnt=0;
del_effect[k].col=enemy[s].back_col;//消滅色用敵機的背景色
del_effect[k].x=enemy[s].x;//消滅位置,設定為敵機的位置
del_effect[k].y=enemy[s].y;
}
}
//消滅特效的計算,載入
void calc_del_effect(){
int k;
for(int i=0;i<DEL_EFFECT_MAX;i++){
if(del_effect[i].flag>0){
if(del_effect[i].cnt%2==0){// 每隔 1/30秒進行設定
if((k=search_effect())!=-1){//尋找空編號
memset(&effect[k],0,sizeof(effect_t));//初始化
effect[k].flag=1;//設定標記
effect[k].brt=255;//亮度設定為最大值
effect[k].ang=rang(PI);//角度進行隨機
effect[k].col=del_effect[i].col;//設定顏色
effect[k].eff=1;//1號是光影特效。設定為光影特效
effect[k].img=img_del_effect[effect[k].col];//設定消除影象
effect[k].knd=0;//特效的種類為0,(消除特效為0號)
effect[k].x=del_effect[i].x;//設定座標
effect[k].y=del_effect[i].y;
effect[k].spd=0;
}
}
if(del_effect[i].cnt>8){
del_effect[i].flag=0;
}
del_effect[i].cnt++;
}
}
}
//炸彈的載入
void enter_bom(){
int k;
bom.flag=1;
bom.cnt=0;
bom.knd=0;
ch.mutekicnt=1;//無敵
se_flag[14]=1;//啾~ 的聲音
//豎線
if((k=search_effect())!=-1){
effect[k].flag=1;
effect[k].cnt=0;
effect[k].knd=3;//炸彈的線條的特效
effect[k].brt=0;//α值
effect[k].ang=PI/2;//影象的朝向
effect[k].mvang=-PI/2;//特效前進的方向
effect[k].spd=1;//速度
effect[k].r=1;//大小
effect[k].eff=2;//α混合
effect[k].img=img_eff_bom[3];
effect[k].x=70;//座標
effect[k].y=300;
}
//橫線
if((k=search_effect())!=-1){
effect[k].flag=1;
effect[k].cnt=0;
effect[k].knd=3;//炸彈的線條的特效
effect[k].brt=0;
effect[k].ang=0;
effect[k].mvang=0;
effect[k].spd=1;
effect[k].r=1;
effect[k].eff=2;
effect[k].img=img_eff_bom[3];
effect[k].x=100;
effect[k].y=350;
}
//字元
if((k=search_effect())!=-1){
effect[k].flag=1;
effect[k].cnt=0;
effect[k].knd=2;//炸彈的文字・線的特效
effect[k].brt=0;
effect[k].ang=0;
effect[k].mvang=-PI/2;
effect[k].spd=0.7;
effect[k].r=1;
effect[k].eff=2;
effect[k].img=img_eff_bom[2];
effect[k].x=260;
effect[k].y=300;
}
}
//炸彈的計算
void bom_calc(){
int n,k,shot_angle[4]={0,PI,PI/2,PI*1.5};//4發特效飛行的角度
if(ch.flag==0 && bom.flag==0){//角色在通常的狀態、炸彈在關閉狀態的話
if(CheckStatePad(configpad.bom)==1){//炸彈鍵被按下的話
enter_bom();
}
}
if(bom.flag==1){//炸彈正在釋放狀態下的話
if(bom.cnt%10==0){//每1/6秒執行一次
n=(bom.cnt/10);
if(n<4 && (k=search_effect())!=-1){
effect[k].flag=1;
effect[k].cnt=0;
effect[k].knd=1;//特效編號1:炸彈的特效
effect[k].brt=0;
effect[k].ang=rang(PI);//影象的朝向隨機
effect[k].mvang=shot_angle[n]-PI/4;//飛行方向
effect[k].spd=13+rang(2);//速度
effect[k].r=0.5;//大小
effect[k].eff=2;//α混合
effect[k].img=img_eff_bom[(bom.cnt/10)/3];//影象
effect[k].x=ch.x;//座標
effect[k].y=ch.y;
}
}
bom.cnt++;
if(bom.cnt<40)
bright_set.brt=255-bom.cnt*5;//影象的明暗設定(變暗)
if(bom.cnt>90)
bright_set.brt=255-40*5+(bom.cnt-90)*5;//影象的明暗設定(變亮)
if(bom.cnt>130){
bom.flag=0;
bright_set.brt=255;
}
}
}
// DUANG 和畫面震動的處理
void dn_calc(){
if(dn.flag==1){
dn.x=(int)rang(dn.size);
dn.y=(int)rang(dn.size);
dn.cnt++;
if(dn.cnt>dn.time){//到達指定的時間就停止
dn.flag=0;
dn.x=0;
dn.y=0;
}
}
}
void effect_main(){
dn_calc();//DUANG 和畫面震動的處理
calc_del_effect();//消除特效的計算
calc_effect();//特效的計算
bom_calc();//炸彈的計算
}</span></span>
————————————————————————————————————————————————————————————————————————
enter_bom 裡,炸彈進行載入播放。載入的炸彈在130 個計數內進行計算,
進行載入特效,畫面的明暗度調整等。
calc_effect()函式是特效的計算函式、添加了對本次新增的1,2,3號特效的處理。
執行結果:
(PS: 繼續來填坑。。。 公司專案蛋疼。。。照著成功專案換皮,問題是,你皮難看,做出來的東西還不是隻能呵呵。。。 結果和原先的相差無幾。。。
好啦,過兩天要考科二了。攢人品啊攢人品。。
文字基本是照翻,有啥不通順的,對照程式碼看吧。。。 我程式碼還沒仔細看呢。。。)
本人CSDN部落格目錄: