我一直在制作一个简单的俄罗斯方块游戏来提高我的java技能,这里有两个类:
import java.awt.*;
import java.util.ArrayList;
public class Piece{
int posX;
int posY;
boolean controllable;
Rectangle pixel;
Rectangle leftBorder = new Rectangle(0,0,20, 400);
Rectangle rightBorder = new Rectangle(180, 0, 20,400);
Rectangle bottomBorder = new Rectangle(0, 300, 200, 20);
ArrayList<Rectangle> boardPieces = new ArrayList<>();
//constructor
public Piece(){
spawnNew();
}
public int getPosX(){
return pixel.x;
}
public int getPosY(){
return pixel.y;
}
public void createPixel(){
pixel = new Rectangle(posX*20, posY*20, 20, 20);
}
public void drawPixel(Graphics g, Rectangle r){
Graphics2D g2D = (Graphics2D) g;
g2D.fill(r);
}
public void spawnNew(){
if (pixel != null){
boardPieces.add(new Rectangle(getPosX(), getPosY(), 20, 20));
}
controllable = true;
posX = 3;
posY = 0;
createPixel();
}
public void move(char c, String s){
if(controllable){
switch (c){
//go in x direction
case 'x':
if(s.equals("+")){//right
posX ++;
createPixel();
if(detectCollision(rightBorder) || detectCollision()){
posX --;
createPixel();
}
}else{//left
posX --;
createPixel();
if(detectCollision(leftBorder) || detectCollision()){
posX ++;
createPixel();
}
}
break;
//go in y direction
case 'y':
if(s.equals("+")){//down
posY ++;
createPixel();
if(detectCollision(bottomBorder) || detectCollision()){
posY--;
controllable = false;
createPixel();
}
}else{//up
posY --;
createPixel();
}
break;
}
}
}
public boolean detectCollision(Rectangle r){
return pixel.intersects(r);
}
public boolean detectCollision(){
boolean collision = false;
for (Rectangle boardPiece : boardPieces) {
if (boardPiece != null) {
collision = pixel.intersects(boardPiece);
}
}
System.out.println(boardPieces.toString());
return collision;
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class GamePanel extends JPanel implements KeyListener{
Piece piece;
//constructor
public GamePanel() {
piece = new Piece();
//set panel attributes
this.setPreferredSize(new Dimension(200, 400));
this.addKeyListener(this);
this.setFocusable(true);
this.requestFocusInWindow();
//create timer
Timer fallTimer = new Timer(500, _-> {
piece.move('y', "+");
if(!piece.controllable){
piece.createPixel();
piece.spawnNew();
}
repaint();
});
fallTimer.start();
}
@Override
public void paintComponent(Graphics g){
//clear background
super.paintComponent(g);
g.setColor(Color.black);
piece.drawPixel(g, piece.pixel);
g.setColor(Color.green);
for (Rectangle i: piece.boardPieces){
if (i != null) {
piece.drawPixel(g, i);
}
}
g.setColor(Color.red);
piece.drawPixel(g, piece.bottomBorder);
piece.drawPixel(g, piece.leftBorder);
piece.drawPixel(g, piece.rightBorder);
}
//empty
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()){
//"a"
case 65:
piece.move('x', "-");
repaint();
break;
//"d"
case 68:
piece.move('x', "+");
repaint();
break;
//"s"
case 83:
piece.move('y', "+");
if(!piece.controllable){
piece.spawnNew();
}
repaint();
break;
//"space"
case 32:
while(piece.controllable){
piece.move('y', "+");
}
repaint();
if(!piece.controllable){
piece.spawnNew();
}
repaint();
break;
}
}
//get key codes
@Override
public void keyReleased(KeyEvent e) {
this.requestFocusInWindow();
System.out.printf("%c: %d\n", e.getKeyChar(), e.getKeyCode());
}
}
我也有一个框架类,但只有几行,例如frame.pack()和frame.add(panel)... 我希望您不要评论我的代码的效率,因为我正在尝试通过自己的生活和解决来解决每个问题。但如果您对我应该如何更改代码有任何批评性和建设性的意见,我不会说不。
由于某种原因,我的碰撞检测仅适用于最后放置的棋子,而不是所有棋盘棋子。我尝试使用 ArrayList 类的 .toArray() 方法,以防数组列表可能出现问题,但这不起作用。
这基本上应该是一条评论,但是有点长。 在您的
detectCollision()
方法中,您迭代棋盘列表,然后返回该测试的最后一个值。 换句话说,您会覆盖每个循环的碰撞检测值,因此您只能获得列表中的最后一个值。
public boolean detectCollision(){
boolean collision = false;
for (Rectangle boardPiece : boardPieces) {
if (boardPiece != null) {
// This overwrites the previous value
collision = pixel.intersects(boardPiece);
}
}
System.out.println(boardPieces.toString());
return collision;
}
通过立即返回碰撞来修复此问题:
if( pixel.intersects(boardPiece) ) return true;
或者通过累积该值,这样它就不会被覆盖。
collision |= pixel.intersects(boardPiece);