Swing 应用程序不显示任何内容
Swing application does not display anything
我目前正在尝试使用 Java Swing 和 AWT 创建一个简单的躲避游戏。现在,我已经创建了一些简单的大纲代码来测试我尝试创建的概念是否可行。我已经使用多态性来尝试创建多种类型的对象 Enemy,它们将具有单独的 draw() 和 act() 代码,使它们由 AWT 绘制,然后根据它们的类型以特定的方式移动。我将 Graphics2D 导入到 draw() 以尝试使代码更可重用。然后我使用 while 循环 运行 Java Swing/AWT 内置线程来允许敌人的动画。然而,当我 运行 代码时,它编译正确,但只显示一个空白屏幕。
我该如何解决?
这是我使用的代码。涉及鼠标的代码不完整。
Game.java
import javax.swing.*;
import java.awt.*;
public class Game extends JPanel {
//FPS Setup
int fps = 30; //FPS
int secConst = 1000; //milliseconds per second
int frmConst = (int) Math.floor((double) secConst / (double) fps); //delay between frames
//FRAME Setup
String appName = "Dodge This"; //app name
int frameW = 500; //frame width
int frameH = 500; //frame height
//ENEMY TEST
//TO REPLACE WITH ARRAY OF ENEMIES
Square square = new Square(0, 100, 0, 10);
Circle circle = new Circle(50, 50, 10);
boolean lose = true;
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//TO REPLACE WITH LOOP THROUGH ARRAY OF ENEMIES
square.act();
square.draw(g2d);
circle.act();
circle.draw(g2d);
if (this.lose) {
g2d.setColor(new Color(0, 0, 0));
g2d.setFont(new Font("Sans Serif", Font.PLAIN, 32));
g2d.drawString("You Lose", 0, 0); //TO REPLACE WITH RANDOMIZED LOSE MESSAGE
}
}
public static void main(String [] args) throws InterruptedException {
Game game = new Game();
JFrame frame = new JFrame(game.appName);
frame.setSize(game.frameW, game.frameH);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
if (MouseInfo.getPointerInfo().getLocation().equals(new Point(game.circle.getX(), game.circle.getY())) && MouseInfo.getPointerInfo().getLocation().equals(new Point(game.square.getX(), game.square.getY()))) {
game.lose = true;
break;
}
game.repaint();
Thread.sleep(game.frmConst);
}
}
}
Enemy.java
import java.awt.*;
public abstract class Enemy {
public int x;
public int y;
public double direction;
public double speed;
//BASIC METHODS
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setDirection(double direction) {
this.direction = direction;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public double getDirection() {
return this.direction;
}
public double getSpeed() {
return this.speed;
}
//METHODS FOR UNIQUE ENEMIES
public abstract void act();
public abstract void draw(Graphics2D g2d);
}
Square.java
import java.awt.*;
public class Square extends Enemy{
//CONSTRUCTORS
public Square() {
this.x = 0;
this.y = 0;
this.direction = (int) Math.floor(Math.random() * 8) * 45;
this.speed = (int) Math.floor(Math.random() * 15);
} //default constructor
public Square(int x, int y) {
this.x = x;
this.y = y;
this.direction = (int) Math.floor(Math.random() * 8) * 45;
this.speed = (int) Math.floor(Math.random() * 15);
}
public Square(int x, int y, double direction) {
this.x = x;
this.y = y;
this.direction = direction;
this.speed = (int) Math.floor(Math.random() * 15);
}
public Square(int x, int y, double direction, double speed) {
this.x = x;
this.y = y;
this.direction = direction;
this.speed = speed;
}
//ACTIONS
@Override
public void act() {
this.x += Math.floor(this.speed * (Math.cos(this.direction)));
this.y += Math.floor(this.speed * -1 * (Math.sin(this.direction)));
}
@Override
public void draw(Graphics2D g2d) {
g2d.setColor(new Color(100, 100, 100));
g2d.fillRect(this.x, this.y, 50, 50);
}
}
Circle.java
import java.awt.*;
public class Circle extends Enemy{
double mouseX;
double mouseY;
//CONSTRUCTORS
public Circle() {
this.x = 0;
this.y = 0;
this.direction = 0;
this.speed = 5;
} //default constructor
public Circle(int x, int y) {
this.x = x;
this.y = y;
this.direction = 0;
this.speed = 5;
}
public Circle (int x, int y, int speed) {
this.x = x;
this.y = y;
this.direction = 0;
this.speed = speed;
}
//ACTIONS
@Override
public void act() {
this.mouseX = MouseInfo.getPointerInfo().getLocation().getX();
this.mouseY = MouseInfo.getPointerInfo().getLocation().getY();
this.x += this.speed * Math.floor(Math.abs(this.y - this.mouseY) / Math.abs(this.x - this.mouseX));
this.y += this.speed * -1 * Math.floor(Math.abs(this.x - this.mouseX) / Math.abs(this.y - this.mouseY));
}
@Override
public void draw(Graphics2D g2d) {
g2d.setColor(new Color(50, 50, 50));
g2d.fillOval(this.x, this.y, 10, 10);
}
}
请参阅以下代码以了解程序结构的一些改进以及更好地使用 Swing
工具。注意评论:
import java.awt.*;
import javax.swing.*;
public class Game extends JPanel {
//FPS Setup
int fps = 3; // FPS (slow for testing)
int secConst = 1000; //milliseconds per second
int frmConst = secConst / fps; //delay between frames
private Timer timer;
String appName = "Dodge This"; //app name
int frameW = 500, frameH = 500; //frame width and height
Square square = new Square(0, 100, 0., 10.);
Circle circle = new Circle(50, 50, 0., 10.);
boolean lose = false; //the correct state at start ;
//override paintComponent rather than paint
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
square.draw(g2d);
circle.draw(g2d);
if (lose) {
g2d.setColor(new Color(0, 0, 0));
g2d.setFont(new Font("Sans Serif", Font.PLAIN, 32));
g2d.drawString("You Lose", 0, 0);
}
}
public void start(){
//use swing timer to invoke game cycles
if(timer != null && timer.isRunning()) {
timer.stop();
}
timer = new Timer(frmConst, e->{
if(lose) {
timer.stop();
} else {
play();
}
}
);
timer.start();
}
public void play(){
square.act();
circle.act();
//lose criteria (not sure what are you trying to check)
if (MouseInfo.getPointerInfo().getLocation().equals(new Point(circle.getX(), circle.getY()))
&& MouseInfo.getPointerInfo().getLocation().equals(new Point(square.getX(), square.getY()))) {
lose = true;
}
repaint();
}
public static void main(String [] args) throws InterruptedException {
Game game = new Game();
JFrame frame = new JFrame(game.appName);
frame.setSize(game.frameW, game.frameH);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(game);// add game to frame
game.start();
}
}
abstract class Enemy {
public int x,y;
public double direction, speed;
public Enemy(int x, int y, double speed) {
this(x,y,0, speed);
}
public Enemy(int x, int y, double direction, double speed) {
this.x = x;
this.y = y;
this.direction = direction;
this.speed = speed;
}
//BASIC METHODS
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setDirection(double direction) {
this.direction = direction;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public double getDirection() {
return direction;
}
public double getSpeed() {
return speed;
}
//METHODS FOR UNIQUE ENEMIES
public abstract void act();
public abstract void draw(Graphics2D g2d);
}
class Square extends Enemy{
public Square(int x, int y, double direction, double speed) {
super(x, y, direction, speed);
}
@Override
public void act() {
x += Math.floor(speed * Math.cos(direction));
y += Math.floor(speed * -1 * Math.sin(direction));
}
@Override
public void draw(Graphics2D g2d) {
g2d.setColor(new Color(100, 100, 100));
g2d.fillRect(x, y, 50, 50);
}
}
class Circle extends Enemy{
double mouseX, mouseY;
public Circle(int x, int y, double direction, double speed) {
super(x, y, direction, speed);
}
@Override
public void act() {
mouseX = MouseInfo.getPointerInfo().getLocation().getX();
mouseY = MouseInfo.getPointerInfo().getLocation().getY();
x += speed * Math.floor(Math.abs(y - mouseY) / Math.abs(x - mouseX));
y += speed * -1 * Math.floor(Math.abs(x - mouseX) / Math.abs(y - mouseY));
}
@Override
public void draw(Graphics2D g2d) {
g2d.setColor(new Color(50, 50, 50));
g2d.fillOval(x, y, 10, 10);
}
}
(运行它在线here)
我目前正在尝试使用 Java Swing 和 AWT 创建一个简单的躲避游戏。现在,我已经创建了一些简单的大纲代码来测试我尝试创建的概念是否可行。我已经使用多态性来尝试创建多种类型的对象 Enemy,它们将具有单独的 draw() 和 act() 代码,使它们由 AWT 绘制,然后根据它们的类型以特定的方式移动。我将 Graphics2D 导入到 draw() 以尝试使代码更可重用。然后我使用 while 循环 运行 Java Swing/AWT 内置线程来允许敌人的动画。然而,当我 运行 代码时,它编译正确,但只显示一个空白屏幕。
我该如何解决?
这是我使用的代码。涉及鼠标的代码不完整。
Game.java
import javax.swing.*;
import java.awt.*;
public class Game extends JPanel {
//FPS Setup
int fps = 30; //FPS
int secConst = 1000; //milliseconds per second
int frmConst = (int) Math.floor((double) secConst / (double) fps); //delay between frames
//FRAME Setup
String appName = "Dodge This"; //app name
int frameW = 500; //frame width
int frameH = 500; //frame height
//ENEMY TEST
//TO REPLACE WITH ARRAY OF ENEMIES
Square square = new Square(0, 100, 0, 10);
Circle circle = new Circle(50, 50, 10);
boolean lose = true;
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//TO REPLACE WITH LOOP THROUGH ARRAY OF ENEMIES
square.act();
square.draw(g2d);
circle.act();
circle.draw(g2d);
if (this.lose) {
g2d.setColor(new Color(0, 0, 0));
g2d.setFont(new Font("Sans Serif", Font.PLAIN, 32));
g2d.drawString("You Lose", 0, 0); //TO REPLACE WITH RANDOMIZED LOSE MESSAGE
}
}
public static void main(String [] args) throws InterruptedException {
Game game = new Game();
JFrame frame = new JFrame(game.appName);
frame.setSize(game.frameW, game.frameH);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
if (MouseInfo.getPointerInfo().getLocation().equals(new Point(game.circle.getX(), game.circle.getY())) && MouseInfo.getPointerInfo().getLocation().equals(new Point(game.square.getX(), game.square.getY()))) {
game.lose = true;
break;
}
game.repaint();
Thread.sleep(game.frmConst);
}
}
}
Enemy.java
import java.awt.*;
public abstract class Enemy {
public int x;
public int y;
public double direction;
public double speed;
//BASIC METHODS
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setDirection(double direction) {
this.direction = direction;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public double getDirection() {
return this.direction;
}
public double getSpeed() {
return this.speed;
}
//METHODS FOR UNIQUE ENEMIES
public abstract void act();
public abstract void draw(Graphics2D g2d);
}
Square.java
import java.awt.*;
public class Square extends Enemy{
//CONSTRUCTORS
public Square() {
this.x = 0;
this.y = 0;
this.direction = (int) Math.floor(Math.random() * 8) * 45;
this.speed = (int) Math.floor(Math.random() * 15);
} //default constructor
public Square(int x, int y) {
this.x = x;
this.y = y;
this.direction = (int) Math.floor(Math.random() * 8) * 45;
this.speed = (int) Math.floor(Math.random() * 15);
}
public Square(int x, int y, double direction) {
this.x = x;
this.y = y;
this.direction = direction;
this.speed = (int) Math.floor(Math.random() * 15);
}
public Square(int x, int y, double direction, double speed) {
this.x = x;
this.y = y;
this.direction = direction;
this.speed = speed;
}
//ACTIONS
@Override
public void act() {
this.x += Math.floor(this.speed * (Math.cos(this.direction)));
this.y += Math.floor(this.speed * -1 * (Math.sin(this.direction)));
}
@Override
public void draw(Graphics2D g2d) {
g2d.setColor(new Color(100, 100, 100));
g2d.fillRect(this.x, this.y, 50, 50);
}
}
Circle.java
import java.awt.*;
public class Circle extends Enemy{
double mouseX;
double mouseY;
//CONSTRUCTORS
public Circle() {
this.x = 0;
this.y = 0;
this.direction = 0;
this.speed = 5;
} //default constructor
public Circle(int x, int y) {
this.x = x;
this.y = y;
this.direction = 0;
this.speed = 5;
}
public Circle (int x, int y, int speed) {
this.x = x;
this.y = y;
this.direction = 0;
this.speed = speed;
}
//ACTIONS
@Override
public void act() {
this.mouseX = MouseInfo.getPointerInfo().getLocation().getX();
this.mouseY = MouseInfo.getPointerInfo().getLocation().getY();
this.x += this.speed * Math.floor(Math.abs(this.y - this.mouseY) / Math.abs(this.x - this.mouseX));
this.y += this.speed * -1 * Math.floor(Math.abs(this.x - this.mouseX) / Math.abs(this.y - this.mouseY));
}
@Override
public void draw(Graphics2D g2d) {
g2d.setColor(new Color(50, 50, 50));
g2d.fillOval(this.x, this.y, 10, 10);
}
}
请参阅以下代码以了解程序结构的一些改进以及更好地使用 Swing
工具。注意评论:
import java.awt.*;
import javax.swing.*;
public class Game extends JPanel {
//FPS Setup
int fps = 3; // FPS (slow for testing)
int secConst = 1000; //milliseconds per second
int frmConst = secConst / fps; //delay between frames
private Timer timer;
String appName = "Dodge This"; //app name
int frameW = 500, frameH = 500; //frame width and height
Square square = new Square(0, 100, 0., 10.);
Circle circle = new Circle(50, 50, 0., 10.);
boolean lose = false; //the correct state at start ;
//override paintComponent rather than paint
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
square.draw(g2d);
circle.draw(g2d);
if (lose) {
g2d.setColor(new Color(0, 0, 0));
g2d.setFont(new Font("Sans Serif", Font.PLAIN, 32));
g2d.drawString("You Lose", 0, 0);
}
}
public void start(){
//use swing timer to invoke game cycles
if(timer != null && timer.isRunning()) {
timer.stop();
}
timer = new Timer(frmConst, e->{
if(lose) {
timer.stop();
} else {
play();
}
}
);
timer.start();
}
public void play(){
square.act();
circle.act();
//lose criteria (not sure what are you trying to check)
if (MouseInfo.getPointerInfo().getLocation().equals(new Point(circle.getX(), circle.getY()))
&& MouseInfo.getPointerInfo().getLocation().equals(new Point(square.getX(), square.getY()))) {
lose = true;
}
repaint();
}
public static void main(String [] args) throws InterruptedException {
Game game = new Game();
JFrame frame = new JFrame(game.appName);
frame.setSize(game.frameW, game.frameH);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(game);// add game to frame
game.start();
}
}
abstract class Enemy {
public int x,y;
public double direction, speed;
public Enemy(int x, int y, double speed) {
this(x,y,0, speed);
}
public Enemy(int x, int y, double direction, double speed) {
this.x = x;
this.y = y;
this.direction = direction;
this.speed = speed;
}
//BASIC METHODS
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setDirection(double direction) {
this.direction = direction;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public double getDirection() {
return direction;
}
public double getSpeed() {
return speed;
}
//METHODS FOR UNIQUE ENEMIES
public abstract void act();
public abstract void draw(Graphics2D g2d);
}
class Square extends Enemy{
public Square(int x, int y, double direction, double speed) {
super(x, y, direction, speed);
}
@Override
public void act() {
x += Math.floor(speed * Math.cos(direction));
y += Math.floor(speed * -1 * Math.sin(direction));
}
@Override
public void draw(Graphics2D g2d) {
g2d.setColor(new Color(100, 100, 100));
g2d.fillRect(x, y, 50, 50);
}
}
class Circle extends Enemy{
double mouseX, mouseY;
public Circle(int x, int y, double direction, double speed) {
super(x, y, direction, speed);
}
@Override
public void act() {
mouseX = MouseInfo.getPointerInfo().getLocation().getX();
mouseY = MouseInfo.getPointerInfo().getLocation().getY();
x += speed * Math.floor(Math.abs(y - mouseY) / Math.abs(x - mouseX));
y += speed * -1 * Math.floor(Math.abs(x - mouseX) / Math.abs(y - mouseY));
}
@Override
public void draw(Graphics2D g2d) {
g2d.setColor(new Color(50, 50, 50));
g2d.fillOval(x, y, 10, 10);
}
}
(运行它在线here)