C语言实现打飞机小游戏

本文实例为大家分享了C语言实现打飞机小游戏的具体代码,供大家参考,具体内容如下

编译环境:vs2019

需求:

在同一个平面内,控制大炮发射的三个方向,空格发射炮弹,敌军和友军飞机会一直随机在天上飞过,击中天上飞行的敌军飞机加一分,击中友军飞机减一分

思路:

先初始化程序,再画出说明和地图,接着进入无限循环,循环中分别实现飞机不停地在天上飞、通过awd空格键控制游戏内容、符合游戏条件时加分三个主要步骤。

做法:

首先要实现飞机的动画效果,本质是要在控制台上输出三条x轴上输出一个字符串,并要让这三个字符串看起来在同时移动。这里我借助了写赌马大赛的经验:在第一次无限循环内分别循环输出第1、2、3条的字符串表示走出第一步,然后再自增三个字符串x轴坐标数值,第二次无限循环清除上一次字符串移动痕迹,并再分别输出三条字符串,表示走出第二步。由于内层for循环没有休眠函数,这样看起来就是三个字符串同时移动的效果。这样就可以通过无限循环表示三架飞机不停地移动了。
接下来是通过getch函数改变大炮炮口指向方向(一个字符),在炮口指向切换的同时,炮弹初始化的位置也同样会改变,当按下空格时,炮弹(一个字符)会从他的初始化位置沿设定好的路线不停移动,当横纵轴坐标与飞机坐标相匹配时判断是否为敌军飞机|—0>,是则得分加一,否则得分减一。
此外程序里还有很多细节,这里不一一赘述。

难点:

看起来让三个字符串同时移动。这是一种算法,学会了就应该应该像记住基础知识一样牢牢记住他。明白了原理之后,比较容易掌握。

说明:

这是一个简单的小程序,实现该程序中相同的效果有着很多种方法,而我则大量地使用了数组来存放、统计和使用各种不同的数据,其实类似效果还可以通过单链表来实现。在我目前的认知中使用数组和直接输出字符串的写法有着简洁明了的优点。但同时也导致出一个显示效果上比较致命的缺陷。

注意:

由于编译器原因程序中_kbhit()和_getch()函数可能在其他编译器上编译会出现错误,解决办法是去掉函数前面的 “_”。

运行效果:

代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <string.h>

void HideCursor();  //隐藏光标
void gotoxy(int x, int y); //光标定位

#define R 26  //飞机每次随机尾x坐标最大值
#define N 20  //通关分数

int ax[3] = { 0 };  //三个飞机尾坐标,全局
int y[3] = { 3,7,11 }; //三个y轴,全局,查表法确定飞机的y轴位置
    //因为炮弹的飞行距离是一次加两个格子,为了奇偶对应这里的y轴必须都是偶数
int i;   //循环用变量
int fd[3];   //控制飞机种类

void cshcxhs()    //初始化函数
{
 system("title 打飞机小游戏");  //标题
 system("mode con cols=100 lines=30"); //宽100,高30
 HideCursor();    //光标隐藏

 gotoxy(46, 12);    //介绍游戏规则
 printf("游戏规则:");
 gotoxy(36, 14);
 printf("w a d键控制方向,空格键发射炮弹");
 gotoxy(26, 16);
 printf("击中敌军飞机 |---0> 加一分,击中友军飞机 >>>>>> 减一分");
 gotoxy(40, 18);
 printf("累计得分 %d 结束游戏",N);
 Sleep(2800);

 system("cls");

 int k;     //循环用变量
 gotoxy(40, R);    //初始化炮台
 for (k = 0; k < 17; k++)
 printf("_");

 gotoxy(46, R);
 printf("[_O_]");
 gotoxy(48, 25);    //中间x:48
 printf("|");

 int j;
 srand((unsigned)time(NULL));  //初始化随机种子
 for (j = 0; j < 3; j++)   //初始化飞机的初始x坐标,写在循环之外
 {
 ax[j] = rand() % R;
 fd[j] = rand() % 2;
 }

 gotoxy(0, R);
 printf(" 得分:");   //分数x坐标9
}

void hcfjhs()   //画出飞机函数
{
 gotoxy(ax[i], y[i]);  //首先在飞机尾处输出整架飞机

 if (fd[i] == 1)
 printf("|---0>");
 else
 printf(">>>>>>"); 

 gotoxy(ax[i] - 1, y[i]); //清除飞机尾部留下的痕迹
 printf(" ");

 ax[i]++;   //然后飞机尾坐标自增,下次自飞机尾输出整架飞机
}

void dhpdxshs()   //画出飞机,并让飞机在飞过x94的时候消失
{
 for (i = 0; i < 3; i++)  //每架飞机都走一步
 {
 hcfjhs();

 if (ax[i] + 6 >= 94) //判断每架飞机头有没有超过94
 {
  gotoxy(94, y[i]); //满足条件在每架飞机的94处输出空格
  printf(" ");
  if (ax[i]+6 > 100) //每架飞机的飞机头超过100,则重置一个随机数
  {
  ax[i] = rand() % R; //修改为小于R的随机数
  fd[i] = rand() % 2;
  }
 }
 }
}

int da = 2;  //da = 1为最左 默认中间 炮台方向,全局变量
int yip = 0;  //是否开炮,0不开,1,2,3三个方向
int rtde = 1;  //是否发射完毕,必须等待炮弹发射完成

int shells_x;  //炮弹坐标
int shells_y;

void ckkzhs()
{
 char ch;
 ch = _getch();

 if (ch == 'd' || ch == 'D')
 {
 gotoxy(49, 25);
 printf("/");  //炮台右转
 gotoxy(47, 25);
 printf(" ");
 da = 3;   //最右状态
 }
 if (ch == 'A' || ch == 'a')
 {
 gotoxy(47, 25);
 printf("\\");  //转义转义字符
 gotoxy(48, 25);
 printf(" ");
 da = 1;   //最左状态
 }
 if (ch == 'W' || ch == 'w')
 {
 gotoxy(48, 25);
 printf("|");
 gotoxy(47, 25);
 printf(" ");
 gotoxy(49, 25);
 printf(" ");
 da = 2;
 }

 if (ch == ' '&& rtde == 0) //大炮处于发射完毕状态,且按下空格
 {
 if (da == 2)  //中 炮台朝向
  yip = 2;

 if (da == 1)  //左
 {
  yip = 1;
  shells_x = 45;  //初始化炮弹的坐标
 }
 if (da == 3)  //右
 {
  yip = 3;
  shells_x = 51;
 }
 shells_y = 23;  //初始化炮弹的坐标
 }
}

void dpfshs()   //向三个不同方向发射炮弹
{
 rtde = 1;   //循环,炮弹移动时代表未开炮完毕
 if (yip == 2)
 {
 shells_x = 48;
 gotoxy(shells_x, shells_y-=2);
 printf("o");
 gotoxy(shells_x, shells_y+2);
 printf(" ");
 }
 if (yip == 1)
 {
 gotoxy(shells_x-=2, shells_y-=2);
 printf("o");
 gotoxy(shells_x+2, shells_y+2);
 printf(" ");
 }
 if (yip == 3)
 {
 gotoxy(shells_x+=2, shells_y-=2);
 printf("o");
 gotoxy(shells_x-2, shells_y+2);
 printf(" ");
 }

 if (shells_y <= 1)  //炮弹越界,消除炮弹
 {
 yip = 0;  //炮弹越界,炮弹停下
 gotoxy(48, 1);  //并消除
 printf(" ");
 gotoxy(23, 1);
 printf(" ");
 gotoxy(73, 1);
 printf(" ");
 rtde = 0;  //炮弹越界,开炮完毕,可进行下一轮开炮
 }
}

int score;   //得分

void pdfsjzhs()  //判断是否击中和统计信息
{

 for (i = 0; i < 3; i++)
 {
  if (shells_x >= ax[i] && shells_x <= ax[i] + 6 && shells_y == y[i])//击中时
  {
  if(fd[i]==1)
   score++;   //击中一次,得分加一
  else
  {
   score--;
   if (score <= 0)
   score = 0;
  }

  rtde = 0;   //击中时,开炮完成

  gotoxy(ax[i]-1, y[i]);  //击中后,在原飞机尾巴处消除飞机
  printf(" ");

  ax[i] = rand() % R;  //修改为小于10的随机数
  fd[i] = rand() % 2;  //飞机种类发生变化

  gotoxy(shells_x, shells_y); //在击中飞机的地方输出空格消除炮弹尸体
  printf(" ");

  shells_x = 0, shells_y = 0; //炮弹击中飞机,炮弹越界,下一次空格将自动初始化炮弹
  }
 }

 gotoxy(9, R);
 printf("%d",score);

 if (score >= N)  //游戏结束判断
 {
 system("cls"); //清屏
 gotoxy(39,15);
 printf("您通关了,最终得分:%d !", N);
 gotoxy(0, 29);
 exit(0);
 }

}

void process()  //流程
{
 while (1)
 {
 dhpdxshs();  //飞机动画函数

 if (_kbhit())
 {
  ckkzhs(); //操作函数
 }

 dpfshs();  //大炮效果函数
 pdfsjzhs();  //判断是否击中和统计信息

 Sleep(18);
 }
}

int main()
{
 cshcxhs(); //初始化程序

 process(); //流程

 return 0;
}

void HideCursor()
{
 CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void gotoxy(int x, int y)
{
 COORD pos = { x,y };
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

不足之处:

我在程序中输出飞机时使用了在飞机尾直接输出整架飞机,飞机尾x坐标自增的写法,这是一种很笨但又很简单的做法。这种做法导致飞机在飞过控制台最大宽度的同时无法逐个消除飞机机身,飞机头一旦越过控制台最大宽度就会出现程序输出错误,所以我为了保留“让飞机逐节身体地飞出边界”这个让飞机消失时看起来比较自然的效果,只好用最后飞机所在y轴最后6个x轴格子作为遮挡飞机的板子,以此来实现类似的效果。

由于该程序出了创意之外,全是由本人靠自己写的,由于我能力有限,在写这个程序的同时隐约感觉到我的程序存在着大量代码复用性、结构严谨性、运行效率低下上的问题,同时很多函数和变量标识符我采用了瞎写、中文拼音组成的做法。

作为一名c语言新手,我对未知的知识始终抱有学习和谦卑的态度,如有贵人能够对我的程序提出复用性、严谨性、运行效率上的建议,我将不胜感激。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C语言实现简单飞机大战

    本文实例为大家分享了C语言实现飞机大战的具体代码,供大家参考,具体内容如下 定义四个函数实现飞机大战 #include<stdio.h> #include<windows.h> #include<conio.h> //定义全局变量 int high,width; //定义边界 int position_x,position_y; //飞机位置 int bullet_x,bullet_y; //子弹位置 int enemy_x,enemy_y; int score; in

  • C语言实现打飞机小游戏

    本文实例为大家分享了C语言实现打飞机小游戏的具体代码,供大家参考,具体内容如下 编译环境:vs2019 需求: 在同一个平面内,控制大炮发射的三个方向,空格发射炮弹,敌军和友军飞机会一直随机在天上飞过,击中天上飞行的敌军飞机加一分,击中友军飞机减一分 思路: 先初始化程序,再画出说明和地图,接着进入无限循环,循环中分别实现飞机不停地在天上飞.通过awd空格键控制游戏内容.符合游戏条件时加分三个主要步骤. 做法: 首先要实现飞机的动画效果,本质是要在控制台上输出三条x轴上输出一个字符串,并要让这三

  • C语言控制台实现打飞机小游戏

    本文实例为大家分享了C语言实现打飞机小游戏的具体代码,供大家参考,具体内容如下 初学C语言总觉得不能做些什么好玩的,这个小游戏只需 "一点点" (千真万确)C语言知识就能完成! 总计不到200行的非空白代码(没有强行压缩行数) 操作说明: 1.W.S.A.D 控制 上 .下.左.右 方向,空格 攻击 2.每击中一架敌机增加1分,界面下方显示实时分数 3.撞到敌机后显示 game over! 2.5秒(时间可更改) 子弹连发 移动的同时发射子弹 飞机撞上敌机结束游戏 可通过更改相关变量的

  • C语言实现飞机小游戏

    本文实例为大家分享了C语言实现飞机小游戏的具体代码,供大家参考,具体内容如下 #include<stdio.h> #include<windows.h> int zdj_x,zdj_y; int zd_x,zd_y; int dj_x,dj_y; int speed; int map[21][41]; int score; int H=20,C=40; //墙是1:飞机2:子弹3:敌机4: void start()//设置初始值 { zdj_x=15; zdj_y=20; zd_x

  • Java实现飞机小游戏

    本文实例为大家分享了Java实现飞机小游戏的具体代码,供大家参考,具体内容如下 该小游戏使用java语言实现,使用工具idea. 共写9个类 Constant:Explode:GameObject:GameUtil:Plane:Shell:image:images:Plan: 本文实例为大家分享了vue + element ui实现锚点定位的具体代码,供大家参考,具体内容如下 1,Constant:专门放常量 package com.game2; //专门放常量的一个类 public class

  • go语言实现猜数字小游戏的方法

    本文实例讲述了go语言实现猜数字小游戏的方法.分享给大家供大家参考.具体分析如下: 随机生成一个数字,输入一个数字看是否匹对,匹配则结速,反之提示是大了还是小了 复制代码 代码如下: package main import (     "bufio"     "fmt"     "math/rand"     "os"     "strconv"     "time" ) var (  

  • 纯javascript模仿微信打飞机小游戏

    七夕情人节也不要忘了打游戏喔喔-,下面小编为大家准备的情人节礼物之纯javascript模仿微信打飞机小游戏分享给天下的情人们. 首先给大家展示效果图: 查看演示      源码下载 纯JavaScript模仿微信打飞机游戏,做网页小游戏的借鉴下,界面设计是竖长形仿手机屏幕风格,游戏效果流畅.具有分数统计,里面的JS封装类中包括有创建飞机类.飞机移动行为控制,创建子弹类,产生min到max之间的随机数,判断本方飞机是否移出边界,如果移出边界,则取消mousemove事件,反之加上mousemov

  • C语言实现Flappy Bird小游戏

    本文实例为大家分享了C语言实现Flappy Bird小游戏的具体代码,供大家参考,具体内容如下 #include<stdio.h> #include<stdlib.h> #include<conio.h> #include<time.h> #include<Windows.h> /********函数变量声明********/ #define PR_Box printf("■") #define PR_Gold printf(

  • C语言实现贪吃蛇小游戏

    本文实例为大家分享了C语言实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 一.程序实现的原理: 1.构造蛇身:定义一个坐标数组,存放的是蛇的每一节蛇身所在的坐标位置.这样就将移动蛇身的操作转换为移动数组的操作,将吃食物增加蛇身体长度的操作转换为在数组后面追加元素的操作. 2.移动效果:每次移动时,将每一节蛇身(蛇头除外)依次往前移动一节,然后擦去蛇的最后一节,最后确定蛇头的方向,再绘制一个蛇头.这样就会显示一个移动效果. 3.身体增加效果:每次移动时候,判断蛇头是否碰到了食物,如果碰到了食

  • C语言简单实现扫雷小游戏

    本文实例为大家分享了C语言简单实现扫雷小游戏 的具体代码,供大家参考,具体内容如下 游戏规则: 以9*9棋盘为例,棋盘上随机分布着10个地雷,玩家在棋盘上进行点击,如果被点击的格子是地雷,则玩家被炸"死",游戏结束:如果被点击的格子上没有地雷,与被点击的格子相邻的格子(被点击格子的上下左右还有斜向,共八个格子)有地雷,则在被点击的格子上显示这些地雷的总数,如果与被点击的格子相邻的八个格子都没有地雷,则棋盘自动展开,直到与展开的格子相邻的格子有地雷才停止.此时最后被展开的格子显示其相邻格

  • C语言实现控制台扫雷小游戏

    C语言实现控制台"扫雷"小游戏 根据以往的游戏经验,我们能首先可以确定扫雷游戏胜利的规则是:翻开所有不是雷的区域才能算是胜利. 接下来我们需要确定整个程序的设计思路: 1.首先,我们定义两个9*9的二维数还是未翻开的状态组.第一个数组用来表示雷区地图的展开情况,即每个素组元素的位置的状态是处于展开状态还是未展开状态,我们命名为showMap().第二个数组我们用来表示地雷的分布情况,素组中的每个元素位置都被标记为是否为地雷,我们命名为minMap(). 2.初始化两个地图,并将地图打印

随机推荐