【发布时间】:2021-12-06 15:53:16
【问题描述】:
这是我创建主方法的主文件。我在此处添加了 JFrame 以使其更易于理解。我在第二个文件中创建了一个布尔变量,只要按下空格键,该变量就会更新为 true。然后我通过在主类中创建一个对象来使用该变量,然后添加条件语句以使 1 帧可见,反之亦然。
import javax.swing.JFrame;
public class MainCode{
public static void main(String args[]){
JFrame f=new JFrame();
Gameplay GP = new Gameplay();
GameplayLv2 g2 = new GameplayLv2();
JFrame frame2 = new JFrame();
f.setBounds(10,10,1000,700);
f.setTitle("Breakout Ball");
f.setResizable(false);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(GP);
if(GP.flagCheck==true){
f.setVisible(false);
f.remove(GP);
frame2.setBounds(10,10,1000,700);
frame2.setTitle("Breakout Ball");
frame2.setResizable(false);
frame2.setVisible(true);
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.add(g2);
}
}
}
这是游戏文件,级别 1。我一直面临的问题是这段代码的底部,即 keyEvent 块。
import javax.swing.JPanel;
import java.awt.*;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Graphics;
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.JFrame;
public class Gameplay extends JPanel implements KeyListener, ActionListener{
public boolean play=false; //prevents game from starting on its own...
public int score=0; //scorebar will be 0 by default...
public int totalBlocks = 30; //no.of tiles/blocks player must knock down...
public Timer speed; //speed of ball...
public int delay=5; //speed of ball....
public int playerX = 300; //starting position of the slider..
public int ballPosX = 210; //starting position of the ball..(x-axis)
public int ballPosY = 350; //starting position of the ball..(y-axis)
public int ballDirX = -1; //direction for ball to start moving in...(x axis)
public int ballDirY = -2; //direction for ball to start moving in...(y axis) //ALSO CONTROLS SPEED OF BALL ALONG Y-AXIS
public boolean flagCheck;
MapGen map;
Color ball_color = new Color(255, 252, 37); //Setting custom colors for every element using RGB values...
Color border_color = new Color(232, 20, 171);
Color border2_color = new Color(20, 232, 213);
Color slider_color = new Color(0, 240, 255);
Color bg_color = new Color(11,10,30);
Color tiles_color = new Color(255, 255, 255);
JFrame frame1 = new JFrame();
public Gameplay(){
map = new MapGen(3,10);
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
speed = new Timer(delay,this);
speed.start();
flagCheck = false;
}
public void paint(Graphics g){
g.setColor(bg_color);
g.fillRect(1, 1, 1000, 700);
//drawing the map(tiles)
map.draw((Graphics2D)g);
// adding borders so that whenever ball hits border, game ends..
g.setColor(border_color);
g.fillRect(0, 0, 10, 1000);
g.setColor(border_color);
g.fillRect(975, 0, 10, 1000);
g.setColor(border2_color);
g.fillRect(0, 0, 1000, 10);
// editing the slider/player...
g.setColor(slider_color);
g.fillRect(playerX, 620, 120, 5);
// editing the ball...
g.setColor(ball_color);
g.fillOval(ballPosX, ballPosY, 20, 20);
//scoring system
g.setColor(Color.white);
g.setFont(new Font("helvetica", Font.BOLD, 20));
g.drawString("SCORE:"+score, 800, 650);
if(ballPosY>670){ //what'll happen when the ball moves out of screen?(anything after y-axis670)? This...
play=false;
ballDirX=0;
ballDirY=0;
g.setColor(bg_color); //this BG will act as a layer on top of the previous screen, hence, covering unnecessarry elements...
g.fillRect(1, 1, 1000, 700);
g.setColor(slider_color);
g.setFont(new Font("helvetica", Font.BOLD, 25)); //scoreboard display after game ends..
g.drawString("SCORE:"+score, 440, 200);
g.setColor(slider_color);
g.setFont(new Font("helvetica", Font.BOLD, 40)); //game over text displayed after game ends..
g.drawString("GAME OVER!", 370, 300);
g.setColor(slider_color);
g.setFont(new Font("helvetica", Font.BOLD, 40)); //restart text displayed after game ends..
g.drawString("Press enter to retry", 260, 405);
}
if(score==30){ //make it 150 //what'll happen when the score is 150, ie win
play=false;
ballDirX=210;
ballDirY=350;
g.setColor(bg_color); //this BG will act as a layer on top of the previous screen, hence, covering unnecessarry elements...
g.fillRect(1, 1, 1000, 700);
g.setColor(slider_color);
g.setFont(new Font("helvetica", Font.BOLD, 25)); //scoreboard display after game ends..
g.drawString("SCORE:"+score, 420, 200);
g.setColor(slider_color);
g.setFont(new Font("helvetica", Font.BOLD, 40)); //game over text displayed after game ends..
g.drawString("YOU WIN", 400, 300);
g.setColor(slider_color);
g.setFont(new Font("helvetica", Font.BOLD, 40)); //go to next level text displayed after game ends..
g.drawString("Press space to continue to next level", 155, 405);
}
g.dispose();
}
@Override
public void actionPerformed(ActionEvent e) {
speed.start();
if(play==true){
if(new Rectangle(ballPosX, ballPosY, 20, 20).intersects(new Rectangle(playerX, 620, 120, 10)))
//creates an invisible rectangle around the slider and ball which helps with interaction control
{
ballDirY=-ballDirY;
}
A: for(int i=0; i<map.map.length; i++){ //one of the maps are MapGen map; while the other map is from @mapGen class to access the double dimensional array...
for(int j=0; j<map.map[0].length; j++){
if(map.map[i][j]>0){
int tX = j*map.tW+80;
int tY = i*map.tH+50;
int tW = map.tW;
int tH = map.tH;
Rectangle rect = new Rectangle(tX, tY, tW, tH); //creates invisible rects around tiles to detect interaction with ball...
Rectangle ballRect = new Rectangle(ballPosX, ballPosY, 20, 20);
Rectangle tileRect = rect;
if(ballRect.intersects(tileRect)){ //removes one triangle everytime interaction takes place and increases the score by 5...
map.setTileValue(0, i, j);
totalBlocks--;
score+=5;
if(ballPosX+19 <= tileRect.x || ballPosX+1 >= tileRect.x + tileRect.width){ //specifies which direction the ball must head to after interacting with the tiles...
ballDirX=-ballDirX;
}
else{
ballDirY=-ballDirY;
}
break A;
}
}
}
}
ballPosX+=ballDirX;
ballPosY+=ballDirY;
//specifies where the ball will have to shift position. In this case, on hitting either of the borders, position(x-y-coordinates) will change....
if(ballPosX<0)
ballDirX=-ballDirX;
if(ballPosY<0)
ballDirY=-ballDirY;
if(ballPosX>960)
ballDirX=-ballDirX;
}
repaint(); //will re-draw every element(slider etc)...
}
@Override
public void keyTyped(KeyEvent e) {} //unnecessarry methods that when removed produced error...so..yeah...
@Override
public void keyReleased(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_RIGHT)
{
if(playerX>=855) //prevents the paddle/slider from moving out of the screen
playerX=855;
else
moveRight();
}
if(e.getKeyCode()==KeyEvent.VK_LEFT)
{
if(playerX<=10) //prevents the paddle/slider from moving out of the screen
playerX=10;
else
moveLeft();
}
if(e.getKeyCode()==KeyEvent.VK_ENTER){ //What actions must take place when "ENTER" key is pressed. In this context, restarting of game...
if(!play){
play=false;
ballPosX = 210;
ballPosY = 350;
ballDirX = -1;
ballDirY = -2;
playerX = 300;
score=0;
totalBlocks=30;
map=new MapGen(3,10);
repaint();
}
}
if(e.getKeyCode()==KeyEvent.VK_SPACE){ //what actions must take place when "SPACE" key is pressed. In this context, moving to new level-to be implmented...
if(!play && score==30){
flagCheck=true;
System.out.println(flagCheck); //console stuff
}
}
}
public void moveRight(){ //helps with the movement of slider. +values move right on x-axis whereas -values move left on x-axis
play=true;
playerX+=40;
}
public void moveLeft(){
play=true;
playerX-=40;
}
}
【问题讨论】:
-
1) 在键监听器上使用键绑定。 2)使用布局。 3) Edit 添加minimal reproducible example。显示关键侦听器失败不需要 2 个类和 300 多行代码。他们可以在 20 LOC 内做到这一点。
-
长答案是,不是那样的。除了使用键绑定之外,您不需要切换窗口,而是有一个“主”面板为您进行切换。另外,不要覆盖
paint,也不要在正在运行的绘画过程中调用repaint -
谢谢你们的帮助!