模拟一定范围内用挡板使小球不下落的经典小游戏。

目录

宽高在此修改

设置小球可能出现的形状

其他全局参数

建立挡板类

建立小球类

实现与挡板碰撞

考虑小球间的相互碰撞

实现小球移动

打印界面

主程序

完整源代码及注释

首先需要初始化游戏参数:宽度,高度,小球数,挡板长度。

宽高在此修改

static int length = 24, height = 12;              //宽度要大于挡板

设置小球可能出现的形状

static string Shape = "abcdefghijklmnopqrstuvwxyz"; //小球形状库

其他全局参数

static int score = 0, gclock = 2 * height, flat; //gclock判断游戏是否继续,flat为简单模式,不会结束

其中原始得分为0,gclock用以判断游戏是否结束,我们用小球上下一个来回都没有得分判断游戏结束,gclock初值为两个高度,得分后重新赋予两个高度的值,再在循环里递减,小于0时结束。

flat的值在程序准备阶段确定,设置游戏是否有底部,若选休闲模式(1)则有挑战模式(0)则无。因此,只有选择了挑战模式(0)才会出现游戏结束,结算得分界面,休闲模式(1)为无限循环

int n;
cout << "小球数:";
cin >> n;
cout << "模式选择:" << endl << "挑战模式(0)" << endl << "休闲模式(1)" << endl;
cin >> flat;
ball* p = new ball[n];

建立挡板类

class plate {
public:int l, x, y, vx, vy;plate(int tl = 3, int tx = 1, int ty = height, int tvx = 3, int tvy = 1) :l(tl), x(tx), y(ty), vx(tvx), vy(tvy) {}void move();
};

初始化臂长l = 3出生坐标左下角(x = 1,y = height),默认速度:水平(vx = 3),竖直(vy = 1)

(在tl参数修改臂长,tvx、tvy修改板移速)

实现挡板的上下左右移动(挑战模式只能左右),用头文件为#include<conio.h>下的_kbhit()函数判断键盘有无输入,用_getch()函数得到输入的键值(ASCII码值),经判断后作变量更改。

void plate::move() {if (_kbhit()) {                           //键盘输入w、s、a、d控制挡板上下左右int ch = _getch();if (ch == 97) {                       //a的ASCII码if (x > vx) x -= vx;else if (x > 1) x = 1;}else if (ch == 100) {                 //d的ASCII码if (x <= length - 2 * l - vx) x += vx;else if (x < length - 2 * l) x = length - 2 * l;}else if (ch == 115 && flat) {                 //s的ASCII码if (y < height - vy) y += vy;else y = height;}else if (ch == 119 && flat) {                 //w的ASCII码if (y > vy) y -= vy;else y = 1;}}
}

效果图:

建立小球类

​class ball {
public:int x, y, vx, vy;char shape;ball(int tx = rand() % (length - 1) + 1, int ty = rand() % (height / 2) + 1, int tvx = rand() % 3 - 1, int tvy = rand() % 3 - 1, char ts = Shape[rand() % 26]) :x(tx), y(ty), vx(tvx), vy(tvy), shape(ts) {}void crash_edge();void crash_board(plate board);bool crash_ball(ball& tb);void Swap(ball& tb);void next();
};​

初始化横坐标随机1~length - 1,纵坐标随机1~height/2,防止开局掉落,水平和竖直速度均随机-1~1

实现边缘反弹:(休闲模式flat = 1,触底反弹)

void ball::crash_edge() {if (x + vx == 0 || x + vx == length + 1)vx *= -1;if (y + vy == 0 || (y + vy == height + 1 && flat))vy *= -1;}

效果图:

实现与挡板碰撞

void ball::crash_board(plate board) {                  //考虑与挡板碰撞,只有上反弹得分if (y + vy == board.y && abs(x + vx - board.x - board.l) <= board.l) {vy *= -1;if(y == board.y - 1)score++;gclock = 2 * height;                           //用一个来回不得分判断游戏结束}if (y == board.y) {if ((x == board.x - 1 && vx == 1) || (x == board.x + 2 * board.l + 1 && vx == -1)) vx *= -1;else if (x >= board.x && x <= board.x + 2 * board.l) vy *= -1;}
}

效果图:

考虑小球间的相互碰撞

bool ball::crash_ball(ball& tb) {                      //判断小球间碰撞if (((x + vx == tb.x) && (tb.x + tb.vx == x) && (y + vy == tb.y) && (tb.y + tb.vy == y)) || (x == tb.x && y == tb.y)) {return true;}return false;
}
void ball::Swap(ball& tb) {                            //交换两球速度swap(vx, tb.vx);swap(vy, tb.vy);
}

设小球质量都相同,这里只简单地做出速度交换和碰撞反馈。

实现小球移动

void ball::next() {x += vx;y += vy;
}

加一次现速度。

打印界面

void display(plate board, ball *p, int n) {          //打印边界、挡板和球for (int i = 0; i <= height + 1; i++) {for (int j = 0; j <= length; j++) {if (i == 0 || (i == height + 1 && flat))cout << "0";else {int flag = 1;for (int k = 0; k < n; k++) {if (p[k].x == j && p[k].y == i) {          //两球碰撞合成Xfor (int l = k + 1; l < n; l++) {if (flag && p[l].x == j && p[l].y == i) {cout << "X";flag = 0;break;}}if (flag) {cout << p[k].shape;flag = 0;break;}}}if (flag && (i == board.y && abs(j - board.x - board.l) <= board.l))cout << "-";else if (j == 0) cout << "0";else if (flag || (!flag && j == length)) cout << " "; //打边界会凸起}}cout << "0" << endl;}
}

逐帧打印小球、挡板位置,建议小球数不要设置太多,宽高也不要太大,会有些闪QAQ

可以看到使用了多层循环,优化极差,设计打到右边界会凸起以至于没那么死板,若出现同一个位置的碰撞打印反馈为“X”。

主程序

int main() {plate board;int n;cout << "小球数:";cin >> n;cout << "模式选择:" << endl << "挑战模式(0)" << endl << "休闲模式(1)" << endl;cin >> flat;ball* p = new ball[n];while (1) {board.move();system("cls");display(board,p,n);cout << "得分数:" << score;Sleep(100);for (int i = 0; i < n; i++) {                   //检查相撞情况for (int j = i + 1; j < n; j++) {if (p[i].crash_ball(p[j])) {p[i].Swap(p[j]);break;}}p[i].crash_board(board);p[i].crash_edge();p[i].next();}gclock--;if (gclock < 0 && !flat) {system("cls");break;delete[]p;}}cout << "游戏结束,最终得分:" << score;string s;cin >> s;return 0;
}

完整源代码及注释

#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;
static int length = 24, height = 12;              //宽度要大于挡板
static string Shape = "abcdefghijklmnopqrstuvwxyz"; //小球形状库
static int score = 0, gclock = 2 * height, flat; //gclock判断游戏是否继续,flat为简单模式,不会结束
class plate {                                      //建立挡板类
public:int l, x, y, vx, vy;plate(int tl = 3, int tx = 1, int ty = height, int tvx = 3, int tvy = 1) :l(tl), x(tx), y(ty), vx(tvx), vy(tvy) {}void move();
};
class ball {                                       //建立球类
public:int x, y, vx, vy;char shape;ball(int tx = rand() % (length - 1) + 1, int ty = rand() % (height / 2) + 1, int tvx = rand() % 3 - 1, int tvy = rand() % 3 - 1, char ts = Shape[rand() % 26]) :x(tx), y(ty), vx(tvx), vy(tvy), shape(ts) {}void crash_edge();void crash_board(plate board);bool crash_ball(ball& tb);void Swap(ball& tb);void next();
};
void display(plate board, ball *p, int n) {          //打印边界、挡板和球for (int i = 0; i <= height + 1; i++) {for (int j = 0; j <= length; j++) {if (i == 0 || (i == height + 1 && flat))cout << "0";else {int flag = 1;for (int k = 0; k < n; k++) {if (p[k].x == j && p[k].y == i) {          //两球碰撞合成Xfor (int l = k + 1; l < n; l++) {if (flag && p[l].x == j && p[l].y == i) {cout << "X";flag = 0;break;}}if (flag) {cout << p[k].shape;flag = 0;break;}}}if (flag && (i == board.y && abs(j - board.x - board.l) <= board.l))cout << "-";else if (j == 0) cout << "0";else if (flag || (!flag && j == length)) cout << " "; //打边界会凸起}}cout << "0" << endl;}
}
void plate::move() {if (_kbhit()) {                           //键盘输入w、s、a、d控制挡板上下左右int ch = _getch();if (ch == 97) {                       //a的ASCII码if (x > vx) x -= vx;else if (x > 1) x = 1;}else if (ch == 100) {                 //d的ASCII码if (x <= length - 2 * l - vx) x += vx;else if (x < length - 2 * l) x = length - 2 * l;}else if (ch == 115 && flat) {                 //s的ASCII码if (y < height - vy) y += vy;else y = height;}else if (ch == 119 && flat) {                 //w的ASCII码if (y > vy) y -= vy;else y = 1;}}
}
void ball::crash_edge() {                             //考虑与边界碰撞if (x + vx == 0 || x + vx == length + 1)vx *= -1;if (y + vy == 0 || (y + vy == height + 1 && flat))vy *= -1;}
void ball::crash_board(plate board) {                  //考虑与挡板碰撞,只有上反弹得分if (y + vy == board.y && abs(x + vx - board.x - board.l) <= board.l) {vy *= -1;if(y == board.y - 1)score++;gclock = 2 * height;                           //用一个来回不得分判断游戏结束}if (y == board.y) {if ((x == board.x - 1 && vx == 1) || (x == board.x + 2 * board.l + 1 && vx == -1)) vx *= -1;else if (x >= board.x && x <= board.x + 2 * board.l) vy *= -1;}
}
bool ball::crash_ball(ball& tb) {                      //判断小球间碰撞if (((x + vx == tb.x) && (tb.x + tb.vx == x) && (y + vy == tb.y) && (tb.y + tb.vy == y)) || (x == tb.x && y == tb.y)) {return true;}return false;
}
void ball::Swap(ball& tb) {                            //交换两球速度swap(vx, tb.vx);swap(vy, tb.vy);
}
void ball::next() {x += vx;y += vy;
}
int main() {plate board;int n;cout << "小球数:";cin >> n;cout << "模式选择:" << endl << "挑战模式(0)" << endl << "休闲模式(1)" << endl;cin >> flat;ball* p = new ball[n];while (1) {board.move();system("cls");display(board,p,n);cout << "得分数:" << score;Sleep(100);for (int i = 0; i < n; i++) {                   //检查相撞情况for (int j = i + 1; j < n; j++) {if (p[i].crash_ball(p[j])) {p[i].Swap(p[j]);break;}}p[i].crash_board(board);p[i].crash_edge();p[i].next();}gclock--;if (gclock < 0 && !flat) {system("cls");break;delete[]p;}}cout << "游戏结束,最终得分:" << score;string s;cin >> s;return 0;
}

欢迎大家测试游玩,你们的反馈就是我创作的动力,来试试挑战模式你能得多少分?

C++ 简易弹球游戏(分块解释、源码、注释)相关推荐

  1. 基于stm32、0.96寸OLED实现的贪吃蛇小游戏(详细源码注释)

    简介:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的贪吃蛇小游戏.项目源码地址:点击下载. 硬件设计: 普通摇杆,0.96寸OLED 单色屏幕(SPI协议通讯), ...

  2. 基于stm32、0.96寸OLED实现的俄罗斯方块小游戏(详细源码注释)

    概述:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的俄罗斯方块小游戏.项目源码地址:点击下载. 硬件要求: 普通摇杆,两个电位器和一个开关组成,左右摇动控制一个电 ...

  3. C语言做的接鸡蛋小游戏(附源码注释)【原创】

    //以下是接鸡蛋小游戏源码 .建议在VS中运行调试! /* 头文件 */ # include <windows.h> # include <stdlib.h> # includ ...

  4. 如何提高游戏陪玩app源码的代码可读性?

    1.Why 对一线开发人员来说,每天工作内容大多是在已有游戏陪玩app源码的基础上继续堆代码.当游戏陪玩app源码实在堆不动时就需要寻找收益来重构代码.既然我们的大多数时间都花在坐在显示器前读写代码这 ...

  5. <2021SC@SDUSC>【Overload游戏引擎】源码模块简介及项目分工

    <2021SC@SDUSC>[Overload游戏引擎]源码模块简介及项目分工 模块简介 Overload SDK Overload 应用程序 项目分工 模块简介 Overload 由12 ...

  6. 游戏陪玩系统源码中聊天室内礼物系统的实现

    游戏陪玩系统源码中聊天室的礼物系统,第一步用户看到的无外乎都是礼物的列表界面 纵观主流聊天室的礼物列表应该都是使用UICollectionView实现的,所以我也不例外,下面就是各种撸代码.效果如下 ...

  7. 畅玩mt3单机游戏服务器维护,【梦幻西游】MT3仿端手工游戏服务端源码[教程+授权物品后台]...

    [梦幻西游]MT3仿端手工游戏服务端源码[教程+授权物品后台] 架设教程 系统:CentOS 6.8  64位 1.关闭防火墙 chkconfig iptables off service iptab ...

  8. mfc使用cef源代码实现_如何获得微信小游戏跳一跳源码以及源代码组合包括哪些...

    很多小游戏都是由源代码编写而成的,那大家知道源代码组合包括哪些吗?手机游戏源代码怎么使用的呢?还有,如何获得微信小游戏跳一跳源码?下面就由奇瑰网小编带大家来了解一下相关的内容吧. 源代码组合包括哪些 ...

  9. ASP游戏工作室网站源码v1.0

    介绍: ASP游戏工作室网站源码v1.0下载,内核为ASPCMS的.具体的大家可以搜索下ASPCMS,是一款非常成熟的老款ASP语言的开源程序. 源码安装方法: 上传到空间即可使用.网站内容栏目均可在 ...

  10. 帝国CMS仿写朵朵云棋牌游戏官网源码

    帝国CMS仿写朵朵云棋牌游戏官网源码 下载地址: http://www.bytepan.com/aLBtMe2g40P

最新文章

  1. 在线作图丨数据降维方法⑥——消除趋势对应分析(Detrended correspondence analysis, DCA)
  2. Visual Studio——理解多字节编码与Unicode码
  3. Java09-day09【ArrayList(概述、构造方法、常用方法、遍历)、简易学生管理系统】
  4. 【hadoop】1.简介
  5. 数学界最恐怖的存在,学过数学的人,一辈子都不会忘记!
  6. 孙叫兽进阶之路之Gitlab的使用(图文教程)
  7. 简单的Excel导出(两种方式)
  8. 计算机谭音乐同桌的你,同桌的你_Ava_clover_新浪博客
  9. MQ如何防止消息丢失
  10. 当网页数据到达用户计算机,当网页数据到达用户计算机时,数据进行转换步骤是()...
  11. oracle 查看隐含参数的脚步
  12. UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb8 in position 24: invalid start byte
  13. CentOS 7.0系统安装配置LAMP服务器(Apache+PHP+MariaDB)
  14. javascript 容错处理代码【屏蔽js错误】
  15. 电工学习笔记————稳压二极管伏安特性
  16. 跟着翁凯老师学Cday1#学习记录#
  17. 加点字符就能让qq昵称很酷的神奇代码?
  18. Ubuntu无法解析域名
  19. Java8新特性-Optional类
  20. java秒表计时器_Java实现的计时器【秒表】功能示例

热门文章

  1. 中值定理中辅助函数的构造方法
  2. pat 乙级 1020 吃月饼(25)
  3. PAT甲级——1166 Summit (25 分)
  4. bzoj2592 Symmetry
  5. NSX-T 系列:第 8部分 - 添加Edge节点和配置Edge集群
  6. 组态软件——工业控制中的“操作平台”
  7. 【论文笔记】AAAI2022:Do Feature Attribution Methods Correctly Attribute Features?
  8. PHP使用FPDF、Fpdi类库给PDF文件添加水印
  9. 佳能hdr_不要忘了相机自带的HDR功能_佳能 6D_数码影像评测-中关村在线
  10. 好口才让你成为真正的演讲高手