C語言實(shí)現(xiàn)飛機(jī)游戲(2)
本文實(shí)例為大家分享了C語言實(shí)現(xiàn)飛機(jī)游戲的具體實(shí)現(xiàn)代碼,供大家參考,具體內(nèi)容如下
本節(jié)我們將在上一節(jié)的基礎(chǔ)上對飛機(jī)游戲進(jìn)行改造完善。
基本框架
從本節(jié)起,為了避免把所有代碼都放進(jìn)main函數(shù)而使得代碼看起來臃腫,我們將通過以下基本框架來實(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; //飛機(jī)坐標(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("*"); //輸出飛機(jī) *?
?? ??? ??? ?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;
}新款子彈
之前我們實(shí)現(xiàn)的激光是覆蓋整條線的,對于敵人來說比較不友好(反正挨打的是敵人),那么為了保證游戲體驗(yàn)(并沒有),我們在此給游戲加一個新款子彈。
可以設(shè)置初始化子彈坐標(biāo):
// 子彈在飛機(jī)上方 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 ...
// 子彈前進(jìn)
void updateWithoutInput()
{
?? ?if(bullet_x > -1)
?? ??? ?bullet_x --;
}
// 寫在用戶輸入判斷中
if(input == ' ')
{?? ?
?? ?// 子彈在飛機(jī)上方
?? ?bullet_x = position_x - 1;
?? ?// 子彈 y 坐標(biāo)不變
?? ?bullet_y = position_y;
}敵機(jī)【終于來了】
用“@”表示敵機(jī),用 enemy_x 和 enemy_y 表示敵機(jī)坐標(biāo),使用和加入子彈大致一樣的方法加入敵機(jī)。
注意:敵機(jī)的移動不能和子彈那樣,不然每回你只能看到一個大黑耗子跑過去了。
// 敵機(jī)位置
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 ...
// 控制敵機(jī)移動
static int speed = 0;
if(speed<10)
?? ?speed ++;
if(speed == 10){
?? ?enemy_x ++;
?? ?speed = 0;
}可以看到,在實(shí)現(xiàn)敵機(jī)移動時,我們?yōu)榱吮苊獬霈F(xiàn)大黑耗子嗖一下就過去的問題使用了 static 關(guān)鍵字來定義一個靜態(tài)變量 speed 從而實(shí)現(xiàn)敵機(jī)緩慢移動。
由 static 定義的局部變量在每次循環(huán)不會重新定義它的值,第一次循環(huán)會根據(jù)語句把 speed 定義為 0 ,而在之后的循環(huán)中不會重新執(zhí)行該賦值語句。
每次循環(huán)判斷當(dāng)其值小于 10 時則加一,并繼續(xù)以后語句。若其值等于 10 ,則將敵機(jī) x 坐標(biāo)加一(也就是敵機(jī)移動),并重新將 speed 歸零。
擊殺與得分
沒錯,在完成以上代碼之后你就會發(fā)現(xiàn):
屏幕上出現(xiàn)了兩個鎖血掛??!
怎么打都打不死,而且一個飛著飛著就沒了!
所以我們需要增加擊殺功能,當(dāng)然還有得分(擊殺獲得)。
而且在每次擊殺以后都要生成新的敵機(jī)(其實(shí)就是敵機(jī)坐標(biāo)重新賦值)。
// 加入updateWithoutInput更新循環(huán)
if((bullet_x == enemy_x)&&(bullet_y == enemy_y))
{ //子彈擊中敵機(jī)
?? ?score ++; //得分加一
?? ?// 敵機(jī)刷新
?? ?enemy_x = -1;
?? ?enemy_y = rand() % width;
?? ?bullet_x = -2; //子彈無效,如果你希望子彈能穿透的話可以去掉
}
if(enemy_x > high) // 敵機(jī)飛出邊界
{
?? ?// 敵機(jī)刷新
?? ?enemy_x = -1;
?? ?enemy_y = rand() % width;
?? ?// 可選,敵機(jī)出界得分減一
?? ?score --;
}
// 定義得分并顯示
int score;
// 顯示部分加在 show() 函數(shù)尾部
printf("得分: %d\n", score);清屏升級
在實(shí)現(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++中BitSet和Bloom_Filter的實(shí)現(xiàn)
本文主要介紹了C++中BitSet和Bloom_Filter的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02
C++文件的數(shù)據(jù)寫入和文件的數(shù)據(jù)讀取的方法實(shí)現(xiàn)
本文主要介紹了C++文件的數(shù)據(jù)寫入和文件的數(shù)據(jù)讀取的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法
這篇文章主要介紹了詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

