前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++ 一款纯C实现的打砖块小游戏

C++ 一款纯C实现的打砖块小游戏

作者头像
一枚大果壳
发布于 2024-05-18 01:10:25
发布于 2024-05-18 01:10:25
22300
代码可运行
举报
文章被收录于专栏:编程驿站编程驿站
运行总次数:0
代码可运行

纯C实现的打码块小游戏!可能不完美,对于学习理解C语言有很大帮助。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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

/*
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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程驿站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
安静100分钟理解js面向对象
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> </body> </html> <script> window.onload=function(){ //安静100分钟来理清js对象,以及类的生成 //深入理解对象原型与constructor //1----------------------------------------- //定义一个对象 function
前朝楚水
2018/04/02
7520
面试官想要的 JS 基本类型
面试的时候我们经常会被问答js的数据类型。大部分情况我们会这样回答包括: 基本类型(值类型或者原始类型): Number、Boolean、String、NULL、Undefined以及ES6的Symb
grain先森
2019/04/17
5920
面试官想要的 JS 基本类型
引用类型、对象拷贝
1.引用类型有哪些?非引用类型有哪些 引用类型 引用类型(对象、数组、函数、正则): 指的是那些保存在堆内存中的对象,变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,由该位置保存对象。 非引用类型(基本类型) 基本类型值(数值、布尔值、null和undefined): 指的是保存在栈内存中的简单数据段; 2.代码练习 (1)如下代码输出什么?为什么 var obj1 = {a:1, b:2}; var obj2 = {a:1, b:2}; console.log(obj1 == ob
小胖
2018/06/27
8010
一文带你解读​JavaScript中的变量、作用域和内存问题
基本数据类型:undefined;null;number;boolean;string;按照值访问的,可以操作保存在变量中的实际的值;
前端皮皮
2021/11/02
6190
一文带你解读​JavaScript中的变量、作用域和内存问题
前端学习(26)~js学习(四):基本数据类型vs引用数据类型
上面的代码中:a 和 b 都是基本数据类型,让 b 等于 a,然后改变 a 的值之后,发现 b 的值并没有被改变。
Vincent-yuan
2020/03/18
5200
js中的值类型和引用类型的区别
(1)值类型(基本类型):字符串(string)、数值(number)、布尔值(boolean)、undefined、null (这5种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值)(ECMAScript 2016新增了一种基本数据类型:symbol es6.ruanyifeng.com/#docs/symbo… )
前端老鸟
2019/10/09
3.8K0
js中的值类型和引用类型的区别
赋值、浅拷贝、深拷贝的区别
基本类型数据保存在在栈内存中 引用类型数据保存在堆内存中,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中。
木子星兮
2020/07/16
1.2K0
JavaScript 对象赋值和浅拷贝的区别
先看赋值,将一个对象赋值给一个新的对象的时候,赋的其实是该对象在栈中的地址,而不是堆中的数据。也就是一个对象的改变就会改变另外一个对象。
GopalFeng
2020/09/24
1.1K0
JavaScript 对象赋值和浅拷贝的区别
JavaScript的变量及作用域(清晰版)
JS是一门弱类型(松散型)的语言,这也就是说其天生就与众不同,独领风骚! 在讲解变量作用域之前,我们先来了解一下JS中的变量。JS中的变量与其它语言有很大的不同,由于JS变量拥有松散(不强制)的本质,从而决定了其只是一个在特定阶段保持特定类型值的名字。
用户1272076
2019/03/26
5610
Swift讲解专题十——类与结构体 原
        Swift中的类与结构体十分相似,和Objective-C不同的是,Swift中的结构体不仅可以定义属性,也可以像类一样为其定义方法。
珲少
2018/08/15
4060
Web前端学习 第3章 JavaScript基础教程19 原始类型
原始类型赋值给变量,遍历存储的是这个值本身,而你用类型赋值给变量,变量存储的是一个引用,这个引用会指向内存中的这个对象。
学习猿地
2020/06/17
3780
Js基础---红宝书读书日记(1)-------基本类型和引用类型
JS的变量可能包含两种不同数据类型的值,基本类型和引用类型; 基本类型是指简单的数据段,引用类型是指可能由多个值构成的对象; JS高级程序设计第三章介绍了变量分为 5种简单数据类型(string/number/undefined/null/boolean)--------基本类型(按值访问): 这五种数据类型是按值访问的,可以操作保存在变量中的实际的值. 1个复杂数据类型(object)--------引用类型(按索引访问): 引用类型的值是保存在内存中的对象;js不予许直接访问内存中的位置,也就是说不能直
李文杨
2018/03/27
8610
Js基础---红宝书读书日记(1)-------基本类型和引用类型
从JS底层理解var、let、const
基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值。引用数据类型的值是保存在内存中的对象,JS不允许直接访问内存中的位置,所以在操作的时候操作的是对象的引用;因此是引用数据类型是按照引用访问的。
木子星兮
2020/07/16
2.1K0
【react】利用shouldComponentUpdate钩子函数优化react性能以及引入immutable库的必要性
根据文章内容总结的摘要
啦啦啦321
2018/01/03
1.5K0
【react】利用shouldComponentUpdate钩子函数优化react性能以及引入immutable库的必要性
js 判断循环引用
利用JSON.stringify的报错信息来做 var obj1 = {a:"1"}; obj1.b = {}; obj1.b.a = obj1.b; var obj2 = {a: {c: "1"}}; obj2.a.b = obj2; var obj3 = {a: 1, b: 2, c: {d: 4}, d: {}, e: {}} var obj1 = {a:"1"}; obj1.b = {}; obj1.b.a = obj1.b; obj1.b.b = obj1.b; var obj1 = {a:"
windseek
2020/05/18
20.5K0
JavaScript 数据结构与算法之美 - 栈内存与堆内存 、浅拷贝与深拷贝
栈内存与堆内存 、浅拷贝与深拷贝,可以说是前端程序员的内功,要知其然,知其所以然。
夜尽天明
2019/07/10
6790
JavaScript 数据结构与算法之美 - 栈内存与堆内存 、浅拷贝与深拷贝
javascript 拷贝赋值
在JavaScript编程中,经常会涉及到对象赋值和拷贝的操作。这里我们将深入探讨JavaScript中的对象赋值和拷贝相关的知识,帮助开发者更好地理解和使用对象的赋值操作。
大盘鸡拌面
2024/04/27
1810
JS 深拷贝与浅拷贝
其实在工作写代码和面试中,会经常碰到这两个概念:深拷贝,浅拷贝。但今天的重点是深拷贝。
Umbrella1024
2021/02/18
2.2K0
JavaScript中基本数据类型和引用数据类型的区别
  当我们把变量赋值给一个变量时,解析器首先要确认的就是这个值是基本类型值还是引用类型值。
江一铭
2022/06/17
6410
JavaScript中基本数据类型和引用数据类型的区别
前端学习(32)~js学习(九):对象简介和对象的基本操作
对象的作用是:封装信息。比如Student类里可以封装学生的姓名、年龄、成绩等。
Vincent-yuan
2020/03/18
6670
相关推荐
安静100分钟理解js面向对象
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验