游戏界面预览:
菜单预览:
自定义每个小方块颜色功能界面:
游戏主要有四部分组成:Square类,Block类,gameField类,游戏引擎
Square类:
这个类描述的对象是组成大方块中的每个小正方形实体。
类设计:
class Square
{
public Point location; //小方块的坐标
public Size size; //小方块大小
public Color foreColor; //小方块前景色
public Color backColor; //小方块背景色
public Square(Size initSize,Color initForeColor,Color initBackColor) //构造函数
{ ……}
public void Draw(SystemIntPtr winHandle) //在指定设备上画方块
{ …… }
public void Erase(SystemIntPtr winHandle)//擦除方块
{ …… }
}
Block类:
这个类描述的对象是某一个大方块的实体。每个大方块由四个小正方形组成,一共有7种组合方式。这个类需要实现一个大方块实体所有的属性和动作。包括:方块的形状,位置,方块左移,右移,下移,旋转等。
类设计:
class Block
{
public Square square1; //组成block的四个小方块
public Square square2;
public Square square3;
public Square square4; private const int squareSize = GameFieldSquareSize; //小方块的边长
public enum BlockTypes
{
undefined = 0,
square = 1,
line = 2,
J = 3,
L = 4,
T = 5,
Z = 6,
S = 7
};//一共有7种形状
public BlockTypes blockType; //方块的形状
//七个小方块的颜色数组
private Color foreColor;
private Color backColor;
//方块的方向
public enum RotateDirections
{
North = 1,
East = 2,
South = 3,
West = 4
};
public RotateDirections myRotation = RotateDirectionsNorth;
public Block(Point thisLocation,BlockTypes bType)
{ ……}
//含有自定义颜色的重载
public Block(Point thisLocation, BlockTypes bType,Color fc,Color bc)
{ ……} /画方块/
public void Draw(SystemIntPtr winHandle)
{…… }
/擦方块/
public void Erase(SystemIntPtr winHandle)
{…… } /移动/
public bool down()
{……}
public bool left()
{……}
public bool right()
{……}
/旋转block/
public void Rotate()
{……}
/检测是否到顶/
public int Top()
{……}
}
GameField类:
这个类描述的对象是游戏场景实体,包括场景的背景色,大小,方块是否还可以移动,以及场景中填满一行的检测等。
类设计:
class GameField
{
public const int width = 20; //场景的宽,以方块个数为单位
public const int height = 30;
public const int SquareSize = 15; //每个四分之一小方块的边长
public static Color BackColor; //场景的背景色
public static SystemIntPtr winHandle; //场景的handle
public static Color[] BlockForeColor ={ ColorBlue, ColorBeige, ColorDarkKhaki, ColorDarkMagenta, ColorDarkOliveGreen, ColorDarkOrange, ColorDarkRed };
public static Color[] BlockBackColor ={ ColorLightCyan, ColorDarkSeaGreen, ColorBeige, ColorBeige, ColorBeige, ColorBeige, ColorBeige };
public static bool isChanged=false; //设置是否被更改的标志位
public static SoundPlayer sound = new SoundPlayer(); //播放声音 public static Square[,] arriveBlock = new Square[width, height]; //保存已经不能再下落了的方块
public static int[] arrBitBlock=new int[height]; //位数组:当某个位置有方块时,该行的该位为1
private const int bitEmpty = 0x0; //0000 0000 0000 0000 0000
private const int bitFull = 0xFFFFF; //1111 1111 1111 1111 1111 /检测某个位置是否为空/
public static bool isEmpty(int x, int y)
{……}
/将方块停住/
public static void stopSquare(Square sq, int x, int y)
{……}
/检测行是否满
返回:成功消除的行数和 (方便统计分数)
/
public static int CheckLines()
{ ……}
/播放声音/
public static void PlaySound(string soundstr)
{……}
/重画/
public static void Redraw()
{ …… }
//结束
}
游戏引擎:
游戏引擎正如其名,就像一个发动机一样让游戏不间断运行。本游戏中就是让方块以一定的速度下落。并响应键盘事件,实行左右移动,和向下加速功能。(代码见源码)
声音播放:
音效是游戏不可缺少的一部分。在Net20中已经提供了一个类来播放声音。在using SystemMedia;命名空间。
本游戏中播放声音的代码如下:(在 GameField类中)
using SystemMedia;
public static SoundPlayer sound = new SoundPlayer();
/播放声音/
public static void PlaySound(string soundstr)
{
switch (soundstr)
{
case "FinishOneLine": //消除一行的声音
if (!FileExists("FinishOneLinewav")) return;
soundSoundLocation = "FinishOneLinewav";
break;
case "CanNotDo": //当无法 *** 作时
if (!FileExists("CanNotDowav")) return;
soundSoundLocation = "CanNotDowav";
break;
}
soundPlay();
}
要播放的时候调用PlaySound()方法即可。
其实步骤很简单,先引用SystemMedia空间,然后创建一个SoundPlayer 对象,用SoundLocation 属性设置声音文件的地址,然后调用Play()方法即可播放。不过注意,这个类可以播放的声音格式只有Wav文件。
保存游戏设置:
在游戏中经常要保存用户自定义的设置。本游戏通过写进ini文件来保存。
主要代码如:
/加载窗体时从配置文件Settingini中读取游戏设置/
private void getSettings()
{
if (!FileExists("Settingini"))
return;
FileStream fs = new FileStream("Settingini", FileModeOpenOrCreate, FileAccessReadWrite);
StreamReader sr = new StreamReader(fs);
string line1=srReadLine();
string line2=srReadLine();
string line3=srReadLine();
if (line1 != null && line1Split('=')Length > 1)
{
GameFieldBackColor = ColorFromArgb(intParse(line1Split('=')[1]));
picBackGroundBackColor = GameFieldBackColor;
}
if (line2 != null && line2Split('=')Length > 1)
GameFieldBlockForeColor = strToColor(line2Split('=')[1]);
if (line3 != null && line3Split('=')Length > 1)
GameFieldBlockBackColor = strToColor(line3Split('=')[1]);
srClose();
fsClose();
}
/如果游戏设置被更改,将新的设置保存到Settingini/
private void saveSettings()
{
FileStream fs = new FileStream("Settingini", FileModeCreate, FileAccessReadWrite);
StreamWriter sw = new StreamWriter(fs);
swWriteLine("GameFieldColor="+GameFieldBackColorToArgb());
swWriteLine("BlockFroeColor=" + colorToStr(GameFieldBlockForeColor));
swWriteLine("BlockBackColor=" + colorToStr(GameFieldBlockBackColor));
swFlush();
swClose();
fsClose();
}
要源码+QQ348199903
俄罗斯方块——java源代码提供 import javaawt; import javaawtevent; //俄罗斯方块类 public class ERS_Block extends Frame{ public static boolean isPlay=false; public static int level=1,score=0; public static TextField scoreField,levelField; public static MyTimer timer; GameCanvas gameScr; public static void main(String[] argus){ ERS_Block ers = new ERS_Block("俄罗斯方块游戏 V10 Author:Vincent"); WindowListener win_listener = new WinListener(); ersaddWindowListener(win_listener); } //俄罗斯方块类的构造方法 ERS_Block(String title){ super(title); setSize(600,480); setLayout(new GridLayout(1,2)); gameScr = new GameCanvas(); gameScraddKeyListener(gameScr); timer = new MyTimer(gameScr); timersetDaemon(true); timerstart(); timersuspend(); add(gameScr); Panel rightScr = new Panel(); rightScrsetLayout(new GridLayout(2,1,0,30)); rightScrsetSize(120,500); add(rightScr); //右边信息窗体的布局 MyPanel infoScr = new MyPanel(); infoScrsetLayout(new GridLayout(4,1,0,5)); infoScrsetSize(120,300); rightScradd(infoScr); //定义标签和初始值 Label scorep = new Label("分数:",LabelLEFT); Label levelp = new Label("级数:",LabelLEFT); scoreField = new TextField(8); levelField = new TextField(8); scoreFieldsetEditable(false); levelFieldsetEditable(false); infoScradd(scorep); infoScradd(scoreField); infoScradd(levelp); infoScradd(levelField); scorepsetSize(new Dimension(20,60)); scoreFieldsetSize(new Dimension(20,60)); levelpsetSize(new Dimension(20,60)); levelFieldsetSize(new Dimension(20,60)); scoreFieldsetText("0"); levelFieldsetText("1"); //右边控制按钮窗体的布局 MyPanel controlScr = new MyPanel(); controlScrsetLayout(new GridLayout(5,1,0,5)); rightScradd(controlScr); //定义按钮play Button play_b = new Button("开始游戏"); play_bsetSize(new Dimension(50,200)); play_baddActionListener(new Command(Commandbutton_play,gameScr)); //定义按钮Level UP Button level_up_b = new Button("提高级数"); level_up_bsetSize(new Dimension(50,200)); level_up_baddActionListener(new Command(Commandbutton_levelup,gameScr)); //定义按钮Level Down Button level_down_b =new Button("降低级数"); level_down_bsetSize(new Dimension(50,200)); level_down_baddActionListener(new Command(Commandbutton_leveldown,gameScr)); //定义按钮Level Pause Button pause_b =new Button("游戏暂停"); pause_bsetSize(new Dimension(50,200)); pause_baddActionListener(new Command(Commandbutton_pause,gameScr)); //定义按钮Quit Button quit_b = new Button("退出游戏"); quit_bsetSize(new Dimension(50,200)); quit_baddActionListener(new Command(Commandbutton_quit,gameScr)); controlScradd(play_b); controlScradd(level_up_b); controlScradd(level_down_b); controlScradd(pause_b); controlScradd(quit_b); setVisible(true); gameScrrequestFocus(); } } //重写MyPanel类,使Panel的四周留空间 class MyPanel extends Panel{ public Insets getInsets(){ return new Insets(30,50,30,50); } } //游戏画布类 class GameCanvas extends Canvas implements KeyListener{ final int unitSize = 30; //小方块边长 int rowNum; //正方格的行数 int columnNum; //正方格的列数 int maxAllowRowNum; //允许有多少行未削 int blockInitRow; //新出现块的起始行坐标 int blockInitCol; //新出现块的起始列坐标 int [][] scrArr; //屏幕数组 Block b; //对方快的引用 //画布类的构造方法 GameCanvas(){ rowNum = 15; columnNum = 10; maxAllowRowNum = rowNum - 2; b = new Block(this); blockInitRow = rowNum - 1; blockInitCol = columnNum/2 - 2; scrArr = new int [32][32]; } //初始化屏幕,并将屏幕数组清零的方法 void initScr(){ for(int i=0;i<rowNum;i++) for (int j=0; j<columnNum;j++) scrArr[j]=0; breset(); repaint(); } //重新刷新画布方法 public void paint(Graphics g){ for(int i = 0; i < rowNum; i++) for(int j = 0; j < columnNum; j++) drawUnit(i,j,scrArr[j]); } //画方块的方法 public void drawUnit(int row,int col,int type){ scrArr[row][col] = type; Graphics g = getGraphics(); tch(type){ //表示画方快的方法 case 0: gsetColor(Colorblack);break; //以背景为颜色画 case 1: gsetColor(Colorblue);break; //画正在下落的方块 case 2: gsetColor(Colormagenta);break; //画已经落下的方法 } gfill3DRect(colunitSize,getSize()height-(row+1)unitSize,unitSize,unitSize,true); gdispose(); } public Block getBlock(){ return b; //返回block实例的引用 } //返回屏幕数组中(row,col)位置的属性值 public int getScrArrXY(int row,int col){ if (row < 0 || row >= rowNum || col < 0 || col >= columnNum) return(-1); else return(scrArr[row][col]); } //返回新块的初始行坐标方法 public int getInitRow(){ return(blockInitRow); //返回新块的初始行坐标 } //返回新块的初始列坐标方法 public int getInitCol(){ return(blockInitCol); //返回新块的初始列坐标 } //满行删除方法 void deleteFullLine(){ int full_line_num = 0; int k = 0; for (int i=0;i<rowNum;i++){ boolean isfull = true; L1:for(int j=0;j<columnNum;j++) if(scrArr[j] == 0){ k++; isfull = false; break L1; } if(isfull) full_line_num++; if(k!=0 && k-1!=i && !isfull) for(int j = 0; j < columnNum; j++){ if (scrArr[j] == 0) drawUnit(k-1,j,0); else drawUnit(k-1,j,2); scrArr[k-1][j] = scrArr[j]; } } for(int i = k-1 ;i < rowNum; i++){ for(int j = 0; j < columnNum; j++){ drawUnit(i,j,0); scrArr[j]=0; } } ERS_Blockscore += full_line_num; ERS_BlockscoreFieldsetText(""+ERS_Blockscore); } //判断游戏是否结束方法 boolean isGameEnd(){ for (int col = 0 ; col <columnNum; col ++){ if(scrArr[maxAllowRowNum][col] !=0) return true; } return false; } public void keyTyped(KeyEvent e){ } public void keyReleased(KeyEvent e){ } //处理键盘输入的方法 public void keyPressed(KeyEvent e){ if(!ERS_BlockisPlay) return; tch(egetKeyCode()){ case KeyEventVK_DOWN:bfallDown();break; case KeyEventVK_LEFT:bleftMove();break; case KeyEventVK_RIGHT:brightMove();break; case KeyEventVK_SPACE:bleftTurn();break; } } } //处理控制类 class Command implements ActionListener{ static final int button_play = 1; //给按钮分配编号 static final int button_levelup = 2; static final int button_leveldown = 3; static final int button_quit = 4; static final int button_pause = 5; static boolean pause_resume = true; int curButton; //当前按钮 GameCanvas scr; //控制按钮类的构造方法 Command(int button,GameCanvas scr){ curButton = button; thisscr=scr; } //按钮执行方法 public void actionPerformed (ActionEvent e){ tch(curButton){ case button_play:if(!ERS_BlockisPlay){ scrinitScr(); ERS_BlockisPlay = true; ERS_Blockscore = 0; ERS_BlockscoreFieldsetText("0"); ERS_Blocktimerresume(); } scrrequestFocus(); break; case button_levelup:if(ERS_Blocklevel < 10){ ERS_Blocklevel++; ERS_BlocklevelFieldsetText(""+ERS_Blocklevel); ERS_Blockscore = 0; ERS_BlockscoreFieldsetText(""+ERS_Blockscore); } scrrequestFocus(); break; case button_leveldown:if(ERS_Blocklevel > 1){ ERS_Blocklevel--; ERS_BlocklevelFieldsetText(""+ERS_Blocklevel); ERS_Blockscore = 0; ERS_BlockscoreFieldsetText(""+ERS_Blockscore); } scrrequestFocus(); break; case button_pause:if(pause_resume){ ERS_Blocktimersuspend(); pause_resume = false; }else{ ERS_Blocktimerresume(); pause_resume = true; } scrrequestFocus(); break; case button_quit:Systemexit(0); } } } //方块类 class Block { static int[][] pattern = { {0x0f00,0x4444,0x0f00,0x4444},//用十六进至表示,本行表示长条四种状态 {0x04e0,0x0464,0x00e4,0x04c4}, {0x4620,0x6c00,0x4620,0x6c00}, {0x2640,0xc600,0x2640,0xc600}, {0x6220,0x1700,0x2230,0x0740}, {0x6440,0x0e20,0x44c0,0x8e00}, {0x0660,0x0660,0x0660,0x0660} }; int blockType; //块的模式号(0-6) int turnState; //块的翻转状态(0-3) int blockState; //快的下落状态 int row,col; //块在画布上的坐标 GameCanvas scr; //块类的构造方法 Block(GameCanvas scr){ thisscr = scr; blockType = (int)(Mathrandom() 1000)%7; turnState = (int)(Mathrandom() 1000)%4; blockState = 1; row = scrgetInitRow(); col = scrgetInitCol(); } //重新初始化块,并显示新块 public void reset(){ blockType = (int)(Mathrandom() 1000)%7; turnState = (int)(Mathrandom() 1000)%4; blockState = 1; row = scrgetInitRow(); col = scrgetInitCol(); dispBlock(1); } //实现“块”翻转的方法 public void leftTurn(){ if(assertValid(blockType,(turnState + 1)%4,row,col)){ dispBlock(0); turnState = (turnState + 1)%4; dispBlock(1); } } //实现“块”的左移的方法 public void leftMove(){ if(assertValid(blockType,turnState,row,col-1)){ dispBlock(0); col--; dispBlock(1); } } //实现块的右移 public void rightMove(){ if(assertValid(blockType,turnState,row,col+1)){ dispBlock(0); col++; dispBlock(1); } } //实现块落下的 *** 作的方法 public boolean fallDown(){ if(blockState == 2) return(false); if(assertValid(blockType,turnState,row-1,col)){ dispBlock(0); row--; dispBlock(1); return(true); }else{ blockState = 2; dispBlock(2); return(false); } } //判断是否正确的方法 boolean assertValid(int t,int s,int row,int col){ int k = 0x8000; for(int i = 0; i < 4; i++){ for(int j = 0; j < 4; j++){ if((int)(pattern[t][s]&k) != 0){ int temp = scrgetScrArrXY(row-i,col+j); if (temp<0||temp==2) return false; } k = k >> 1; } } return true; } //同步显示的方法 public synchronized void dispBlock(int s){ int k = 0x8000; for (int i = 0; i < 4; i++){ for(int j = 0; j < 4; j++){ if(((int)pattern[blockType][turnState]&k) != 0){ scrdrawUnit(row-i,col+j,s); } k=k>>1; } } } } //定时线程 class MyTimer extends Thread{ GameCanvas scr; public MyTimer(GameCanvas scr){ thisscr = scr; } public void run(){ while(true){ try{ sleep((10-ERS_Blocklevel + 1)100); } catch(InterruptedException e){} if(!scrgetBlock()fallDown()){ scrdeleteFullLine(); if(scrisGameEnd()){ ERS_BlockisPlay = false; suspend(); }else scrgetBlock()reset(); } } } } class WinListener extends WindowAdapter{ public void windowClosing (WindowEvent l){ Systemexit(0); } } 22
#include<stdioh>
#include<stringh>
#include<biosh>
#include<stdlibh>
#include<timeh>
#include<dosh>
int dx[4],dy[4]; /定义全局变量/
int zt1,zt2,str[15][19];
/str[15][19]是把整个屏幕分为1519个方格,每一个方格用一个数组单元表示,
如果=15,则这个方格已被占用,=0,则还是空的/
int cx[8][5][4],cy[8][5][4]; /该变量表示每种状态下,旋转时坐标的改变/
int x,y,j,ji,c;
int maxzt[8]={0,2,1,4,2,2,4,4}; /各个种类的方块分别有几种状态/
cir() /旋转的处理函数/
{ dx[0]=dx[0]+cx[zt1][zt2][0];dy[0]=dy[0]+cy[zt1][zt2][0];
dx[2]=dx[2]+cx[zt1][zt2][2];dy[2]=dy[2]+cy[zt1][zt2][2];
dx[3]=dx[3]+cx[zt1][zt2][3];dy[3]=dy[3]+cy[zt1][zt2][3];
}
jiance() /检测旋转或移动能否进行的函数,能则j=1,不能j=0/
{ j=1;
for(ji=0;ji<4;ji++)
{ x=dx[ji];y=dy[ji];
if(str[x][y]!=' ') j=0;
}
c=bioskey(1);
if(c!=0) c=bioskey(0);
}
main()
{ int dotx[4],doty[4],score; /dotx[]doty[]表示一个方块个点的坐标/
int ddx,ddy;
int rzt1,rzt2,i,u,t=1;
int a[5],b[11],o,p,an,bn;
int rotx[4],roty[4],spd=0;
begin: system("cls"); /游戏初始化阶段/
printf("londing");
for(i=0;i<12;i++) /变量初始阶段/
{ for(u=0;u<19;u++)
str[i][u]=' ';
}
for(i=0;i<12;i++)
{ str[i][0]='-';str[i][18]='-'; }
for(u=0;u<19;u++)
{ str[0][u]='|';str[11][u]='|'; }
cx[1][1][0]=1;cx[1][1][2]=-1;cx[1][1][3]=-2; /对旋转变量进行赋值/
cy[1][1][0]=1;cy[1][1][2]=-1;cy[1][1][3]=-2;
cx[1][2][0]=-1;cx[1][2][2]=1;cx[1][2][3]=2;
cy[1][2][0]=-1;cy[1][2][2]=1;cy[1][2][3]=2;
cx[2][1][0]=0;cx[2][1][2]=0;cx[2][1][3]=0;
cy[2][1][0]=0;cy[2][1][2]=0;cy[2][1][3]=0;
cx[3][1][0]=1;cx[3][1][2]=-1;cx[3][1][3]=1;
cy[3][1][0]=-1;cy[3][1][2]=1;cy[3][1][3]=1;
cx[3][2][0]=1;cx[3][2][2]=-1;cx[3][2][3]=-1;
cy[3][2][0]=1;cy[3][2][2]=-1;cy[3][2][3]=1;
cx[3][3][0]=-1;cx[3][3][2]=1;cx[3][3][3]=-1;
cy[3][3][0]=1;cy[3][3][2]=-1;cy[3][3][3]=-1;
cx[3][4][0]=-1;cx[3][4][2]=1;cx[3][4][3]=1;
cy[3][4][0]=-1;cy[3][4][2]=1;cy[3][4][3]=-1;
cx[4][1][0]=-1;cx[4][1][2]=1;cx[4][1][3]=2;
cy[4][1][0]=1;cy[4][1][2]=1;cy[4][1][3]=0;
cx[4][2][0]=1;cx[4][2][2]=-1;cx[4][2][3]=-2;
cy[4][2][0]=-1;cy[4][2][2]=-1;cy[4][2][3]=0;
cx[5][1][0]=1;cx[5][1][2]=1;cx[5][1][3]=0;
cy[5][1][0]=-1;cy[5][1][2]=1;cy[5][1][3]=2;
cx[5][2][0]=-1;cx[5][2][2]=-1;cx[5][2][3]=0;
cy[5][2][0]=1;cy[5][2][2]=-1;cy[5][2][3]=-2;
cx[6][1][0]=1;cx[6][1][2]=-1;cx[6][1][3]=0;
cy[6][1][0]=-1;cy[6][1][2]=1;cy[6][1][3]=2;
cx[6][2][0]=1;cx[6][2][2]=-1;cx[6][2][3]=-2;
cy[6][2][0]=1;cy[6][2][2]=-1;cy[6][2][3]=0;
cx[6][3][0]=-1;cx[6][3][2]=1;cx[6][3][3]=0;
cy[6][3][0]=1;cy[6][3][2]=-1;cy[6][3][3]=-2;
cx[6][4][0]=-1;cx[6][4][2]=1;cx[6][4][3]=2;
cy[6][4][0]=-1;cy[6][4][2]=1;cy[6][4][3]=0;
cx[7][1][0]=-1;cx[7][1][2]=1;cx[7][1][3]=2;
cy[7][1][0]=1;cy[7][1][2]=-1;cy[7][1][3]=0;
cx[7][2][0]=-1;cx[7][2][2]=1;cx[7][2][3]=0;
cy[7][2][0]=-1;cy[7][2][2]=1;cy[7][2][3]=2;
cx[7][3][0]=1;cx[7][3][2]=-1;cx[7][3][3]=-2;
cy[7][3][0]=-1;cy[7][3][2]=1;cy[7][3][3]=0;
cx[7][4][0]=1;cx[7][4][2]=-1;cx[7][4][3]=0;
cy[7][4][0]=1;cy[7][4][2]=-1;cy[7][4][3]=-2;
srand(time(0)); /对随机数函数rand()进行初始化/
zt1=rand()%7+1; /生成第一、二个方块/
if(zt1==2) zt2=1;
if(zt1==1||zt1==4||zt1==5) zt2=rand()%2+1;
if(zt1==3||zt1==6||zt1==7) zt2=rand()%4+1;
rzt1=rand()%7+1;
if(rzt1==2) rzt2=1;
if(rzt1==1||rzt1==4||rzt1==5) rzt2=rand()%2+1;
if(rzt1==3||rzt1==6||rzt1==7) rzt2=rand()%4+1;
score=0;
for(o=1;o<11;o++) b[o]=0;
switch(zt110+zt2)
/zt1和zt2分别代表方块的种类和状态,这步是根据这两个变量确定方块的四个点的坐标/
{ case 11: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=7;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=2;
break;
case 12: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=5;
doty[0]=4;doty[1]=3;doty[2]=2;doty[3]=1;
break;
case 21: dotx[0]=5;dotx[1]=6;dotx[2]=5;dotx[3]=6;
doty[0]=1;doty[1]=1;doty[2]=2;doty[3]=2;
break;
case 31: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=5;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 32: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=1;doty[1]=2;doty[2]=3;doty[3]=2;
break;
case 33: dotx[0]=6;dotx[1]=5;dotx[2]=4;dotx[3]=5;
doty[0]=1;doty[1]=1;doty[2]=1;doty[3]=2;
break;
case 34: dotx[0]=6;dotx[1]=6;dotx[2]=6;dotx[3]=5;
doty[0]=3;doty[1]=2;doty[2]=1;doty[3]=2;
break;
case 41: dotx[0]=6;dotx[1]=5;dotx[2]=5;dotx[3]=4;
doty[0]=2;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 42: dotx[0]=5;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=3;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 51: dotx[0]=4;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=2;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 52: dotx[0]=5;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=1;doty[1]=2;doty[2]=2;doty[3]=3;
break;
case 61: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 62: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=1;doty[1]=2;doty[2]=3;doty[3]=3;
break;
case 63: dotx[0]=6;dotx[1]=5;dotx[2]=4;dotx[3]=4;
doty[0]=1;doty[1]=1;doty[2]=1;doty[3]=2;
break;
case 64: dotx[0]=6;dotx[1]=6;dotx[2]=6;dotx[3]=5;
doty[0]=3;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 71: dotx[0]=6;dotx[1]=5;dotx[2]=4;dotx[3]=4;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 72: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=3;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 73: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=1;doty[1]=1;doty[2]=1;doty[3]=2;
break;
case 74: dotx[0]=6;dotx[1]=6;dotx[2]=6;dotx[3]=5;
doty[0]=1;doty[1]=2;doty[2]=3;doty[3]=3;
break;
}
switch(rzt110+rzt2) /确定第二个方块各个点的坐标/
{ case 11: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=7;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=2;
break;
case 12: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=5;
roty[0]=4;roty[1]=3;roty[2]=2;roty[3]=1;
break;
case 21: rotx[0]=5;rotx[1]=6;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=2;roty[3]=2;
break;
case 31: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=5;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 32: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=2;
break;
case 33: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=5;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 34: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=2;
break;
case 41: rotx[0]=6;rotx[1]=5;rotx[2]=5;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 42: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 51: rotx[0]=4;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 52: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=2;roty[3]=3;
break;
case 61: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 62: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
case 63: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 64: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 71: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 72: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 73: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 74: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
}
system("cls"); /显示初始阶段/
printf("\n\n\n"); /游戏区域下移3/
for(u=0;u<19;u++)
{ for(i=0;i<12;i++)
printf("%c",str[i][u]);
printf("\n");
}
gotoxy(16,5);printf("--------");
gotoxy(16,12);printf("--------");
for(i=6;i<12;i++)
{ gotoxy(16,i);printf("|");gotoxy(23,i);printf("|"); }
for(i=6;i<12;i++)
{ gotoxy(16,i);printf("|");gotoxy(23,i);printf("|"); }
for(i=0;i<4;i++)
{ gotoxy(rotx[i]+14,roty[i]+6);printf("%c",15);
}
begin2: delay(26000); /游戏开始,延迟1/
speed: delay(10000); /加速,延迟2/
gotoxy(16,14);printf("Score:%d",score);
for(i=0;i<4;i++)
{ gotoxy(dotx[i]+1,doty[i]+4);printf(" ");
ddx=dotx[i];ddy=doty[i];
str[ddx][ddy]=' ';
}
an=an-04; /表示按键是否一直按着,用于方块落地后的移动/
c=bioskey(1); /按键处理部分/
/bioskey(1)是用来检测是否按下案件的函数/
if(c!=0)
{ c=bioskey(0);
if(c==8292||c==19712)
{ for(i=0;i<4;i++)
{ dx[i]=dotx[i]+1;dy[i]=doty[i]; }
jiance();
for(i=0;i<4;i++)
dotx[i]=(j) dx[i] : dotx[i];
an=(j||bn);
}
if(c==7777||c==19200)
{ for(i=0;i<4;i++)
{ dx[i]=dotx[i]-1;dy[i]=doty[i]; }
jiance();
for(i=0;i<4;i++)
dotx[i]=(j) dx[i] : dotx[i];
an=(j||bn);
}
if(c==6512) /暂停的处理/
{ while(1)
{ c=bioskey(0);
if(c==6512) break;
}
goto begin3;
}
if(c==8051||c==20480) spd=1; /加速(spd==1表示加速状态)/
if(c==4471||c==18432) /旋转的处理/
{ for(i=0;i<4;i++)
{ dx[i]=dotx[i];dy[i]=doty[i]; }
/dx[]与dy[]是临时变量,这样一旦判断为不能旋转,就可方便的回复旋转前的坐标/
cir(); /旋转/
jiance(); /判断旋转是否能进行/
for(i=0;i<4;i++)
{ dotx[i]=(j) dx[i] : dotx[i]; doty[i]=(j)dy[i] : doty[i]; }
/根据jiance()得到的j值,判断是对dotx[]与doty[]赋旋转后的还是旋转前的值/
if(j==1) /如果旋转可已经行,就对原方块的状态进行改变/
{ an=(j||bn);zt2=zt2+1;
if(zt2>maxzt[zt1]) zt2=1;
goto overif; /结束旋转的处理/
}
for(i=0;i<4;i++)
{ dx[i]=dotx[i]+1;dy[i]=doty[i]; }
/如果不能旋转,再判断坐标右移一个后能否旋转/
cir();
jiance();
for(i=0;i<4;i++)
{ dotx[i]=(j) dx[i] : dotx[i]; doty[i]=(j)dy[i] : doty[i]; }
if(j==1)
{ an=(j||bn);zt2=zt2+1;
if(zt2>maxzt[zt1]) zt2=1;
goto overif;
}
if(dotx[2]==1) goto overif;
for(i=0;i<4;i++)
{ dx[i]=dotx[i]-1;dy[i]=doty[i]; }
/判断坐标左移一个后能否旋转/
cir();
jiance();
for(i=0;i<4;i++)
{ dotx[i]=(j) dx[i] : dotx[i]; doty[i]=(j)dy[i] : doty[i]; }
if(j==1)
{ an=(j||bn);zt2=zt2+1;
if(zt2>maxzt[zt1]) zt2=1;
goto overif;
}
overif: ;
}
}
begin3: for(i=0;i<4;i++) /方块下移的处理/
{ dx[i]=dotx[i];dy[i]=doty[i]+1; }
jiance();
bn=j;
for(i=0;i<4;i++)
doty[i]=(j) dy[i] : doty[i];
for(i=0;i<4;i++)
{ gotoxy(dotx[i]+1,doty[i]+4);printf("%c",15);
ddx=dotx[i];ddy=doty[i];
str[ddx][ddy]=15;
}
if(j==1&&spd==1) { spd=0;goto speed; }
if(j==1||an>0) goto begin2;
for(u=17;u>0;u--) /方块停止下移(方块移动到底了)的处理/
{ for(i=1;i<11;i++) /判断每一行是否排满/
if(str[i][u]==15) b[i]=1;
if (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]+b[7]+b[8]+b[9]+b[10]<10)
{ for(o=1;o<11;o++) b[o]=0;
continue;
}
for(o=1;o<11;o++) b[o]=0;
a[t]=u;t++;
}
score+=(t)(t-1)/2;
for(i=1;i<11;i++)
if(str[i][1]==15) b[i]=1;
if (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]+b[7]+b[8]+b[9]+b[10]>0 &&t==1) goto over;
for(o=1;o<11;o++) b[o]=0;
if(t==1) goto ran;
switch(t) /消除方块的处理,t=要消除的函数+1/
{ case 5: for(u=a[4];u>1;u--) { for(i=1;i<11;i++) str[i][u]=str[i][u-1]; }
/将要消除的行中,最上面一行,上面的方格整体下移,下面的case 4,3,2类似/
case 4: for(u=a[3];u>1;u--) { for(i=1;i<11;i++) str[i][u]=str[i][u-1]; }
case 3: for(u=a[2];u>1;u--) { for(i=1;i<11;i++) str[i][u]=str[i][u-1]; }
case 2: for(u=a[1];u>1;u--) { for(i=1;i<11;i++) str[i][u]=str[i][u-1]; }
}
t=1;
for(u=1;u<18;u++)
{ for(i=1;i<11;i++)
{ gotoxy(i+1,u+4);
printf("%c",str[i][u]);
}
}
ran: zt1=rzt1;zt2=rzt2;rzt1=rand()%7+1; /生成下两个方块/
if(rzt1==2) rzt2=1;
if(rzt1==1||rzt1==4||rzt1==5) rzt2=rand()%2+1;
if(rzt1==3||rzt1==6||rzt1==7) rzt2=rand()%4+1;
for(i=0;i<4;i++)
{ dotx[i]=rotx[i];doty[i]=roty[i];
gotoxy(dotx[i]+1,doty[i]+4);printf("%c",15);
}
switch(rzt110+rzt2)
{ case 11: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=7;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=2;
break;
case 12: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=5;
roty[0]=4;roty[1]=3;roty[2]=2;roty[3]=1;
break;
case 21: rotx[0]=5;rotx[1]=6;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=2;roty[3]=2;
break;
case 31: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=5;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 32: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=2;
break;
case 33: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=5;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 34: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=2;
break;
case 41: rotx[0]=6;rotx[1]=5;rotx[2]=5;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 42: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 51: rotx[0]=4;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 52: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=2;roty[3]=3;
break;
case 61: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 62: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
case 63: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 64: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 71: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 72: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 73: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 74: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
}
for(i=6;i<12;i++) /刷新一下用来显示下一个方块的那个区域/
{ gotoxy(16,i);printf("|");gotoxy(23,i);printf("|"); }
for(i=6;i<12;i++)
for(u=17;u<23;u++) { gotoxy(u,i);printf("%c",32); }
for(i=0;i<4;i++)
{ gotoxy(rotx[i]+14,roty[i]+6);printf("%c",15); }
c=bioskey(1);an=0;
if(c!=0) c=bioskey(0);
if(spd==1) { spd=0;goto speed; }
goto begin2;
over: system("cls");
gotoxy(36,11);printf("GAME OVER");
bioskey(0);
system("cls");
printf("Your score is %d\n\n",score);
printf("Press 'Q' to exit\nIf you want to play again,please press other keys");
score=0;
c=bioskey(0);
if(c!=4209) goto begin;
}
这里把游戏的关键设计放在三个盒子和一个坐标上:
大盒子:一个两维数组,记录着方块点阵的开与关(把游戏的舞台想像
成一个点阵),在下面也把这个东西称为地图
两个55小盒子:两维数组,一个盛放着正在下落的方块,一个盛放在
下一个下落的方块(即next),当然这两个也必须想像成一个点阵:如长条
的点阵为:
00000
00100
00100
00100
00100
现在你只要有这么一个概念:一个不断定时下落的小盒子从大盒子顶
部下降到底部,之后再将next盒子放在下落盒子,再进行下一轮的下落
中间的控制等尚不要太着急
现在面临着一个问题:
下落的盒子和地图之间要怎么联系起来
一个好的方法是再定义一个坐标:x,y,保存着小盒子左上角在地图上对应
的下标(位置),即当x
=
0,
y
=
0时,小盒子处于地图的左上部如此,当
小盒子需要移动时,即只须要改变x,y的值
现在说说旋转
小盒子保存着当前下落形状的点阵,那么旋转就只须要将这个点阵旋
转90度:例如:
00000
00000
00100
00000
00100
->
01111
00100
00000
00100
00000
这一点实现起来还是不太难的
判断碰撞
通常这种情况只须要在有移动小盒或旋转盒子时发生:也即点阵非空
是互斥的,当小盒要向下移(x++)时,如果小盒里的点阵与地图上的点阵(非
空的地方)重叠,则不能下移,(卡住了),旋转则转换后的形状与地图有冲
突则要放弃旋转
到了这里,你应该有一个大概的了解了,至于怎样在屏幕上画出来,这
个是比较简单的,下面的代码会慢慢与你解释
/
/接下一贴/
// 程序名称:俄罗斯方块
// 最后更新:2010-12-18
//
#include <graphicsh>
#include <conioh>
#include <timeh> /////////////////////////////////////////////
// 定义常量、枚举量、结构体、全局变量
/////////////////////////////////////////////#define WIDTH 10 // 游戏区宽度
#define HEIGHT 22 // 游戏区高度
#define SIZE 20 // 每个游戏区单位的实际像素// 定义 *** 作类型
enum CTRL
{
CTRL_ROTATE, // 方块旋转
CTRL_LEFT, CTRL_RIGHT, CTRL_DOWN, // 方块左、右、下移动
CTRL_SINK, // 方块沉底
CTRL_QUIT // 退出游戏
};// 定义绘制方块的方法
enum DRAW
{
SHOW, // 显示方块
HIDE, // 隐藏方块
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
{0x0360, 0x4620, 0x0360, 0x4620, GREEN}, // 反Z
{0x4E00, 0x4C40, 0x0E40, 0x4640, BROWN}}; // T// 定义当前方块、下一个方块的信息
struct BLOCKINFO
{
byte id; // 方块 ID
char x, y; // 方块在游戏区中的坐标
byte dir:2; // 方向
} g_CurBlock, g_NextBlock;// 定义游戏区
BYTE g_World[WIDTH][HEIGHT] = {0}; /////////////////////////////////////////////
// 函数声明
/////////////////////////////////////////////void Init(); // 初始化游戏
void Quit(); // 退出游戏
void NewGame(); // 开始新游戏
void GameOver(); // 结束游戏
CTRL GetControl(bool _onlyresettimer = false); // 获取控制命令
void DispatchControl(CTRL _ctrl); // 分发控制命令
void NewBlock(); // 生成新的方块
bool CheckBlock(BLOCKINFO _block); // 检测指定方块是否可以放下
void DrawBlock(BLOCKINFO _block, DRAW _draw = SHOW); // 画方块
void OnRotate(); // 旋转方块
void OnLeft(); // 左移方块
void OnRight(); // 右移方块
void OnDown(); // 下移方块
void OnSink(); // 沉底方块 /////////////////////////////////////////////
// 函数定义
/////////////////////////////////////////////// 主函数
void main()
{
Init(); CTRL c;
while(true)
{
c = GetControl();
DispatchControl(c); // 按退出时,显示对话框咨询用户是否退出
if (c == CTRL_QUIT)
{
HWND wnd = GetHWnd();
if (MessageBox(wnd, "您要退出游戏吗?", "提醒", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
Quit();
}
}
}
// 初始化游戏
void Init()
{
initgraph(640, 480);
srand((unsigned)time(NULL)); // 显示 *** 作说明
setfont(14, 0, "宋体");
outtextxy(20, 330, " *** 作说明");
outtextxy(20, 350, "上:旋转");
outtextxy(20, 370, "左:左移");
outtextxy(20, 390, "右:右移");
outtextxy(20, 410, "下:下移");
outtextxy(20, 430, "空格:沉底");
outtextxy(20, 450, "ESC:退出"); // 设置坐标原点
setorigin(220, 20); // 绘制游戏区边界
rectangle(-1, -1, WIDTH SIZE, HEIGHT SIZE);
rectangle((WIDTH + 1) SIZE - 1, -1, (WIDTH + 5) SIZE, 4 SIZE); // 开始新游戏
NewGame();
}
// 退出游戏
void Quit()
{
closegraph();
exit(0);
}
// 开始新游戏
void NewGame()
{
// 清空游戏区
setfillstyle(BLACK);
bar(0, 0, WIDTH SIZE - 1, HEIGHT SIZE - 1);
ZeroMemory(g_World, WIDTH HEIGHT); // 生成下一个方块
g_NextBlockid = rand() % 7;
g_NextBlockdir = rand() % 4;
g_NextBlockx = WIDTH + 1;
g_NextBlocky = HEIGHT - 1; // 获取新方块
NewBlock();
}
// 结束游戏
void GameOver()
{
HWND wnd = GetHWnd();
if (MessageBox(wnd, "游戏结束。\n您想重新来一局吗?", "游戏结束", MB_YESNO | MB_ICONQUESTION) == IDYES)
NewGame();
else
Quit();
}
// 获取控制命令
CTRL GetControl(bool _onlyresettimer)
{
static DWORD oldtime = GetTickCount(); // 重置计时器
if (_onlyresettimer)
{
oldtime = GetTickCount();
return CTRL_DOWN; // 仅仅为了重置计时器,随便返回一个值
} // 获取控制值
while(true)
{
// 如果超时,自动下落一格
俄罗斯方块——java源代码提供
import javaawt;
import javaawtevent;
//俄罗斯方块类
public class ERS_Block extends Frame{
public static boolean isPlay=false;
public static int level=1,score=0;
public static TextField scoreField,levelField;
public static MyTimer timer;
GameCanvas gameScr;
public static void main(String[] argus){
ERS_Block ers = new ERS_Block("俄罗斯方块游戏 V10 Author:Vincent");
WindowListener win_listener = new WinListener();
ersaddWindowListener(win_listener);
}
//俄罗斯方块类的构造方法
ERS_Block(String title){
super(title);
setSize(600,480);
setLayout(new GridLayout(1,2));
gameScr = new GameCanvas();
gameScraddKeyListener(gameScr);
timer = new MyTimer(gameScr);
timersetDaemon(true);
timerstart();
timersuspend();
add(gameScr);
Panel rightScr = new Panel();
rightScrsetLayout(new GridLayout(2,1,0,30));
rightScrsetSize(120,500);
add(rightScr);
//右边信息窗体的布局
MyPanel infoScr = new MyPanel();
infoScrsetLayout(new GridLayout(4,1,0,5));
infoScrsetSize(120,300);
rightScradd(infoScr);
//定义标签和初始值
Label scorep = new Label("分数:",LabelLEFT);
Label levelp = new Label("级数:",LabelLEFT);
scoreField = new TextField(8);
levelField = new TextField(8);
scoreFieldsetEditable(false);
levelFieldsetEditable(false);
infoScradd(scorep);
infoScradd(scoreField);
infoScradd(levelp);
infoScradd(levelField);
scorepsetSize(new Dimension(20,60));
scoreFieldsetSize(new Dimension(20,60));
levelpsetSize(new Dimension(20,60));
levelFieldsetSize(new Dimension(20,60));
scoreFieldsetText("0");
levelFieldsetText("1");
//右边控制按钮窗体的布局
MyPanel controlScr = new MyPanel();
controlScrsetLayout(new GridLayout(5,1,0,5));
rightScradd(controlScr);
//定义按钮play
Button play_b = new Button("开始游戏");
play_bsetSize(new Dimension(50,200));
play_baddActionListener(new Command(Commandbutton_play,gameScr));
//定义按钮Level UP
Button level_up_b = new Button("提高级数");
level_up_bsetSize(new Dimension(50,200));
level_up_baddActionListener(new Command(Commandbutton_levelup,gameScr));
//定义按钮Level Down
Button level_down_b =new Button("降低级数");
level_down_bsetSize(new Dimension(50,200));
level_down_baddActionListener(new Command(Commandbutton_leveldown,gameScr));
//定义按钮Level Pause
Button pause_b =new Button("游戏暂停");
pause_bsetSize(new Dimension(50,200));
pause_baddActionListener(new Command(Commandbutton_pause,gameScr));
//定义按钮Quit
Button quit_b = new Button("退出游戏");
quit_bsetSize(new Dimension(50,200));
quit_baddActionListener(new Command(Commandbutton_quit,gameScr));
controlScradd(play_b);
controlScradd(level_up_b);
controlScradd(level_down_b);
controlScradd(pause_b);
controlScradd(quit_b);
setVisible(true);
gameScrrequestFocus();
}
}
//重写MyPanel类,使Panel的四周留空间
class MyPanel extends Panel{
public Insets getInsets(){
return new Insets(30,50,30,50);
}
}
//游戏画布类
class GameCanvas extends Canvas implements KeyListener{
final int unitSize = 30; //小方块边长
int rowNum; //正方格的行数
int columnNum; //正方格的列数
int maxAllowRowNum; //允许有多少行未削
int blockInitRow; //新出现块的起始行坐标
int blockInitCol; //新出现块的起始列坐标
int [][] scrArr; //屏幕数组
Block b; //对方快的引用
//画布类的构造方法
GameCanvas(){
rowNum = 15;
columnNum = 10;
maxAllowRowNum = rowNum - 2;
b = new Block(this);
blockInitRow = rowNum - 1;
blockInitCol = columnNum/2 - 2;
scrArr = new int [32][32];
}
//初始化屏幕,并将屏幕数组清零的方法
void initScr(){
for(int i=0;i<rowNum;i++)
for (int j=0; j<columnNum;j++)
scrArr[j]=0;
breset();
repaint();
}
//重新刷新画布方法
public void paint(Graphics g){
for(int i = 0; i < rowNum; i++)
for(int j = 0; j < columnNum; j++)
drawUnit(i,j,scrArr[j]);
}
//画方块的方法
public void drawUnit(int row,int col,int type){
scrArr[row][col] = type;
Graphics g = getGraphics();
tch(type){ //表示画方快的方法
case 0: gsetColor(Colorblack);break; //以背景为颜色画
case 1: gsetColor(Colorblue);break; //画正在下落的方块
case 2: gsetColor(Colormagenta);break; //画已经落下的方法
}
gfill3DRect(colunitSize,getSize()height-(row+1)unitSize,unitSize,unitSize,true);
gdispose();
}
public Block getBlock(){
return b; //返回block实例的引用
}
//返回屏幕数组中(row,col)位置的属性值
public int getScrArrXY(int row,int col){
if (row < 0 || row >= rowNum || col < 0 || col >= columnNum)
return(-1);
else
return(scrArr[row][col]);
}
//返回新块的初始行坐标方法
public int getInitRow(){
return(blockInitRow); //返回新块的初始行坐标
}
//返回新块的初始列坐标方法
public int getInitCol(){
return(blockInitCol); //返回新块的初始列坐标
}
//满行删除方法
void deleteFullLine(){
int full_line_num = 0;
int k = 0;
for (int i=0;i<rowNum;i++){
boolean isfull = true;
L1:for(int j=0;j<columnNum;j++)
if(scrArr[j] == 0){
k++;
isfull = false;
break L1;
}
if(isfull) full_line_num++;
if(k!=0 && k-1!=i && !isfull)
for(int j = 0; j < columnNum; j++){
if (scrArr[j] == 0)
drawUnit(k-1,j,0);
else
drawUnit(k-1,j,2);
scrArr[k-1][j] = scrArr[j];
}
}
for(int i = k-1 ;i < rowNum; i++){
for(int j = 0; j < columnNum; j++){
drawUnit(i,j,0);
scrArr[j]=0;
}
}
ERS_Blockscore += full_line_num;
ERS_BlockscoreFieldsetText(""+ERS_Blockscore);
}
//判断游戏是否结束方法
boolean isGameEnd(){
for (int col = 0 ; col <columnNum; col ++){
if(scrArr[maxAllowRowNum][col] !=0)
return true;
}
return false;
}
public void keyTyped(KeyEvent e){
}
public void keyReleased(KeyEvent e){
}
//处理键盘输入的方法
public void keyPressed(KeyEvent e){
if(!ERS_BlockisPlay)
return;
tch(egetKeyCode()){
case KeyEventVK_DOWN:bfallDown();break;
case KeyEventVK_LEFT:bleftMove();break;
case KeyEventVK_RIGHT:brightMove();break;
case KeyEventVK_SPACE:bleftTurn();break;
}
}
}
//处理控制类
class Command implements ActionListener{
static final int button_play = 1; //给按钮分配编号
static final int button_levelup = 2;
static final int button_leveldown = 3;
static final int button_quit = 4;
static final int button_pause = 5;
static boolean pause_resume = true;
int curButton; //当前按钮
GameCanvas scr;
//控制按钮类的构造方法
Command(int button,GameCanvas scr){
curButton = button;
thisscr=scr;
}
//按钮执行方法
public void actionPerformed (ActionEvent e){
tch(curButton){
case button_play:if(!ERS_BlockisPlay){
scrinitScr();
ERS_BlockisPlay = true;
ERS_Blockscore = 0;
ERS_BlockscoreFieldsetText("0");
ERS_Blocktimerresume();
}
scrrequestFocus();
break;
case button_levelup:if(ERS_Blocklevel < 10){
ERS_Blocklevel++;
ERS_BlocklevelFieldsetText(""+ERS_Blocklevel);
ERS_Blockscore = 0;
ERS_BlockscoreFieldsetText(""+ERS_Blockscore);
}
scrrequestFocus();
break;
case button_leveldown:if(ERS_Blocklevel > 1){
ERS_Blocklevel--;
ERS_BlocklevelFieldsetText(""+ERS_Blocklevel);
ERS_Blockscore = 0;
ERS_BlockscoreFieldsetText(""+ERS_Blockscore);
}
scrrequestFocus();
break;
case button_pause:if(pause_resume){
ERS_Blocktimersuspend();
pause_resume = false;
}else{
ERS_Blocktimerresume();
pause_resume = true;
}
scrrequestFocus();
break;
case button_quit:Systemexit(0);
}
}
}
//方块类
class Block {
static int[][] pattern = {
{0x0f00,0x4444,0x0f00,0x4444},//用十六进至表示,本行表示长条四种状态
{0x04e0,0x0464,0x00e4,0x04c4},
{0x4620,0x6c00,0x4620,0x6c00},
{0x2640,0xc600,0x2640,0xc600},
{0x6220,0x1700,0x2230,0x0740},
{0x6440,0x0e20,0x44c0,0x8e00},
{0x0660,0x0660,0x0660,0x0660}
};
int blockType; //块的模式号(0-6)
int turnState; //块的翻转状态(0-3)
int blockState; //快的下落状态
int row,col; //块在画布上的坐标
GameCanvas scr;
//块类的构造方法
Block(GameCanvas scr){
thisscr = scr;
blockType = (int)(Mathrandom() 1000)%7;
turnState = (int)(Mathrandom() 1000)%4;
blockState = 1;
row = scrgetInitRow();
col = scrgetInitCol();
}
//重新初始化块,并显示新块
public void reset(){
blockType = (int)(Mathrandom() 1000)%7;
turnState = (int)(Mathrandom() 1000)%4;
blockState = 1;
row = scrgetInitRow();
col = scrgetInitCol();
dispBlock(1);
}
//实现“块”翻转的方法
public void leftTurn(){
if(assertValid(blockType,(turnState + 1)%4,row,col)){
dispBlock(0);
turnState = (turnState + 1)%4;
dispBlock(1);
}
}
//实现“块”的左移的方法
public void leftMove(){
if(assertValid(blockType,turnState,row,col-1)){
dispBlock(0);
col--;
dispBlock(1);
}
}
//实现块的右移
public void rightMove(){
if(assertValid(blockType,turnState,row,col+1)){
dispBlock(0);
col++;
dispBlock(1);
}
}
//实现块落下的 *** 作的方法
public boolean fallDown(){
if(blockState == 2)
return(false);
if(assertValid(blockType,turnState,row-1,col)){
dispBlock(0);
row--;
dispBlock(1);
return(true);
}else{
blockState = 2;
dispBlock(2);
return(false);
}
}
//判断是否正确的方法
boolean assertValid(int t,int s,int row,int col){
int k = 0x8000;
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
if((int)(pattern[t][s]&k) != 0){
int temp = scrgetScrArrXY(row-i,col+j);
if (temp<0||temp==2)
return false;
}
k = k >> 1;
}
}
return true;
}
//同步显示的方法
public synchronized void dispBlock(int s){
int k = 0x8000;
for (int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
if(((int)pattern[blockType][turnState]&k) != 0){
scrdrawUnit(row-i,col+j,s);
}
k=k>>1;
}
}
}
}
//定时线程
class MyTimer extends Thread{
GameCanvas scr;
public MyTimer(GameCanvas scr){
thisscr = scr;
}
public void run(){
while(true){
try{
sleep((10-ERS_Blocklevel + 1)100);
}
catch(InterruptedException e){}
if(!scrgetBlock()fallDown()){
scrdeleteFullLine();
if(scrisGameEnd()){
ERS_BlockisPlay = false;
suspend();
}else
scrgetBlock()reset();
}
}
}
}
class WinListener extends WindowAdapter{
public void windowClosing (WindowEvent l){
Systemexit(0);
}
}
以上就是关于C语言中的俄罗斯方块全部的内容,包括:C语言中的俄罗斯方块、俄罗斯方块的源代码、如何用C语言编一个俄罗斯方块等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)