#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include<mmsystem.h>
#pragma comment(lib, "WINMM.LIB")

#define BRICK_NUM 100
//形状类型
#define SQUARE 1
#define STAR 2
#define DIAMOND 3

/*
建立对应模型:20/80 程序:核心代码20% 非核心的代码80%
1、砖块:描述砖块
2、球
3、条形木块
*/
typedef struct Point
{
int x;
int y;
} Point;
//球数据模型
typedef struct Ball
{
//坐标
Point point;
//形状,普通 火球 激光
int shape;
//水平方向 r:1 l:-1 : 'l' 'r'
int hdir;
//垂直方向 u :1 d:-1
int vdir;
//速度
int speed;
} Ball;

//木板
typedef struct Board
{
//坐标
Point point;
//长度
int length;
//方向 左(-1) 右(1)
int dir;
//速度
int speed;
} Board;

//构建类型,摸拟砖块
typedef struct Brick
{
//坐标
Point point;
//形状 :1:正方形(普通砖块 10) 2(圆形 20) 3:
int shape;
} Brick;

//砖块
Brick bricks[BRICK_NUM];

//构建一个球
Ball ball;
//构建一个木板
Board board;

//计数器,
int count=0;
//总分值
int totalScore=0;

void init()
{
srand(time(0));
//初始化球
ball.point.x=36;
ball.point.y=22;
ball.shape=1;
ball.speed=200;
ball.vdir=1;//向上 u 向下 d 向左 l 向右 r
ball.hdir=-1;
//初始化木板
board.point.x=32;
board.point.y=23;
board.length=5;
board.speed=300;
board.dir=-1;
//初始化砖块
initBrick();
}

/*
功能:定位光标(输出)位置
*/
void setPosition(Point point)
{
//用户坐标信息转换成内部坐标信息
COORD coord= {point.x,point.y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}

/*
可视化显示木板,球
*/
void showBall()
{
setPosition(ball.point);
//颜色:r g b
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY) ;
printf("◎");
}

/*
*可视化显示木板 (重构)--》进化--》
*/
void showBorad()
{
int index=0;
setPosition(board.point);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED | FOREGROUND_INTENSITY) ;
for(index=0; index<board.length; index++)
{
printf("〓");
}
}

/*
随机数字
*/
int createRan()
{
return rand()%3+1;// 0 12
}

/*
初始化砖块信息
*/
void initBrick()
{
//确定第一个砖块位置 x ,y 程序逻辑会引起修改
int x=10;
int y=2;
int i=0;
//保存最初坐标
int index=0;
//100=25*4
for(index=0; index<BRICK_NUM; index++)
{
//确定每一行起始坐标
if(index!=0 && index%25==0) //25 50 75
{
//换行
x=bricks[i*25].point.x;
y=bricks[i*25].point.y+1;
i++;
}
//具体化
bricks[index].point.x=x;
bricks[index].point.y=y;
//形状
bricks[index].shape=createRan();
x=x+2;
}
}

/*
*图形化砖块
*/
void showBrick()
{
int index=0;
for(index=0; index<BRICK_NUM; index++)
{
setPosition(bricks[index].point);
switch(bricks[index].shape)
{
case SQUARE:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
printf("■");
break;
case STAR:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
FOREGROUND_GREEN | FOREGROUND_INTENSITY);

printf("★");
break;
case DIAMOND:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_INTENSITY);
printf("◆");
break;
}
}
}

/*
检查小球是否碰到了木板
1 碰
0 没有碰到
*/
int ballToBoard()
{
//木板的启始x值
int bxs=board.point.x;
int bxe=board.point.x+board.length*2;
if( (ball.point.x>=bxs && ball.point.x<=bxe) && ball.point.y==board.point.y-1 )
{
return 1;
}
return 0;
}

void selDir(){
//函数:异步
if(GetAsyncKeyState(VK_LEFT)){
board.dir=-1;
}else if(GetAsyncKeyState(VK_RIGHT)){
board.dir=1;
}
}

/*
移动木板
*/
void moveBoard()
{
int index=0;
setPosition(board.point);
//清除
for(index=0; index<board.length; index++)
{
printf(" ");
}
//新坐标:
board.point.x+=2*board.dir;
//重新
setPosition(board.point);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED | FOREGROUND_INTENSITY) ;
for(index=0; index<board.length; index++)
{
printf("〓");
}
}

/*
检查小球是否碰到砖块
0
1
2
3
*/
int ballToBrick(){
int index=0;
for(index=0;index<BRICK_NUM;index++){
if(bricks[index].point.x==ball.point.x && bricks[index].point.y==ball.point.y){
return bricks[index].shape;;
}
}
return 0;
}

/*
移动小球
*/
void moveBall()
{
int left=4;
int right=64;
int top=2;
int bottom=24;
//水平、垂直增量
int stepx=2;
int stepy=1;
int shape=0;
Point p={76,10};
//得到小球原来位置
Point oldPoint=ball.point;
srand(time(0));
//原来位置图形清除
setPosition(oldPoint);
printf(" ");

//检查水平方向
if(ball.point.x<left)
{
//改变水平方向
ball.hdir=1;
}
else if(ball.point.x>right)
{
ball.hdir=-1;
}

//检查垂直方向
if(ball.point.y<top)
{
ball.vdir=-1;
}
else if(ball.point.y>bottom)
{
ball.vdir=1;
}
else if(ballToBoard()==1)
{
ball.vdir=1;
}

//确定小球的新的位置
ball.point.x=oldPoint.x+stepx*ball.hdir;
ball.point.y=oldPoint.y-stepy*ball.vdir;

//判断是否碰到砖块 0 1 2 3
shape=ballToBrick();
//计算碰了多少块砖块
count+=shape>0?1:0;

setPosition(p);
totalScore+=shape*10;
printf("小球碰了%d砖块,计分:%d",count,totalScore);
//重新绘制
setPosition(ball.point);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY) ;
printf("◎");
}

/*
功能模块:绘制围墙 1B=8bit A:1B 中文:2B
*/
void paintWall()
{
int index=0;
Point point;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),11);
//上边。下边
for(index=0; index<70; index=index+2)
{
point.x=index;
point.y=0;
setPosition(point);
printf("■");
point.y=26;
setPosition(point);
printf("■");
}
//左边、右边akes[0].x=oldX+2;
for(index=1; index<=26; index++)
{
point.x=0;
point.y=index;
setPosition(point);
printf("■");
point.x=68;
setPosition(point);
printf("■");
}
}

void show()
{
paintWall();
showBrick();
showBall();
showBorad();
}

int main()
{

init();
show();
while(1)
{
moveBall();
selDir();
moveBoard();
//速度
Sleep(ball.speed);
}
return 0;
}

c语言 弹弹球小游戏的更多相关文章

  1. java 图形化小工具Abstract Window Toolit :画笔Graphics,画布Canvas(),弹球小游戏

    画笔Graphics Java中提供了Graphics类,他是一个抽象的画笔,可以在Canvas组件(画布)上绘制丰富多彩的几何图和位图. Graphics常用的画图方法如下: drawLine(): ...

  2. 初识python:tkinter 实现 弹球小游戏(面向对象)

    使用蹩脚式面相对象,实现弹球小游戏(非面向对象实现,主要介绍tk基础用法). #!/user/bin env python # author:Simple-Sir # time:2020/8/7 10 ...

  3. 初识python:tkinter 实现 弹球小游戏(非面相对象)

    通过 tkinter 采用非面相对象式实现弹球小游戏(使用蹩脚式面相对象实现). #!/user/bin env python # author:Simple-Sir # time:2020/8/3 ...

  4. 简单的C语言猜数字小游戏

    猜数字小游戏可谓是C语言最为基础的一个知识点了,我们可以在此基础上进行延伸,实现随机数的猜测,然后是加入再来一局的模式,等等.这里是抛砖引玉,希望你能做出你的经典之作. #include <st ...

  5. C语言实现2048小游戏

    目录 2048 一.设计思路 1.游戏规则 2.思路 二.代码实现 1.存储结构 2.初始化游戏数据 3.向左合并 4.其他方向合并 5.产生新的方块 6.源代码 7.实例演示 三.问题 2048 一 ...

  6. c语言----<项目>_小游戏<2048>

    2048 小游戏 主要是针对逻辑思维的一个训练. 主要学习方面:1.随机数产生的概率.2.行与列在进行移动的时候几种情况.3.MessageBox的使用 #include <iostream&g ...

  7. java_弹球小游戏

    弹球游戏实现原理: 隔一定时间(小于1秒)重新绘制图像,因为Graphics类是一个抽象类,创建子类的时候需要把所有涉及的方法都得重写,所以这里使用的是创建Canvas的子类,只需要重写它的paint ...

  8. 【C语言程序设计】小游戏之俄罗斯方块(一)!适合初学者上手、练手!

    俄罗斯方块的核心玩法非常简单,所以制作起来并不是很复杂,我准备先用2篇文字的篇幅详细讲解一下俄罗斯方块的制作方法. 今天咱们算是第一篇,主要讲解俄罗斯方块中如何定义方块,以及如何实现方块的移动.旋转. ...

  9. 【C语言程序设计】小游戏之俄罗斯方块(二)!适合初学者上手、练手!

    第二篇,主要实现俄罗斯方块中的主体部分,包括容器的数据结构以及容器的相关操作,特别是大方块和容器之间的交互逻辑,包括碰撞检测,消除检测等等. 1. 容器的表示 大方块的实现涉及到位运算,而容器同样如此 ...

随机推荐

  1. LOJ#2353 货币兑换

    CDQ分治优化斜率优化DP. 有个结论就是每天买完卖完....知道这个之后考虑今天卖的是哪天买的就能写出n²DP了. 发现形式是fi = max(aibj + cidj)的形式.我们可以把ci除出来, ...

  2. 网页HTML代码在线运行器

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. Runtime.getRuntime().exec(...),当参数中有空格时!

    原以为不会有什么问题,但在测试时发现,问题大了. 如果想调用f:\mp3\i love you.mp3时, 我原以为正确的写法是: //在文件名前后加个双引号来解决文件名中有空格的情况 String ...

  4. 斯坦福大学公开课机器学习: advice for applying machine learning | regularization and bais/variance(机器学习中方差和偏差如何相互影响、以及和算法的正则化之间的相互关系)

    算法正则化可以有效地防止过拟合, 但正则化跟算法的偏差和方差又有什么关系呢?下面主要讨论一下方差和偏差两者之间是如何相互影响的.以及和算法的正则化之间的相互关系 假如我们要对高阶的多项式进行拟合,为了 ...

  5. POJ 3249 Test for Job (记忆化搜索)

    Test for Job Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11830   Accepted: 2814 Des ...

  6. 退回win7后无法上网 的解决方法

    如果网卡驱动没问题的话,那你是不是装了360安全卫士,如果装了你打开网络和共享中心———更改适配器设置————右键本地连接———属性————把360局域网防护驱动程序前面的对勾去掉然后确定,一般就能解 ...

  7. (map)水果 hdu1263

    水果 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...

  8. Ajax的请求规范(二)

    第一种方式:send()不带参数 function doAjax(url,fnSucc,fnFaild) { //1.创建Ajax对象 if (window.XMLHttpRequest) {//判断 ...

  9. bzoj2733 离线+并查集+主席树

    https://www.lydsy.com/JudgeOnline/problem.php?id=2733 网上清一色的合并线段树题解,我又不会,只能自己胡来,没想到Rush过去了 永无乡包含 n 座 ...

  10. 我们数学中常用的自然常数e代表什么?看完长知识了!

    我们在学习期间都接触过自然常数e,也知道e ≍ 2.718,学过极限的同学应该也知道 那么大家知道e的含义是什么吗?为啥叫“自然常数”? e的含义可以用一个计算利息的例子来解释. 假如你有1块钱,银行 ...