俄罗斯方块java代码_俄罗斯方块源代码

[c++]代码库#include

#include

#include

#define CELL 20

#define ROWS 25

#define COLS 15

//升级所需分数值

#define SCORE_LEVEL_INC 80

#define ID_TIMER 1

/全局变量/

HWND hwnd; //保存窗口句柄

int score=0; //分数

int level=0; //级数

int interval_unit=25; //随级数递增的时间间隔增量

int interval_base=300; //时间间隔基量

int old_interval; //保存当前的时间间隔,用于加速操作

int cur_left,cur_top; //记录方块当前的位置

int width_block,height_block; //方块的宽带和高度

bool isPause=false; //暂停标识

UINT timer_id=0; //保存计时器ID

static byte *block=NULL; //方块,方块为随机大小,采用动态分配内存方式,所以这里是指针变量

byte g_panel[ROWS][COLS]={0};

LRESULT CALLBACK WndProc ( HWND,UINT,WPARAM,LPARAM );

void DrawPanel ( HDC hdc ); //绘制表格

void RefreshPanel ( HDC hdc ); //刷新面板

void DoDownShift ( HDC hdc ); //下移

void DoLeftShift ( HDC hdc ); //左移

void DoRightShift ( HDC hdc ); //右移

void DoAccelerate ( HDC hdc ); //加速

void DoRedirection ( HDC hdc ); //改变方向

void ClearRow ( HDC hdc ); //消行

bool ExportBlock(); //输出方块,

//该函数会直接修改全局变量block,width_block,height_block,

//cur_left和cur_top

bool IsTouchBottom ( HDC hdc ); //判断是否到达底部

int main()

{

HINSTANCE hInstance=GetModuleHandle ( NULL );

TCHAR szAppName[]=TEXT ( "teris" );

MSG msg;

WNDCLASS wc;

wc.style=CS_HREDRAW|CS_VREDRAW;

wc.lpfnWndProc=WndProc;

wc.cbClsExtra=0;

wc.cbWndExtra=0;

wc.hInstance=hInstance;

wc.hIcon=LoadIcon ( NULL,IDI_APPLICATION );

wc.hCursor=LoadCursor ( NULL,IDC_ARROW );

wc.hbrBackground= ( HBRUSH ) GetStockObject ( WHITE_BRUSH );

wc.lpszMenuName=NULL;

wc.lpszClassName=szAppName;

if ( !RegisterClass ( &wc ) )

{

printf ( "RegisterClass occur errors!" );

return 0;

}

hwnd=CreateWindow ( szAppName,TEXT ( "Teris Demo" ),

WS_OVERLAPPEDWINDOW,

0,0,0,0,

NULL,

NULL,

hInstance,

NULL );

ShowWindow ( hwnd,SW_SHOW );

UpdateWindow ( hwnd );

while ( GetMessage ( &msg,NULL,0,0 ) )

{

TranslateMessage ( &msg );

DispatchMessage ( &msg );

}

return msg.wParam;

}

void DrawPanel ( HDC hdc ) //绘制游戏面板

{

int x,y;

RECT rect;

for ( y=0; y

{

for ( x=0; x

{

//计算方块的边框范围

rect.top=y*CELL+1;

rect.bottom= ( y+1 ) *CELL-1;

rect.left=x*CELL+1;

rect.right= ( x+1 ) *CELL-1;

FrameRect ( hdc,&rect, ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) );

}

}

}

void DoDownShift ( HDC hdc ) //下移

{

if ( NULL==block ) return;

//判断是否到达底部

if ( IsTouchBottom ( hdc ) ) //到底部

{

//消行处理

ClearRow ( hdc );

ExportBlock(); //输出下一个方块

}

cur_top++;

RefreshPanel ( hdc );

}

void DoLeftShift ( HDC hdc ) //左移

{

int x,y;

if ( NULL==block ) return;

if ( 0==cur_left ) return;

if ( cur_top<0 ) return; //方块没有完整显示前,不能左移

for ( y=0; y

{

for ( x=0; x

{

if ( * ( block+y*width_block+x ) )

{

//判断当前方格在面板上面左边一个方格是否为实心,是就代表不能再左移

if ( g_panel[cur_top+y][cur_left+x-1] ) return;

break; //只判断最左边的一个实心方格,之后直接扫描下一行

}

}

}

cur_left--;

RefreshPanel ( hdc );

}

void DoRightShift ( HDC hdc ) //右移

{

int x,y;

if ( NULL==block ) return;

if ( COLS-width_block==cur_left ) return;

if ( cur_top<0 ) return; //方块完整显示前不能右移

for ( y=0; y

{

for ( x=width_block-1; x>=0; x-- ) //从右边开始扫描,获取该行最右边的实心方格块

{

if ( * ( block+y*width_block+x ) )

{

//判断当前方格在面板上右边一个方格是否为实心,是就代表不能再右移

if ( g_panel[cur_top+y][cur_left+x+1] ) return;

break; //只判断最右边的一个实心方格

}

}

}

cur_left++;

RefreshPanel ( hdc );

}

void DoRedirection ( HDC hdc ) //改变方向

{

int i,j;

byte * temp=NULL;

if ( NULL==block ) return;

if ( cur_top<0 ) return; //方块完整显示前不能转向

temp= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );

for ( i=0; i

{

for ( j=0; j

{

//temp[i][j]=block[height_block-j-1][i];

* ( temp+i*height_block+j ) =* ( block+ ( height_block-j-1 ) *width_block+i );

}

}

//给方块重新定位

int incHeight=width_block-height_block;

int incWidth=height_block-width_block;

int temp_cur_top=cur_top-incHeight/2;

int temp_cur_left=cur_left-incWidth/2;

//system("cls");

//printf("temp_top=%d, temp_left=%d",temp_cur_top,temp_cur_left);

//判断当前空间是否足够让方块改变方向

int max_len=max ( width_block,height_block );

//防止下标访问越界

if ( temp_cur_top+max_len-1>=ROWS||temp_cur_left<0||temp_cur_left+max_len-1>=COLS )

{

free ( temp ); //退出前必须先释放内存

return;

}

for ( i=0; i

{

for ( j=0; j

{

//转向所需的空间内有已被占用的实心方格存在,即转向失败

if ( g_panel[temp_cur_top+i][temp_cur_left+j] )

{

free ( temp ); //退出前必须先释放内存

return;

}

}

}

//把临时变量的值赋给block,只能赋值,而不能赋指针值

for ( i=0; i

{

for ( j=0; j

{

//block[i][j]=temp[i][j];

* ( block+i*width_block+j ) =* ( temp+i*width_block+j );

}

}

//全局变量重新被赋值

cur_top=temp_cur_top;

cur_left=temp_cur_left;

//交换

i=width_block;

width_block=height_block;

height_block=i;

free ( temp ); //释放为临时变量分配的内存

RefreshPanel ( hdc );

}

void DoAccelerate ( HDC hdc ) //加速

{

if ( NULL==block ) return;

if ( IsTouchBottom ( hdc ) )

{

//消行处理

ClearRow ( hdc );

ExportBlock();

}

cur_top++;

RefreshPanel ( hdc );

}

bool IsTouchBottom ( HDC hdc )

{

int x,y;

int i,j;

if ( NULL==block ) return false;

if ( ROWS==cur_top+height_block )

{

//固定方块

for ( i=0; i

{

for ( j=0; j

{

if ( * ( block+i*width_block+j ) ) g_panel[cur_top+i][cur_left+j]=1;

}

}

return true;

}

for ( y=height_block-1; y>=0; y-- ) //从底行开始扫描

{

//判断第一个实心方块在面板上邻接的下方方格是否为实心,是就代表已经到达底部

for ( x=0; x

{

if ( * ( block+y*width_block+x ) )

{

if ( cur_top+y+1<0 ) return false;

if ( g_panel[cur_top+y+1][cur_left+x] )

{

//判断是否gameover

if ( cur_top<=0 )

{

if ( timer_id )

{

KillTimer ( hwnd,ID_TIMER );

timer_id=0;

}

MessageBox ( hwnd,TEXT ( "游戏结束" ),TEXT ( "MSG" ),MB_OK|MB_ICONEXCLAMATION );

SendMessage ( hwnd,WM_CLOSE,0,0 );

}

//

//固定方块

for ( i=0; i

{

for ( j=0; j

{

if ( * ( block+i*width_block+j ) ) g_panel[cur_top+i][cur_left+j]=1;

}

}

return true;

}

}

}

}

return false;

}

void ClearRow ( HDC hdc ) //消行

{

int i,j,k;

int count=0; //消行次数

bool isFilled;

//消行处理

for ( i=ROWS-1; i>=0; i-- )

{

isFilled=true;

for ( j=0; j

{

if ( !g_panel[i][j] )

{

isFilled=false;

break;

}

}

if ( isFilled )

{

for ( j=0; j

{

g_panel[i][j]=0;

}

//所有方块往下移

for ( k=i-1; k>=0; k-- )

{

for ( j=0; j

{

g_panel[k+1][j]=g_panel[k][j];

}

}

i=i+1;

count++;

}

}

//最高级别为9级,所以分数极限为(9+1)*SCORE_LEVEL_INC-1

if ( score>=10*SCORE_LEVEL_INC-1 ) return;

//加分规则:消除行数,1行加10分,2行加15分,3行加20分,4行加30分

switch ( count )

{

case 1:

score+=10;

break;

case 2:

score+=15;

break;

case 3:

score+=20;

break;

case 4:

score+=30;

break;

}

int temp_level=score/SCORE_LEVEL_INC;

if ( temp_level>level )

{

level=temp_level;

//撤销当前计时器,然后重设

if ( timer_id ) KillTimer ( hwnd,ID_TIMER );

timer_id=SetTimer ( hwnd,ID_TIMER,interval_base-level*interval_unit,NULL );

}

system ( "cls" );

printf ( "score: %d, level: %d ",score,level );

}

void RefreshPanel ( HDC hdc ) //刷新面板

{

int x,y;

RECT rect;

HBRUSH h_bSolid= ( HBRUSH ) GetStockObject ( GRAY_BRUSH ),

h_bEmpty= ( HBRUSH ) GetStockObject ( WHITE_BRUSH );

if ( NULL==block ) return;

//先刷屏

for ( y=0; y

{

for ( x=0; x

{

//为避免刷掉方块的边框,rect范围必须比边框范围小1

rect.top=y*CELL+2;

rect.bottom= ( y+1 ) *CELL-2;

rect.left=x*CELL+2;

rect.right= ( x+1 ) *CELL-2;

if ( g_panel[y][x] )

FillRect ( hdc,&rect,h_bSolid );

else

FillRect ( hdc,&rect,h_bEmpty );

}

}

//再定位方块

for ( y=0; y

{

for ( x=0; x

{

if ( * ( block+y*width_block+x ) ) //实心

{

rect.top= ( y+cur_top ) *CELL+2;

rect.bottom= ( y+cur_top+1 ) *CELL-2;

rect.left= ( x+cur_left ) *CELL+2;

rect.right= ( x+cur_left+1 ) *CELL-2;

FillRect ( hdc,&rect,h_bSolid );

}

}

}

}

bool ExportBlock() //输出方块

{

int sel;

if ( block )

{

free ( block ); //释放之前分配的内存

block=NULL;

}

sel=rand() %7;

switch ( sel )

{

case 0: //水平条

width_block=4;

height_block=1;

block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );

* ( block+0 ) =1; //可以理解为*(block+0*width_block+0)=1,即第一行的第一个方格,下面同理

* ( block+1 ) =1; //*(block+0*width_block+1)=1

* ( block+2 ) =1; //*(block+0*width_block+2)=1

* ( block+3 ) =1; //*(block+0*width_block+3)=1

cur_top=0-height_block;

cur_left= ( COLS-width_block ) /2;

break;

case 1: //三角

width_block=3;

height_block=2;

block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );

* ( block+0 ) =0; //可以理解为*(block+0*width_block+0)=0,即第一行的第一个方格,下面同理

* ( block+1 ) =1; //*(block+0*width_block+1)=1

* ( block+2 ) =0; //*(block+0*width_block+2)=0

* ( block+3 ) =1; //*(block+1*width_block+0)=1,第二行开始

* ( block+4 ) =1; //*(block+1*width_block+1)=1

* ( block+5 ) =1; //*(block+1*width_block+2)=1

cur_top=0-height_block;

cur_left= ( COLS-width_block ) /2;

break;

case 2: //左横折

width_block=3;

height_block=2;

block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );

* ( block+0 ) =1; //可以理解为*(block+0*width_block+0)=1,下面同理

* ( block+1 ) =0; //*(block+0*width_block+1)=0

* ( block+2 ) =0; //*(block+0*width_block+2)=0

* ( block+3 ) =1; //*(block+1*width_block+0)=1

* ( block+4 ) =1; //*(block+1*width_block+1)=1

* ( block+5 ) =1; //*(block+1*width_block+2)=1

cur_top=0-height_block;

cur_left= ( COLS-width_block ) /2;

break;

case 3: //右横折

width_block=3;

height_block=2;

block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );

* ( block+0 ) =0; //可以理解为*(block+0*width_block+0)=0,下面同理

* ( block+1 ) =0; //*(block+0*width_block+1)=0

* ( block+2 ) =1; //*(block+0*width_block+2)=1

* ( block+3 ) =1; //*(block+1*width_block+0)=1

* ( block+4 ) =1; //*(block+1*width_block+1)=1

* ( block+5 ) =1; //*(block+1*width_block+2)=1

cur_top=0-height_block;

cur_left= ( COLS-width_block ) /2;

break;

case 4: //左闪电

width_block=3;

height_block=2;

block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );

* ( block+0 ) =1; //可以理解为*(block+0*width_block+0)=1,下面同理

* ( block+1 ) =1; //*(block+0*width_block+1)=1

* ( block+2 ) =0; //*(block+0*width_block+2)=0

* ( block+3 ) =0; //*(block+1*width_block+0)=0

* ( block+4 ) =1; //*(block+1*width_block+1)=1

* ( block+5 ) =1; //*(block+1*width_block+2)=1

cur_top=0-height_block;

cur_left= ( COLS-width_block ) /2;

break;

case 5: //右闪电

width_block=3;

height_block=2;

block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );

* ( block+0 ) =0; //可以理解为*(block+0*width_block+0)=0,下面同理

* ( block+1 ) =1; //*(block+0*width_block+1)=1

* ( block+2 ) =1; //*(block+0*width_block+2)=1

* ( block+3 ) =1; //*(block+1*width_block+0)=1

* ( block+4 ) =1; //*(block+1*width_block+1)=1

* ( block+5 ) =0; //*(block+1*width_block+2)=0

cur_top=0-height_block;

cur_left= ( COLS-width_block ) /2;

break;

case 6: //石头

width_block=2;

height_block=2;

block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );

* ( block+0 ) =1; //可以理解为*(block+0*width_block+0)=1,下面同理

* ( block+1 ) =1; //*(block+0*width_block+1)=1

* ( block+2 ) =1; //*(block+1*width_block+0)=1

* ( block+3 ) =1; //*(block+1*width_block+1)=1

cur_top=0-height_block;

cur_left= ( COLS-width_block ) /2;

break;

}

return block!=NULL;

}

LRESULT CALLBACK WndProc ( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )

{

HDC hdc;

PAINTSTRUCT ps;

//TCHAR szBuffer[1024];

switch ( message )

{

case WM_CREATE:

MoveWindow ( hwnd,400,10,CELL*COLS+8,CELL*ROWS+32,FALSE ); //补齐宽度和高度

srand ( time ( NULL ) );

ExportBlock();

timer_id=SetTimer ( hwnd,ID_TIMER,interval_base-level*interval_unit,NULL );

return 0;

case WM_TIMER:

hdc=GetDC ( hwnd );

DoDownShift ( hdc );

ReleaseDC ( hwnd,hdc );

return 0;

case WM_KEYDOWN:

hdc=GetDC ( hwnd );

switch ( wParam )

{

case VK_LEFT: //左移

if ( !isPause ) DoLeftShift ( hdc );

break;

case VK_RIGHT: //右移

if ( !isPause ) DoRightShift ( hdc );

break;

case VK_UP: //转向

if ( !isPause ) DoRedirection ( hdc );

break;

case VK_DOWN: //加速

if ( !isPause ) DoAccelerate ( hdc );

break;

case VK_SPACE: //暂停

isPause=!isPause;

if ( isPause )

{

if ( timer_id ) KillTimer ( hwnd,ID_TIMER );

timer_id=0;

}

else

{

timer_id=SetTimer ( hwnd,ID_TIMER,interval_base-level*interval_unit,FALSE );

}

break;

}

ReleaseDC ( hwnd,hdc );

return 0;

case WM_PAINT:

hdc=BeginPaint ( hwnd,&ps );

DrawPanel ( hdc ); //绘制面板

RefreshPanel ( hdc ); //刷新

EndPaint ( hwnd,&ps );

return 0;

case WM_DESTROY:

if ( block ) free ( block );

if ( timer_id ) KillTimer ( hwnd,ID_TIMER );

PostQuitMessage ( 0 );

return 0;

}

return DefWindowProc ( hwnd,message,wParam,lParam );

}

694748ed64b9390909c0d88230893790.png

Java俄罗斯方块】 增加保存配置信息到文件的功能,声音设置、显示设置、关卡选择等配置信息在修改后将会保存在jar包同级目录下(以jar相同的文件名+.cfg后缀保存) 2010-10-05 【Java俄罗斯方块】 这个程序是用Java开发的,需要安装JRE,应该不会说了吧 运行方式,也应该不会说了吧 解压,tetris.zhh.1.1.jar --> 右键 --> 打开方式 --> 点Java有关的那个选项 或者 开始 --> 运行 --> cmd --> 转到解压目录 --> java -jar tetris.zhh.1.1.jar 【菜单选项】 也做了不少菜单选项 可自定义控制键,可设置单色彩色显示,可设置网格是否显示网格 关卡有三组选择: 标准关卡:难度中等,7种基本形状,共分2级,50000分一级,速度递增,下落一格的速度每2000分减少10毫秒 速度关卡:难度较大,7种基本形状,共分10级,10000分一级,速度快且随着分数的增加而递增 复杂性关卡:难度较大,共分10级,8000分一级,随着级别越高复杂度越来越大,会出现随机填充的障碍物,以及难以应付的复杂形状,到第4级以后会出现16种基本形状,够你难受的了 【已知Bug】 1. 偶尔会出在现形状下落的过程中形状的某一块没有被擦除掉,原因不明 可能原因为,程序在刷新视图时并没有全部擦除重画,只是根据形状在上一次的显示位置将这一小块重画了一个空块以覆盖 仔细测试过,后台明明执行了这个过程,视图却没有被擦除掉,不知是不是JDK的问题 2. 一直按住回车键,程序将在开始游戏和结束游戏之间不停切换,偶尔会出现蒙层未盖住形状的问题 蒙层:程序会在游戏暂停时蒙上一层淡蓝色,而在游戏停止时蒙上一层淡红色 【关于俄罗斯方块游戏】 游戏简介 俄罗斯方块是一款益智方块类游戏, 这款游戏最初是由苏联的电脑科学家帕吉特诺夫(Alex Pajitnov)于1985年制作的, 作者给了他一个源自希腊字4(tetra)的名字Tetris。 1989年由任天堂于发行GameBoy版,推出后风靡全球,成为益智方块类型游戏中知名度最高的一款。 它看似简单但却变化无穷,上手极其容易,但是要熟练地掌握其中的操作与摆放技巧,难度却不低。 玩法简介 游戏具有一个用于摆放小方块的平面虚拟场地, 一组由几个小方块组成的规则形状(Tetromino), 游戏每次随机输出一种形状到场地顶部,自动以一定的速度下落, 用户在形状的过程中可以控制形状的左右移动及旋转以将形状填充到场地中, 直至形状下落至场地底部或被场地中已有的方块阻挡而不能再下落, 游戏再次输出一个形状,周而复始。 如果这次填充将场地的一行或多行完全填满,则组成这些行的所有方块将被消除, 并且以此来换取一定的积分奖励, 而未被消除的方块会一直累积,并对后来的形状摆放造成各种影响, 如果下一个形状的输出位置已经被未消除的方块所占据,则游戏结束。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值