一个游戏,类似俄罗斯方块经典版但是是四个一组的方块让选择放入上方方格中凑成一行消灭,求名字!!

推荐到广播
611970 人聚集在这个小组
(让我睡吧)
(你才是飞机场)
(宝南和宝北)
第三方登录:暂时没有公告
一个俄罗斯方块游戏源程序
///////////////////[safx.cpp]/////////////////////////
// stdafx.cpp : source file that includes just the standard includes//&ToyBricks.pch will be the pre-compiled header//&stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in SAFX.H// and not in this fil
//////////////////////////////////////[stdafx.h]//////////////////////////////////////////
// stdafx.h : include file for standard system include files,//& or project specific include files that are used frequently, but//&&&&& are changed infrequently//
#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1___INCLUDED_)#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1___INCLUDED_
#if _MSC_VER & 1000#pragma once#endif // _MSC_VER & 1000
#define WIN32_LEAN_AND_MEAN&&// Exclude rarely-used stuff from Windows headers
#include &.h&
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1___INCLUDED_)
/////////////////////////////////[game.cpp]////////////////////////////////////////////////////
// ToyBricks.cpp : Defines the entry point for the application.//
#include "StdAfx.h"
/*******************************************************/
#include &windows.h&&&&&&&&&&& //windows.h文件中包含应用程序中所需的数据类型和数据结构的定义#include &time.h&&&&&&&&&&&&&& //包含SetTimer()、KillTimer()等关于定时器的函数#include &stdlib.h&
#define CELL&15&&&&&&&&&&&& // 【方格】的边长(pix)& #define W&&20&&&&&&&&&&&& // 区宽(12个【方格】边长,8个格子用来绘制"下一个"方块)#define H&&26&&&&&&&&&&&& // 游戏区高(26个【方格】边长)#define MS_NEWBLOCK&WM_USER+1& // 消息ID,产生新的【方块】#define MS_DRAW&&WM_USER+2& // 消息ID,用来画【方块】#define MS_NEXTBLOCK WM_USER+3 //消息ID,用来显示下一个【俄罗斯方块】形状
//------------------------窗口函数的说明------------------------LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM);
//---------------------------------------------------------------int WINAPI WinMain ( HINSTANCE&hInstance,&&&&&& HINSTANCE&hPrevInstance, &&&&& PSTR&&szCmdLine, &&&&& int&&iCmdShow)
{&static char AppName[]="ToyBrick";&&&&&&&&&& //窗口类名&HWND&&&&&&&&&&MSG&&&&&&&&&&//消息结构&WNDCLASSEX&&&&&&&//窗口类&int&&&iScreenW&&&&&&&&&&&&&&&&&&& //定义一个整型变量来取得窗口的宽度&&
&wndclass.cbSize&&&= sizeof(wndclass);&wndclass.style&&&= CS_HREDRAW|CS_VREDRAW;//窗口类型&&& &&&&&&&&& //CS_HREDRAW :Redraws the entire window if a movement or size &&&&&&&&&&&&&&&&&&&&&&&&&&& //&&&&&&&&&&&& adjustment changes the width of the client area.&&&&&&&&& //CS_VREDRAW :Redraws the entire window if a movement or size&&&&&&&&&&&&&&&&&&&&&&&&&&& //&&&&&&&&&&&& adjustment changes the height of the client area.&&&&wndclass.lpfnWndProc&= WndP&&&&&&&&//窗口处理函数为 WndProc&wndclass.cbClsExtra&&= 0;&&&&&&&&&//窗口类无扩展&wndclass.cbWndExtra&&= 0;&&&&&&&&&//窗口实例无扩展&&&&wndclass.hInstance&&= hI&&&&&&&&&&&&&&&&&&&&&&&&&&& //当前实例句柄&wndclass.hIcon&&&= LoadIcon (NULL, IDI_APPLICATION);&&&& //默认图标&wndclass.hCursor&&= LoadCursor (NULL,IDC_ARROW);&&&&&&&&& //箭头光标&wndclass.hbrBackground&= (HBRUSH)GetStockObject (WHITE_BRUSH); //背景为黑色 &wndclass.lpszMenuName&= NULL;&&&&&&&&&//窗口中无菜单&wndclass.lpszClassName&= AppN&&&&&&&&&& //类名为"ToyBrick"&wndclass.hIconSm&&= LoadIcon (NULL, IDI_APPLICATION);&
//----------------------------------窗口类的注册-----------------------------------------
&if(!RegisterClassEx (&wndclass))&&&&&&&&& //如果注册失败则发出警报声音,返回FALSE&{&&MessageBeep(0);&&&&&&&&&&&&&&&&&&&&&&&&& &&return FALSE;&}
&// 获取显示器分辨率的X值iScreenWide,将程序窗口置于屏幕中央&iScreenWide=GetSystemMetrics (SM_CXFULLSCREEN);
&hwnd =CreateWindow (&&&&&&&&&&&&&&&&& AppName,&&&&&&&&&&&&&&&&&&& //窗口类名&&&&&&&&&&&&&&&& "俄罗斯方块模拟项目(软件学院.钱彦江)",&&&&//窗口实例的标题名&&&&&&WS_NIMIZEBOX|WS_SYSMENU , //窗口的风格&&&&&&iScreenWide/2-W*CELL/2,&&&& //窗口左上角横坐标(X)&&&&&&CELL,&&&&&&&&&&&&&&&&&&&&&& //窗口左上角纵坐标(Y)&&&&&&W*CELL,&&&&&&&&& &&&//窗口的宽&&&&&&H*CELL,&&&&&&&&&&&&&&&&&&&& //窗口的高 &&&&&&NULL,&&&&&&&&&&&&&&&&&&&&&& //窗口无父窗口& &&&&&&NULL,&&&&&&//窗口无主菜单&&&&&&hInstance,&&&&&//创建此窗口的应用程序的当前句柄&&&&&&NULL&&&&&&&&&&&&&&&&&&&&&&& //不使用该值&&&&&& );&if(!hwnd) return FALSE;&&& //显示窗口&ShowWindow (hwnd,iCmdShow);&//绘制用户区&UpdateWindow (hwnd);&MessageBox(hwnd,"&&&&& 开始游戏\n\n_软件学院模拟项目","开始",MB_OK);&SendMessage(hwnd,MS_NEWBLOCK,0,0);&&& SetTimer (hwnd, 1, 500,NULL);&& &//消息循环&while (GetMessage (&msg, NULL, 0, 0))&{&&TranslateMessage (&msg);&&DispatchMessage (&msg);&}&&& //消息循环结束即程序终止时将消息返回系统&return msg.wP&&& }
// 函数DrawRact: 画【正方形】----- (□)// 参数: 设备环境句柄和【正方形】的四角坐标void DrawRect (HDC hdc, int l, int t, int r, int b){&MoveToEx (hdc, l, t, NULL);&& //将光标移动到(l,t)&LineTo (hdc, r, t);&&&&&&&&& &LineTo (hdc, r, b);&LineTo (hdc, l, b);&LineTo (hdc, l,t);}
// 函数DrawCell: 画【方格】-----(红色■)// 参数: 设备环境句柄和【方格】的四角坐标void DrawCell (HDC hdc, int l, int t, int r, int b){&&HBRUSH&
&hbrush=CreateSolidBrush(RGB(255,0,0));&&& // 红色画刷&&& SelectObject(hdc,hbrush);&&&&&&&&&&&&& && &Rectangle(hdc,l, t, r, b);&&& DeleteObject (hbrush);
//绘出游戏区域的方格,其中包括"游戏空间"和"显示下一个【方块】空间"//此函数包含在Cover函数中。参数:设备环境句柄void DrawGamePlace(HDC hdc){&int i,j;&HPEN hpen1,hpen2;&hpen1=CreatePen(PS_SOLID,1,RGB(0,255,0));&hpen2=CreatePen(PS_DASHDOTDOT,3,RGB(0,0,255));
&&& //绘制分割线&SelectObject(hdc,hpen2);&MoveToEx(hdc,(W-8)*CELL,0,NULL); &LineTo(hdc,(W-8)*CELL,H*CELL);&&& //绘制游戏区域方格线(绿色)&SelectObject(hdc,hpen1);&for (i=1; i&H-1; i++)&&for(j=1; j&=W-8; j++)&&&DrawRect (hdc, (j-1)*CELL, (i-1)*CELL, j*CELL, i*CELL);
&//绘制"显示下一个"区域的方格线&for(i=5;i&9;i++)&&&&&&&&&&&&&&&&&&&&&&&&&&&& // 5≤i≤8&&for(j=W-5;j&W-1;j++)&&&&&&&&&&&&&&&&&&&& // 15≤j≤18&&&&DrawRect (hdc, (j-1)*CELL, (i-1)*CELL, j*CELL, i*CELL);&&& &&& DeleteObject(hpen2);&&& DeleteObject(hpen1);&}
// 函数DrawBlock: 画游戏中出现的【俄罗斯方块】// 参数: 设备环境句柄和【俄罗斯方块】中四个【方格】在游戏区域中的位置// 每个【俄罗斯方块】由四个【方格】组成7种不同的形状void DrawBlock (HDC hdc, int block[4][2]){&&for(i=0; i&4; i++)&&DrawCell (hdc, (block[i][0]-1)*CELL, (block[i][1]-1)*CELL, //....&&&&& block[i][0]*CELL, block[i][1]*CELL);
// 函数Cover: 清除原来位置的【俄罗斯方块】// 参数: 设备环境句柄和待清除的【俄罗斯方块】//作用(1) 清除【俄罗斯方块】即在该【俄罗斯方块】的每个【方格】处画一个正方形的白块//&&& (2) 重新绘制游戏区域的方格
void Cover (HDC hdc, int org[4][2]){&&HBRUSH&&& //重新绘制游戏区域&DrawGamePlace(hdc);
&hbrush=(HBRUSH)GetStockObject (WHITE_BRUSH);&&& SelectObject (hdc,hbrush );&for(i=0; i&4; i++)&&Rectangle ( hdc, (org[i][0]-1)*CELL, (org[i][1]-1)*CELL, //.....&&&&&org[i][0]*CELL, org[i][1]*CELL);&&DeleteObject(hbrush);
//-------------------窗口过程函数WndProc-----------------------------
LRESULT CALLBACK WndProc ( HWND&&hwnd, &&&&&&&& UINT&&iMsg, &&&&&&&& WPARAM&wParam, &&&&&&&& LPARAM&lParam ){&int&&&i,j,k,lines,r;&static int&top, sel,&static int&cells[W-6][H];&&&&&&&&&&&&&&&&&&&&&&&&&& // 控制游戏区域的【方格矩阵】&static int&org[4][2], block[4][2],org2[4][2];&&&&&& // 【方块】&HDC&&&&HPEN&&&PAINTSTRUCT
&switch (iMsg)&{&case WM_CREATE:&&//当一个应用程序使用函数CreateWindow或CreateWindowEx来创建一个窗口时,&&//系统将发送该消息给此新建窗口过程。该消息将在创建窗口之后,显示窗口&&//之前发送该消息,该消息将在CreateWindow或CreateWindowEx函数返回之前发送。&&&&&top=H-1;&&// 将第一列和最后一列【方格】置1,控制【方块】不超出游戏区域&&for(i=0; i&H; i++)&&{ &&&cells[0][i]=1;&&&cells[W-7][i]=1;&&}
&&// 将最底下一行【方格】置1,控制【方块】不超出游戏区域&&for(i=0; i&W-6; i++)&&&cells[i][H-1]=1;
&&// 其他【方格】置0,游戏方块只能在这里移动&&for(i=1; i&=W-8; i++)&&&for(j=0; j&H-1; j++)&&&&cells[i][j]=0;&&&&&return 0;
&case MS_NEWBLOCK:&&&flag=0;&&&&&&&& // flag表示【方块】旋转了几次
&&for(i= i&H-1; i++)&&{&&&lines =0;
&&&// 循环语句检查是否有某一行全部被【方格】都填满&&&for(j=1; j&=W-7; j++)&&&&if(! cells[j][i]) &&&&{&&&&&lines=1;&&&&&&&&&}
&&&// 若该行被填满,则将上一行的填充状态复制到该行,依此类推&&&// 即从该行开始,所有的【方格】都下移一行&&&if(!lines)&&&{&for(j=1;j&W-7; j++)&&&&&for(k=i; k&= k--)&&&&&&cells[j][k]=cells[j][k-1];&&&&top++;
&&&&&&&&&&& //该函数把指定窗口用户区域内的矩形加入到该窗口的更新区域之外&&&&&&&&&&& //使该矩形无效。这个无效的矩形,连同更新区域中的其他区域,在收到下&&&&&&&&&&& //一条WM_PAINT消息时将被重画。无效区一直积累在更新区域之中,直到&&&//下一条WM_PAINT消息发生时对该区域进行处理。&&&&InvalidateRect(hwnd, NULL, TRUE);&&&}&&}
&&// 产生随机数0~7,分别代表【方块】的7种形状&&srand( (unsigned)time( NULL ) );&&sel =rand()%7;
&&//【方块】形状初始化&&//【方块】的形状由其每个【方格】的位置决定&&// 游戏区宽W=20,block[?][0]=4/5/6/7,block[?][1]=0/1/2&&// 这样【方块】初始位置在游戏区域的最顶部的中央 &&switch(sel)&&{&&case 0:&&&// ▓▓&&&// ▓▓&&&org[0][0]=block[0][0] =5;&org[0][1]=block[0][1] =0;&&&org[1][0]=block[1][0] =6;&org[1][1]=block[1][1] =0;&&&org[2][0]=block[2][0] =5;&org[2][1]=block[2][1] =1;&&&org[3][0]=block[3][0] =6;&org[3][1]=block[3][1] =1;&&&for(i=0;i&4;i++)&&&{&&&&& &org2[i][0]=org[i][0]+11;&&&&&& org2[i][1]=org[i][1]+5;&&&}
&&case 1:&&&//▓▓▓▓&&&org[0][0]=block[0][0] =4;&org[0][1]=block[0][1] =0;&&&org[1][0]=block[1][0] =5;&org[1][1]=block[1][1] =0;&&&org[2][0]=block[2][0] =6;&org[2][1]=block[2][1] =0;&&&org[3][0]=block[3][0] =7;&org[3][1]=block[3][1] =0;&&&for(i=0;i&4;i++)&&&{&&&&& &org2[i][0]=org[i][0]+11;&&&&&& org2[i][1]=org[i][1]+5;&&&}
&&case 2:&&&//▓&&&//▓▓&&&//& ▓&&&org[0][0]=block[0][0] =5;&org[0][1]=block[0][1] =0;&&&org[1][0]=block[1][0] =5;&org[1][1]=block[1][1] =1;&&&org[2][0]=block[2][0] =6;&org[2][1]=block[2][1] =1;&&&org[3][0]=block[3][0] =6;&org[3][1]=block[3][1] =2;&&&for(i=0;i&4;i++)&&&{&&&&& &org2[i][0]=org[i][0]+11;&&&&&& org2[i][1]=org[i][1]+5;&&&}
&&case 3:&&&//& ▓&&&//▓▓&&&//▓&&&org[0][0]=block[0][0] =6;&org[0][1]=block[0][1] =0;&&&org[1][0]=block[1][0] =6;&org[1][1]=block[1][1] =1;&&&org[2][0]=block[2][0] =5;&org[2][1]=block[2][1] =1;&&&org[3][0]=block[3][0] =5;&org[3][1]=block[3][1] =2;&&&for(i=0;i&4;i++)&&&{&&&&& &org2[i][0]=org[i][0]+11;&&&&&& org2[i][1]=org[i][1]+5;&&&}
&&&&&&&&case 4:&&&//▓&&&//▓&&&//▓▓&&&org[0][0]=block[0][0] =5;&org[0][1]=block[0][1] =0;&&&org[1][0]=block[1][0] =5;&org[1][1]=block[1][1] =1;&&&org[2][0]=block[2][0] =5;&org[2][1]=block[2][1] =2;&&&org[3][0]=block[3][0] =6;&org[3][1]=block[3][1] =2;&&&for(i=0;i&4;i++)&&&{&&&&& &org2[i][0]=org[i][0]+11;&&&&&& org2[i][1]=org[i][1]+5;&&&}
&&case 5:&&&//& ▓&&&//& ▓&&&//▓▓&&&org[0][0]=block[0][0] =5;&org[0][1]=block[0][1] =0;&&&org[1][0]=block[1][0] =5;&org[1][1]=block[1][1] =1;&&&org[2][0]=block[2][0] =5;&org[2][1]=block[2][1] =2;&&&org[3][0]=block[3][0] =4;&org[3][1]=block[3][1] =2;&&&for(i=0;i&4;i++)&&&{&&&&& &org2[i][0]=org[i][0]+11;&&&&&& org2[i][1]=org[i][1]+5;&&&}
&&&&&case 6:&&&//& ▓&&&//▓▓▓&&&org[0][0]=block[0][0] =5;&org[0][1]=block[0][1] =0;&&&org[1][0]=block[1][0] =4;&org[1][1]=block[1][1] =1;&&&org[2][0]=block[2][0] =5;&org[2][1]=block[2][1] =1;&&&org[3][0]=block[3][0] =6;&org[3][1]=block[3][1] =1;&&&for(i=0;i&4;i++)&&&{&&&&& &org2[i][0]=org[i][0]+11;&&&&&& org2[i][1]=org[i][1]+5;&&&}
&&&&&&&& &SendMessage (hwnd, MS_NEXTBLOCK, 0, 0);&&&
&&default:&&&&&&SendMessage (hwnd, MS_NEWBLOCK, 0, 0);&&&SendMessage (hwnd, MS_NEXTBLOCK, 0, 0);&&&&&}
&&return 0;
&case WM_TIMER:&&&&// 每个时间节拍【方块】自动下移一行&&for(i=0; i&4; i++)&&&block[i][1]++;
&&// 检查【方块】下移是否被档住,即判断下移后新位置是否有【方格】&&for(i=0; i&4; i++)&&&if(cells[ block[i][0] ][ block[i][1] ])&&&{ &&&&SendMessage (hwnd, MS_NEXTBLOCK, 0, 0);
&&&&for(i=0; i&4; i++) &&&&&cells[ org[i][0] ][ org[i][1] ]=1;
&&&&if(top&org[0][1]-2)&&&&&top=org[0][1]-2;
&&&&if (top&1)&&&&{&&&&&KillTimer (hwnd, 1);&&&&&MessageBox (hwnd, "游戏结束,即将退出 !\n四川大学软件学院", "退出", MB_OK);&&&&&PostQuitMessage (0);&&&&}&&&&&&& &&&&&SendMessage (hwnd, MS_NEWBLOCK, 0, 0);&&&&return 0;&&&}
&&SendMessage (hwnd, MS_DRAW, 0, 0);
&&return 0;
&// 响应键盘控制&case WM_KEYDOWN:&&r=0;&&switch((int)wParam)&&{&&case VK_LEFT:&&&for(i=0; i&4; i++)&&&&block[i][0]--;&&&
&&case VK_RIGHT:&&&for(i=0; i&4; i++)&&&&block[i][0]++;&&&&&case VK_DOWN:&&&for(i=0; i&4; i++)&&&&block[i][1]++;&&&
&&// 按[向上键],【方块】顺时针旋转&&//【方块】的旋转不是真正的旋转,而是根据不同的【方块】形状和该【方块】旋转过的&&// 次数来移动其中的一个或几个【方格】,从而达到旋转的效果 。这样做很复杂,算法&&// 不够理想,但是能够保持【方块】旋转时的重心比较稳定。&& &&case VK_UP:&&&r=1;&&&flag++;&&&&&&&&&&&&&&&&&&&&&&&& //【方块】旋转加1
&&&switch(sel)&&&&&&&&&&&&&&&&&&&& // sel代表当前【方块】的形状&&&{&&&case 0:
&&&case 1: &&&&flag =flag%2;&&&&for(i=0; i&4; i++)&&&&{&&&&&block[i][(flag+1)%2] =org[2][(flag+1)%2];&&&&&block[i][flag] =org[2][flag]-2+i;&&&&}&&&&
&&&case 2:&&&&flag =flag%2;&&&&if(flag)&&&&{&block[0][1] +=2;&block[3][0] -=2;&}&&&&else&&&&{&block[0][1] -=2;&block[3][0] +=2;&}&&&&
&&&case 3:&&&&flag =flag%2;&&&&if(flag)&&&&{&block[0][1] +=2;&block[3][0] +=2;&}&&&&else&&&&{&block[0][1] -=2;&block[3][0] -=2;&}&&&&
&&&case 4:&&&&flag=flag%4;&&&&switch(flag)&&&&{&&&&case 0:&&&&&block[2][0] +=2;&block[3][0] +=2;&&&&&block[2][1] +=1;&block[3][1] +=1;&&&&&&&&&case 1:&&&&&block[2][0] +=1;&block[3][0] +=1;&&&&&block[2][1] -=2;&block[3][1] -=2;&&&&&&&&&case 2:&&&&&block[2][0] -=2;&block[3][0] -=2;&&&&&block[2][1] -=1;&block[3][1] -=1;&&&&&&&&&case 3:&&&&&block[2][0] -=1;&block[3][0] -=1;&&&&&block[2][1] +=2;&block[3][1] +=2;&&&&&&&&&}&&&&
&&&case 5:&&&&flag=flag%4;&&&&switch(flag)&&&&{&&&&case 0:&&&&&block[2][0] +=1;&block[3][0] +=1;&&&&&block[2][1] +=2;&block[3][1] +=2;&&&&&&&&&case 1:&&&&&block[2][0] +=2;&block[3][0] +=2;&&&&&block[2][1] -=1;&block[3][1] -=1;&&&&&&&&&case 2:&&&&&block[2][0] -=1;&block[3][0] -=1;&&&&&block[2][1] -=2;&block[3][1] -=2;&&&&&&&&&case 3:&&&&&block[2][0] -=2;&block[3][0] -=2;&&&&&block[2][1] +=1;&block[3][1] +=1;&&&&&&&&&}&&&&
&&&case 6:&&&&flag =flag%4;&&&&switch(flag)&&&&{&&&&case 0:&&&&&block[0][0]++; block[0][1]--;&&&&&block[1][0]--; block[1][1]--;&&&&&block[3][0]++; block[3][1]++;&&&&&&&&&case 1:&&&&&block[1][0]++; block[1][1]++;&&&&case 2:&&&&&block[0][0]--; block[0][1]++;&&&&case 3:&&&&&block[3][0]--; block[3][1]--;&&&&}&&&&&&&}&&&&&}
&&// 判断【方块】旋转后新位置是否有【方格】,若有,则旋转取消&&for(i=0; i&4; i++)&&&if(cells[ block[i][0] ][ block[i][1] ])&&&{ &&&&if(r) flag +=3;&&&&for(i=0; i&4; i++)&&&&&for(j=0; j&2; j++)&&&&&&block[i][j]=org[i][j];&&&&return 0;&&&}&&SendMessage(hwnd, MS_DRAW, 0, 0);;&&return 0;
&&& // 清楚当前【方块】,并在显示“下一个方块”处绘制下一个【方块】&case MS_NEXTBLOCK:
&&&&&&& hdc=GetDC(hwnd);&& &&Cover(hdc,org2);//&&&DrawBlock(hdc,org2);
&&return 0;
&// 清除当前【方块】,并在新的位置重新绘制【方块】&case MS_DRAW:&&&hdc =GetDC (hwnd);&&Cover (hdc, org);
&&DrawBlock(hdc,org2);
&&for(i=0; i&4; i++)&&&for(j=0; j&2; j++)&&&&org[i][j]=block[i][j];
&&DrawBlock (hdc,block);&&ReleaseDC (hwnd, hdc);&&&&return 0;
&// 按照【方格矩阵】重绘游戏区域的【方格】&case WM_PAINT:&&&&hdc =BeginPaint (hwnd, &ps);&&DrawGamePlace(hdc);&&TextOut(hdc,15*CELL,12*CELL,"Score",lstrlen("Score"));&&&TextOut(hdc,15*CELL,13*CELL,"i",lstrlen("i"));&&TextOut(hdc,15*CELL,15*CELL,"Level",lstrlen("Level"));&&TextOut(hdc,15*CELL-5,19*CELL,"钱彦江",lstrlen("钱彦江"));&&hpen =CreatePen (PS_SOLID,1,RGB(0,255,0));&&SelectObject (hdc,hpen);&&for (i= i&H-1; i++)&&&for(j=1; j&=W-8; j++)&&&&if( cells[j][i] ) &&&&&DrawCell (hdc, (j-1)*CELL, (i-1)*CELL, j*CELL, i*CELL);&&&&&DeleteObject (hpen);&&EndPaint (hwnd, &ps);&&return 0;
&case WM_DESTROY:&&KillTimer (hwnd, 1);&&PostQuitMessage (0);&&return 0;&}
&return DefWindowProc (hwnd, iMsg, wParam, lParam);}
&/*************************-----结------束------*******************************/
论坛精华帖
文章来源于
软件测试技术文章排行榜
软件测试技术分类最新内容
版权所有(C)
TestAge()|| All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室
技术支持和业务联系:.cn 电话:010-
 |  |  |  |  |  |  | 博客访问: 1075885
博文数量: 121
博客积分: 3526
博客等级: 中校
技术积分: 1824
注册时间:
认证徽章:
记录总结自己的工作
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 嵌入式
&& &前几天看Android自带的例子代码,其中有个贪吃蛇的游戏,看了其代码后觉得写得非常好,同时又有了想写一个俄罗斯方块游戏的想法。俄罗斯方块的游戏我以前曾经用JAVA实现过,当时实现得很复杂,而现在有了这个贪吃蛇的例子后,实现起来就简单多了。在贪吃蛇游戏中有个类TileView.java,这个类基本实现了对单个方块的操作,因此我就直接拿来用了,并没有做任何的修改,这个类的代码就不在这里贴出了。
&& &俄罗斯方块游戏比贪吃蛇稍微复杂一些,其主要的难点主要有:
&& &1.实现方块的旋转。我们都知道在游戏中按上方块是要旋转的,我对方块的旋转就是选择一个方块作为中心,另外3个方块都绕着它顺时针旋转90度。需要注意的一点就是田形的方块是不需要旋转的,如果按照我的方法旋转田形方块就会造成方块平移的结果。
&& &2.边界的判定。就是判断一下方块是否可以移动,这包含两方面的内容,一方面是水平方向的移动,这里需要注意的就是在边界上旋转方块又可能使方块旋转出边界,所以在旋转前必要预先判断一下旋转后的方块是否已经超出了边界;另一方面是往下移动,一旦不能移动了就需要冻结方块并产生新的方块。
&& &3.消行。每落下一个方块都需要判断一下是否可以消行。而消行后上面的方块又都要垂直下落,同时原来的位置也要被清空。
&& &下面说一下实现这个游戏的步骤:
&& &1.创建一个新的ANDROID工程,命名为Tetris,包名为com.test。
&& &2.创建一个activity类,命名为:Tetris.java。
package com.test;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Tetris extends Activity {
&&&&private String TAG = "Tetris";
&&&&private TetrisView tetrisView;
&&&&private TextView highestScore;
&&&&private TextView info;
&&&&private TextView currentScore;
&&&&private TextView currentLevel;
&&&&String NAME = "score.txt";
&&&&&* 保存数据时用到的key
&&&&private static String ICICLE_KEY = "tetris-view";
&&&&&* 游戏的主要activity
&&&&public void onCreate(Bundle savedInstanceState) {
&&&&&&&&super.onCreate(savedInstanceState);
&&&&&&&&setContentView(R.layout.tetris_layout);
&&&&&&&&tetrisView = (TetrisView)findViewById(R.id.tetris);
&&&&&&&&highestScore = (TextView)findViewById(R.id.highest_score);
&&&&&&&&currentScore = (TextView)findViewById(R.id.current_score);
&&&&&&&&info = (TextView)findViewById(R.id.info);
&&&&&&&&currentLevel = (TextView)findViewById(R.id.current_level);
&&&&&&&&// 为view实例化这些文本框
&&&&&&&&tetrisView.setTextView(currentScore, highestScore, info, currentLevel);
&&&&&&&&if (savedInstanceState == null) {
&&&&&&&&&&&&// 开始一个新游戏,将游戏的状态设为READY
&&&&&&&&&&&&tetrisView.setMode(TetrisView.READY);
&&&&&&&&} else {
&&&&&&&&&&&&// 如果存储了一个游戏的状态,则将状态读出来,可以继续游戏
&&&&&&&&&&&&Bundle map = savedInstanceState.getBundle(ICICLE_KEY);
&&&&&&&&&&&&if (map != null) {
&&&&&&&&&&&&&&&&tetrisView.restoreState(map);
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&tetrisView.setMode(TetrisView.PAUSE);
&&&&&&&&&&&&}
&&&&&&&&// 读取历史最高分
&&&&&&&&FileInputStream in;
&&&&&&&&byte[] by = new byte[10];
&&&&&&&&try {
&&&&&&&&&&&&in = openFileInput(NAME);
&&&&&&&&&&&&in.read(by);
&&&&&&&&&&&&StringBuffer buffer = new StringBuffer();
&&&&&&&&&&&&for (int i = 0; i < 10; i++) {
&&&&&&&&&&&&&&&&if (by[i] != 0) {
&&&&&&&&&&&&&&&&&&&&buffer.append(by[i] - 48);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&Log.d("dd", buffer.toString());
&&&&&&&&&&&&tetrisView.historyScore = Long.valueOf(buffer.toString());
&&&&&&&&} catch (FileNotFoundException e) {
&&&&&&&&} catch (IOException e) {
&&&&&&&&&&&&// TODO Auto-generated catch block
&&&&&&&&&&&&e.printStackTrace();
&&&&@Override
&&&&protected void onPause() {
&&&&&&&&//如果分数超出了历史最高分,则保存数据
&&&&&&&&if (tetrisView.overhistroy) {
&&&&&&&&&&&&FileOutputStream fos;
&&&&&&&&&&&&try {
&&&&&&&&&&&&&&&&fos = openFileOutput(NAME, Context.MODE_PRIVATE);
&&&&&&&&&&&&&&&&fos.write(String.valueOf(TetrisView.historyScore).getBytes());
&&&&&&&&&&&&&&&&fos.close();
&&&&&&&&&&&&} catch (FileNotFoundException e) {
&&&&&&&&&&&&&&&&// TODO Auto-generated catch block
&&&&&&&&&&&&&&&&e.printStackTrace();
&&&&&&&&&&&&} catch (IOException e) {
&&&&&&&&&&&&&&&&// TODO Auto-generated catch block
&&&&&&&&&&&&&&&&e.printStackTrace();
&&&&&&&&&&&&}
&&&&&&&&super.onPause();
&&&&&&&&// 暂停游戏
&&&&&&&&tetrisView.setMode(TetrisView.PAUSE);
&&&&@Override
&&&&public void onSaveInstanceState(Bundle outState) {
&&&&&&&&// 保存游戏状态
&&&&&&&&outState.putBundle(ICICLE_KEY, tetrisView.saveState());
package com.test;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
public class TetrisView extends TileView {
&&&&private static final String TAG = "TetrisView";
&&&&&* 游戏的四种状态
&&&&private int mMode = READY;
&&&&public static final int PAUSE = 0;
&&&&public static final int READY = 1;
&&&&public static final int RUNNING = 2;
&&&&public static final int LOSE = 3;
&&&&&* 三种背景图片,由这些图片拼装成游戏的基本界面
&&&&private static final int RED_STAR = 1;
&&&&private static final int YELLOW_STAR = 2;
&&&&private static final int GREEN_STAR = 3;
&&&&&* 产生随机数,根据随机数决定方块的形状
&&&&private static final Random RNG = new Random();
&&&&&* 当前游戏的分数
&&&&private long mScore = 0;
&&&&&* 历史最高分
&&&&public static long historyScore = 0;
&&&&&* 是否超出了最高分,如果超出了,则在退出时会保存数据
&&&&public static boolean overhistroy=false;
&&&&&* 方块移动的速度,数值越小则方块的速度越高,难度也就越大
&&&&private long mMoveDelay;
&&&&&* 当前方块移动的速度,和mMoveDelay配合使用,在游戏中更改游戏的速度都是更改此变量值
&&&&&* 在每个方块产生的时候,将此变量值赋给mMoveDelay。之所以采用两个变量是因为当按下加速 方块落下之后,下一个方块的速度还要保持原来的速度。
&&&&private long currentDelay;
&&&&&* 预先显示的方块,在前一个方块落下后,使其变为当前方块
&&&&private ArrayList<Coordinate> preShape = new ArrayList<Coordinate>();
&&&&&* 当前正在下落的方块
&&&&private ArrayList<Coordinate> mShape = new ArrayList<Coordinate>();
&&&&private ArrayList<Coordinate> oldShape = new ArrayList<Coordinate>();
&&&&&* 显示历史最高分的文本框
&&&&private TextView highestScore;
&&&&&* 显示当前分数的文本框
&&&&private TextView currentScore;
&&&&&* 显示当前游戏级别的文本框
&&&&private TextView currentLevel;
&&&&&* 记录游戏的级别
&&&&private int gameLevel = 1;
&&&&&* 在屏幕中央显示提示信息的文本框
&&&&private TextView info;
&&&&&* 记录目前落下的方块的最高层数
&&&&private int highLevel = 0;
&&&&&* 当前方块类型,主要用来标示田形方块,从而在旋转方块的时候可以让田形方块不旋转
&&&&private int shapeType;
&&&&&* 预先显示方块的类型
&&&&private int preType;
&&&&&* 构造方法
&&&&public TetrisView(Context context, AttributeSet attrs) {
&&&&&&&&super(context, attrs);
&&&&&&&&initGame();
&&&&public TetrisView(Context context, AttributeSet attrs, int defStyle) {
&&&&&&&&super(context, attrs, defStyle);
&&&&&&&&initGame();
&&&&&* 通过一个handler来更新界面的显示,以及方块下落的速度
&&&&private RefreshHandler mRedrawHandler = new RefreshHandler();
&&&&class RefreshHandler extends Handler {
&&&&&&&&@Override
&&&&&&&&public void handleMessage(Message msg) {
&&&&&&&&&&&&TetrisView.this.update();
&&&&&&&&&&&&TetrisView.this.invalidate();
&&&&&&&&public void sleep(long delayMillis) {
&&&&&&&&&&&&this.removeMessages(0);
&&&&&&&&&&&&sendMessageDelayed(obtainMessage(0), delayMillis);
&&&&&* 初始化游戏
&&&&private void initGame() {
&&&&&&&&setFocusable(true);
&&&&&&&&Resources r = this.getContext().getResources();
&&&&&&&&resetTiles(4);
&&&&&&&&loadTile(RED_STAR, r.getDrawable(R.drawable.redstar));
&&&&&&&&loadTile(YELLOW_STAR, r.getDrawable(R.drawable.yellowstar));
&&&&&&&&loadTile(GREEN_STAR, r.getDrawable(R.drawable.greenstar));
&&&&&* 开始一个新游戏,重置各种数据
&&&&private void startGame() {
&&&&&&&&clearTiles();
&&&&&&&&gameLevel = 1;
&&&&&&&&highLevel = 0;
&&&&&&&&currentDelay = 600;
&&&&&&&&mScore = 0;
&&&&&&&&currentScore.setText("当前分数:\n" + mScore);
&&&&&&&&currentLevel.setText("当前级别:\n" + gameLevel);
&&&&&&&&highestScore.setText("最高分数:\n"+historyScore);
&&&&&&&&setMode(RUNNING);
&&&&&* 将arraylist转换为数组,从而可以将该部分数据保存起来
&&&&private int[] coordArrayListToArray(ArrayList<Coordinate> cvec) {
&&&&&&&&int count = cvec.size();
&&&&&&&&int[] rawArray = new int[count * 2];
&&&&&&&&for (int index = 0; index < count; index++) {
&&&&&&&&&&&&Coordinate c = cvec.get(index);
&&&&&&&&&&&&rawArray[2 * index] = c.x;
&&&&&&&&&&&&rawArray[2 * index + 1] = c.y;
&&&&&&&&return rawArray;
&&&&&* 将已经落下来的方块的坐标保存在一个ArrayList中
&&&&private ArrayList<Coordinate> tailsToList(int[][] tileGrid) {
&&&&&&&&ArrayList<Coordinate> tranList = new ArrayList<Coordinate>();
&&&&&&&&for (int i = 0; i < mXTileCount - 6; i++) {
&&&&&&&&&&&&for (int j = 1; j < mYTileCount - 1; j++) {
&&&&&&&&&&&&&&&&if (tileGrid[i][j] == RED_STAR) {
&&&&&&&&&&&&&&&&&&&&Coordinate cor = new Coordinate(i, j);
&&&&&&&&&&&&&&&&&&&&tranList.add(cor);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&return tranList;
&&&&&* 保存游戏的状态,从而在切换游戏后还可以继续游戏
&&&&&* @return a Bundle with this view's state
&&&&public Bundle saveState() {
&&&&&&&&Bundle map = new Bundle();
&&&&&&&&map.putIntArray("preShapeList", coordArrayListToArray(preShape));
&&&&&&&&map.putIntArray("mShapeList", coordArrayListToArray(mShape));
&&&&&&&&map.putLong("mMoveDelay", Long.valueOf(mMoveDelay));
&&&&&&&&map.putLong("mScore", Long.valueOf(mScore));
&&&&&&&&map.putLong("hisScore", Long.valueOf(historyScore));
&&&&&&&&map.putInt("mLevel", highLevel);
&&&&&&&&map.putIntArray("tailList", coordArrayListToArray(tailsToList(mTileGrid)));
&&&&&&&&return map;
&&&&&* 将数组转换为Arraylist,从而将保存的数据转化为游戏的状态
&&&&&* @param rawArray : [x1,y1,x2,y2,...]
&&&&&* @return a ArrayList of Coordinates
&&&&private ArrayList<Coordinate> coordArrayToArrayList(int[] rawArray) {
&&&&&&&&ArrayList<Coordinate> coordArrayList = new ArrayList<Coordinate>();
&&&&&&&&int coordCount = rawArray.length;
&&&&&&&&for (int index = 0; index < coordCount; index += 2) {
&&&&&&&&&&&&Coordinate c = new Coordinate(rawArray[index], rawArray[index + 1]);
&&&&&&&&&&&&coordArrayList.add(c);
&&&&&&&&return coordArrayList;
&&&&&* 从保存的数据中读取已经落下的方块坐标,并重新在界面上画出这些方块
&&&&private void listToTail(ArrayList<Coordinate> cor) {
&&&&&&&&int count = cor.size();
&&&&&&&&for (int index = 0; index < count; index++) {
&&&&&&&&&&&&Coordinate c = cor.get(index);
&&&&&&&&&&&&mTileGrid[c.x][c.y] = RED_STAR;
&&&&&* 切换到游戏的时候,读取所保存的数据,重现游戏先前的状态
&&&&&* @param icicle a Bundle containing the game state
&&&&public void restoreState(Bundle icicle) {
&&&&&&&&setMode(PAUSE);
&&&&&&&&historyScore = icicle.getLong("hisScore");
&&&&&&&&highLevel = icicle.getInt("mLevel");
&&&&&&&&mMoveDelay = icicle.getLong("mMoveDelay");
&&&&&&&&mScore = icicle.getLong("mScore");
&&&&&&&&preShape = coordArrayToArrayList(icicle.getIntArray("preShapeList"));
&&&&&&&&mShape = coordArrayToArrayList(icicle.getIntArray("mShapeList"));
&&&&&&&&listToTail(coordArrayToArrayList(icicle.getIntArray("tailList")));
&&&&&* 对按键的响应
&&&&public boolean onKeyDown(int keyCode, KeyEvent msg) {
&&&&&&&&// 按下了上键
&&&&&&&&if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
&&&&&&&&&&&&if (mMode == READY | mMode == LOSE) {
&&&&&&&&&&&&&&&&startGame();
&&&&&&&&&&&&&&&&setMode(RUNNING);
&&&&&&&&&&&&&&&&return (true);
&&&&&&&&&&&&} else if (mMode == RUNNING) {
&&&&&&&&&&&&&&&&transShape();
&&&&&&&&&&&&&&&&update();
&&&&&&&&&&&&&&&&return (true);
&&&&&&&&&&&&}
&&&&&&&&&&&&if (mMode == PAUSE) {
&&&&&&&&&&&&&&&&setMode(RUNNING);
&&&&&&&&&&&&&&&&update();
&&&&&&&&&&&&&&&&return (true);
&&&&&&&&&&&&}
&&&&&&&&// 按下了下键
&&&&&&&&if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
&&&&&&&&&&&&moveDown();
&&&&&&&&&&&&return (true);
&&&&&&&&// 按下了左键
&&&&&&&&if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
&&&&&&&&&&&&moveLeft();
&&&&&&&&&&&&updateShape();
&&&&&&&&&&&&return (true);
&&&&&&&&// 按下了右键
&&&&&&&&if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
&&&&&&&&&&&&moveRight();
&&&&&&&&&&&&updateShape();
&&&&&&&&&&&&return (true);
&&&&&&&&return super.onKeyDown(keyCode, msg);
&&&&&* 加速方块的下落
&&&&private void moveDown() {
&&&&&&&&mMoveDelay = 50;
&&&&&* 将方块向右移动,在移动前要判断一下是否可以移动
&&&&private void moveRight() {
&&&&&&&&newToOld(mShape, oldShape);
&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&c.x = c.x + 1;
&&&&&&&&// 如果不可以移动,则保持位置不变
&&&&&&&&if (!isMoveAble(mShape)) {
&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&c.x = c.x - 1;
&&&&&&&&&&&&}
&&&&&* 将方块向左移动
&&&&private void moveLeft() {
&&&&&&&&newToOld(mShape, oldShape);
&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&c.x = c.x - 1;
&&&&&&&&if (!isMoveAble(mShape)) {
&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&c.x = c.x + 1;
&&&&&&&&&&&&}
&&&&&* 旋转方块
&&&&private void transShape() {
&&&&&&&&Coordinate core = mShape.get(0);
&&&&&&&&if (shapeType == 3) {
&&&&&&&&&&&&// 田形,不用做任何事情
&&&&&&&&} else {
&&&&&&&&&&&&newToOld(mShape, oldShape);
&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&int x = core.x + (core.y - c.y);
&&&&&&&&&&&&&&&&int y = core.y + (c.x - core.x);
&&&&&&&&&&&&&&&&c.x = x;
&&&&&&&&&&&&&&&&c.y = y;
&&&&&&&&&&&&}
&&&&&&&&&&&&// 如果可以旋转,则旋转90度并更新显示
&&&&&&&&&&&&if (isMoveAble(mShape)) {
&&&&&&&&&&&&&&&&updateShape();
&&&&&&&&&&&&&&&&TetrisView.this.invalidate();
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&&&&&int x = core.x + (c.y - core.y);
&&&&&&&&&&&&&&&&&&&&int y = core.y + (core.x - c.x);
&&&&&&&&&&&&&&&&&&&&c.x = x;
&&&&&&&&&&&&&&&&&&&&c.y = y;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&* 将一个方块的形状赋给另外一个
&&&&&* @param mShape2
&&&&&* @param oldShape2
&&&&private void newToOld(ArrayList<Coordinate> mShape2, ArrayList<Coordinate> oldShape2) {
&&&&&&&&oldShape2.clear();
&&&&&&&&for (int i = 0; i < 4; i++) {
&&&&&&&&&&&&Coordinate c1 = mShape2.get(i);
&&&&&&&&&&&&Coordinate c2 = new Coordinate(c1.x, c1.y);
&&&&&&&&&&&&oldShape2.add(c2);
&&&&&* 处理游戏的更新
&&&&public void update() {
&&&&&&&&if (mMode == RUNNING) {
&&&&&&&&&&&&// clearTiles();
&&&&&&&&&&&&updateBlackGround();
&&&&&&&&&&&&if (mXTileCount != 0) {
&&&&&&&&&&&&&&&&// 如果是刚开始游戏,则初始化方块形状
&&&&&&&&&&&&&&&&if (mShape.size() == 0) {
&&&&&&&&&&&&&&&&&&&&shapeType = RNG.nextInt(7);
&&&&&&&&&&&&&&&&&&&&mShape = getShape(shapeType);
&&&&&&&&&&&&&&&&&&&&preType = RNG.nextInt(7);
&&&&&&&&&&&&&&&&&&&&preShape = getShape(preType);
&&&&&&&&&&&&&&&&&&&&mMoveDelay = currentDelay;
&&&&&&&&&&&&&&&&&&&&// 设置方块的初始位置
&&&&&&&&&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&&&&&&&&&c.x = c.x + mXTileCount / 3;
&&&&&&&&&&&&&&&&&&&&&&&&c.y = c.y + 1;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&// 将方块往下移动一格
&&&&&&&&&&&&&&&&newToOld(mShape, oldShape);
&&&&&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&&&&&c.y++;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&// 如果方块可以往下移动,则更新图形
&&&&&&&&&&&&&&&&if (canMoveDown(mShape)) {
&&&&&&&&&&&&&&&&&&&&updateShape();
&&&&&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&&&&&// 如果不可以往下移动则将方块的状态改为已落下并开始落下新方块
&&&&&&&&&&&&&&&&&&&&updateBlew();
&&&&&&&&&&&&&&&&&&&&mShape = preShape;
&&&&&&&&&&&&&&&&&&&&shapeType = preType;
&&&&&&&&&&&&&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&&&&&&&&&&&&&c.x = c.x + mXTileCount / 3;
&&&&&&&&&&&&&&&&&&&&&&&&c.y = c.y + 1;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&preType = RNG.nextInt(7);
&&&&&&&&&&&&&&&&&&&&preShape = getShape(preType);
&&&&&&&&&&&&&&&&&&&&mMoveDelay = currentDelay;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&updatePreShape();
&&&&&&&&&&&&}
&&&&&&&&// 设置方块落下的速度
&&&&&&&&mRedrawHandler.sleep(mMoveDelay);
&&&&// 方块落下过程中颜色为黄色
&&&&private void updateShape() {
&&&&&&&&for (Coordinate c : oldShape) {
&&&&&&&&&&&&setTile(0, c.x, c.y);
&&&&&&&&&&&&Log.d(TAG, "old" + c.x + c.y);
&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&Log.d(TAG, "new" + c.x + c.y);
&&&&&&&&&&&&if (mXTileCount != 0) {
&&&&&&&&&&&&&&&&setTile(YELLOW_STAR, c.x, c.y);
&&&&&&&&&&&&}
&&&&// 方块落下后颜色为红色
&&&&private void updateBlew() {
&&&&&&&&for (Coordinate c : mShape) {
&&&&&&&&&&&&if (mXTileCount != 0) {
&&&&&&&&&&&&&&&&setTile(RED_STAR, c.x, c.y - 1);
&&&&&&&&&&&&&&&&if (mYTileCount - c.y > highLevel) {
&&&&&&&&&&&&&&&&&&&&highLevel = mYTileCount - c.y;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&// GAME OVER
&&&&&&&&if (highLevel > mYTileCount - 3) {
&&&&&&&&&&&&setMode(LOSE);
&&&&&&&&// 已经消去的行数
&&&&&&&&int deleRows = 0;
&&&&&&&&for (int i = 1; i <= highLevel + 1; i++) {
&&&&&&&&&&&&int redCount = 0;
&&&&&&&&&&&&for (int x = 1; x < mXTileCount - 7; x++) {
&&&&&&&&&&&&&&&&if (mTileGrid[x][mYTileCount - i] == RED_STAR) {
&&&&&&&&&&&&&&&&&&&&redCount++;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&// 如果某一行的红色方格数等于列总数,则该列需要消去
&&&&&&&&&&&&if (redCount == mXTileCount -8 ) {
&&&&&&&&&&&&&&&&deleRows++;
&&&&&&&&&&&&&&&&continue;
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&// 将不需要消去的行向下移动,移动的幅度取决于前面消去的行数
&&&&&&&&&&&&&&&&if (deleRows != 0) {
&&&&&&&&&&&&&&&&&&&&for (int x = 1; x < mXTileCount - 6; x++) {
&&&&&&&&&&&&&&&&&&&&&&&&mTileGrid[x][mYTileCount - i + deleRows] = mTileGrid[x][mYTileCount - i];
&&&&&&&&&&&&&&&&&&&&&&&&mTileGrid[x][mYTileCount - i] = 0;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&// 更改分数,一次性消去的行数越多,得到的分数就越多
&&&&&&&&switch (deleRows) {
&&&&&&&&&&&&case 1:
&&&&&&&&&&&&&&&&mScore = mScore + 100;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 2:
&&&&&&&&&&&&&&&&mScore = mScore + 300;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 3:
&&&&&&&&&&&&&&&&mScore = mScore + 500;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 4:
&&&&&&&&&&&&&&&&mScore = mScore + 800;
&&&&&&&&&&&&&&&&break;
&&&&&&&&// 更新最高分
&&&&&&&&if (mScore > historyScore) {
&&&&&&&&&&&&overhistroy=true;
&&&&&&&&&&&&historyScore = mScore;
&&&&&&&&&&&&highestScore.setText("最高分数: \n" + historyScore);
&&&&&&&&// 更新当前分
&&&&&&&&currentScore.setText("当前分数:\n" + mScore);
&&&&&&&&// 当级别达到一定的程度后不再增加方块下落的速度
&&&&&&&&if (mScore >= (500 * (gameLevel * 2 - 1))) {
&&&&&&&&&&&&gameLevel++;
&&&&&&&&&&&&currentDelay -= 50;
&&&&&&&&&&&&if (currentDelay < 50)
&&&&&&&&&&&&&&&&currentDelay = 50;
&&&&&&&&// 更新当前级别
&&&&&&&&currentLevel.setText("当前级别:\n" + gameLevel);
&&&&&* 设置游戏的状态
&&&&&* @param newMode
&&&&public void setMode(int newMode) {
&&&&&&&&int oldMode = mMode;
&&&&&&&&mMode = newMode;
&&&&&&&&if (newMode == RUNNING & oldMode != RUNNING) {
&&&&&&&&&&&&info.setVisibility(View.INVISIBLE);
&&&&&&&&&&&&update();
&&&&&&&&&&&&return;
&&&&&&&&Resources res = getContext().getResources();
&&&&&&&&CharSequence str = "";
&&&&&&&&if (newMode == PAUSE) {
&&&&&&&&&&&&str = res.getText(R.string.mode_pause);
&&&&&&&&if (newMode == READY) {
&&&&&&&&&&&&str = res.getText(R.string.mode_ready);
&&&&&&&&if (newMode == LOSE) {
&&&&&&&&&&&&str = res.getString(R.string.mode_lose_prefix) + mScore
&&&&&&&&&&&&&&&&&&&&+ res.getString(R.string.mode_lose_suffix);
&&&&&&&&// 显示提示信息
&&&&&&&&info.setText(str);
&&&&&&&&info.setVisibility(View.VISIBLE);
&&&&&* 更新预先显示方块
&&&&private void updatePreShape() {
&&&&&&&&for (int x = mXTileCount - 4; x < mXTileCount; x++) {
&&&&&&&&&&&&for (int y = 1; y < 6; y++) {
&&&&&&&&&&&&&&&&setTile(0, x, y);
&&&&&&&&&&&&}
&&&&&&&&for (Coordinate c : preShape) {
&&&&&&&&&&&&if (mXTileCount != 0) {
&&&&&&&&&&&&&&&&setTile(YELLOW_STAR, c.x + mXTileCount - 3, c.y + 2);
&&&&&&&&&&&&}
&&&&&* 判断方块是否可以移动
&&&&&* @param list
&&&&&* @return
&&&&private boolean isMoveAble(ArrayList<Coordinate> list) {
&&&&&&&&boolean moveAble = true;
&&&&&&&&for (Coordinate c : list) {
&&&&&&&&&&&&if (mTileGrid[c.x][c.y] != GREEN_STAR && mTileGrid[c.x][c.y] != RED_STAR) {
&&&&&&&&&&&&&&&&continue;
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&moveAble = false;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&}
&&&&&&&&return moveAble;
&&&&&* 判断方块是否可以往下移动
&&&&&* @param list
&&&&&* @return
&&&&private boolean canMoveDown(ArrayList<Coordinate> list) {
&&&&&&&&boolean moveAble = true;
&&&&&&&&for (Coordinate c : list) {
&&&&&&&&&&&&if (c.y < mYTileCount - 1 && mTileGrid[c.x][c.y] != RED_STAR) {
&&&&&&&&&&&&&&&&continue;
&&&&&&&&&&&&} else {
&&&&&&&&&&&&&&&&moveAble = false;
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&}
&&&&&&&&return moveAble;
&&&&&* 画出游戏的背景.即游戏的边框
&&&&private void updateBlackGround() {
&&&&&&&&for (int x = 0; x < mXTileCount - 5; x++) {
&&&&&&&&&&&&setTile(GREEN_STAR, x, 0);
&&&&&&&&&&&&setTile(GREEN_STAR, x, mYTileCount - 1);
&&&&&&&&for (int y = 1; y < mYTileCount - 1; y++) {
&&&&&&&&&&&&setTile(GREEN_STAR, 0, y);
&&&&&&&&&&&&setTile(GREEN_STAR, mXTileCount - 6, y);
&&&&&* 根据随机数产生各种形状的方块
&&&&&* @param n
&&&&&* @return
&&&&private ArrayList<Coordinate> getShape(int n) {
&&&&&&&&ArrayList<Coordinate> shape = new ArrayList<Coordinate>();
&&&&&&&&switch (n) {
&&&&&&&&&&&&case 1:
&&&&&&&&&&&&&&&&// 反Z拐角
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 1));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 2:
&&&&&&&&&&&&&&&&// 正Z拐角
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 1));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 3:
&&&&&&&&&&&&&&&&// 田形
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 1));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 4:
&&&&&&&&&&&&&&&&// 长条
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(2, 0));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 5:
&&&&&&&&&&&&&&&&// 长左拐形
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 2));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 6:
&&&&&&&&&&&&&&&&// 长右拐形
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 2));
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&case 0:
&&&&&&&&&&&&&&&&// 凸形
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(-1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(1, 0));
&&&&&&&&&&&&&&&&shape.add(new Coordinate(0, 1));
&&&&&&&&&&&&&&&&break;
&&&&&&&&return shape;
&&&&public void setTextView(TextView curView, TextView higView, TextView infView, TextView levView) {
&&&&&&&&currentScore = curView;
&&&&&&&&highestScore = higView;
&&&&&&&&info = infView;
&&&&&&&&currentLevel = levView;
&&&&&* 用来标示某一坐标上的方块
&&&&private class Coordinate {
&&&&&&&&public int x;
&&&&&&&&public int y;
&&&&&&&&public Coordinate(int newX, int newY) {
&&&&&&&&&&&&x = newX;
&&&&&&&&&&&&y = newY;
&&&&&&&&public boolean equals(Coordinate other) {
&&&&&&&&&&&&if (x == other.x && y == other.y) {
&&&&&&&&&&&&&&&&return true;
&&&&&&&&&&&&}
&&&&&&&&&&&&return false;
&&&&&&&&public String toString() {
&&&&&&&&&&&&return "Coordinate: [" + x + "," + y + "]";
&& 4.创建类TileView.java。该类是从贪吃蛇中复制过来的,没做任何修改,可以直接拿来用。可
以在sdk的smples/android 2.x.x/Snake目录中找到。
&& 5.将贪吃蛇游戏res/drawable目录下的三个图片文件复制到自己工程的res/drawable目录中,如果没有这个目录可以创建或者放在其他的drawable-xxx目录中。
&& 6.创建布局文件tetris_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
&&&&xmlns:android="/apk/res/android"
&&&&android:layout_width="match_parent"
&&&&android:layout_height="match_parent">
&&&&<com.test.TetrisView
&&&&&&&&android:id="@+id/tetris"
&&&&&&&&android:layout_width="match_parent"
&&&&&&&&android:layout_height="match_parent"
&&&&&&&&tileSize="24" />
&&&&<RelativeLayout
&&&&&&&&android:layout_width="match_parent"
&&&&&&&&android:layout_height="match_parent">
&&&&&&&&<TextView
&&&&&&&&&&&&android:id="@+id/info"
&&&&&&&&&&&&android:text="@string/mode_ready"
&&&&&&&&&&&&android:visibility="visible"
&&&&&&&&&&&&android:layout_width="wrap_content"
&&&&&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&&&&&android:layout_centerInParent="true"
&&&&&&&&&&&&android:gravity="center_horizontal"
&&&&&&&&&&&&android:textColor="#ff8888ff"
&&&&&&&&&&&&android:textSize="20sp" />
&&&&&&&&<TextView
&&&&&&&&&&&&android:id="@+id/current_score"
&&&&&&&&&&&&android:text="当前分数:\n 0"
&&&&&&&&&&&&android:visibility="visible"
&&&&&&&&&&&&android:layout_width="wrap_content"
&&&&&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&&&&&android:layout_centerVertical="true"
&&&&&&&&&&&&android:layout_alignParentRight="true"
&&&&&&&&&&&&android:textColor="#ff8888ff"
&&&&&&&&&&&&android:textSize="16sp" />
&&&&&&&&<TextView
&&&&&&&&&&&&android:id="@+id/highest_score"
&&&&&&&&&&&&android:text="最高分数:\n 0"
&&&&&&&&&&&&android:visibility="visible"
&&&&&&&&&&&&android:layout_width="wrap_content"
&&&&&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&&&&&android:layout_above="@id/current_score"
&&&&&&&&&&&&android:layout_alignParentRight="true"
&&&&&&&&&&&&android:textColor="#ff8888ff"
&&&&&&&&&&&&android:textSize="16sp" />
&&&&&&&&<TextView
&&&&&&&&&&&&android:id="@+id/current_level"
&&&&&&&&&&&&android:text="当前级别:\n 1"
&&&&&&&&&&&&android:visibility="visible"
&&&&&&&&&&&&android:layout_width="wrap_content"
&&&&&&&&&&&&android:layout_height="wrap_content"
&&&&&&&&&&&&android:layout_below="@id/current_score"
&&&&&&&&&&&&android:layout_alignParentRight="true"
&&&&&&&&&&&&android:textColor="#ff8888ff"
&&&&&&&&&&&&android:textSize="16sp" />
&&&&</RelativeLayout>
</FrameLayout>
&&7.打开res/values/strings.xml,将其修改为以下内容:
<?xml version="1.0" encoding="utf-8"?>
<resources>
&&&&<string
&&&&&&&&name="app_name">Tetris</string>
&&&&<string
&&&&&&&&name="mode_ready">\n按上开始游戏 </string>
&&&&<string
&&&&&&&&name="mode_pause"> 暂停\n按上继续游戏 </string>
&&&&<string
&&&&&&&&name="mode_lose_prefix">Game Over\nScore: </string>
&&&&<string
&&&&&&&&name="mode_lose_suffix">\n按上重新开始游戏 </string>
</resources>
&& &8.打开AndroidManifest.xml,修改其内容如下:
<?xml version="1.0" encoding="utf-8"?>
&&&&xmlns:android="/apk/res/android"
&&&&package="com.test"
&&&&android:versionCode="1"
&&&&android:versionName="1.0">
&&&&<application
&&&&&&&&android:icon="@drawable/icon"
&&&&&&&&android:label="@string/app_name">
&&&&&&&&<activity
&&&&&&&&&&&&android:name=".Tetris"
&&&&&&&&&&&&android:theme="@android:style/Theme.NoTitleBar"
&&&&&&&&&&&&android:screenOrientation="portrait"
&&&&&&&&&&&&android:configChanges="keyboardHidden|orientation">
&&&&&&&&&&&&<intent-filter>
&&&&&&&&&&&&&&&&<action
&&&&&&&&&&&&&&&&&&&&android:name="android.intent.action.MAIN" />
&&&&&&&&&&&&&&&&<category
&&&&&&&&&&&&&&&&&&&&android:name="android.intent.category.LAUNCHER" />
&&&&&&&&&&&&</intent-filter>
&&&&&&&&</activity>
&&&&</application>
</manifest>
&& &至此,一个简单的俄罗斯方块游戏就完成了,游戏运行时的图片为:
& & 项目源码请移步
阅读(9989) | 评论(2) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
:您好,可以分享这整个项目所有资源给我吗?我是个初学者
源码已经附上了 |
您好,可以分享这整个项目所有资源给我吗?我是个初学者
请登录后评论。

我要回帖

更多关于 俄罗斯方块高清版 的文章

 

随机推荐