怎样做小游戏挖金子(VC,源码5)
今天的程序講課,開始。
前面幾講,涉及程序框架、地圖文件、叉子的擺動、旋轉拉伸,這幾方面都可以歸納為基本數據處理,今天講“交互”,很簡單,判斷叉子抓到物品,當拉回后,增加金錢數量。核心是碰撞檢測。
網上的這個游戲是FLASH作的,FLASH的碰撞檢測就一個函數,即可實現各式各樣的圖形檢測。VC中,就用自己動手。最初的想法,是把叉子看成一個圓形,各種礦石也看成圓形,做兩個圓形的檢測,只要檢測圓心距離就可以了。看起來很好,我還是用了另外一個方法,叉子口的連線是一個線段,礦石看成圓形,檢測線段和圓是否相交。代碼如下:
int?GAMEMAP::DetectCatch(int?x,int?y,int?iangle){
????int?i;
????int?j;
????int?x0,y0;?//中點
????int?tempx,tempy;
????int?xoff,yoff;
????//將爪子邊上的直線5等分,依次取點比較
????int?point[]={0,2,4,-2,-4};
????if(iCatchId!=-1)
????{
????????return?0;//當前已經獲得了物品
????}
????xoff=8*cos(10*iangle*1.57/90);
????yoff=8*sin(10*iangle*1.57/90);
????x0=x+8*xoff;//中點坐標
????y0=y+8*yoff;
????for(i=0;i<iObjectNum;i++)
????{
????????//如果當前物品已經取走,繼續判斷下一個
????????if(0==objectarray[i].id)
????????????continue;
????????for(j=0;j<5;j++)
????????{
????????????tempx=x0+point[j]*yoff;
????????????tempy=y0-point[j]*xoff;
????????????if(CmpDistance(objectarray[i].x+objecthit[objectarray[i].id-1].x,
????????????????objectarray[i].y+objecthit[objectarray[i].id-1].y,
????????????????tempx,tempy,
????????????????objecthit[objectarray[i].id-1].id))
????????????{
????????????????iCatchId=i;
????????????????return?1;
????????????}
????????}
????}
????return?0;
}
是不是不像線段和圓的判斷?這不是嚴格的數學檢測,我只取了線段的5個等分點,然后判斷各點和礦石的距離是否小于礦石的半徑。這個計算過程通過一個宏和一個函數實現:
#define?DISTANCE(x,y,x2,y2)?(((x)-(x2))*((x)-(x2))+((y)-(y2))*((y)-(y2)))int?CmpDistance(int?x,int?y,int?x2,int?y2,int?l)
{
????if(DISTANCE(x,y,x2,y2)<=l*l)
????{
????????return?1;
????}
????return?0;
}
有了數學模型,那么,礦石的“圓心”和“半徑”怎樣獲得呢?需要設置一個數組:
?//各個物體的檢測半徑,檢測圓心坐標(偏移量)
?GAMEOBJECT temp[]={
??{14,14,14},
??{25,25,25},
??{30,30,30},
??{23,23,23},
??{14,14,14}
?};
這是半徑、圓心坐標(相對于圖形左上角的偏移量)。碰撞檢測完成。
礦石的移動
需要把叉子移動的狀態、代碼,賦予?各個礦石嗎?不需要。只要在WM_TIMER消息中,根據叉子的坐標刷新物體的坐標即可。代碼為:
void?GAMEMAP::MoveObject(int?x,int?y,int?iangle)
{
????if(-1==iCatchId)
????????return;
????objectarray[iCatchId].x=x+20*cos(iangle*10*1.59/90);
????objectarray[iCatchId].y=y+20*sin(iangle*10*1.59/90);
????if(y<=58)
????{
????????//增加錢幣
????????iMoneyNow+=object_value[objectarray[iCatchId].id-1];
????????//一個物品拉到目的地
????????objectarray[iCatchId].id=0;????????
????????iCatchId=-1;????????
????}
}
拉回礦石,增加金錢
這個小游戲核心的邏輯就是“拉回礦石,增加金錢”。如同上方的代碼,當叉子的坐標小于58(初始的縱坐標),認為拉回了礦石,金錢增加。同時把物品數組objectarray的ID域清零,即從畫面中消除了該物品。
各種物品的金錢值放在一維數組中:?int tempvalue[]={50,150,500,15,600};
至此,游戲的主要功能就完成了。
附加功能:道具使用
提供了兩種道具:炮和藥水。點擊“炮”,增加炮的數量;點擊“藥水”,設置叉子的拉回速度。代碼為:
void?GAMEMAP::UseEquip(int?money,int?iequip,GAMECATCH?&c){
????iMoneyNow-=money;
????if(iMoneyNow<0)
????{
????????iMoneyNow=0;
????}
????switch(iequip)
????{
????case?0:
????????//增加炮的數量
????????iFireNum++;
????????break;
????case?1:
????????//增加拉動速度
????????c.iSpeedMore=2;
????????break;
????}
}
炮的使用也很簡單,在用戶按“上”時,清除當前抓到的物品:代碼為:
void?GAMEMAP::KeyProc(int?iKey){
????switch(iKey)
????{
????case?VK_UP:
????????if(iFireNum>0?&&?iCatchId>=0)
????????{
????????????iFireNum--;
????????????bBombAni.SetAni(objectarray[iCatchId].x,objectarray[iCatchId].y);
????????????//一個物銷毀
????????????objectarray[iCatchId].id=0;????????
????????????iCatchId=-1;????????
????????}
????????break;
????}
}
至此,所有的交互功能已全部介紹完,游戲制作完成。還有幾個部分,像按鈕、道具選擇界面、動畫播放,定時器。概括起來是兩項:位圖操作、時間控制,應該有很大的優化空間,我就不介紹了。歡迎參考原工程“挖金子VC版源碼”(在CSDN下載頻道)。
謝謝!
總結
以上是生活随笔為你收集整理的怎样做小游戏挖金子(VC,源码5)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RTX二次开发问题
- 下一篇: sql server 2000(迷你sq