每周一坑--打飞机游戏

简介: 每周一坑--打飞机游戏

看了知乎上的一个C语言做的打飞机游戏(控制台)https://zhuanlan.zhihu.com/p/24798125

决定自己做一个C++版的。

先说一下原来游戏的思路。

首先主函数: 先初始化,然后再一个循环里不断地

显示-->更新与用户无关数据-->用户输入、根据输入更新。

显示是通过一个二维数组canvas (画布)来实现的,通过一个二层循环来在画布上进行绘制(输出字符)

字符的形状代表是 飞机或子弹或者空气。

更新与用户无关数据是按照一个规律:敌机往下飞,子弹往上飞,这样更新的。

根据输入更新            是根据用户输入的'a' 'd'或空格 来设置自己的位置和发射子弹。


 

int main()
{
  startup();  // 数据初始化  
  while (1)  // 游戏循环执行
  {
    show();  // 显示画面
    updateWithoutInput();  // 与用户输入无关的更新
    updateWithInput();  // 与用户输入有关的更新
  }
  return 0;
}

下面具体地操作。

 

那么既然要用C++,飞机就可以做成一个基类了。

然后从飞机 派生出两个类 一个是自己,一个是敌机。

自己和敌机有什么不同? 在这里为了简化,敌机不发射子弹,只是简单地往下移动。 自己是可以发射子弹的。

class Plane
{
private:
  int x;
  int y;
  int MoveSpeed;
public:
  Plane() :x(0), y(0) {};
  Plane(int x, int y) :x(x), y(y) {}
  ~Plane(){}
  int getX() { return x; }
  int getY() { return y; }
  int getMoveSpeed(){ return MoveSpeed; }
  void setX(int x) { this->x =x; }
  void setY(int y) { this->y = y; }
  void setMoveSpeed(int speed){ MoveSpeed = speed; }
};
 
class MyPlane : public Plane
{
private:
  int BulletWidth;
 
public:
  int getBulletWidth() { return BulletWidth; }
  void setBulletWidth(int width) { this->BulletWidth = width; }
 
};
class EnemyPlane : public Plane
{
 
};



 

除了飞机,其他的基本根据原来的改写,因为图像的显示主要依靠画布,所以如果画布不改动的话,其余的基本改变不大。

改写时为了方便,我将原来的长函数分解成短函数,看起来更容易。

最后的代码:

 

main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include"plane.h"
#include"updateFunction.h"
 
const int High     = 15;// 游戏画面尺寸
const int Width    = 25;
const int EnemyNum = 5;// 敌机个数
 
// 全局变量
MyPlane myPlane; // 飞机
EnemyPlane enemyPlane[EnemyNum];  // 敌机
int canvas[High+1][Width+1] = { 0 }; // 二维数组存储游戏画布中对应的元素
                   // 0为空格,1为飞机*,2为子弹|,3为敌机@
int score; // 得分
 
 //光标移动到(x,y)位置
void gotoxy(int x, int y) 
{
  HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
  COORD pos;
  pos.X = x;
  pos.Y = y;
  SetConsoleCursorPosition(handle, pos);
}
 
void startup() // 数据初始化
{
  //下面的两行用于隐藏光标,防止乱闪
  CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
  SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
 
  //设自己置飞机位置
  startupMyPlane();
  //设置敌机位置
   startupEnemyPlane();
   score = 0;
}
 
void startupMyPlane()
{
  myPlane.setX(High - 1);
  myPlane.setY(Width - 2);
  myPlane.setBulletWidth(0);
}
void startupEnemyPlane()
{
  for (int k = 0; k < EnemyNum; k++)
  {
    enemyPlane[k].setX(rand() % 2);
    enemyPlane[k].setY(rand() % Width);
    enemyPlane[k].setMoveSpeed(20);
  }
}
 
// 显示画面
void show()  
{
  gotoxy(0, 0);  // 光标移动到原点位置,以下重画清屏
  for (int i = 0; i < High; i++)
  {
    for (int j = 0; j < Width; j++)
    {
      if (canvas[i][j] == 0)
        printf(" ");   //   输出空格
      else if (canvas[i][j] == 1)
        printf("*");   //   输出飞机*
      else if (canvas[i][j] == 2)
        printf("|");   //   输出子弹|
      else if (canvas[i][j] == 3)
        printf("@");   //  输出飞机@
    }
    printf("\n");
  }
  printf("得分:%d\n", score);
  Sleep(20);
}
 
// 与用户输入无关的更新
void updateWithoutInput()  
{   //更新子弹位置
  for (int i = 0; i < High; i++) {
    for (int j = 0; j < Width; j++) {
      if (canvas[i][j] == 2)    {
        updateBullet(i, j);
      }
    }
  }
  static int speed = 0;
  if (speed < enemyPlane[0].getMoveSpeed())
    speed++;
  updatePlane(speed );
}
 
 
void updateBullet(int i,int j)
{
  for (int k = 0; k < EnemyNum; k++) {
    if ((i == enemyPlane[k].getX()) && (j == enemyPlane[k].getY()))  // 子弹击中敌机
    {
      score++;                // 分数加1
      if (score % 5 == 0 && enemyPlane[k].getMoveSpeed() > 3)   // 达到一定积分后,敌机变快
        enemyPlane[k].setMoveSpeed(enemyPlane[k].getMoveSpeed() - 1);
      if (score % 5 == 0)   // 达到一定积分后,子弹变厉害
        myPlane.setBulletWidth(myPlane.getBulletWidth() + 1);
      canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 0;
      enemyPlane[k].setX(rand() % 2);           // 产生新的飞机
      enemyPlane[k].setY(rand() % Width);
      canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 3;
      canvas[i][j] = 0;      // 子弹消失
    }
  }
  // 子弹向上移动
  canvas[i][j] = 0;
  if (i > 0)
    canvas[i - 1][j] = 2;
}
void updatePlane(int& speed )
{
  for (int k = 0; k < EnemyNum; k++)
  {
    if ((myPlane.getX() == enemyPlane[k].getX()) && (myPlane.getY() == enemyPlane[k].getY()))  // 敌机撞到我机
    {
      printf("失败!\n");
      Sleep(3000);
      system("pause");
      exit(0);
    }
 
    if (enemyPlane[k].getX() > High)   // 敌机跑出显示屏幕
    {
      canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 0;
      enemyPlane[k].setX(rand() % 2);           // 产生新的飞机
      enemyPlane[k].setY(rand() % Width);
      canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 3;
      score--;  // 减分
    }
 
    if (speed == enemyPlane[0].getMoveSpeed())
    {
      // 敌机下落
      for (k = 0; k < EnemyNum; k++)
      {
        canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 0;
        enemyPlane[k].setX(enemyPlane[k].getX() + 1);
        speed = 0;
        canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 3;
      }
    }
  }
}
 
void updateWithInput()  // 与用户输入有关的更新
{
  char input;
  if (_kbhit())  // 判断是否有输入
  {
    input = _getch();  // 根据用户的不同输入来移动,不必输入回车
    if (input == 'a' && myPlane.getX() > 0)
    {
      canvas[myPlane.getX()][myPlane.getY()] = 0;
      myPlane.setY(myPlane.getY()-1);  // 位置左移
      canvas[myPlane.getX()][myPlane.getY()] = 1;
    }
    else if (input == 'd' && myPlane.getY() < Width - 1)
    {
      canvas[myPlane.getX()][myPlane.getY()] = 0;
      myPlane.setY(myPlane.getY() +1);  // 位置右移
      canvas[myPlane.getX()][myPlane.getY()] = 1;
    }
    else if (input == 'w')
    {
      canvas[myPlane.getX()][myPlane.getY()] = 0;
      myPlane.setX(myPlane.getX() - 1);;  // 位置上移
      canvas[myPlane.getX()][myPlane.getY()] = 1;
    }
    else if (input == 's')
    {
      canvas[myPlane.getX()][myPlane.getY()] = 0;
      myPlane.setX(myPlane.getX() +1);;  // 位置上移
      canvas[myPlane.getX()][myPlane.getY()] = 1;
    }
    else if (input == ' ')  // 发射子弹
    {
      int left = myPlane.getY() - myPlane.getBulletWidth() ;
      int right = myPlane.getY() + myPlane.getBulletWidth();
      if (left < 0)
        left = 0;
      if (right > Width - 1)
        right = Width - 1;
      int k;
      for (k = left; k <= right; k++) // 发射闪弹
        canvas[myPlane.getX() - 1][k] = 2; // 发射子弹的初始位置在飞机的正上方
    }
  }
}
 
int main()
{
  startup();  // 数据初始化  
  while (1)  // 游戏循环执行
  {
    show();  // 显示画面
    updateWithoutInput();  // 与用户输入无关的更新
    updateWithInput();  // 与用户输入有关的更新
  }
  return 0;
}

updateFunction.h

#pragma once
void startupMyPlane();
void startupEnemyPlane();
void updateBullet(int i, int j);
void updatePlane(int& speed);

plane.h

#pragma once
 
class Plane
{
private:
  int x;
  int y;
  int MoveSpeed;
public:
  Plane() :x(0), y(0) {};
  Plane(int x, int y) :x(x), y(y) {}
  ~Plane(){}
  int getX() { return x; }
  int getY() { return y; }
  int getMoveSpeed(){ return MoveSpeed; }
  void setX(int x) { this->x =x; }
  void setY(int y) { this->y = y; }
  void setMoveSpeed(int speed){ MoveSpeed = speed; }
  int condition;
};
 
 
class MyPlane : public Plane
{
private:
  int BulletWidth;
 
public:
  MyPlane(){ Plane(); condition = 1; };
  MyPlane(int x, int y) :Plane(x, y) { condition = 1; }
  ~MyPlane() {}
  int getBulletWidth() { return BulletWidth; }
  void setBulletWidth(int width) { this->BulletWidth = width; }
 
};
class EnemyPlane : public Plane
{
public:
  static int num;
public:
  EnemyPlane() { Plane(); condition = 3; };
  EnemyPlane(int x, int y) : Plane(x, y) { condition = 3; }
  ~EnemyPlane() {}
 
};



相关文章
|
索引 Python
星际争霸之小霸王之小蜜蜂(七)--消失的子弹
星际争霸之小霸王之小蜜蜂(七)--消失的子弹
|
存储
飞机大战-飞机爆炸(8)
编写飞机大战,完成飞机爆炸功能。
78 0
|
5月前
小鸟飞行游戏【附源码】
小鸟飞行游戏【附源码】
54 2
小鸟飞行游戏【附源码】
|
5月前
|
图形学 开发者
【unity小技巧】两种办法解决FPS游戏枪或者人物穿墙穿模问题
【unity小技巧】两种办法解决FPS游戏枪或者人物穿墙穿模问题
238 0
|
Python 容器
星际争霸之小霸王之小蜜蜂(六)--让子弹飞
星际争霸之小霸王之小蜜蜂(六)--让子弹飞
|
6月前
|
容器
塔防游戏开发实战教程(1):实现防守塔,添加敌人的路径点
塔防游戏开发实战教程(1):实现防守塔,添加敌人的路径点
114 0
塔防游戏开发实战教程(1):实现防守塔,添加敌人的路径点
|
11月前
|
图形学
Unity小游戏——使被砍中的怪物四处飞散
Unity小游戏——使被砍中的怪物四处飞散
C#实现的打飞机游戏(课程设计)
C#实现的打飞机游戏(课程设计)
146 1
|
Python
飞机大战-显示我方飞机
用Python进行编写飞机大战,显示我方飞机。
63 0
两句话,ChatGPT帮我写一个打飞机的游戏
两句话,ChatGPT帮我写一个打飞机的游戏