C语言数组实现打砖块游戏

 更新时间:2022年05月12日 09:48:37   作者:无限的菜鸟  
这篇文章主要为大家详细介绍了C语言数组实现打砖块游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

这次我们使用数组来改进打砖块游戏

反弹的球

首先我们实现一个可以在荧幕上反弹的小球。使用二维数组 int canvas[High][Width] ( 和js的canvas没有一毛钱关系)来储存画布上的所有元素,值为0时输出空格,值为1时输出小球。

设小球坐标为(ball_x, ball_y),则有canvas[ball_x][ball_y] = 1 ,且暂时将其他元素的值设为0。

每次更新小球位置时将原位置元素设为0,将新位置元素设为1即可。

注意:gotoxy函数用于清屏重画,很久以前讲过的。

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <cwindow.h>
// 画面尺寸设定
#define High 15
#define Width 20

//全局变量
int ball_x,ball_y;    //小球坐标
int ball_vx,ball_vy;//小球速度
int canvas[High][Width] = [0];

void gotoxy(int x, int y)    //移动光标便于清屏重画
{
    HANDLE handle = GetStdHandle(STD_UOTPUT_HANDLE);
    CROOD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);
}

void startup()                //数据初始化
{
    ball_x = 0;
    ball_y = Width/2;
    ball_vx = 1;
    ball_vy = 1;
    canvas[ball_x][ball_y] = 1;
}

void show()
{
    gotoxy(0, 0);
    int i,j;
    for(i=0; i<High; i++)
    {
        for(j=0; j<Width; j++)
        {
            if (canvas[i][j] == 0)
                printf(" ");//输出空格
            else if (canvas[i][j] == 1)
                printf("O");//输出小球
        }
        printf("|\n");//每画完一行显示边界并换行
    }
    for(j=0; j<Width; j++)
        printf("-");//最后画下边界
}

void updateWithoutInput()    //无关输入的更新
{
    //小球移动
    canvas[ball_x][ball_y] = 0;
    ball_x = ball_x + ball_vx;
    ball_y = ball_y + ball_vy;
    //反弹判断
    if ((ball_x == 0)||(ball_x == High - 1))
        ball_vx = -ball_vx;
    if ((ball_y == 0)||(ball_y == Width - 1))
        ball_vy = -ball_vy;
            
    canvas[ball_x][ball_y] = 1;
    //休眠时间,避免刷新过快
    sleep(50);
}

void updateWithInput()
{}

int main()
{
    startup();
    while(1)
    {
        show();
        updateWithoutInput();
        updateWithInput();
    }
    return 0;
}

这里要注意的是:

  • updateWithInput留空,因为现在还没有用户操作的功能实现。
  • main是死循环,所以测试时要注意,当然也可以改进。

增加挡板

现在我们可以新定义,当数组中某一元素值为2时,输出挡板“ * ”。

并且为updateWithInput增加移动挡板的功能,每次移动一个单位作为其速度(当然可以改成别的数)。

挡板的刷新方式和小球一样,先将原位置清零然后把新位置元素改为2。

需要增加的内容如下:

//全局变量
int position_x,position_y; //挡板中心坐标
int ridus;    //挡板半径,就是延伸的长度
int left,right;    //挡板左右位置

//初始化
ridus = 5;
position_x = High - 1;
position_y = Width/2;
left = position_y - ridus;
right = position_x + ridus;

int k;
for(k=left; k<=right; k++)
    canvas[position_x][k] = 2;

//输出部分
...
else if (canvas[i][j] == 2)
    printf("*");
...

//更新部分(与输入无关)
if (ball_x == High - 2)
{
    //判断是否挡住
    if ((ball_y >= left)&&(ball_y <= right))
    {
        printf("\a");
    }
    else    //未挡住
    {
        printf("游戏失败\n");
        printf("pause");
        exit(0);
    }
}

//与输入有关的更新
void updateWithInput()
{
    char input;
    if (kbhit())    //判断是否有输入
        input = getch();
    if ((input == 'a')&&(left > 0))//左移
    {
        canvas[position_x][right] = 0;
        position_y --;
        left = position_y - ridus;
        right = position_x + ridus;
        canvas[position_x][left] = 2;
    }
    if ((input == 'd')&&(right < Width -1))//右移
    {
        canvas[position_x][left] = 0;
        position_y ++;
        left = position_y - ridus;
        right = position_x + ridus;
        canvas[position_x][right] = 2;    
    }
}

打砖块

这部分内容就和之前的内容一样了。

需要增加的内容有:

1. 初始砖块
2. 小球碰到砖块的判定
3. 碰到砖块后的更新(砖块消失、小球反弹)

具体代码如下:

//初始化
int k,i;

for(k=0; k<Width; k++)
    for(i=0; i<high/4; i++)    //这里是画砖块,可以根据修改 i 的范围改变砖块的排数
        canvas[i][k] = 3;
//输出
...
else if (canvas[i][j] == 3)
    printf("#");
...
//碰到砖块后
if (canvas[ball_x + ball_vx][ball_y + ball_vy] == 3)
{
    canvas[ball_x + ball_vx][ball_y + ball_vy] = 0;
    ball_vx = -ball_vx;
    ball_vy = -ball_vy;
    printf("\a");
}

最后

1. 坐标系是x轴向下,y 轴向右。
2. 实际对碰撞的判定是在斜方向上,当然可以改进判定内容。
3. 游戏胜利条件还没有完善。

全代码:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <cwindow.h>
// 画面尺寸设定
#define High 15
#define Width 20

//全局变量
int ball_x,ball_y;    //小球坐标
int ball_vx,ball_vy;//小球速度
int canvas[High][Width] = [0];
int position_x,position_y; //挡板中心坐标
int ridus;    //挡板半径,就是延伸的长度
int left,right;    //挡板左右位置

void gotoxy(int x, int y)    //移动光标便于清屏重画
{
    HANDLE handle = GetStdHandle(STD_UOTPUT_HANDLE);
    CROOD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);
}

void startup()                //数据初始化
{
    ball_x = 0;
    ball_y = Width/2;
    ball_vx = 1;
    ball_vy = 1;
    canvas[ball_x][ball_y] = 1;

    ridus = 5;
    position_x = High - 1;
    position_y = Width/2;
    left = position_y - ridus;
    right = position_x + ridus;

    int k,i;
    for(k=left; k<=right; k++)
    canvas[position_x][k] = 2;

    for(k=0; k<Width; k++)
        for(i=0; i<high/4; i++)    //这里是画砖块,可以根据修改 i 的范围改变砖块的排数
            canvas[i][k] = 3;
}

void show()
{
    gotoxy(0, 0);
    int i,j;
    for(i=0; i<High; i++)
    {
        for(j=0; j<Width; j++)
        {
            if (canvas[i][j] == 0)
                printf(" ");//输出空格
            else if (canvas[i][j] == 1)
                printf("O");//输出小球
            else if (canvas[i][j] == 2)
                printf("*");
            else if (canvas[i][j] == 3)
                printf("#");
        }
        printf("|\n");//每画完一行显示边界并换行
    }
    for(j=0; j<Width; j++)
        printf("-");//最后画下边界
}

void updateWithoutInput()    //无关输入的更新
{
    if (canvas[ball_x + ball_vx][ball_y + ball_vy] == 3)
    {
        canvas[ball_x + ball_vx][ball_y + ball_vy] = 0;
        ball_vx = -ball_vx;
        ball_vy = -ball_vy;
        printf("\a");
    }
    if (ball_x == High - 2)
    {
        //判断是否挡住
        if ((ball_y >= left)&&(ball_y <= right))
        {
            printf("\a");
        }
        else    //未挡住
        {
            printf("游戏失败\n");
            printf("pause");
            exit(0);
        }
    }
    //小球移动
    canvas[ball_x][ball_y] = 0;
    ball_x = ball_x + ball_vx;
    ball_y = ball_y + ball_vy;
    //反弹判断
    if ((ball_x == 0)||(ball_x == High - 1))
        ball_vx = -ball_vx;
    if ((ball_y == 0)||(ball_y == Width - 1))
        ball_vy = -ball_vy;
            
    canvas[ball_x][ball_y] = 1;
    //休眠时间,避免刷新过快
    sleep(50);
}

void updateWithInput()
{
    char input;
    if (kbhit())    //判断是否有输入
        input = getch();
    if ((input == 'a')&&(left > 0))//左移
    {
        canvas[position_x][right] = 0;
        position_y --;
        left = position_y - ridus;
        right = position_x + ridus;
        canvas[position_x][left] = 2;
    }
    if ((input == 'd')&&(right < Width -1))//右移
    {
        canvas[position_x][left] = 0;
        position_y ++;
        left = position_y - ridus;
        right = position_x + ridus;
        canvas[position_x][right] = 2;    
    }
}

int main()
{
    startup();
    while(1)
    {
        show();
        updateWithoutInput();
        updateWithInput();
    }
    return 0;
}

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

相关文章

  • C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析

    C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析

    这篇文章主要介绍了C++实现图的邻接矩阵存储和广度、深度优先遍历,实例分析了C++实现图的遍历技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • C/C++ 中怎样使用SetConsoleTextAttribute()函数来控制输出字符的颜色

    C/C++ 中怎样使用SetConsoleTextAttribute()函数来控制输出字符的颜色

    这篇文章主要介绍了C/C++ 中如何使用SetConsoleTextAttribute()函数来控制输出字符的颜色,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • sigsetjmp的用法总结

    sigsetjmp的用法总结

    sigsetjmp()会保存目前堆栈环境,然后将目前的地址作一个记号,而在程序其他地方调用siglongjmp()时便会直接跳到这个记号位置,然后还原堆栈,继续程序的执行
    2013-09-09
  • C++ Boost Xpressive示例分析使用

    C++ Boost Xpressive示例分析使用

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • C语言 详细讲解逻辑运算符的使用

    C语言 详细讲解逻辑运算符的使用

    在C语言中,逻辑运算符有&&、||、!;&&表示“与”的意思,需要两端的表达式的值都为true,该式的值才为true。||表示“或”的意思,两端的表达式的值只要有一端为true,该式的值就为true。!表示“非”的意思,将该式的真值换成相反的真值,即false和true互换
    2022-04-04
  • 基于VC编写COM连接点事件的分析介绍

    基于VC编写COM连接点事件的分析介绍

    本篇文章是对VC编写COM连接点事件进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • Qt自定义图形实现拖拽效果

    Qt自定义图形实现拖拽效果

    这篇文章主要为大家详细介绍了Qt自定义图形实现拖拽效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • C++ 复制控制之复制构造函数的实现

    C++ 复制控制之复制构造函数的实现

    所谓的“复制控制”即通过这三个成员函数控制对象复制的过程,本文主要介绍了C++ 复制控制之复制构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • C语言实现简易五子棋

    C语言实现简易五子棋

    这篇文章主要为大家详细介绍了C语言实现简易五子棋,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • C++利用栈实现中缀表达式转后缀表达式

    C++利用栈实现中缀表达式转后缀表达式

    这篇文章主要为大家详细介绍了C++利用栈实现中缀表达式转后缀表达式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04

最新评论