【发布时间】:2021-09-30 23:12:45
【问题描述】:
我目前正在尝试使用 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);
}
}
【问题讨论】:
-
您似乎没有将
Game面板添加到框架中。 -
Swing 不是线程安全的,你很“狂野”
while-loop会导致很多问题。MouseInfo并不是监视鼠标位置的最佳选择,因为您需要将坐标从屏幕上下文转换为组件上下文,最好使用各种MouseListeners。我还建议不要覆盖paint,并且作为一般偏好,请改为覆盖paintComponent。所有这些都需要改变你思考问题的方式 -
在任何情况下,
square.act()和circle.act()都不应该在绘画方法中。您无法控制绘画何时发生;系统会。各种你无法控制的事情都可能触发绘画,包括移动窗口,甚至将鼠标移到窗口上方。 -
@khelwood 我不敢相信我忘记添加了