效果图

用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种相应的代码来描绘。而且这样扩展性不好,若以后设计了新的方块,则需要更改大量源代码。

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

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

1000

1000

1100

0000

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

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

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

[cpp] view plaincopy print?
  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. //每4次 换行 转到下一行继续画
  16. i%4 == 0 ? (rockY += ROCK_SQUARE_WIDTH, rockX = currentLocatePtr->left)
  17. :  rockX += ROCK_SQUARE_WIDTH ;
  18. mask >>= 1 ;
  19. }

我们把俄罗斯方块点阵的数位存在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

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

  1. C语言如何让图形的眼睛动起来,C语言图形编程--俄罗斯方块制作(一)详解

    效果图 用C语言实现俄罗斯方块,需要先解决下面几个问题: 1.如何用C语言绘制图形界面 EasyX图形库(http://www.easyx.cn)即TC的图形库在VC下的移植. 包含库#include ...

  2. C语言图形编程--俄罗斯方块制作(二)源代码

    所有源代码文件,此为本人2年前所作,设计上还有些缺陷.希望大家不吝指正. 设计详解点击这里 下面是头文件head.h /************************ (C) COPYRIGHT 2 ...

  3. C语言网络编程:accept函数详解

    文章目录 前言 函数描述 代码实例 如何得到客户端的IP 和 端口号 前言 当使用tcp服务器使用socket创建通信文件描述符,bind绑定了文件描述符,服务器ip和端口号,listen将服务器端的 ...

  4. C语言网络编程:listen函数详解

    文章目录 前言 函数描述 代码实例 TCP服务器为什么调用listen 前言 根据TCP编程模型中我们可以看到之前的socket和bind接口是tcp服务器在为接收客户端的链接做准备,保证tcp的面向 ...

  5. C语言网络编程:bind函数详解

    文章目录 函数功能 函数头文件 函数使用 函数参数 函数举例 为什么需要bind函数 服务器如何知道客户端的ip和端口号 htons函数 `htons`兄弟函数`htonl`,`ntohs`,`nto ...

  6. C语言网络编程:send函数详解

    函数描述 #include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t len, int flags); ...

  7. Linux·C语言高级编程·attribute和section详解

    目录 01. 扩展关键字: attribute 02. 属性声明: section 03. 属性在Uboot中应用 01. 扩展关键字: attribute GNU C 增加一个 atttribute ...

  8. C语言图形编程(绘图函数部分),C语言图形编程(三、绘图函数-02)12

    C语言图形编程(三.绘图函数-02)12 } 84. putimage() 输出图像函数 功能: 函数putimage()将一个先前保存在内存中的图像输出到屏幕上. 用法: 此函数调用方式为void ...

  9. c 语言绘图函数,c语言图形编程(三、绘图函数-)(C language graphics programming (three, drawing function -)).doc...

    c语言图形编程(三.绘图函数-)(C language graphics programming (three, drawing function -)).doc c语言图形编程(三.绘图函数-01) ...

  10. c语言编程基础课件,第7章_C语言图形编程基础课件

    第7章_C语言图形编程基础课件 狭义的组织变革是指组织根据外部环境的变化和内部情况的变化及时地改变自己的内在组织结构,以适应客观发展的需要. 狭义的组织变革是指组织根据外部环境的变化和内部情况的变化及 ...

最新文章

  1. python3 python2 字符串与hex互转区别
  2. Linux C编程--string h函数解析
  3. CTF---密码学入门第一题 这里没有key
  4. Django和Ajax
  5. SH1B LMR62014XMFE/NOPB
  6. 面试常备题----数组总结篇(上)
  7. [转载] Java static关键字与static{}语句块
  8. 计算机英语 考研 翻译,研究生英语翻译笔记
  9. 兮米安装包制作工具图文教程集锦电子书
  10. 检查oracle用户默认密码的账户
  11. Microsoft Enterprise Library 5.0 系列(二) Cryptography Application Block (高级)
  12. Sum nyoj215
  13. 云丁智能锁说明书_真硬核!行业爆发前夜,这把锁登上航母
  14. 关于C笔记使用体验和比较
  15. 小米蓝牙耳机持续白灯_小米蓝牙耳机不能自动串联问题
  16. cdr 表格自动填充文字_常平办公软件培训分享之word表格自动填充序号
  17. 一个超简单的Qt数字按键
  18. 撩妹方式,你值得拥有!!
  19. 64Mbit SOIC8封装SPI接口的国产串行SRAM EMI7064
  20. 不得不说!这个让我受益良多的思维利器!

热门文章

  1. mysql的新特性_MySQL 8.0的关系数据库新特性详解
  2. vac虚拟声卡我linux,下载_Virtual Audio Cable(虚拟声卡) V4.65 完美免费版_6z6z下载站
  3. DataInputStream和DataOutputStream
  4. 关于swf转fla 软件的间题
  5. Android项目报错:Could not resolve com.android.support.constraint:constraint-layout:2.0.2.
  6. VSCode中安装Django插件后实现html语法提示
  7. Android mc怎么和win10联机,我的世界手机版与win10版联机可完美互通
  8. RecycleView 使用GridView样式列表添加头部
  9. 二类查询(中兴笔试)
  10. Android 源码查看网站分享