您的位置:首页 > 编程语言 > Java开发

java实现的俄罗斯方块游戏--powered by dustin

2016-02-22 09:44 801 查看
学习java时间不长,跟着学习视频敲过一个贪吃蛇的游戏代码,遂产生了仿写一个俄罗斯方游戏的想法。用了六天时间终于实现了最基本的功能,然而bug仍然很多,不过运行成功玩几局仍然很开森哇!期间遇到了很多难题,很伤脑筋,不过还是一个个地解决掉了,真心希望自己在学习java的路上能一直保持热情,keep fighting!!

在游戏中我使用了两个类(貌似不是最优的面向对象思维),一个是游戏的窗体Yard类,另一个是方块Brick类。算法的思想主要有:1.使用二维数组保存方块的形状。2.起一个线程用于方块的刷新和重绘。3.在方块未触底时(即isReachDown()返回FALSE)方块对象调用向下自动运动的方法。4.当方块触底,新new一个方块的形状。5.采用一个巨大的二维数组保存落地的方块,这是方块对象和落地方块用不同的数组进行保存。6.有了这个背景数组之后,消行和下行就很好实现了。
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.util.Random;

public class Brick {
boolean reachdown = false;
private static Random r = new Random();
public  boolean[][] s = new boolean[4][4];
boolean[][] s1 = new boolean[4][4];
final boolean[][] b1 = {{false,false,false,false},{false,false,false,false},{false,false,false,false},{true,true,true,true} };//任意位置
final boolean[][] b2 = {{false,false,false,false},{false,false,false,false},{true,false,false,false},{true,true,true,false} };//靠左
final boolean[][] b3 = {{false,false,false,true},{false,false,false,true},{false,false,false,true},{false,true,true,true} };//靠右
final boolean[][] b4 = {{false,false,false,false},{false,false,false,false},{true,true,false,false},{true,true,false,false} };//靠左

final boolean[][] b5 = {{false,false,false,false},{false,false,false,false},{false,false,true,false},{false,true,true,true} };//靠右
final boolean[][] b6 = {{false,false,false,false},{false,false,false,false},{false,true,false,false},{false,true,false,false} };

boolean[][] background={{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false},
{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false},
{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false},
{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false},
{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false},
{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false},
{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false},
{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}};
S_node[][] background_str = new S_node[8][15];
S_node[][] str = new S_node[4][4];

int[] downside = new int[15];
int[] upside = new int[4];

int begin_r = 1;
int begin_c = 11;

private class S_node{
final int node_w = Yard.NODE_SIZE;
final int node_h = Yard.NODE_SIZE;
int row,col;

S_node(int row,int col){
this.row =row ;
this.col = col;

}

void draw(Graphics g){
Color c = g.getColor();
g.setColor(Color.WHITE);
g.fillRect(col *node_w, row *node_h, node_w, node_h);
g.setColor(c);
}
}

public void getCode(){
switch((r.nextInt(6))){
case 0 :
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b1[i][j];
}
}
break;

case 1:
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b2[i][j];
}
}
break;
case 2 :
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b3[i][j];
}
}
break;

case 3:
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b4[i][j];
}
}
break;
case 4 :
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b5[i][j];
}
}
break;
case 5 :
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b6[i][j];
}
}
break;

}
}

public void getStr(){
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){

if(s[i][j]==true){
str[i][j] = new S_node(begin_r+i,begin_c+j);             //绝对坐标

}

}
}
}

public void draw(Graphics g){

this.getStr();

for(int i=0; i<4; i++){
upside[i] = 0;
}

for(int i=0; i<15; i++){
downside[i] = 0;
}
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
str[i][j].draw(g);
}

}

}

for(int i=0;i<8;i++){
for(int j=0;j<15;j++){
if(background[i][j]==true){
background_str[i][j] = new S_node(16+i,j+5);
}
if(background[i][j]==false){
background_str[i][j] = null;
}

if(background_str[i][j]!=null){
background_str[i][j].draw(g);
}

}
//************          让满行的消掉********************//
if((background[i][0]==true)&&(background[i][1]==true)&&(background[i][2]==true)&&(background[i][4]==true)&&
(background[i][5]==true)&&(background[i][6]==true)&&(background[i][7]==true)&&(background[i][8]==true)&&
(background[i][9]==true)&&(background[i][10]==true)&&(background[i][11]==true)&&(background[i][12]==true)&&
(background[i][13]==true)&&(background[i][14]==true)&&(background[i][3]==true)){

for(int k= 0;k<15;k++){
background[i][k]=false;
}

//********************  下行一行*****************//

for(int l=i;l>0;l--){
for(int m=0;m<15;m++){
background[l][m]=background[l-1][m];
}
}
for(int n=0;n<15;n++){
background[0]
=false;
}

}
// *************************************************//

}
//****************** 用以记录上下目标位置的数组赋值***************//
for(int j=7; j>=0; j--){
for(int i=0; i<15; i++){
if(background[j][i]==true){
downside[i] = 8-j;
continue;
}
}
}

for(int i=0; i<4; i++){
for(int j=3; j>=0; j--){
if(str[j][i]!=null){
upside[i]=3-j;         //离最下一行的空缺数
break;
}
else upside[i]=4;
}
}

//***************************************************//
if(!isReachDown()){
this.moveDown();
}
else{

for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
background[this.begin_r+ i - 16][this.begin_c + j - 5 ]=true;
}

}
}

reachdown=false;
this.begin_r=1;
this.begin_c=10;

for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
str[i][j]=null;
s[i][j]=false;

}
}

this.getCode();

}

}

public void moveDown(){
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
str[i][j]=new S_node(begin_r+i,begin_c+j);
}
}
}
begin_r++;

}

public void moveLeft(){
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
str[i][j]=new S_node(begin_r+i,begin_c+j);
}
}
}
begin_c--;
}

public void moveRight(){
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
str[i][j]=new S_node(begin_r+i,begin_c+j);
}
}
}
begin_c++;
}

public boolean isReachDown(){

//************************  碰撞式触底*************//          解决当str[i]==null的情况

if((str[3][1].row<=(22+upside[0]-downside[str[3][1].col-6]))&&(str[3][1].row<=(22+upside[1]-downside[str[3][1].col-5]))&&(str[3][1].row<=(22+upside[2]-downside[str[3][1].col-4]))&&(str[3][1].row<=(22+upside[3]-downside[str[3][1].col-3])))
return reachdown;

//*********************************************//

reachdown=true;
return reachdown;

}

public void keyPressed(KeyEvent e){
int Key = e.getKeyCode();
switch(Key){
case KeyEvent.VK_LEFT :
this.moveLeft();
break;
case KeyEvent.VK_RIGHT:
this.moveRight();
break;

}
}

}
Brick类
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Yard extends Frame {

public static final int ROW = 25 ;
public static final int COL = 25 ;
public static final int NODE_SIZE = 20 ;
public boolean flag = true;

public Brick b = new Brick();

public void launch(){
this.setLocation(200, 200);
this.setSize(COL * NODE_SIZE, ROW *NODE_SIZE);
this.setVisible(true) ;
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
);

b.getCode();

this.addKeyListener(new KeyMonitor());
new Thread(new Spaint()).start();
}

public void paint(Graphics g){
Color c = g.getColor();
g.setColor(new Color(0,0,128));
g.fillRect(0, 0, COL * NODE_SIZE, ROW * NODE_SIZE);
g.setColor(new Color(50,205,50));
g.fillRect(0,0,COL * NODE_SIZE,NODE_SIZE*2);   //将边框刷白
g.fillRect(0,0,NODE_SIZE*5,NODE_SIZE*ROW);
g.fillRect(0,NODE_SIZE*(ROW - 1),COL * NODE_SIZE,NODE_SIZE*2);
g.fillRect(NODE_SIZE*(ROW - 5),0 , NODE_SIZE*6, NODE_SIZE*ROW);

g.setColor(new Color(255,255,255));

g.drawString("Designed ", 420, 200);
g.drawString("By ", 420, 250);
g.drawString("Dustin ", 420, 300);
g.setColor(c);

b.draw(g);
}

private class Spaint implements Runnable{
public void run(){
while(flag){
repaint();

for(int i=0; i<15; i++){
System.out.print(b.downside[i]);

}
System.out.println();
for(int i=0; i<4; i++){
System.out.print(b.upside[i]);

}
System.out.println();

try{
Thread.sleep(400);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}

private class KeyMonitor extends KeyAdapter{
public void keyPressed(KeyEvent e){
b.keyPressed(e);
}
}

public static void main(String[] args) {
new Yard().launch();

}

}

Yard类
代码如上所示,总共用了400余行,游戏还存在着两个主要的问题,一是有些情况会出现数组越界的异常,这是由于方块的二维数组中为空的地方超出了背景数组的范围,我认为可以通过增加背景数组的宽度解决。第二是我还没有添加变形的功能,也希望喜欢编程的朋友能完善它,一起交流学习!共同提高!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: