教你用c语言写俄罗斯方块
来如鹏挺长时间了,受益很多希望更多的朋学加入进来
做俄罗斯方块是因为无意中在杨老师的帖子看到说最少也要能做出俄罗斯方块这样的东西出来,我想这个意思能做出俄罗斯方块就说明水平到了一个层次了吧。
刚才注意到音乐播放器居然下载超过400次!我反醒我上传的代码很少解释
而且做的都是没有趣味的东西。
俄罗斯方块如鹏已经有好几个同学做出来了,但是我想还有很多同学做不出来,我抛砖引玉,其实俄罗斯方块并不复杂
今天先告诉大家第一步,
在屏幕上把方块显示出来
cfree 新建一个工程选窗口程序显示helloworld的
win32的 api 图形函数都要用到 HDC 这是一个保存窗口图形的数据的句柄
比如我要画一个正方形可以用
Rectangle (hdc,标X,左上角坐标y,右下角坐标x,右下角坐标y);
为了方便我们直接在
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// 这个下面添加代码
Rectangle (hdc,50,50,100,100);
然后编译运行
这是效果就是一个正方形没别的东西?别着急哈,慢慢来。
俄罗斯方块每块都是四部分的所以要画4个
这里面需要一小点数学知识
把这些复制到刚才的位置看一下效果
{
int x,y;
const int size=50;//方块大小
x=y=50;//从窗口的左上角位置开始画
//第一个方块
Rectangle (hdc,x,y,x+size,y+size);
x+=size; //向右一块位置画第二个方块
Rectangle (hdc,x,y,x+size,y+size);
x+=size; //向右一块位置画第三个方块
Rectangle (hdc,x,y,x+size,y+size);
//最后一个方块
//相对于第三个方块左下角的位置
x-=50;y-=50;
Rectangle (hdc,x,y,x+size,y+size);
}
这个画好像很麻烦我们可以自定义一个函数huafangkuai
专门负责画这个正方形以后所有的其他函数也必须经过他才能画正方形
这个类似于win32 api的封装思想
void huafangkuai(int x,int y,int color);
x y是方块的坐标color 就是color
函数原理是x y 是相对于游戏里的坐标而不是屏幕坐标
屏幕坐标要经过函数自己转换这样我们就可以把心关注在游戏的事情而不必分心了void huafangkuai(HDC hdc,int x,int y,int color)
{
const int BEGINX= 50;//游戏图形的开始位置
const int BEGINY= 50 ;
const int FSIZE= 35 ; //方块大小
int screenx=BEGINX +x*FSIZE; //方块左上角的坐标是x乘方块大小再加上起始位置
int screeny=BEGINY +y*FSIZE;
Rectangle (hdc,screenx,screeny,screenx+FSIZE,screeny+FSIZE);
}
这样我们再画就四个就容易多了 color 先不管
int x,y;
x=5;y=5;
huafangkuai(hdc,x,y,0);
huafangkuai(hdc,x+1,y,0);
huafangkuai(hdc,x+2,y,0);
huafangkuai(hdc,x+1,y+1,0);
这样就画出了一个方块形状但是怎么能画出其它的呢?请听下回分解.
弄这点东西我费了一个多小时时间 ...我终于理解为什么杨老师问最近没人反馈备课再加录视频一定花了很多心血可是没有几个同学问问题或做作业的心情...
leeco 说的是
我以前很少写注释这回一写反而乱写一通下次改进
下一步有一些麻烦了
为了省代码还是再定义一个函数
void DrawTetris(HDC hdc, int dir,int shape,int color,int x,int y)
dir 是方块的4个方向 shape 是形状比如有L 形 |形和田形 x y 游戏中的坐标我们定义一个全局数组把俄罗斯方块中7种不同的正式形状都保存在里面
调用这个函数之后能把要求的方块显示出来
void DrawTetris(HDC hdc, int dir,int shape,int color,int x,int y)
{
int nx,ny;
for(int i=0;i<4;i++)
{
nx=SQRARRAY[shape][dir].x+x;ny=SQRARRAY[shape][dir].y+y;
huafangkuai(hdc,nx,ny,color);
}
}
要求所有的方块的形状都弄好我费了不少时间
这个就是全局数组放到代码的最上面
每4行是1个形状最后一个全是一样的就是田形const POINT SQRARRAY[7][FOUR][FOUR]=
{
{0,-1,0,0,1,0,2,0,
1,0,0,0,0,1,0,2,
0,1,0,0,-1,0,-2,0,
-1,0,0,0,0,-1,0,-2},
{-1,0,0,0,0,1,0,2,
-1,0,0,0,-2,0,0,-1,
0,-1,0,0,0,-2,1,0,
0,1,0,0,1,0,2,0},
{ -1,0,0,0,0,-1,1,0,
0,-1,0,0,1,0,0,1,
-1,0,0,0,0,1,1,0,
-1,0,0,0,0,-1,0,1},
{ 0,-1,0,0,1,0,1,1,
1,0,0,0,0,1,-1,1,
0,-1,0,0,1,0,1,1,
1,0,0,0,0,1,-1,1,
},
{ 0,-1,0,0,-1,0,-1,1,
-1,0,0,0,0,1,1,1,
0,-1,0,0,-1,0,-1,1,
-1,0,0,0,0,1,1,1},
{-1,0,0,0,1,0,2,0,
0,-1,0,0,0,1,0,2,
-1,0,0,0,1,0,2,0,
0,-1,0,0,0,1,0,2},
{-1,0,0,0,-1,1,0,1,
-1,0,0,0,-1,1,0,1,
-1,0,0,0,-1,1,0,1,
-1,0,0,0,-1,1,0,1}
} ;
先调用试试效果
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//在这的加入这些
static int shape=0;
static int dir=0;
++dir%=4;
++shape%=7;
DrawTetris(hdc,dir,shape,0,3,3);
运行之后双击程序的标题栏要求窗口刷新每次图形都会变化下一步是想让图形怎么动起来
这个要响应键盘消息
在wm_paint 下面找到break;
在break;下面的地方加入
由于不在wm_paint 里面我们只能自己用getdc得到HDC
case WM_KEYDOWN:
switch(wParam)
{
case VK_SPACE:
HDC hdc= GetDC(hWnd);
static int shape=0;
++shape%=7;
DrawTetris(hdc,0,shape,0,6,2);
ReleaseDC(hWnd,hdc);
break;
}
break;
这回VK_SPACE 就是空格
还有其它键比如
VK_DOWN
VK_LEFT
VK_RIGHT
再运行之后按空格键图形都在一直变化
但是变成这样的了因为每显示一次都不清除前面的话就这样
这个怎么解决呢?未完待续...
谢谢支持
我以为没有同学感兴趣呢
为了不显示混乱所以一定要先擦除前的
用的方法是用背景色的画笔再画一遍
定义一个结构体保存现在方块和以前方块的位置
struct PosInfo
{
int x,y,dir,shape;
};
PosInfo CurrentPos,PrePos;//全局变量
HPEN PenArray[10];
PosInfo CurrentPos,PrePos;
再定义一组画笔
在程序开始时用这个函数初初化
void Init(HWND hwnd)
{
PenArray [0]=CreatePen(PS_SOLID,0,RGB(255,255,255));//现在是白色背景PenArray [1]=CreatePen(PS_SOLID,0,RGB(120,120,120));
CurrentPos.dir=0;
CurrentPos.shape=0;
CurrentPos.x=2;
CurrentPos.y=2;
PrePos=CurrentPos;
}
在键盘击下后用这个函数改变方块位置
void KeyDown(int keycode,HWND hwnd)
{
HDC hdc= GetDC(hwnd);
switch(keycode)
{
case VK_LEFT:
break;
case VK_RIGHT:
CurrentPos.x++;
DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);
DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); PrePos=CurrentPos;
break;
case VK_DOWN:
break;
case VK_SPACE:
break;
}
ReleaseDC(hwnd,hdc);
}
然后就是检查方块是不是出格了
用这个函数 MAPX MAPY 是游戏里数组的长和高
map [][]是保存方块有没被放置状态有还是没有
bool Check(int dir,int pX,int pY,int shape)
{
int x,y;
for(int ff=0;ff<4;ff++)
{
x= SQRARRAY[shape][dir][ff].x+pX;
y= SQRARRAY[shape][dir][ff].y+pY;
if(x<0 || x>=MAPX || y<0 ||y>=MAPY ||map[Pos[ff].x][Pos[ff].y]!=0)
{
return FALSE;
}
}
return TRUE;
}
1.#include "tetris.h"
2.const int BEGINX= 50;//游戏图形的开始位置
3.const int BEGINY= 50 ;
4.const int FSIZE= 19 ; //方块大小
5.const int FOUR =4;
6.const int MAPX =10;
7.const int MAPY=20;
8.struct PosInfo
9.{
10.int x,y,dir,shape;
11.};
12.
13.PosInfo CurrentPos,PrePos;//全局变量
14.int GameMap[MAPX][MAPY]; //游戏方格
15.
16.HBRUSH PenArray[10];//用画刷可以用fillrect 画实心的图形
17.void Init(HWND hwnd)
18.{
19.
20.PenArray [0]=CreateSolidBrush(RGB(255,255,255));//现在是白色背景
21.PenArray [1]=CreateSolidBrush(RGB(120,120,120));
22.CurrentPos.dir=0;
23.CurrentPos.shape=0;
24.CurrentPos.x=2;
25.CurrentPos.y=2;
26.PrePos=CurrentPos;
27.}
28.
29.
30.const POINT SQRARRAY[7][FOUR][FOUR]=
31.{
32.{0,-1,0,0,1,0,2,0,
33.1,0,0,0,0,1,0,2,
34.0,1,0,0,-1,0,-2,0,
35.-1,0,0,0,0,-1,0,-2},
36.{-1,0,0,0,0,1,0,2,
37.-1,0,0,0,-2,0,0,-1,
38.0,-1,0,0,0,-2,1,0,
39.0,1,0,0,1,0,2,0},
40.
41.{ -1,0,0,0,0,-1,1,0,
42.0,-1,0,0,1,0,0,1,
43.-1,0,0,0,0,1,1,0,
44.-1,0,0,0,0,-1,0,1},
45.{ 0,-1,0,0,1,0,1,1,
46.1,0,0,0,0,1,-1,1,
47.0,-1,0,0,1,0,1,1,
48.1,0,0,0,0,1,-1,1,
49.},
50.{ 0,-1,0,0,-1,0,-1,1,
51.-1,0,0,0,0,1,1,1,
52.0,-1,0,0,-1,0,-1,1,
53.-1,0,0,0,0,1,1,1},
54.
55.{-1,0,0,0,1,0,2,0,
56.0,-1,0,0,0,1,0,2,
57.-1,0,0,0,1,0,2,0,
58.0,-1,0,0,0,1,0,2},
59.
60.{-1,0,0,0,-1,1,0,1,
61.-1,0,0,0,-1,1,0,1,
62.-1,0,0,0,-1,1,0,1,
63.-1,0,0,0,-1,1,0,1}
64.} ;
65.
66.
67.
68.
69.void huafangkuai(HDC hdc,int x,int y,int color)
70.{
71.
72.int screenx=BEGINX +x*FSIZE; //方块左上角的坐标是x乘方块大小再加上起始位置
73.int screeny=BEGINY +y*FSIZE;
74.RECT rt;
75.rt.left=screenx;
76.rt.top=screeny;
77.rt.right=screenx+FSIZE;
78.rt.bottom=screeny+FSIZE;
79.FillRect(hdc,&rt ,PenArray[color]);
80.
81.
82.}
83.
84.//画所有7种俄罗斯方块 dir方块的方向 shape 方块的形状
85.void DrawTetris(HDC hdc, int dir,int shape,int color,int x,int y)
86.{
87.
88.
89.
90.int nx,ny;
91.for(int i=0;i<4;i++)
92.{
93.
94.nx=SQRARRAY[shape][dir].x+x;ny=SQRARRAY[shape][dir].y+y;
95.huafangkuai(hdc,nx,ny,color);
96.}
97.}
98.
99.
100.void KeyDown(int keycode,HWND hwnd)
101.{
102.HDC hdc= GetDC(hwnd);
103.
104.switch(keycode)
105.{
106.case VK_LEFT:
107.if(!Check(CurrentPos.dir,CurrentPos.x-1,CurrentPos.y,CurrentPos.shape)) 108.{
109.return;
110.}
111.
112.CurrentPos.x--;
113.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);
114.DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); 115.PrePos=CurrentPos;
116.break;
117.case VK_RIGHT:
118.
119.if(!Check(CurrentPos.dir,CurrentPos.x+1,CurrentPos.y,CurrentPos.shape)) 120.{
121.return;
122.}
123.CurrentPos.x++;
124.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);
125.DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); 126.PrePos=CurrentPos;
127.break;
128.case VK_DOWN:
129.if(!Check(CurrentPos.dir,CurrentPos.x,CurrentPos.y+1,CurrentPos.shape))
130.{
131.return;
132.}
133.CurrentPos.y++;
134.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);
135.DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); 136.PrePos=CurrentPos;
137.break;
138.case VK_SPACE:
139.if(!Check((CurrentPos.dir+1)%4,CurrentPos.x,CurrentPos.y,CurrentPos.shape)) 140.{
141.return;
142.}
143.++CurrentPos.dir%=4;
144.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y);
145.DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); 146.PrePos=CurrentPos;
147.break;
148.}
149.ReleaseDC(hwnd,hdc);
150.}
151.
152.
153.//check 检查方块移动时是否有数组越界情况有则什么也不执行
154.bool Check(int dir,int pX,int pY,int shape)
155.
156.{
157.int x,y;
158.for(int ff=0;ff<4;ff++)
159.{
160.x= SQRARRAY[shape][dir][ff].x+pX;
161.y= SQRARRAY[shape][dir][ff].y+pY;
162.if(x<0 || x>=MAPX || y<0 ||y>=MAPY ||GameMap[x][y]!=0)
163.{
164.return FALSE;
165.}
166.}
167.
168.return TRUE;
169.
170.}
171.
172.//画已经放在下面的方块通过检查数组是否大于0 是则画数数里面的色彩
173.//否则画白色擦除
174.void DrawMap(HDC hdc )
175.{
176.
177.Rectangle(hdc,BEGINX-10,BEGINY-10,BEGINX+MAPX*FSIZE+10,BEGINY+MAPY*FSIZE+10); 178.//画基本的外框
179.for(int x=0;x 180.{ 181.for(int y=0;y 182.{ 183.if(GameMap[x][y]>0) 184.{ 185.huafangkuai(hdc,x,y,GameMap[x][y]); 186.} 187.else 188.{ 189.huafangkuai(hdc,x,y,0); 190.} 191.} 192.} 193.} 194.DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y); DrawTetris(hdc,CurrentPos.dir,CurrentPos.shape,1,CurrentPos.x,CurrentPos.y); 这个0就是调用和窗口一样的画刷 1呢是我定义的方块的颜色 PrePos 保存的是方块未移动时的位置 DrawTetris(hdc,PrePos.dir,PrePos.shape,0,PrePos.x,PrePos.y); 之后因为和之前画的在一个地方而且是白色的所以前面画的就清除掉了 195. /*学无止境*/ #include void Init(); void Down(); void GoOn(); void ksdown(); void Display(int color); void Give(); int Touch(int x,int y,int dx,int dy); int GeyKey(); void Select(); void DetectFill(); void GetScores(); void Fail(); void Help(); void Quit(); void DrawBox(int x,int y,int Color); void OutTextXY(int x,int y,char *String); void DispScore(int x,int y,char Ch); void DrawNext(int Color); int Heng=12,Shu=20; /*横竖*/ int Position[MAX][MAX]; int middle[MAX][MAX]; int ActH,ActS; Tc2.0中怎么样设置图形显示? Tc2.0中有两种显示模式,一种是我们所熟知的字符模式,另一种是图形模式。在字符模式下只能显式字符,如ASCII字符。一般是显示25 行,每行80个字符。程序缺省的是字符模式。在字符模式下不能显式图形和进行绘图操作。要想进行图形显示和绘图操作,必须切换到图形模 式下。 Tc2.0中用initgraph()函数可以切换到图形模式,用closegraph()可以从图形模式切换回字符模式。initgraph()和closegraph()都是图形 函数,使用图形函数必须包括头文件graphics.h。 void far initgraph(int far *graphdriver,int far *graphmode,char far *pathtodriver);graphdriver是上涨指向图形驱动序号变量的指针;graphmode是在graphdriver选定后,指向图形显示模式序号变量的指针。pathtodriver表示存放图形驱动文件的路径。 Tc2.0中有多种图形驱动,每种图形驱动下又有几种图形显示模式。在我的程序中图形驱动序号为VGA,图形显示模式序号为VGAHI。这是一种分辨率为640*480(从左到右坐标依次为0-639,从上到下坐标依次为0-479),能够显示16种颜色的图形模式。别的图形驱动序号和图形显示模式序号,可以从手册或联机帮助中找到。 pathtodriver指示存放图形驱动文件的路径。图形驱动序号不同,图形驱动文件也不同。序号为VGA图形驱动对应egavga.bgi这个图形驱动文件。egavga.bgi一般在Tc目录下。 void far closegraph(void); 没有参数,从图形模式直接返回字符模式。 initgraph()和closegraph()的常用用法如下: int gdriver = VGA, gmode=VGAHI, errorcode; /* initialize graphics mode */ initgraph(&gdriver, &gmode, e:tc2); /* read result of initialization */ errorcode = graphresult(); if (errorcode != grOk) /* an error occurred */ { printf(Graphics error: %sn, grapherrormsg(errorcode)); printf(Press any key to halt:); getch(); exit(1); /* return with error code */ } /* return to text mode */ closegraph(); 【转载】88行代码实现俄罗斯方块游戏(含讲解) 来源:https://www.360docs.net/doc/2d6014686.html,/p/8 在正式阅读本文之前,请你记得你应该用娱乐的心态来看, 本代码所使用到的技巧,在工作了的人眼里会觉得很纠结,很蛋疼,很不可理喻,很丑, 注意,是你蛋疼,不关我的事 通常,写一个俄罗斯方块,往往动不动就几百行,甚至上千行,而这里只有88行 正所谓头脑风暴,打破常规。这里将使用很多不平常的手段来减少代码 以下是Win-TC可以成功编译并执行的代码(代码保证单行长度不超过80字符,如果你是Win7系统,那请看后文): 程序代码: #include"graphics.h" #include 1、新建“.h”头文件,将“头文件” 代码粘贴至其中, 2、新建“.c”源文件,将“源代码” 代码粘贴到其中。 3、新建空白工程,将头文件和源代码 添加进去,调试使用。 //头文件 //1.自定义枚举类型,定义7种形态的游戏方块 typedef enum tetris_shape { ZShape=0, SShape, LineShape, TShape, SquareShape, LShape, MirroredLShape }shape; //2.函数声明 //(1)操作方块函数 int maxX();//取得当前方块的最大x坐标 int minX();//取得当前方块的最小x坐标 void turn_left();//当前方块逆时针旋转90度 void turn_right(); int out_of_table(); void transform(); int leftable(); int rightable(); int downable(); void move_left(); void move_right(); //(2)操作游戏桌面的函数 int add_to_table(); void remove_full(); //(3)控制游戏函数 void new_game(); void run_game(); void next_shape(); int random(int seed); //(4)绘图函数 void paint(); void draw_table(); //(5)其他功能函数 void key_down(WPARAM wParam); void resize(); void initialize(); void finalize(); //(6)回调函数,用来处理Windows消息 LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM); //源代码 //1.文件包含 #include 俄罗斯方块 学号: 班级: 姓名: 指导教师: 完成日期:2012年5月 目录 1.引言 (1) 1.1开发工具 (1) 1.1.1 C是中级预言 (1) 1.1.2 C是结构化语言 (1) 1.1.3 C语言功能齐全 (1) 1.1.4 C语言可移植性好 (1) 2 游戏设计 (2) 2.1游戏设计要求 (2) 2.1.1. 设计题目:俄罗斯方块游戏 (2) 2.1.2. 设计内容: (2) 2.1.3. 功能模块划分: (2) 2.2 游戏设计思想 (2) 2.2.1游戏界面: (2) 2.2.2 设计思路 (2) 2.3:游戏功能 (3) 2.3.1:开始部分 (3) 2.3.2.运行部分 (3) 3.实验总结: (4) 3.1 开发背景与需求分析 (4) 3.2 系统功能介绍 (4) 4. 核心代码: (8) 总结 (21) 参考文献: (22) 基于C语言的俄罗斯方块游戏 [摘要]:俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏。俄罗斯方块的基 本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并 且消除得分。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。 [关键词]:C语言;心得体会;影响 1.引言 随着社会的发展,人们生活的步调日益加快,越来越多的人加入了全球化的世界.人们不在拘泥 于一小块天地.加班,出差成了现代人不可避免的公务.而此时一款可以随时随地娱乐的游戏成了必 需品.在手机和电脑成为人们日用品的社会,一款能在其上能便捷运行的游戏成为买家的参考点. 现在我们所要设计的这一款基于C语言的游戏——贪吃蛇,就是满足以上要求而设计出来的,希望能给玩家带来娱乐.贪吃蛇这一游戏简单易行,操作方便,娱乐性较强,吸引了不少人.这一款游戏紧紧地抓住了人们的心理,虽然简单,却起乐无穷,在人们不断追求更多的欲望下,该游戏给人们带来了追逐的快感,以及成功后的满足感,对于一直处于高压下的现代人是很好的放松工具. 1.1开发工具 《C/C++程序设计学习与试验系统》 该系统继承了Turbo C2.0/C++3.0、GCC、Visua C++6.0这四种常见的编译器,可以很好满足目前主流的C语言教材的实验需求。 C语言具有下列特点: 1.1.1 C是中级预言 它把高级语言的基本结构和语句与低级语言的实用性结合起来,C语言可以像汇编语言一样对位、字节和地址进行操作,通常还是称C为高级语言。 1.1.2 C是结构化语言 结构化语言的特点是程序的各个部分除了必要地数据交流外彼此独立。这种结构化方式可使程序层次清晰,便于使用,维护及调试。 1.1.3 C语言功能齐全 C语言具有多种数据类型,并引入了指针概念,可使程序效率更高;C语言也具有强大的图形功能;具有较强的计算功能、逻辑判断功能。 1.1.4 C语言可移植性好 与汇编语言相比,C语言程序适用范围大,可用于各种操作系统和各种型号的计算机。 C语言课程设计报告 俄罗斯方块程序设计报告 一、问题描述 俄罗斯方块(Tetris,俄文:Тетрис)是一款电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。 在本次设计中,要求支持键盘操作和若干种不同类型方块的旋转变换,并且界面上显示下一个方块的提示以及当前的玩家的得分,随着游戏的进行,等级越高,游戏难度越大,即方块的下落速度越快,相应的等级,等级越高,为玩家提供了不同的选择。 二、功能分析 I、俄罗斯方块游戏需要解决的问题包括: ⑴、随机产生方块并自动下移 ⑵、用Esc键退出游戏 ⑶、用键变体 ⑷、用键和键左右移动方块 ⑸、用空格键使游戏暂停 ⑹、能正确判断满行并消行、计分、定级别 ⑺、设定游戏为不同级别,级别越高难度越大 II、俄罗斯方块游戏需要设计的功能函数包括: ⑴、声明俄罗斯方块的结构体 ⑵、函数原型声明 ⑶、制作游戏窗口 ⑷、制作俄罗斯方块 ⑸、判断是否可动 ⑹、随机产生俄罗斯方块类型的序号 ⑺、打印俄罗斯方块 ⑻、清除俄罗斯方块的痕迹 ⑼、判断是否满行并删除满行的俄罗斯方块 三、程序设计 1、程序总体结构设计 (1)、游戏方块预览功能。在游戏过程中,游戏界面右侧会有预览区。由于在此游戏中存在多种不同的游戏方块,所以在游戏方块预览区域中显示随机生成的游戏方块有利于游戏玩家控制游戏的策略。 (2)、游戏方块控制功能。通过各种条件的判断,实现对游戏方块的左移、右移、自由下落、旋转功能,以及行满消除行的功能。 (3)、游戏数据显示功能。在游戏玩家进行游戏过程中,需要按照一定的游戏规则给玩家计算游戏分数。例如,消除一行加100分,游戏分数达到一定数量 来如鹏挺长时间了,受益很多希望更多的朋学加入进来 做俄罗斯方块是因为无意中在杨老师的帖子看到说最少也要能做出俄罗斯方块这样的东西出来,我想这个意思能做出俄罗斯方块就说明水平到了一个层次了吧。 刚才注意到音乐播放器居然下载超过400次!我反醒我上传的代码很少解释 而且做的都是没有趣味的东西。 俄罗斯方块如鹏已经有好几个同学做出来了,但是我想还有很多同学做不出来,我抛砖引玉,其实俄罗斯方块并不复杂 今天先告诉大家第一步, 在屏幕上把方块显示出来 cfree 新建一个工程选窗口程序显示helloworld的 win32的 api 图形函数都要用到 HDC 这是一个保存窗口图形的数据的句柄 比如我要画一个正方形可以用 Rectangle (hdc,标X,左上角坐标y,右下角坐标x,右下角坐标y); 为了方便我们直接在 switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // 这个下面添加代码 Rectangle (hdc,50,50,100,100); 然后编译运行 这是效果就是一个正方形没别的东西?别着急哈,慢慢来。 俄罗斯方块每块都是四部分的所以要画4个 这里面需要一小点数学知识 把这些复制到刚才的位置看一下效果 { int x,y; const int size=50;//方块大小 x=y=50;//从窗口的左上角位置开始画 //第一个方块 Rectangle (hdc,x,y,x+size,y+size); x+=size; //向右一块位置画第二个方块 Rectangle (hdc,x,y,x+size,y+size); x+=size; //向右一块位置画第三个方块 Rectangle (hdc,x,y,x+size,y+size); //最后一个方块 //相对于第三个方块左下角的位置 x-=50;y-=50; Rectangle (hdc,x,y,x+size,y+size); } 这个画好像很麻烦我们可以自定义一个函数huafangkuai 专门负责画这个正方形以后所有的其他函数也必须经过他才能画正方形 这个类似于win32 api的封装思想 void huafangkuai(int x,int y,int color); x y是方块的坐标color 就是color 函数原理是x y 是相对于游戏里的坐标而不是屏幕坐标 屏幕坐标要经过函数自己转换这样我们就可以把心关注在游戏的事情而不必分心了void huafangkuai(HDC hdc,int x,int y,int color) { const int BEGINX= 50;//游戏图形的开始位置 const int BEGINY= 50 ; const int FSIZE= 35 ; //方块大小 int screenx=BEGINX +x*FSIZE; //方块左上角的坐标是x乘方块大小再加上起始位置 int screeny=BEGINY +y*FSIZE; Rectangle (hdc,screenx,screeny,screenx+FSIZE,screeny+FSIZE); } 这样我们再画就四个就容易多了 color 先不管 int x,y; x=5;y=5; huafangkuai(hdc,x,y,0); huafangkuai(hdc,x+1,y,0); huafangkuai(hdc,x+2,y,0); ````````` 学院:数计学院 班级:13级数媒班 学号: 姓名: 摘要 …………………………………………………………………………………………………….. 关键字: 目录 第一部分设计总概........................................................................................................................... 摘要………………………………………………………………………………………………… 一、设计目的............................................................................................................................. 二、设计要求............................................................................................................................. 三、设计内容............................................................................................................................. 四、系统分析与设计................................................................................................................. 第二部分数据结构设计................................................................................................................... 第三部分功能实现与程序调试………………………………………………………………….第四部分完成设计........................................................................................................................... 一、实习日记............................................................................................................................. 二、实习总结............................................................................................................................. 三、教师评语............................................................................................................................. 四、程序使用说明书…………………………………………………………………………. 第一部分设计总概 一、设计目的 二、设计要求 三、设计内容 四、系统分析与设计 其中的主要逻辑有: (1)由于c的随机性函数不好,所以每次游戏开始根据bios时间设置种子。 (2)得分越高,方块下降速度越快(每200分为单位)。 (3)每下落一个方块加1分,每消除一行加10分,两行加30分,三行加70分,四行加150分。初试分数为100分。 游戏控制: up-旋转;空格-下落到底;左右下方向键-控制方向。P-开始或暂停游戏。ESC-退出。 特点: (1)由于tc不支持中文,所以基本都是英文注释。 (2)函数命名尽可能规范的表达其内部处理目的和过程。 (3)代码加上注释仅有577行。(我下载过的两个俄罗斯方块代码一个在1087行,一个在993行,我的比它们代码少)。 (4)除了消除空格时算法比较复杂,其他算法都比较简单易读。 (5)绘图效率和局部代码效率扔有待提高。 (6)FrameTime参数可能依据不同硬件环境进行具体设置,InitGame需要正确的TC路径。 俄罗斯方块源于大约9年前上大一时的一个梦,我们在学习c语言时,我的同寝室友邀请我合作一起完成俄罗斯方块(课外作业性质),但是当时限于我们的水平比较菜和学习状态比较懒散,我们没有完成。大一的时候我在机房里无意发现别人留下的俄罗斯方块程序,运行,老师发现后激动的问我是我写的吗,我惭愧的摇摇头。那时看到别人做c的大程序深感羡慕(自己只是写几十行的程序)。数年后我仍然看到有不同样式的实现,但是我一直没有实现它,知道今天忽然有这个想法去做,算是弥补多年前的遗憾和心愿吧。 --------------------------------------------- Q&A: ---------------------------------------------- Q:我编译时出现错误:fatal error C1083: Cannot open include file: 'bios.h': Nosuch file or directory,该如何解决? A:正文中的代码,是使用Borland公司的TC2.0编译的,编译结果运行在Windows的16位虚拟机上。bi os.h是属于TC的头文件,在VC或者其他编译器中可能没有这个头文件。因此会产生这个错误。 解决办法: (1)可以下载附件中的压缩包,是使用VC6.0进行编译的版本,编译结果是Windows程序,运行在wind ows 32系统上。两者之间的算法完全一致,区别仅仅是绘图时采用的接口不同,TC下采用BGI(进入图形模式),VC下采用的是GDI(使用DC进行绘图)。 (2)下载TC2.0进行编译。 Q:使用TC3.0进行编译时,提示未能初始化图形模式,请使用initgraph函数。 A:这是因为TC3.0的BGI文件的路径和TC2.0有所不同。TC2.0的BGI文件位于TC路径下。而TC3.0的BGI文件位于BGI文件夹中。请把initgame函数中的initgraph函数中的第三个参数设置为正确的路径。例如:initgraph(&..,&..,"C:\\TC\\BGI"); Q:编译后运行时,弹出错误对话框报告16位虚拟机遇到不可执行的指令,点击确定后退出。 A:该问题在某些环境中出现,可能是基于软件或者硬件环境造成,具体原因暂时未知。为避免该问题,请加载附件中的压缩包VC6.0版本。 用C语言写的一个简单的俄罗斯方块!会用到graphics.h的库,需要自己准备,可以在网上下载EasyX 解决。下边是源代码(扩展名为.cpp): #include enum DRAW { SHOW, // 显示方块 CLEAR, // 擦除方块 FIX // 固定方块 }; // 定义七种俄罗斯方块 struct BLOCK { WORD dir[4]; // 方块的四个旋转状态 COLORREF color; // 方块的颜色 } g_Blocks[7] = { {0x0F00, 0x4444, 0x0F00, 0x4444, RED}, // I {0x0660, 0x0660, 0x0660, 0x0660, BLUE}, // 口 {0x4460, 0x02E0, 0x0622, 0x0740, MAGENTA}, // L {0x2260, 0x0E20, 0x0644, 0x0470, YELLOW}, // 反L {0x0C60, 0x2640, 0x0C60, 0x2640, CYAN}, // Z /*学无止境*/ #include <> #include <> #include <> #define ESC 27 #define UP 328 #define DOWN 336 #define LEFT 331 #define RIGHT 333 #define BLANK 32 #define BOTTOM 2 #define CANNOT 1 #define CAN 0 #define MAX 30 #define F1 315 #define ADD 43 #define EQUAL 61 #define DEC 45 #define SOUNDs 115 #define SOUNDS 83 #define PAUSEP 80 #define PAUSEp 112 void Init(); void Down(); void GoOn(); void ksdown(); void Display(int color); void Give(); int Touch(int x,int y,int dx,int dy); int GeyKey(); void Select(); void DetectFill(); void GetScores(); void Fail(); void Help(); void Quit(); void DrawBox(int x,int y,int Color); void OutTextXY(int x,int y,char *String); void DispScore(int x,int y,char Ch); void DrawNext(int Color); int Heng=12,Shu=20; /*横竖*/ int Position[MAX][MAX]; int middle[MAX][MAX]; int ActH,ActS; #include #include C语言之游戏 俄罗斯方块课程设计报告 专业:[] 学生姓名:[] 指导教师:[] 完成时间: 目录 一、需求分析 ................................. 错误!未定义书签。 二、概要设计 ................................. 错误!未定义书签。 三、详细设计 ................................. 错误!未定义书签。 四、调试分析 (19) 五、用户手册 (20) 六、测试数据 ................................. 错误!未定义书签。 七、附录..................................... 错误!未定义书签。 一、需求分析 1.该程序是完成一个简易的俄罗斯方块的任务,其要完成几个重要的功能:界面,方块下落,旋转,判断是否还能下落,左右移动,分数,速度设置,清楚满的每行,下个方块的预览等; 2.可用#include 课程名称《数据结构》课程设计指导老师 所在学院 专业年级 提交日期 成绩 小组成员表 课程设计实验 一、需求分析 我们对俄罗斯方块这个游戏一点也不陌生,知道游戏的玩法和实现后,我们很快就着手开干。游戏要有出现场景、方块、消除方块得分、判断游戏结束等几个大功能。结构清晰简洁便于分工。 二、算法原理介绍 游戏主要使用了数组这个数据结构。不过与以往的程序不同,这个游戏有一个大数组包含很多个小数组,大数组不断的吸收小数组内的元素,达到条件得分。 三、概要设计 1、功能块各函数列表 2、场景的设置 int map[28][17]={ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1}, {0,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1}, {0,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1}, {0,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1}, {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} }; void showmap() { int i,j; for(i=5;i<28;i++) { for(j=1;j<17;j++) { gotoxy(2*j,i); if(j==1||j==2||j==15||j==16) {printf("┃");} else if(i==26||i==27) {printf("━");} else if(map[i][j]==1) printf("■"); else if(map[i][j]==0) printf("□"); } } } 一个c语言写的俄罗斯方块的代码#include <stdlib.h> #include <graphics.h> #include <bios.h> #define mDRAW 5 #define mLINE 6 #define mADOWN 7 #define mGEN 8 #define mLEFT 75 #define mRIGHT 77 #define mSPACE 57 #define mESC 1 #define TIMEINT 2 #define MAXX 9 #define MAXY 30 #define BACKCOLOR BLACK #define WINX 50 #define WINY 470 #define GAP 6 #define AREAX (WINX+GAP) #define AREAY (WINY-GAP) int oldarea[MAXY+1][MAXX]; int area[MAXY+1][MAXX]; int actW,actH,actX,actY; int curX,curY,curColor,curW,curH; int newX,newY,newColor,newW,newH; int active; int box[4][4]; int FORCOLOR; int MESSAGE; int BOX[7][4][4]={ { {1,1,1,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} },{ {1,1,1,0}, {1,0,0,0}, {0,0,0,0}, {0,0,0,0} },{ > #include <> #include <> #include <> __cplusplus #define __CPPARGS ... #else #define __CPPARGS #define MINBOXSIZE 15 /* 最小方块的尺寸*/ #define BGCOLOR 7 /* 背景着色*/ #define GX 200 #define GY 10 #define SJNUM 10000 /* 每当玩家打到一万分等级加一级*/ /* 按键码*/ #define VK_LEFT 0x4b00 #define VK_RIGHT 0x4d00 #define VK_DOWN 0x5000 #define VK_UP 0x4800 #define VK_HOME 0x4700 #define VK_END 0x4f00 #define VK_SPACE 0x3920 #define VK_ESC 0x011b #define VK_ENTER 0x1c0d /* 定义俄罗斯方块的方向(我定义他为4种)*/ #define F_DONG 0 #define F_NAN 1 #define F_XI 2 #define F_BEI 3 #define NEXTCOL 20 /* 要出的下一个方块的纵坐标*/ #define NEXTROW 12 /* 要出的下一个方块的横从标*/ #define MAXROW 14 /* 游戏屏幕大小*/ #define MAXCOL 20 #define SCCOL 100 /*游戏屏幕大显示器上的相对位置*/ #define SCROW 60 int gril[22][16]; /* 游戏屏幕坐标*/ int col=1,row=7; /* 当前方块的横纵坐标*/ int boxfx=0,boxgs=0; /* 当前寺块的形壮和方向*/ int nextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/ int minboxcolor=6,nextminboxcolor=6; int num=0; /*游戏分*/ int dj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/* 游戏等级*/ /* 以下我用了一个3组来纪录方块的最初形状和方向*/ int boxstr[7][4][16]={{C语言俄罗斯方块游戏源代码
C语言写俄罗斯方块
俄罗斯方块C语言代码
C语言课程设计俄罗斯方块源代码
C语言编写俄罗斯方块论文
俄罗斯方块C语言程序设计报告
教你用c语言写俄罗斯方块
C语言编写俄罗斯方块实验报告
C语言程序设计-俄罗斯方块源程序
C语言编写的俄罗斯方块
C语言俄罗斯方块游戏源代码
C语言俄罗斯方块(详解..)
c语言俄罗斯方块代码
c语言俄罗斯方块实验报告
c语言数据结构程序设计俄罗斯方块
一个c语言写的俄罗斯方块的代码
俄罗斯方块C语言代码