C語言實現(xiàn)飛機游戲(2)
本文實例為大家分享了C語言實現(xiàn)飛機游戲的具體實現(xiàn)代碼,供大家參考,具體內(nèi)容如下
本節(jié)我們將在上一節(jié)的基礎(chǔ)上對飛機游戲進行改造完善。
基本框架
從本節(jié)起,為了避免把所有代碼都放進main函數(shù)而使得代碼看起來臃腫,我們將通過以下基本框架來實現(xiàn)游戲內(nèi)容。
//全局變量定義 int main(){ ?? ?startup(); //游戲初始化 ?? ?while(1) //游戲循環(huán)體 ?? ?{ ?? ??? ?show(); //顯示界面 ?? ??? ?updateWithoutInput(); //與輸入無關(guān)的更新 ?? ??? ?updateWithInput(); //與輸入有關(guān)的更新 ?? ?} ?? ?return 0; }
代碼重構(gòu)
現(xiàn)在我們要對上一節(jié)的代碼通過基本框架來重構(gòu)一遍。
#include <stdio.h> #include <stdlib.h> #include <conio.h> //全局變量 int position_x,position_y; //飛機坐標(biāo) int high,width; //畫面尺寸 void startup() //數(shù)據(jù)初始化 { ?? ?high = 20; ?? ?width = 30; ?? ?position_x = high/2; ?? ?position_y = width/2; } void show() //顯示畫面 { ?? ?system("cls"); //清屏函數(shù),linux使用clear命令 ?? ?int i,j; ?? ?for(i=0; i<high; i++){ ?? ??? ?for(j=0; j<width; j++){ ?? ??? ??? ?if((i==position_x)&&(j==position_y)) ?? ??? ??? ??? ?printf("*"); //輸出飛機 *? ?? ??? ??? ?else ?? ??? ??? ??? ?printf(" "); //輸出空格 ?? ??? ?} ?? ??? ?printf("\n"); ?? ?} } void updateWithoutInput() //與輸入無關(guān)的更新 { } void updateWithInput() //與輸入有關(guān)的更新 { ?? ?char input; ?? ?if(kbhit()) //判斷是否有輸入 ?? ?{ ?? ??? ?input = getch(); ?? ??? ?if(input=='a') ?? ??? ??? ?position_y --; ?? ??? ?if(input=='d') ?? ??? ??? ?position_y ++; ?? ??? ?if(input=='w') ?? ??? ??? ?position_x --; ?? ??? ?if(input=='s') ?? ??? ??? ?position_x ++;?? ??? ? ?? ?} } int main(){ ?? ?startup(); ?? ?while(1){ ?? ??? ?show(); ?? ??? ?updateWithoutInput(); ?? ??? ?updateWithInput(); ?? ?} ?? ?return 0; }
新款子彈
之前我們實現(xiàn)的激光是覆蓋整條線的,對于敵人來說比較不友好(反正挨打的是敵人),那么為了保證游戲體驗(并沒有),我們在此給游戲加一個新款子彈。
可以設(shè)置初始化子彈坐標(biāo):
// 子彈在飛機上方 bullet_x = position_x - 1; // 子彈 y 坐標(biāo)不變 bullet_y = position_y; // 每次循環(huán)子彈往上飛 1 bullet_x --;?
所以我們需要在 show() 函數(shù) 與 update 中加入控制子彈的代碼:
// 定義子彈坐標(biāo)變量 int bullet_x,bullet_y; //初始化子彈 bullet_x = -1; bullet_y = position_y; // 寫在輸出循環(huán)中 if ... else if ((i==bullet_x)&&(j==bullet_y)) ?? ?printf("|"); //輸出子彈 else ... // 子彈前進 void updateWithoutInput() { ?? ?if(bullet_x > -1) ?? ??? ?bullet_x --; } // 寫在用戶輸入判斷中 if(input == ' ') {?? ? ?? ?// 子彈在飛機上方 ?? ?bullet_x = position_x - 1; ?? ?// 子彈 y 坐標(biāo)不變 ?? ?bullet_y = position_y; }
敵機【終于來了】
用“@”表示敵機,用 enemy_x 和 enemy_y 表示敵機坐標(biāo),使用和加入子彈大致一樣的方法加入敵機。
注意:敵機的移動不能和子彈那樣,不然每回你只能看到一個大黑耗子跑過去了。
// 敵機位置 int enemy_x,enemy_y; // 數(shù)據(jù)初始化 enemy_x = 0; enemy_y = position_y; // 加入輸出循環(huán) if ... else if ((i==enemy_x)&&(j==enemy_y)) ?? ?printf("@"); else ... // 控制敵機移動 static int speed = 0; if(speed<10) ?? ?speed ++; if(speed == 10){ ?? ?enemy_x ++; ?? ?speed = 0; }
可以看到,在實現(xiàn)敵機移動時,我們?yōu)榱吮苊獬霈F(xiàn)大黑耗子嗖一下就過去的問題使用了 static 關(guān)鍵字來定義一個靜態(tài)變量 speed 從而實現(xiàn)敵機緩慢移動。
由 static 定義的局部變量在每次循環(huán)不會重新定義它的值,第一次循環(huán)會根據(jù)語句把 speed 定義為 0 ,而在之后的循環(huán)中不會重新執(zhí)行該賦值語句。
每次循環(huán)判斷當(dāng)其值小于 10 時則加一,并繼續(xù)以后語句。若其值等于 10 ,則將敵機 x 坐標(biāo)加一(也就是敵機移動),并重新將 speed 歸零。
擊殺與得分
沒錯,在完成以上代碼之后你就會發(fā)現(xiàn):
屏幕上出現(xiàn)了兩個鎖血掛!!
怎么打都打不死,而且一個飛著飛著就沒了!
所以我們需要增加擊殺功能,當(dāng)然還有得分(擊殺獲得)。
而且在每次擊殺以后都要生成新的敵機(其實就是敵機坐標(biāo)重新賦值)。
// 加入updateWithoutInput更新循環(huán) if((bullet_x == enemy_x)&&(bullet_y == enemy_y)) { //子彈擊中敵機 ?? ?score ++; //得分加一 ?? ?// 敵機刷新 ?? ?enemy_x = -1; ?? ?enemy_y = rand() % width; ?? ?bullet_x = -2; //子彈無效,如果你希望子彈能穿透的話可以去掉 } if(enemy_x > high) // 敵機飛出邊界 { ?? ?// 敵機刷新 ?? ?enemy_x = -1; ?? ?enemy_y = rand() % width; ?? ?// 可選,敵機出界得分減一 ?? ?score --; } // 定義得分并顯示 int score; // 顯示部分加在 show() 函數(shù)尾部 printf("得分: %d\n", score);
清屏升級
在實現(xiàn)以上代碼后,我們發(fā)現(xiàn)游戲時屏幕閃爍很嚴(yán)重,這里提供優(yōu)化清屏的方法。
//清屏前移動光標(biāo) #include <windows.h> void gotoxy(int x, int y){ ?? ?HANDLE handle = GetStdHandle(STD_UOTPUT_HANDLE); ?? ?CROOD pos; ?? ?pos.X = x; ?? ?pos.Y = y; ?? ?SetConsoleCursorPosition(handle, pos); } //解決光標(biāo)閃爍 void HideCursor(){ ?? ?CONSOLE_CURSOR_INFO cursor_info = {1, 0}; //第二個值為0表示隱藏光標(biāo) ?? ?SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解析C++中的for循環(huán)以及基于范圍的for語句使用
這篇文章主要介紹了解析C++中的for循環(huán)以及基于范圍的for語句使用,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2016-01-01