首页 > 解决方案 > Swing 应用程序不显示任何内容

问题描述

我目前正在尝试使用 Java Swing 和 AWT 创建一个简单的躲闪游戏。现在,我创建了一些简单的大纲代码来测试我尝试创建的概念是否有效。我使用多态性来尝试创建多种类型的对象 Enemy,它们将具有单独的 draw() 和 act() 代码,使它们由 AWT 绘制,然后根据它们的类型以特定的方式移动。我将 Graphics2D 导入到 draw() 以尝试使代码更可重用。然后我使用了一个 while 循环来运行 Java Swing/AWT 内置线程以允许为敌人制作动画。但是,当我运行代码时,它可以正确编译,但只显示一个空白屏幕。

Java Swing 输出

我该如何解决?

这是我使用的代码。涉及鼠标的代码不完整。

游戏.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);
            }
        }
    }

敌人.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);
        }
    }

标签: javaswingawt

解决方案


有关程序结构的一些改进以及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);
    }
}

(在这里在线运行)


推荐阅读