用Java编写的砖块支撑游戏

用Java编写的砖块支撑游戏,java,Java,我是Java新手,正在尝试用Java构建一个破砖游戏。我已经从网上搜索了很多说明来构建这个。我这里有一个问题,我无法在网上找到解决方案 当我运行代码时,它工作得很好,但是当球击中帧的顶部时,它只是穿过它,再也不会回来。我想让球击中顶部并从中反射。谁能帮我解决这个问题。我写了三节课。请让我知道任何有帮助的事情 这是主要课程: package brickBreaker; import javax.swing.JFrame; class Main { public static void

我是Java新手,正在尝试用Java构建一个破砖游戏。我已经从网上搜索了很多说明来构建这个。我这里有一个问题,我无法在网上找到解决方案

当我运行代码时,它工作得很好,但是当球击中帧的顶部时,它只是穿过它,再也不会回来。我想让球击中顶部并从中反射。谁能帮我解决这个问题。我写了三节课。请让我知道任何有帮助的事情

这是主要课程:

 package brickBreaker;

 import javax.swing.JFrame;

 class Main {

public static void main(String[] args) {
    JFrame obj = new JFrame();
    Gameplay gamePlay = new Gameplay();
    obj.setBounds(10, 10, 700, 600);
    obj.setTitle("Breakout Ball");
    obj.setResizable(false);
    obj.setVisible(true);
    obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    obj.add(gamePlay);
}

}
这是游戏类:

package brickBreaker;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.Timer;
import javax.swing.JPanel;

public class Gameplay extends JPanel implements KeyListener, ActionListener{
private boolean play = false;
private int score = 0;

private int totalBricks = 21;

private Timer timer;
private int delay = 8;

private int playerX = 310;

private int ballposX = 120;
private int ballposY = 350;
private int ballXdir = -1;
private int ballYdir = -2;

private MapGenerator map;

public Gameplay() {
    map = new MapGenerator(3, 7);
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
    timer = new Timer(delay, this);
    timer.start();
}

public void paint(Graphics g) {
    //background
    g.setColor(Color.black);
    g.fillRect(1, 1, 692, 592);
    
    // drawing map
    map.draw((Graphics2D) g);
    
    // scores
    g.setColor(Color.white);
    g.setFont(new Font("serif", Font.BOLD, 25));
    g.drawString(""+score, 590, 30);

    
    // borders
    g.setColor(Color.yellow);
    g.fillRect(0, 0, 3, 592);
    g.fillRect(0 , 0, 692, 3);
    g.fillRect(692, 0, 3, 592);
    
    // the paddle
    g.setColor(Color.green);
    g.fillRect(playerX, 550, 100, 8);
    
    // the ball
    g.setColor(Color.yellow);
    g.fillOval(ballposX, ballposY, 20, 20);
    
    if (ballposY > 570) {
        play = false;
        ballXdir = 0;
        ballYdir = 0;
        g.setColor(Color.red);
        g.setFont(new Font("serif", Font.BOLD, 30));
        g.drawString("Game Over, Scores: ", 190, 300);
        
        g.setFont(new Font("serif", Font.BOLD, 20));
        g.drawString("Press Enter to Restart ", 230, 350);
    }
    
    if (totalBricks <= 0) {
        play = false;
        ballXdir = 0;
        ballYdir = 0;
        g.setColor(Color.red);
        g.setFont(new Font("serif", Font.BOLD, 30));
        g.drawString("You Won, Scores: ", 190, 300);
        
        g.setFont(new Font("serif", Font.BOLD, 20));
        g.drawString("Press Enter to Restart ", 230, 350);
    }
    
    g.dispose();
}

@Override
public void actionPerformed (ActionEvent e) {
    timer.start();
    if (play) {
        if (new Rectangle(ballposX, ballposY, 20, 20).intersects(new Rectangle(playerX, 550, 100, 8))) {
            ballYdir = -ballYdir;
        }
        
        A: for (int i = 0; i <map.map.length; i++) {
            for (int j = 0; j < map.map[0].length; j++) {
                if (map.map[i][j] > 0) {
                    int brickX = j * map.brickWidth + 80;
                    int brickY = i * map.brickHeight + 50;
                    int brickWidth = map.brickWidth;
                    int brickHeight = map.brickHeight;
                    
                    Rectangle rect = new Rectangle(brickX, brickY, brickWidth, brickHeight);
                    Rectangle ballRect = new Rectangle(ballposX, ballposY, 20, 20);
                    Rectangle brickRect = rect;
                    
                    if (ballRect.intersects(brickRect)) {
                        map.setBrickValue(0, i, j);
                        totalBricks--;
                        score += 10;
                        
                        if (ballposX + 19 <= brickRect.x || ballposX + 1 >= brickRect.x + brickRect.width) {
                            ballXdir = -ballXdir;
                        } else {
                            ballYdir = -ballYdir;
                        }
                        
                        break A;
                    }
                }
            }
        }
        
        ballposX += ballXdir;
        ballposY += ballYdir;
        if (ballposX < 0) {
            ballXdir = -ballXdir;
        }
        if (ballposY < 0) {
            ballXdir = -ballYdir;
        }
        if (ballposX > 670) {
            ballXdir = -ballXdir;
        }
    }
    
    
    repaint();
    
}
@Override
public void keyReleased (KeyEvent e) {}

@Override
public void keyTyped (KeyEvent e) {}

@Override
public void keyPressed (KeyEvent e) {
    if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
        if (playerX >= 600) {
            playerX = 600;
        } else {
            moveRight();
        }
    }
    if(e.getKeyCode() == KeyEvent.VK_LEFT) {
        if (playerX < 10) {
            playerX = 10;
        } else {
            moveLeft();
        }
    }
    
    if(e.getKeyCode() == KeyEvent.VK_ENTER) {
        if (!play) {
            play = true;
            ballposX = 120;
            ballposY = 350;
            ballXdir = -1;
            ballYdir = -2;
            playerX = 310;
            score = 0;
            totalBricks = 21;
            map = new MapGenerator (3, 7);
            
            repaint();
        }
    }
    
}
public void moveRight() {
    play = true;
    playerX += 20;
}
public void moveLeft() {
    play = true;
    playerX -= 20;
}

}
包装拆砖机;
导入java.awt.Color;
导入java.awt.Font;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Rectangle;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入javax.swing.Timer;
导入javax.swing.JPanel;
公共类游戏扩展JPanel实现KeyListener、ActionListener{
私有布尔播放=假;
私人智力得分=0;
私人整数=21;
私人定时器;
专用int延迟=8;
专用整数播放器x=310;
私有int-ballposX=120;
私人整数ballposY=350;
私有int-ballXdir=-1;
私有int-ballYdir=-2;
私有地图生成器地图;
公共游戏{
map=新的MapGenerator(3,7);
addKeyListener(此);
设置聚焦(真);
setFocusTraversalKeysEnabled(false);
定时器=新定时器(延迟,此);
timer.start();
}
公共空间涂料(图g){
//背景
g、 设置颜色(颜色为黑色);
g、 fillRect(1,1692,592);
//制图
绘制地图((图2d)g);
//得分
g、 setColor(Color.white);
g、 setFont(新字体(“衬线”,Font.BOLD,25));
g、 抽绳(“+”分数590,30);
//边界
g、 setColor(颜色为黄色);
g、 fillRect(0,0,3592);
g、 fillRect(0,0692,3);
g、 fillRect(692,0,3592);
//桨
g、 setColor(Color.green);
g、 fillRect(playerX,550100,8);
//球
g、 setColor(颜色为黄色);
g、 fillOval(ballposX,ballposY,20,20);
如果(ballposY>570){
玩=假;
ballXdir=0;
ballYdir=0;
g、 setColor(Color.red);
g、 setFont(新字体(“衬线”,Font.BOLD,30));
g、 抽绳(“游戏结束,分数:”,190300);
g、 setFont(新字体(“衬线”,Font.BOLD,20));
g、 抽绳(“按回车键重新启动”,230、350);
}
如果(总计670){
ballXdir=-ballXdir;
}
}
重新油漆();
}
@凌驾
public void keyReleased(KeyEvent e){}
@凌驾
public void keyTyped(KeyEvent e){}
@凌驾
按下公共无效键(按键事件e){
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
如果(playerX>=600){
playerX=600;
}否则{
moveRight();
}
}
如果(例如getKeyCode()==KeyEvent.VK_左){
如果(playerX<10){
playerX=10;
}否则{
左移();
}
}
如果(例如getKeyCode()==KeyEvent.VK_ENTER){
如果(!玩){
玩=真;
ballposX=120;
ballposY=350;
ballXdir=-1;
ballYdir=-2;
playerX=310;
得分=0;
totalBricks=21;
map=新的MapGenerator(3,7);
重新油漆();
}
}
}
公权{
玩=真;
playerX+=20;
}
公共空间左移(){
玩=真;
playerX-=20;
}
}
这是MapGenerator类:

package brickBreaker;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;

public class MapGenerator {
public int map[][];
public int brickWidth;
public int brickHeight;
public MapGenerator(int row, int col) {
    map = new int [row][col];
    for (int i = 0; i < map.length; i++) {
        for (int j = 0; j < map[0].length; j++) {
            map[i][j] = 1;
        }
    }
    
    brickWidth = 540/col;
    brickHeight = 150/row;
}
public void draw(Graphics2D g) {
    for (int i = 0; i < map.length; i++) {
        for (int j = 0; j < map[0].length; j++) {
            if (map[i][j] > 0) {
                g.setColor(Color.white);
                g.fillRect(j * brickWidth + 80, i * brickHeight + 50, brickWidth, 
brickHeight);
                
                g.setStroke(new BasicStroke(3));
                g.setColor(Color.black);
                g.drawRect(j * brickWidth + 80, i * brickHeight + 50, brickWidth, 
brickHeight);
            }
        }
    }
}
public void setBrickValue(int value, int row, int col) {
    map[row][col] = value;
}
}
包装拆砖机;
导入java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Graphics2D;
公共类映射生成器{
公共整数映射[];
砖缝公共区域;
公共设施;
公共映射生成器(整数行,整数列){
map=新整数[行][列];
对于(int i=0;i0){
g、 setColor(Color.white);
g、 fillRect(j*BRICKWITTH+80,i*BRICKWITTH+50,BRICKWITTH,
砖块);
g、 设定行程(新基本行程(3));
g、 设置颜色(颜色为黑色);
g、 drawRect(j*BRICKWITTH+80,i*BRICKWITTH+50,BRICKWITTH,
砖块);
}
}
}
}
公共值(int值、int行、int列){
映射[行][列]=值;
}
}

在第140-142行,您有

if (ballposY < 0) {
    ballXdir = -ballYdir;
}

它将正确地从顶部弹起。

在第140-142行,您有

if (ballposY < 0) {
    ballXdir = -ballYdir;
}

它将正确地从顶部反弹。

您需要做的是在地图上实现一个边界,并在到达边界顶部时反转运动。可以通过在该边界处启动重新绘制来实现这一点。我建议在每次重新绘制时使用一个函数来检查这些边界,因为您正在构建自己的引擎。我想我已经实现了顶部边界。我如何使用函数来检查边界?顺便说一句,感谢您的回答:)您需要做的是在地图上实现边界,并在到达边界顶部时反转运动。可以通过在该边界处启动重新绘制来实现这一点。我建议在每次重新绘制时使用一个函数来检查这些边界,因为您正在构建自己的引擎。我想我已经实现了顶部边界。如何使用函数检查边界?顺便说一句,感谢您的回答:)