我正在制作多人游戏俄罗斯方块。 TetrisGame类只是使用循环来运行游戏,而Tetris类构造函数创建了一个新的部分(不要担心board2类,它只是绘制碎片)。所以这是两个类:
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.*;
import java.net.MalformedURLException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;
@SuppressWarnings("serial")
public class TetrisGame extends JFrame
{
private board2 myBoard;
private int score;
static Tetris_RafArian tetromino, tet2;
private int speed = 500;
private boolean pause;
private boolean start;
public TetrisGame() throws InterruptedException
{
super("Tetris");
setLayout(new BorderLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
keyListener();
pause=true;
start=true;
score=0;
while(true)
{
if(start)
{
myBoard = new board2(10, 20);
add(myBoard, BorderLayout.CENTER);
tet2 = new Tetris_RafArian(myBoard, 20, 0, 12, 12);
tetromino = new Tetris_RafArian(myBoard, 4, 0, 12, 6);
pack();
runGame();
}
score=0;
Thread.sleep(1);
}
}
/**
* Listens for key action
*/
public void keyListener()
{
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
if (pause && start)
tet2.rotateTetro();
break;
case KeyEvent.VK_W:
if (pause && start)
tetromino.rotateTetro();
break;
case KeyEvent.VK_LEFT:
if (tet2.checkWall(0) && pause && start)
tet2.move(0);
break;
case KeyEvent.VK_A:
if (tetromino.checkWall(0) && pause && start)
tetromino.move(0);
break;
case KeyEvent.VK_RIGHT:
if (tet2.checkWall(1) && pause && start)
tet2.move(1);
break;
case KeyEvent.VK_D:
if (tetromino.checkWall(1) && pause && start)
tetromino.move(1);
break;
case KeyEvent.VK_DOWN:
if (tet2.checkCollision(tet2.tetro()) && pause && start)
tet2.fall();
break;
case KeyEvent.VK_S:
if (tetromino.checkCollision(tetromino.tetro()) && pause && start)
tetromino.fall();
break;
case KeyEvent.VK_SPACE:
if (pause && start)
speed = 10;
break;
case KeyEvent.VK_P:
if (pause && start)
pause = false;
else
pause = true;
if (!start)
start = true;
}
myBoard.repaint();
}
});
}
/**
* Runs a single game
* @throws InterruptedException
*/
public void runGame() throws InterruptedException
{
//System.out.println(tetromino.checkCollision(tetromino.tetro));
while(tetromino.checkCollision(tetromino.tetro())||tetromino.tetro()[1][1]!=0)
{
while(tetromino.checkCollision(tetromino.tetro()))
{
if(pause)
{
//tetromino.fall();
tet2.fall();
myBoard.repaint();
Thread.sleep(speed);
}
}
speed = 500;
int x=0;
for(int i=0 ; i<20 ; i++)
if(myBoard.checkRow(i))
{
myBoard.removeRow(i);
score++;
x++;
}
score+=x;
myBoard.setScore(score);
tetromino.newTetris();
}
start=false;
myBoard.setEnd(true);
myBoard.repaint();
}
public static void main(String[] args) throws InterruptedException, MalformedURLException, LineUnavailableException, UnsupportedAudioFileException, IOException
{
new TetrisGame();
}
}
public class Tetris_RafArian
{
private static board2 myBoard;
private static int color, temColor;
private static int alt=0;
private static int xShift, yShift;
private static int xPos, yPos;
private static int[][] tetro, temTetro, shadTetro; // this is public because Game class needs access
public Tetris_RafArian(board2 bd, int x, int y, int tx, int ty)
{
myBoard=bd;
xShift=x;
yShift=y;
xPos=tx;
yPos=ty;
color = (int)(Math.random()*7)+1;
temColor = (int)(Math.random()*7)+1;
tetro = chooseRandom(color);
temTetro = chooseRandom(temColor);
shadTetro = new int[4][2];
for(int i=0; i<4 ; i++)
for(int j=0; j<2; j++)
shadTetro[i][j]=tetro[i][j];
setShadTetro();
myBoard.setTetris(temTetro, temColor, xPos, yPos);
myBoard.setTetris(tetro, color, xShift, yShift);
}
public int[][] tetro()
{
return tetro;
}
/**
* makes the shadow of the tetris
*/
private void setShadTetro()
{
while(checkCollision(shadTetro))
for(int i=0 ; i<4 ; i++)
shadTetro[i][1]++;
myBoard.setTetris(shadTetro, color+7, xShift, yShift);
}
/**
* A replica of the tetris constructor
* Helps to simply redefine all the values
* since creating multiple tetris objects is unneccessary
*/
public void newTetris()
{
color = temColor;
tetro = temTetro;
for(int i=0; i<4 ; i++)
for(int j=0; j<2; j++)
shadTetro[i][j]=tetro[i][j];
setShadTetro();
myBoard.setTetris(temTetro, 0, xPos, yPos);
temColor = (int)(Math.random()*7)+1;
temTetro = chooseRandom(temColor);
myBoard.setTetris(temTetro, temColor, xPos, yPos);
myBoard.setTetris(tetro, color, xShift, yShift);
}
/**
* chooses a tetromino based on the random number inserted
* @param c
* @return the desired tetromino
*/
private static int[][] chooseRandom(int c)
{
switch(c)
{
case 1:
return new int[][] {{-1,0},{0,0},{1,0},{1,1}};//J
case 2:
return new int[][] {{-1,1},{0,0},{-1,0},{1,0}};//L
case 3:
return new int[][] {{-1,0},{0,0},{1,0},{2,0}};//I
case 4:
return new int[][] {{-1,0},{0,0},{0,1},{1,1}};//Z
case 5:
return new int[][] {{-1,1},{0,0},{0,1},{1,0}};//S
case 6:
return new int[][] {{1,0},{0,0},{1,1},{0,1}};//O
case 7:
return new int[][] {{-1,0},{0,0},{1,0},{0,1}};//T
}
return new int[1][1];
}
/**
* Checks for floor collision
* @param tet
* @return true, if collided
* @return false, if not
*/
public boolean checkCollision(int[][] tet)
{
for(int i=0; i<4 ; i++)
{
if(tet[i][1]+1>19)
{
//System.out.println("1");
return false;
}
if(tet.equals(tetro))
{
int val = myBoard.getValue(tet[i][0]+xShift , tet[i][1]+1);
if(val>0 && val<8 && !contains(tet, tet[i][0], tet[i][1]+1))
{
//System.out.println("2");
return false;
}
}
else if(myBoard.getValue(tet[i][0]+xShift, tet[i][1]+1)!=0 && !contains(tet, tet[i][0], tet[i][1]+1))
{
//System.out.println("3");
return false;
}
}
return true;
}
/**
* checks to see if the inputed coordinates are part of the tetromino or not
* @param tet
* @param r
* @param c
* @return true, if tetromino contains those coordinates
* @return false, if not
*/
private static boolean contains(int[][] tet, int r, int c)
{
for(int i=0 ; i<4 ; i++)
if(r==tet[i][0] && c==tet[i][1])
return true;
return false;
}
/**
* checks for wall collision
* @param direction
* @return true, if collided
*/
public boolean checkWall(int d)
{
if(d>0)
for(int i=0; i<4 ; i++)
{
if(tetro[i][0]>4)
return false;
int val = myBoard.getValue(tetro[i][0]+xShift+1, tetro[i][1]);
if(val>0 && val<8 && !contains(tetro, tetro[i][0]+1, tetro[i][1]))
return false;
}
else
for(int i=0; i<4 ; i++)
{
if(tetro[i][0]<-3)
return false;
int val = myBoard.getValue(tetro[i][0]+xShift-1, tetro[i][1]);
if(val>0 && val <8 && !contains(tetro, tetro[i][0]-1, tetro[i][1]))
return false;
}
return true;
}
/**
* makes the tetromino fall one step
*/
public void fall()
{
myBoard.setTetris(tetro, 0, xShift, yShift);
for(int i=0 ; i<4 ; i++)
tetro[i][1]++;
myBoard.setTetris(tetro, color, xShift, yShift);
}
/**
* moves the tetromino left or right
* @param dir
*/
public void move(int dir)
{
myBoard.setTetris(tetro, 0, xShift, yShift);
if(dir>0)
{
for(int i=0 ; i<4 ; i++)
//if(tetro[i][0]<5)
tetro[i][0]++;
}
else
{
for(int i=0 ; i<4 ; i++)
// if(tetro[i][0]>-3)
tetro[i][0]--;
}
myBoard.setTetris(shadTetro, 0, xShift, yShift);
for(int i=0 ; i<4 ; i++)
for(int j=0 ; j<2 ; j++)
shadTetro[i][j] = tetro[i][j];
setShadTetro();
myBoard.setTetris(tetro, color, xShift, yShift);
myBoard.repaint();
}
/**
* rotates the tetromino
*/
public void rotateTetro()
{
if(color==6) return;
alt++; // this "alt" field let's pieces 's', 'z', and 'i' alternate between clockwise and counter-clockwise,
// since these pieces would shift left/right otherwise.
myBoard.setTetris(tetro, 0, xShift, yShift);
myBoard.setTetris(shadTetro, 0,xShift, yShift);
switch(checkRotation())
{
case 0:
for(int i=0 ; i<4 ; i++)
tetro[i][0]--;
if(color==3)
for(int i=0 ; i<4 ; i++)
tetro[i][0]--;
break;
case 1:
for(int i=0 ; i<4 ; i++)
tetro[i][0]++;
break;
case 2:
for(int i=0 ; i<4 ; i++)
tetro[i][1]--;
break;
case 3:
for(int i=0 ; i<4 ; i++)
tetro[i][1]++;
if(color==3)
for(int i=0 ; i<4 ; i++)
tetro[i][1]++;
break;
case 4:
myBoard.setTetris(tetro, color, xShift, yShift);
return;
}
for(int i=0; i<4 ; i++)
tetro[i] = rotPointOffset(tetro[i][0],tetro[i][1],tetro[1][0],tetro[1][1]);
for(int i=0 ; i<4 ; i++)
for(int j=0 ; j<2 ; j++)
shadTetro[i][j] = tetro[i][j];
setShadTetro();
myBoard.setTetris(tetro, color,xShift, yShift);
myBoard.repaint();
}
/**
* checks to see if rotating causes it to go through the walls or into other pieces
* @return type of collision
*/
public static int checkRotation()
{
int[]tet;
for(int i=0; i<4 ; i++)
{
tet= rotPointOffset(tetro[i][0],tetro[i][1],tetro[1][0],tetro[1][1]);
if(tet[0]>5)
return 0;
if(tet[0]<-xShift)
return 1;
if(tet[1]>19)
return 2;
if(tet[1]<0)
return 3;
if(myBoard.getValue(tet[0]+xShift, tet[1])!=0 && !contains(tetro, tet[0], tet[1]))
return 4;
}
return 5;
}
/**
* rotates coordinate (x,y) about (a,b)
* @param x
* @param y
* @param a
* @param b
* @return
*/
public static int[] rotPointOffset(int x, int y, int a, int b)
{
if(color==7 || color==1 || color==2)
return new int[] {y-b+a,a-x+b};
else
{
if(alt%2==0)
return new int[] {y-b+a,a-x+b};
else
return new int[] {b-y+a,x-a+b};
}
}
}
现在不要忘记所有的方法,什么不是。我的问题与TetrisGame构造函数有关,我创建了两个俄罗斯方块对象:tetromino和tet2。当我第一次创建tet2时,它有自己的俄罗斯方块(这只是一个数组)。但是,在下一行创建tetromino时,tet2对象的俄罗斯方块(以及所有其他字段)也会发生变化。
现在,我评估了情况。基本上,我创建的这两个对象只是Tetris类的访问器,并且出于某种原因,没有像我期望的那样拥有自己独特的字段值集。我还使用toString()方法确认它们的内存位置是分开的。我之前使用过相同的技术制作了多人游戏,但由于某些原因,这种方法无效。任何建议我都有责任。谢谢你。
此外,对于所有想要在计算机上试用的爱好者来说,这是board2课程:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class board2 extends JPanel
{
private int[][] mtx;
private int ver , hor;
private int sz;
//private int[][] nextTet;
//private int nextCol;
private int score;
private Color color;//, nexColor;
private boolean end;
public board2(int r, int c)
{
hor = r; ver = c;
sz=30;
mtx=new int[c][r+16];
setPreferredSize(new Dimension((hor+16)*sz,ver*sz+15));
setBackground(Color.WHITE);
repaint();
}
public boolean checkRow(int r)
{
for(int i=0 ; i<10 ; i++)
if(mtx[r][i]==0)
return false;
return true;
}
public void removeRow(int r) throws InterruptedException
{
for(int i=r ; i>=0 ; i--)
for(int j=0 ; j<10 ; j++)
if(i>0)
mtx[i][j]=mtx [i-1][j];
else
mtx[i][j]=0;
//mtx[0]=new int[26];
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawLine(300, 0, 300, 600);
g.drawLine(306, 0, 306, 580);
g.drawLine(26, 580, 306, 580);
for(int i=0 ; i<ver ; i++)
g.drawLine(306, i*28+20, 300, i*sz);
g.drawLine(0, 600, 300, 600);
for(int i=0 ; i<hor+1 ; i++)
g.drawLine(i*sz, 600, i*28+26, 580);
for(int i=ver-1 ; i>9 ; i--)
for(int j=hor+15 ; j>12 ; j--)
{
setColor(mtx[i][j]);
if(mtx[i][j]>0)
{
//for(int k=0 ; k<26 ; k++)
//{
g.setColor(color.darker().darker());
//g.drawLine(j*sz+k, i*sz+k, (j+1)*sz+k, i*sz+k);
g.fillPolygon(new int[] {j*sz, j*sz, j*28+26, j*28+26}, new int[] {i*sz, i*sz+sz, i*28+28+20, i*28+20}, 4);
g.setColor(color.darker());
g.fillPolygon(new int[] {j*sz, j*sz+sz, j*28+26+28, j*28+26}, new int[] {i*sz, i*sz, i*28+20, i*28+20}, 4);
//g.drawLine(j*sz+k, i*sz+k, j*sz+k, (i+1)*sz+k);
//}
g.setColor(color);
g.fillRect(j*sz, i*sz, sz, sz);
if(mtx[i][j]<8)
g.setColor(Color.BLACK);
else
g.setColor(Color.GRAY);
g.drawRect(j*sz, i*sz, sz, sz);
g.drawPolygon(new int[] {j*sz, j*sz, j*28+26, j*28+26}, new int[] {i*sz, i*sz+sz, i*28+28+20, i*28+20}, 4);
g.drawPolygon(new int[] {j*sz, j*sz+sz, j*28+26+28, j*28+26}, new int[] {i*sz, i*sz, i*28+20, i*28+20}, 4);
//g.fillPolygon(new int[] {j*sz+15, j*sz+45, j*sz+15, j*sz+45}, new int[] {i*sz+15, i*sz+15, i*sz+45, i*sz+45}, 4);
}
//g.drawRect(j*sz, i*sz, sz, sz);
}
for(int i=ver-1 ; i>9 ; i--)
for(int j=0 ; j<13 ; j++)
{
setColor(mtx[i][j]);
if(mtx[i][j]>0)
{
//for(int k=0 ; k<26 ; k++)
//{
g.setColor(color.darker().darker());
// g.drawLine(j*sz+k, i*sz+k, (j+1)*sz+k, i*sz+k);
g.fillPolygon(new int[] { j * sz + sz, j * sz + sz, j * 28 + 26 + 28, j * 28 + 26 + 28 },
new int[] { i * sz, i * sz + sz, i * 28 + 28 + 20, i * 28 + 20 }, 4);
g.setColor(color.darker());
g.fillPolygon(new int[] { j * sz, j * sz + sz, j * 28 + 26 + 28, j * 28 + 26 },
new int[] { i * sz, i * sz, i * 28 + 20, i * 28 + 20 }, 4);
//g.drawLine(j*sz+k, i*sz+k, j*sz+k, (i+1)*sz+k);
//}
g.setColor(color);
g.fillRect(j*sz, i*sz, sz, sz);
if(mtx[i][j]<8)
g.setColor(Color.BLACK);
else
g.setColor(Color.GRAY);
g.drawRect(j*sz, i*sz, sz, sz);
g.drawPolygon(new int[] {j*sz+sz, j*sz+sz, j*28+26+28, j*28+26+28}, new int[] {i*sz, i*sz+sz, i*28+28+20, i*28+20}, 4);
g.drawPolygon(new int[] {j*sz, j*sz+sz, j*28+26+28, j*28+26}, new int[] {i*sz, i*sz, i*28+20, i*28+20}, 4);
}
//g.drawRect(j*sz, i*sz, sz, sz);
}
for(int i=0 ; i<10 ; i++)
for(int j=hor+15 ; j>12 ; j--)
{
setColor(mtx[i][j]);
if(mtx[i][j]>0)
{
//for(int k=0 ; k<26 ; k++)
// {
g.setColor(color.darker());
g.fillPolygon(new int[] { j * sz, j * sz + sz, j * 28 + 26 + 28, j * 28 + 26 },
new int[] { i * sz+sz, i * sz+sz, i * 28 + 28+20, i * 28 + 28 +20 }, 4);
g.setColor(color.darker().darker());
// g.drawLine(j*sz+k, i*sz+k, (j+1)*sz+k, i*sz+k);
g.fillPolygon(new int[] { j * sz, j * sz, j * 28 + 26, j * 28 + 26 },
new int[] { i * sz, i * sz + sz, i * 28 + 28 + 20, i * 28 + 20 }, 4);
// g.drawLine(j*sz+k, i*sz+k, j*sz+k, (i+1)*sz+k);
// }
g.setColor(color);
g.fillRect(j*sz, i*sz, sz, sz);
if(mtx[i][j]<8)
g.setColor(Color.BLACK);
else
g.setColor(Color.GRAY);
g.drawRect(j*sz, i*sz, sz, sz);
g.drawPolygon(new int[] {j*sz, j*sz, j*28+26, j*28+26}, new int[] {i*sz, i*sz+sz, i*28+28+20, i*28+20}, 4);
g.drawPolygon(new int[] {j*sz, j*sz+sz, j*28+26+28, j*28+26}, new int[] {i*sz+sz, i*sz+sz, i*28+28+20, i*28+28+20}, 4);
}
//g.drawRect(j*sz, i*sz, sz, sz);
}
for(int i=0 ; i<10 ; i++)
for(int j=0 ; j<13 ; j++)
{
setColor(mtx[i][j]);
if(mtx[i][j]>0)
{
//for(int k=0 ; k<26 ; k++)
//{
g.setColor(color.darker().darker());
//g.drawLine(j*sz+k, i*sz+k, (j+1)*sz+k, i*sz+k);
g.fillPolygon(new int[] {j*sz+sz, j*sz+sz, j*28+26+28, j*28+26+28}, new int[] {i*sz, i*sz+sz, i*28+28+20, i*28+20}, 4);
g.setColor(color.darker());
g.fillPolygon(new int[] {j*sz, j*sz+sz, j*28+26+28, j*28+26}, new int[] {i*sz+sz, i*sz+sz, i*28+20+28, i*28+20+28}, 4);
//g.drawLine(j*sz+k, i*sz+k, j*sz+k, (i+1)*sz+k);
//}
g.setColor(color);
g.fillRect(j*sz, i*sz, sz, sz);
if(mtx[i][j]<8)
g.setColor(Color.BLACK);
else
g.setColor(Color.GRAY);
g.drawRect(j*sz, i*sz, sz, sz);
g.drawPolygon(new int[] {j*sz+sz, j*sz+sz, j*28+26+28, j*28+26+28}, new int[] {i*sz, i*sz+sz, i*28+28+20, i*28+20}, 4);
g.drawPolygon(new int[] {j*sz, j*sz+sz, j*28+26+28, j*28+26}, new int[] {i*sz+sz, i*sz+sz, i*28+20+28, i*28+20+28}, 4);
//g.fillPolygon(new int[] {j*sz+15, j*sz+45, j*sz+15, j*sz+45}, new int[] {i*sz+15, i*sz+15, i*sz+45, i*sz+45}, 4);
}
//g.drawRect(j*sz, i*sz, sz, sz);
}
Font font = new Font("Typo Round Regular Demo", Font.PLAIN, 20);
g.setFont(font);
g.setColor(Color.BLACK);
g.drawString("NEXT:", (hor+1)*sz, 260);
g.setFont(font.deriveFont(30f));
g.drawString("SCORE:"+score, 345, 30);
if(end)
{
g.setColor(Color.WHITE);
g.fillRect(20, 225, 440, 160);
g.setColor(Color.BLACK);
g.drawRect(20, 225, 440, 160);
g.setFont(font.deriveFont(60f));
g.drawString("GAME OVER", 63, 330);
}
}
public int getValue(int r, int c)
{
return mtx[c][r];
}
public void setTetris(int[][] tet, int c, int xShift, int yShift)
{
for(int i=0 ; i<4 ; i++)
{
//System.out.println((tet[i][0]+xShift)+","+(tet[i][1]+yShift));
mtx[tet[i][1]+yShift][tet[i][0]+xShift]=c;}
//System.out.println("\n\n");
}
public void sendNext(int[][] tetro, int color)
{
for(int i=8; i<11 ; i++)
for(int j=11; j<15 ; j++)
mtx[i][j]=0;
for(int i=0 ; i<4; i++)
mtx[tetro[i][1]+9][tetro[i][0]+12]=color;
}
private void setColor(int i)
{
switch(i)
{
case 1:
color = Color.BLUE;
break;
case 2:
color = new Color(255,128,0);
break;
case 3:
color = Color.CYAN;
break;
case 4:
color = Color.RED;
break;
case 5:
color = new Color(128,255,0);
break;
case 6:
color = Color.YELLOW;
break;
case 7:
color = Color.MAGENTA;
break;
case 8:
color = new Color(190,190,255);
break;
case 9:
color = new Color(255,222,190);
break;
case 10:
color = new Color(190,255,255);
break;
case 11:
color = new Color(255,190,190);
break;
case 12:
color = new Color(222,255,190);
break;
case 13:
color = new Color(255,255,190);
break;
case 14:
color = new Color(255,190,255);
}
}
public void setEnd(boolean s)
{
end =s;
}
public void setScore(int s)
{
score = s;
}
}
我为已经注释掉的所有代码行道歉。我应该把它们整理出来!
答案 0 :(得分:3)
您需要在需要该对象的多个实例的类中删除变量上的静态修饰符。静态意味着类中的变量只有一个值,例如,它可用于跟踪您从球类创建的球数。
有关详细信息,请参阅this。