C语言图形编程--俄罗斯方块制作(一)详解

article/2025/9/30 22:45:21

效果图

 

C语言实现俄罗斯方块,需要先解决下面几个问题:

1、如何用C语言绘制图形界面

EasyX图形库(http://www.easyx.cn)TC的图形库在VC下的移植。

 

包含库#include <graphics.h>

先初始化图形窗口

initgraph(WINDOW_WIDTH, WINDOW_HIGH) ;WINDOW_WIDTH为窗口的宽带,WINDOW_HIGH为窗口的高度。

清空绘图设备

cleardevice();

设置画笔颜色

setcolor(RED) ;

设置线条风格

setlinestyle(PS_SOLID, NULL, 0);

画矩形

rectangle

还有画线、显示文字等函数,可以参照其帮助文档。

 

注意:由于我们用的是EasyX图形库,故源文件后缀要为.cpp,但其中内容都是C的语法。

 

2、如何存储表示出俄罗斯方块的形状

在计算机中如何让一串的01数字,代表俄罗斯方块?

一、我们可以用编号,不同的编号代表不同的俄罗斯方块,根据编号把不同方块的画法写在代码中,这样19

方块就得有19种相应的代码来描绘。而且这样扩展性不好,若以后设计了新的方块,则需要更改大量源代码。

二、我们很自然的想到可用字模点阵的形式来表示,即设置一个44列的数组,元素置1即代表这个位置有小

方块,元素置0即代表这个位置无小方块,这个整个的4*4的数组组成俄罗斯方块的形状。

1000

1000

1100

0000

这个方法挺靠谱,但我们还可以优化一下:不用4*4的数组,而是用16bit位来表示这个点阵。这样存储起来比较方便,故我们用unsigned int 的低16位来表示方块的点阵。

我们可以用掩码与表示俄罗斯方块的位进行操作,来识别并在屏幕上画出方块。

详情见GUI.cpp中的DrawRock函数。

[cpp]  view plain copy
print ? 在CODE上查看代码片 派生到我的代码片
  1. //逐位扫描由unsigned int的低2字节  
  2. //16个位组成的俄罗斯方块形状点阵(其代表4*4的方块形状)  
  3. mask = (unsigned int)1 << 15 ;  
  4. for (i=1; i<=16; i++)  
  5. {  
  6.     //与掩码相与为1的 即为方块上的点  
  7.     if ((rockArray[rockIndex].rockShapeBits & mask) != 0)  
  8.     {  
  9.         //在屏幕上画出此方块  
  10.         rectangle(rockX+2,   
  11.                   rockY+2,   
  12.                   rockX+ROCK_SQUARE_WIDTH-2,   
  13.                   rockY+ROCK_SQUARE_WIDTH-2) ;   
  14.     }  
  15.   
  16.     //每4次 换行 转到下一行继续画  
  17.     i%4 == 0 ? (rockY += ROCK_SQUARE_WIDTH, rockX = currentLocatePtr->left)  
  18.              :  rockX += ROCK_SQUARE_WIDTH ;  
  19.   
  20.     mask >>= 1 ;  
  21. }  


 

我们把俄罗斯方块点阵的数位存在rockArray中,我们可以事先把这19种方块的字模点阵自己转化成十六进制,然后在rockArray数组的初始化时赋值进去。

但这样做未免有点太费力,且扩展性也不太好,若以后设计的新方块种类加入,要改变数组rockArray中的值。

我们可以考虑把所有俄罗斯方块的点阵存储在配置文件中,在程序初始化时读取文件,把这些点阵转换成unsigned int的变量存储在rockArray中。

这样,以后我们增添新的方块形状只需要在配置文件中增加新的点阵即可。

@###

@###

@@##

####   (为使得看起来更醒目,我们用@表示1,用#表示0

 

3、如何让图形动起来

若没有按键的情况下,方块是自动下落的。

如何实现自动下落?在某位置处用函数DrawRock在屏幕上画出俄罗斯方块,然后再擦除掉(即用背景色在原位置处重绘一次方块),最后在下落的下一个位置处用函数DrawRock在屏幕上画出俄罗斯方块,如此循环,中间用计时器间隔一段时间以控制下落的速度。

同理,按下屏幕的左右键也是如此,只是在按下键盘时把方块的位置重新计算了。


那么按下上方向键时,如何让方块翻转呢?

我们在配置文件中就把方块的顺时针翻转形态放在了一起:

@###

@###

@@##

####

 

@@@#

@###

####

####

 

@@##

#@##

#@##

####

 

   ##@#

@@@#

####

####

 

我们每按一次上方向键改变一次方块的形状即可。若一直按上键,形状应该是循环地翻滚。

我们想到了循环链表的数据结构可实现这个效果。

可是我们若把这些一种类的方块的各种形态串成循环链表形式,那么每次重新生成方块时我们就难以随机地生成方块了。

故还是得用数组来存储,但又要有循环链表的功能,于是我们想到了静态循环链表

我们用结构体来作为一个方块在rockArray中的元素

typedef struct ROCK

{  //用来表示方块的形状(每一个字节是8位,用每4位表示方块中的一行)

    unsigned int rockShapeBits ; 

    int          nextRockIndex ;  //下一个方块,在数组中的下标

} RockType ;

这样,当我们按下上方向键时,把传入函数DrawRock中的rockIndex变为当前方块结构体中的nextRockIndex即可。

详情见play.cpp中的ProccessUserHit函数。

 

4、如何判断方块什么时候停止什么时候满行得分

方块一直下落,最终是要停下来的,我们要设置一个边界来约束方块的移动范围。我们把当前游戏界面划分成以俄罗斯方块中的小方格为单位的格子,用一个二维数组g_gameBoard来表示这些小方格的状态,1表示此位置有方块,0表示此位置为空。

我们按照界面的大小和方格的大小来计算此二维数组时,再多设置一圈“围墙”,即多加两行两列,并把它们的值初始化为1

当方块准备下落或是左右移动的时候,前提前检查其即将落下的位置是否为空,若不为空,则停止下落,并把当前俄罗斯方块占用的方格都设置为1

详情见play.cpp中的moveAbled函数。

 

判断满行:

从最后一行开始往上检查g_gameBoard,若有一行全为1,则说明此行满行,将此行擦出,把此行上面的所有行向下移动一个单位。

详情见play.cpp中的ProcessFullRow函数

 

5、其他细节问题:

如何快速下落

详情见play.cpp中的FastFall函数

 

如何暂停

详情见play.cpp中的ProccessUserHit函数

 

此游戏程序的主要逻辑在play.cpp中的PlayGame函数

 

 源代码点击这里



原文链接:http://blog.csdn.net/yang_yulei/article/details/17651737




http://chatgpt.dhexx.cn/article/Ae4avJ8W.shtml

相关文章

C语言图形代码:三角、金字塔、圣诞树、爱心

在C语言的学习过程中&#xff0c;我们熟练掌握循环以后就可以使用循环编写&#xff0c;我们喜欢的图形代码啦&#xff01; 下面我向大家分别展示四种使用C语言循环编写的代码。 后两种都可以用来给自己的女朋友展示喔 1.三角形 2.金字塔 3.圣诞树 4.爱心 &#xff08;1&#…

linux下c语言图形界面实现,「分享」C语言如何编写图形界面

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面。大家也都有回答,需要其他的库。MFC,GTK,QT。 本人近期刚用GTK库加上纯C写成了第一个LINUX实用程序。现在与大家分享: 主界面程序gmaxtrix.c #includ…

c语言图形时钟编程,c语言+图形编程——打造浅易的时钟

全程代码小编就在这里发出来了哈 // c语言图形编程 电脑时钟 //包罗头文件 #include #include #include #define PI 3.141592654 void Draw_Dial();//绘制静态的表盘 void Draw_Hand(int hour, int minute, int secend); //绘制表针 //主函数 int main() { initgraph(640, 4…

简单c语言图形程序设计,c语言简单图形编程

c语言编程如何实现图形化? 如果你是说编写用户界面的C语言编程,那就应该学习平台编程.主流平台有windows,linux等. 楼主是领会到C得要点了.C不像JAVA和C#,它们才叫编写应用程序,因为它们的库直接可以编写出程序的应用部分(比如用户界面,调用系统资源等). 但是C语言不能叫做 c语…

C语言图形编程|设置位置

一、对光标位置进行修改 1、通过自定义函数来实现将光标移动到指定位置 void gotoxy(int x,int y) {HANDLE hCon;hCon GetStdHandle(STD_OUTPUT_HANDLE);COORD Pos;Pos.X x;Pos.Y y;SetConsoleCursorPosition(hCon,Pos); } 代码优化: void gotoxy(int x,int y) {COORD P…

C语言图形化编程

画折线图 #include<stdio.h> #include<conio.h> #include<graphics.h> #include<stdlib.h>void hDrawk(char c[]); void vDrawk(char c[]); void Drawfline(int b[]); int xs48,ys50;void hDrawk(char c[]) {int i,j65;line(65,360,565,360);for(i0;i&…

C语言图形化编程 【一】

C语言图形化编程 一 一、绘图窗口1.1 加载头文件1.2 创建一个窗口1.3 关闭窗口1.4 窗口坐标1.5 颜色1.6 设置颜色1.6.1 背景颜色1.6.2 线颜色1.6.3 文字颜色1.6.4 填充颜色 二、基本的绘图2.1 画点函数2.2 画线函数2.3 画矩形函数非填充(空心&#xff09;填充(实心)有边界线无边…

数据结构——图的五种种类【无向图-有向图-简单图-完全无向图-有向完全图】

目录&#xff1a; 一&#xff1a;无向图 1.定义 2.图形化解释 3.结合​表达式介绍 二&#xff1a;有向图 1.定义 2.图形化解释 3.结合​表达式介绍 有向图和无向图区别&#xff1a; 三&#xff1a;简单图 1.定义 2.图形化解释 四&#xff1a;完全无向图 1.定义 …

完全二分图

G <V,E> V – 》 元素顶点集 E --》 连线边集 V X ∪Y X中的任一顶点与Y中每一个顶点均有且仅有唯一的一条边相连&#xff0c;则称G为完全二分图或完全偶图。

构造完全图

咕咕咕 由于我好久都没有独立思考了&#xff08;抄了好久题解&#xff09;&#xff0c;思维什么的早没有了。 看完题只能想到一种暴力&#xff1a;遍历LCA 题目给出的是一个最小生成树&#xff0c;我们可以从边入手&#xff0c;把每条边所连的左右两个点分别看做一个集合&#…

图(一)

图论 结论&#xff1a; 1.无向完全图&#xff1a;在顶点数给定为n的情况下&#xff0c;边数达到最大的n(n-1)/2条边。 2.有向完全图&#xff1a;在顶点数给定为n的情况下&#xff0c;有向边数达到最大的n(n-1)条边。 3.树是图的特例&#xff1a;无环的无向图 4.生成树有可能不…

完全图的生成树

经典证明&#xff1a;Prfer编码与Cayley公式(转Matrix67) Cayley公式是说&#xff0c;一个完全图K_n有n^(n-2)棵生成树&#xff0c;换句话说n个节点的带标号的无根树有n^(n-2)个。今天我学到了Cayley公式的一个非常简单的证明&#xff0c;证明依赖于Prfer编码&#xff0c;它是对…

完全多部图

解题思想&#xff1a; 对于图中所有节点&#xff0c;如果不相连&#xff0c;按照题意&#xff0c;必须在一个集合里&#xff1b; 所以其实可以从第一个节点入手&#xff0c;找出与该点不相邻点的所有节点组成一个集合&#xff1b; 判断剩余所有点&#xff0c;如果不和该集合中所…

有向完全图和强连通图的区别?

文章目录 首先了解概念区别在哪里&#xff1f;有向完全图和强连通图的区别&#xff1f; 其他概念&#xff1a; 首先了解概念 相邻关系&#xff1a;两个顶点之间存在一条边&#xff0c;则表示两个顶点具有相邻关系 路径&#xff1a;相邻顶点序偶所构成的序列 路径长度&#xff…

【数据结构】图的基本概念—无/有向图、权和网、完全图、路径与回路

&#x1f49f;作者简介&#xff1a;大家好呀&#xff01;我是路遥叶子&#xff0c;大家可以叫我叶子哦&#xff01;❣️ &#x1f4dd;个人主页&#xff1a;【路遥叶子的博客】 &#x1f3c6;博主信息&#xff1a;四季轮换叶&#xff0c;一路招摇胜&#xff01; 专栏 【安利…

初次探图(图的概念--完全图、路径)

完全图 有向完全图 -边数n&#xff08;n-1) 无向完全图-边数n(n-1)/2 端点和邻接点 两顶点存在边相连称为端点&#xff0c; 两顶点存在有向边相连称为邻接点 子图 点集和边集都是另一个图的子集就称为子图 路径和路径长度 路径长度为边的数目 简单路径 针对于顶点来…

【离散数学】各类子图与完全图的定义详解

1. 各类子图&#xff1a; 2. 完全图&#xff1a; 注意上图中的俩条方向相反的有向边 无向完全图则是任意俩个结点间都有边相连&#xff0c;并不是只要可达即可

数据结构:有向完全图和无向完全图的边数

一、无向完全图 一个拥有n个结点的无向完全图的边数为&#xff1a;n(n−1)2 具体的解释&#xff1a; 比如我们有一个拥有4个结点的无向完全图&#xff0c; 我们首尾依次连接&#xff0c;共有4条边。 然后我们选择其他的两条边来连线。 又多出了2条边。一共有4 2 6条边。 我…

图论(2)完全图,顶点的度与度序列

目录 一、完全图 偶图&#xff08;双图或二部图&#xff09; &#xff08;2&#xff09;完全偶图 简单图的补图 自补图 二、顶点的度与图的度序列 顶点的度 图的度序列&#xff08;注意与图序列的区别&#xff09; 图序列 图的频序列及其性质 例题 一、完全图、偶图与补图 …