C编写俄罗斯方块编写h5时 怎样让方块出不了边...

新手求救,怎么把这个俄罗斯方块用opengl和C语言来写_opengl吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:4,962贴子:
新手求救,怎么把这个俄罗斯方块用opengl和C语言来写收藏
/**俄罗斯方块源程序*/#include&stdlib.h&#include&stdio.h&#include&graphics.h&#include&dos.h&/*定义按键码*/#define VK_LEFT
0x4b00#define VK_RIGHT 0x4d00#define VK_DOWN
0x5000#define VK_UP
0x4800#define VK_ESC
0x011b#define TIMER 0x1c
/*设置中断号*//*定义常量*/#define MAX_BOX 19
/*总共有19种各形态的方块*/#define BSIZE 20
/*方块的边长是20个象素*/#define Sys_x 160
/*显示方块界面的左上角x座标*/#define Sys_y 25
/*显示方块界面的左上角y座标*/#define Horizontal_boxs 10
/*水平的方向以方块为单位的长度*/#define Vertical_boxs 15
/*垂直的方向以方块为单位的长度,也就说长是15个方块*/#define Begin_boxs_x Horizontal_boxs/2
/*产生第一个方块时出现的起始位置*/#define FgColor 3
/*前景颜色,如文字.2-green*/#define BgColor 0
/*背景颜色.0-blac*/#define LeftWin_x Sys_x+Horizontal_boxs*BSIZE+46
/*右边状态栏的x座标*/#define false 0#define true 1/*移动的方向*/#define MoveLeft 1#define MoveRight 2#define MoveDown 3#define MoveRoll 4/*以后坐标的每个方块可以看作是像素点是BSIZE*BSIZE的正方形*//*定义全局变量*/int current_box_
/*保存当前方块编号*/int Curbox_x = Sys_x + Begin_boxs_x*BSIZE, Curbox_y = Sys_y;/*x,y是保存方块的当前坐标的*/int flag_newbox =
/*是否要产生新方块的标记0*/int speed = 0;
/*下落速度*/int score = 0;
/*总分*/int speed_step = 30;
/*每等级所需要分数*/void interrupt(*oldtimer)(void);/* 指向原来时钟中断处理过程入口的中断处理函数指针 */struct BOARD
/*游戏底板结构,表示每个点所具有的属性*/{
/*当前状态 只有0和1,1表示此点已被占用*/
/*颜色,游戏底板的每个点可以拥有不同的颜色.增强美观*/} Table_board[Vertical_boxs][Horizontal_boxs];/*方块结构*/struct SHAPE{
char box[2];
/*一个字节等于8位,每4位来表示一个方块的一行如:box[0]=&0x88&,box[1]=&0xc0&表示的是:1000100011000000*/
/*每个方块的颜色*/
/*下个方块的编号*/};/*初始化方块内容.即定义MAX_BOX个SHAPE类型的结构数组,并初始化*/struct SHAPE shapes[MAX_BOX] ={
{ 0x88, 0xc0,
{ 0xe8, 0x0,
{ 0xc4, 0x40,
{ 0x2e, 0x0,
口口 口口口
* 口口 口口口 口
{ 0x44, 0xc0, 5 },
{ 0x8e, 0x0,
{ 0xc8, 0x80,
{ 0xe2, 0x0,
{ 0x8c, 0x40, 9 },
{ 0x6c, 0x0, 8 },
{ 0x4c, 0x80, 11 },
{ 0xc6, 0x0, 10 },
{ 0x4e, 0x0, 13 },
{ 0x8c, 0x80,
{ 0xe4, 0x0,
{ 0x4c, 0x40, 12 },
{ 0x88, 0x88,
{ 0xf0, 0x0, 16 },
{ 0xcc, 0x0, 18 }};unsigned int TimerCounter = 0;
/*定时计数器变量*//* 新的时钟中断处理函数 */void interrupt newtimer(void){
(*oldtimer)();
/* call the old routine */
TimerCounter++;/* increase the global counter */}/* 设置新的时钟中断处理过程 */void SetTimer(void interrupt(*IntProc)(void)){
oldtimer = getvect(TIMER); /*获取中断号为TIMER的中断处理函数的入口地址*/
disable(); /* 设置新的时钟中断处理过程时,禁止所有中断 */
setvect(TIMER, IntProc);
/*将中断号为TIMER的中断处理函数的入口地址改为IntProc()函数的入口地址
即中断发生时,将调用IntProc()函数。*/
/* 开启中断 */}/* 恢复原有的时钟中断处理过程 */void KillTimer(){
disable();
setvect(TIMER, oldtimer);
enable();}void show_intro(int xs, int ys){
char stemp[50];
setcolor(15);
rectangle(xs, ys, xs + 239, ys + 100);
sprintf(stemp, & -Roll
-Downwards&);
stemp[0] = 24;
stemp[8] = 25;
setcolor(14);
outtextxy(xs + 40, ys + 30, stemp);
sprintf(stemp, & -Turn Left
-Turn Right&);
stemp[0] = 27;
stemp[13] = 26;
outtextxy(xs + 40, ys + 45, stemp);
outtextxy(xs + 40, ys + 60, &Esc-Exit &);
setcolor(FgColor);}/*显示分数*/void ShowScore(int score){
char score_str[5];/*保存游戏得分*/
setfillstyle(SOLID_FILL, BgColor);
x = LeftWin_x;
bar(x - BSIZE, y, x + BSIZE * 3, y + BSIZE * 3);
sprintf(score_str, &%3d&, score);
outtextxy(x, y, &SCORE&);
outtextxy(x, y + 10, score_str);}/*显示速度*/void ShowSpeed(int speed){
char speed_str[5];/*保存速度值*/
setfillstyle(SOLID_FILL, BgColor);
x = LeftWin_x;
bar(x - BSIZE, y, x + BSIZE * 3, y + BSIZE * 3);
/*确定一个以(x1,y1)为左上角,(x2,y2)为右下角的矩形窗口, 再按规定图模和颜色填充。*/
sprintf(speed_str, &%3d&, speed + 1);
outtextxy(x, y, &Level&);
outtextxy(x, y + 10, speed_str);
/*输出字符串指针speed_str所指的文本在规定的(x, y)位置*/
outtextxy(x, y + 50, &Nextbox&);}/**********初始化界面********参数说明:*
x,y为左上角坐标*
m,n对应于Vertical_boxs,Horizontal_boxs*
分别表示纵横方向上方块的个数(以方块为单位)*
BSIZE Sys_x Sys_y**********************************/void initialize(int x, int y, int m, int n){
for (j = 0; j&n; j++)
for (i = 0; i&m; i++)
Table_board[j][i].var = 0;
Table_board[j][i].color = BgC
line(x, y, x + BSIZE, y);
line(x, y, x, y + BSIZE);
line(x, y + BSIZE, x + BSIZE, y + BSIZE);
line(x + BSIZE, y, x + BSIZE, y + BSIZE);
x += BSIZE;
y += BSIZE;
Curbox_x =
Curbox_y =/*x,y是保存方块的当前坐标的*/
flag_newbox =
/*是否要产生新方块的标记0*/
speed = 0;
/*下落速度*/
score = 0;
ShowScore(score);
ShowSpeed(speed);}/*
删除一行满的情况*
这里的y为具体哪一行为满*/int DelFullRow(int y){
/*该行游戏板往下移一行*/
int n, top = 0;
/*top保存的是当前最高点,出现一行全空就表示为最点了,移动是到最高点结束*/
register m,
for (n = n &= 0; n--)/*从当前行往上看*/
totoal = 0;
for (m = 0; m&Horizontal_ m++)
if (!Table_board[n][m].var)totoal++;
/*没占有方格+1*/
if (Table_board[n][m].var != Table_board[n - 1][m].var)
/*上行不等于下行就把上行传给下行 xor关系*/
Table_board[n][m].var = Table_board[n - 1][m].
Table_board[n][m].color = Table_board[n - 1][m].
if (totoal == Horizontal_boxs)
/*发现上面有连续的空行提前结束*/
return(top);
/*返回最高点*/}/*找到一行满的情况*/void setFullRow(int t_boardy){
int n, full_numb = 0, top = 0;
/*top保存的是当前方块的最高点*/
t_boardy 口
口口口口口口
口口口口口口
for (n = t_boardy + 3; n &= t_ n--)
if (n&0 || n &= Vertical_boxs)
/*超过低线了*/
for (m = 0; m&Horizontal_ m++)
/*水平的方向*/
if (!Table_board[n + full_numb][m].var)
/*发现有一个是空就跳过该行*/
if (m == Horizontal_boxs)
/*找到满行了*/
if (n == t_boardy + 3)
/*第一次献给了n,最高的*/
top = DelFullRow(n + full_numb);
/*清除游戏板里的该行,并下移数据*/
DelFullRow(n + full_numb);
full_numb++;
/*统计找到的行数*/
if (full_numb)
int oldx, x = Sys_x, y = BSIZE*top + Sys_y;
score = score + full_numb * 10;
/*加分数*/
/*这里相当于重显调色板*/
for (n = n&t_boardy + 4; n++)
if (n &= Vertical_boxs)
/*超过低线了*/
for (m = 0; m&Horizontal_ m++)
/*水平的方向*/
if (Table_board[n][m].var)
setfillstyle(SOLID_FILL, Table_board[n][m].color);/*Table_board[n][m].color*/
setfillstyle(SOLID_FILL, BgColor);
bar(x, y, x + BSIZE, y + BSIZE);
line(x, y, x + BSIZE, y);
line(x, y, x, y + BSIZE);
line(x, y + BSIZE, x + BSIZE, y + BSIZE);
line(x + BSIZE, y, x + BSIZE, y + BSIZE);
x += BSIZE;
y += BSIZE;
ShowScore(score);
if (speed != score / speed_step)
speed = score / speed_
ShowSpeed(speed);
ShowSpeed(speed);
}}/** 将新形状的方块放置在游戏板上,并返回此方块号*/int MkNextBox(int box_numb){
int mask = 128, t_boardx, t_boardy, n,
t_boardx = (Curbox_x - Sys_x) / BSIZE;
t_boardy = (Curbox_y - Sys_y) / BSIZE;
for (n = 0; n&4; n++)
for (m = 0; m&4; m++)
if (((shapes[current_box_numb].box[n / 2]) & mask))
Table_board[t_boardy + n][t_boardx + m].var = 1;/*这里设置游戏板*/
Table_board[t_boardy + n][t_boardx + m].color = shapes[current_box_numb]./*这里设置游戏板*/
mask = mask / (2);
if (mask == 0)mask = 128;
setFullRow(t_boardy);
Curbox_x = Sys_x + Begin_boxs_x*BSIZE, Curbox_y = Sys_y;/*再次初始化座标*/
if (box_numb == -1) box_numb = rand() % MAX_BOX;
current_box_numb = box_
flag_newbox =
return(rand() % MAX_BOX);}/**
擦除(x,y)位置开始的编号为box_numb的box.*/void EraseBox(int x, int y, int box_numb){
int mask = 128, t_boardx, t_boardy, n,
setfillstyle(SOLID_FILL, BgColor);
for (n = 0; n&4; n++)
for (m = 0; m&4; m++)
/*看最左边四个单元*/
if (((shapes[box_numb].box[n / 2]) & mask))/*最左边有方块并且当前游戏板也有方块*/
bar(x + m*BSIZE, y + n*BSIZE, x + m*BSIZE + BSIZE, y + n*BSIZE + BSIZE);
line(x + m*BSIZE, y + n*BSIZE, x + m*BSIZE + BSIZE, y + n*BSIZE);
line(x + m*BSIZE, y + n*BSIZE, x + m*BSIZE, y + n*BSIZE + BSIZE);
line(x + m*BSIZE, y + n*BSIZE + BSIZE, x + m*BSIZE + BSIZE, y + n*BSIZE + BSIZE);
line(x + m*BSIZE + BSIZE, y + n*BSIZE, x + m*BSIZE + BSIZE, y + n*BSIZE + BSIZE);
mask = mask / (2);
if (mask == 0)mask = 128;
}}void ErasePreBox(int x, int y, int box_numb){
int mask = 128, t_boardx, t_boardy, n,
setfillstyle(SOLID_FILL, BgColor);
for (n = 0; n&4; n++)
for (m = 0; m&4; m++)
/*看最左边四个单元*/
if (((shapes[box_numb].box[n / 2]) & mask))/*最左边有方块并且当前游戏板也有方块*/
bar(x + m*BSIZE, y + n*BSIZE, x + m*BSIZE + BSIZE, y + n*BSIZE + BSIZE);
mask = mask / (2);
if (mask == 0)mask = 128;
}}/* 判断是否可以移动* x,y为当前方块位置* box_numb为方块号* direction 方向标志*
返回true 和false#define MoveLeft -1#define MoveRight 1#define MoveDown 0*/int MoveAble(int x, int y, int box_numb, int direction){
int n, m, t_boardx, t_
/*t_boardx 当前方块最左边在游戏板的位置*/
if (direction == MoveLeft)
/*如果向左移*/
mask = 128;
x -= BSIZE;
t_boardx = (x - Sys_x) / BSIZE;
t_boardy = (y - Sys_y) / BSIZE;
for (n = 0; n&4; n++)
for (m = 0; m&4; m++)
/*看最左边四个单元*/
if ((shapes[box_numb].box[n / 2]) & mask)/*最左边有方块并且当前游戏板也有方块*/
if ((x + BSIZE*m)&Sys_x)return(false);/*碰到最左边了*/
else if (Table_board[t_boardy + n][t_boardx + m].var) /*左移一个方块后,此4*4的区域与游戏板有冲突*/
return(false);
mask = mask / (2);
if (mask == 0)mask = 128;
return(true);
else if (direction == MoveRight)
/*如果向右移*/
x += BSIZE;
t_boardx = (x - Sys_x) / BSIZE;
t_boardy = (y - Sys_y) / BSIZE;
mask = 128;
for (n = 0; n&4; n++)
for (m = 0; m&4; m++)
/*看最右边四个单元*/
if ((shapes[box_numb].box[n / 2]) & mask)/*最右边有方块并且当前游戏板也有方块*/
if ((x + BSIZE*m) &= (Sys_x + BSIZE*Horizontal_boxs))return(false);/*碰到最右边了*/
else if (Table_board[t_boardy + n][t_boardx + m].var)
return(false);
mask = mask / (2);
if (mask == 0)mask = 128;
return(true);
else if (direction == MoveDown)
/*如果向下移*/
y += BSIZE;
t_boardx = (x - Sys_x) / BSIZE;
t_boardy = (y - Sys_y) / BSIZE;
mask = 128;
for (n = 0; n&4; n++)
for (m = 0; m&4; m++)
/*看最下边四个单元*/
if ((shapes[box_numb].box[n / 2]) & mask)/*最下边有方块并且当前游戏板也有方块*/
if ((y + BSIZE*n) &= (Sys_y + BSIZE*Vertical_boxs) || Table_board[t_boardy + n][t_boardx + m].var)
flag_newbox =
mask = mask / (2);
/*mask依次为:00,
if (mask == 0)mask = 128;
if (flag_newbox)
return(false);
return(true);
else if (direction == MoveRoll)
t_boardx = (x - Sys_x) / BSIZE;
t_boardy = (y - Sys_y) / BSIZE;
mask = 128;
for (n = 0; n&4; n++)
for (m = 0; m&4; m++)
/*看最下边四个单元*/
if ((shapes[box_numb].box[n / 2]) & mask)/*最下边有方块并且当前游戏板也有方块*/
if ((y + BSIZE*n) &= (Sys_y + BSIZE*Vertical_boxs))return(false);/*碰到最下边了*/
if ((x + BSIZE*n) &= (Sys_x + BSIZE*Horizontal_boxs))return(false);/*碰到最左边了*/
if ((x + BSIZE*m) &= (Sys_x + BSIZE*Horizontal_boxs))return(false);/*碰到最右边了*/
else if (Table_board[t_boardy + n][t_boardx + m].var)
return(false);
mask = mask / (2);
if (mask == 0)mask = 128;
return(true);
return(false);
}}/**显示指定的方块*/void show_box(int x, int y, int box_numb, int color){
int i, ii, ls_x =
if (box_numb&0 || box_numb &= MAX_BOX)/*指定的方块不存在*/
box_numb = MAX_BOX / 2;
setfillstyle(SOLID_FILL, color);
/*********************************
移位来判断第哪一位是1
方块是每1行用半个字节来表示
*********************************/
for (ii = 0; ii&2; ii++)
int mask = 128;
for (i = 0; i&8; i++)
if (i % 4 == 0 && i != 0)
/*表示转到方块的下一行了*/
y += BSIZE;
if ((shapes[box_numb].box[ii])&mask)
bar(x, y, x + BSIZE, y + BSIZE);
line(x, y, x + BSIZE, y);
line(x, y, x, y + BSIZE);
line(x, y + BSIZE, x + BSIZE, y + BSIZE);
line(x + BSIZE, y, x + BSIZE, y + BSIZE);
x += BSIZE;
mask /= 2;
y += BSIZE;
}}void main(){
int GameOver = 0;
int Currentaction = 0;/*标记当前动作状态*/
int gd = VGA, gm = VGAHI,
initgraph(&gd, &gm, &&);
errorcode = graphresult();
if (errorcode != grOk)
printf(&\nNotice:Graphics error: %s\n&, grapherrormsg(errorcode));
printf(&Press any key to quit!&);
setbkcolor(BgColor);
setcolor(FgColor);
randomize();
SetTimer(newtimer);
initialize(Sys_x, Sys_y, Horizontal_boxs, Vertical_boxs);/*初始化*/
nextbox = MkNextBox(-1);
show_box(Curbox_x, Curbox_y, current_box_numb, shapes[current_box_numb].color);
show_box(LeftWin_x, Curbox_y + 200, nextbox, shapes[nextbox].color);
show_intro(Sys_x, Curbox_y + 320);
/* Currentaction=0;
flag_newbox=
检测是否有按键*/
if (bioskey(1))
key = bioskey(0);
switch (key)
case VK_LEFT:
if (MoveAble(Curbox_x, Curbox_y, current_box_numb, MoveLeft))
EraseBox(Curbox_x, Curbox_y, current_box_numb);
Curbox_x -= BSIZE;
Currentaction = MoveL
case VK_RIGHT:
if (MoveAble(Curbox_x, Curbox_y, current_box_numb, MoveRight))
EraseBox(Curbox_x, Curbox_y, current_box_numb);
Curbox_x += BSIZE;
Currentaction = MoveR
case VK_DOWN:
if (MoveAble(Curbox_x, Curbox_y, current_box_numb, MoveDown))
EraseBox(Curbox_x, Curbox_y, current_box_numb);
Curbox_y += BSIZE;
Currentaction = MoveD
else flag_newbox =
case VK_UP:/*旋转方块*/
if (MoveAble(Curbox_x, Curbox_y, shapes[current_box_numb].next, MoveRoll))
EraseBox(Curbox_x, Curbox_y, current_box_numb);
current_box_numb = shapes[current_box_numb].
Currentaction = MoveR
case VK_ESC:
GameOver = 1;
if (Currentaction)
/*表示当前有动作,移动或转动*/
show_box(Curbox_x, Curbox_y, current_box_numb, shapes[current_box_numb].color);
Currentaction = 0;
/*按了往下键,但不能下移,就产生新方块*/
if (flag_newbox)
/*这时相当于方块到底部了,把其中出现点满一行的清去,置0*/
ErasePreBox(LeftWin_x, Sys_y + 200, nextbox);
nextbox = MkNextBox(nextbox);
show_box(LeftWin_x, Curbox_y + 200, nextbox, shapes[nextbox].color);
if (!MoveAble(Curbox_x, Curbox_y, current_box_numb, MoveDown))/*刚一开始,游戏结束*/
show_box(Curbox_x, Curbox_y, current_box_numb, shapes[current_box_numb].color);
GameOver = 1;
flag_newbox =
Currentaction = 0;
/*自由下落*/
if (Currentaction == MoveDown || TimerCounter& (20 - speed * 2))
if (MoveAble(Curbox_x, Curbox_y, current_box_numb, MoveDown))
EraseBox(Curbox_x, Curbox_y, current_box_numb);
Curbox_y += BSIZE;
show_box(Curbox_x, Curbox_y, current_box_numb, shapes[current_box_numb].color);
TimerCounter = 0;
if (GameOver)/*|| flag_newbox==-1*/
printf(&game over,thank you! your score is %d&, score);
KillTimer();
closegraph();}
登录百度帐号推荐应用2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
本帖子已过去太久远了,不再提供回复功能。本帖子已过去太久远了,不再提供回复功能。

参考资料

 

随机推荐