简体   繁体   English

如何在Java Swing中在屏幕上显示球

[英]how to show balls on screen in java swing

this is my board class and i try to call ball object in GameBoard class but i didn't and my problem is didn't show ball on screen. 这是我的棋盘类,我尝试在GameBoard类中调用球对象,但我没有,但我的问题是没有在屏幕上显示球。 Used to execute code after a given delay The attribute is corePoolSize - the number of threads to keep in the pool, even if they are idle 用于在给定的延迟后执行代码属性为corePoolSize-即使在空闲状态下也要保留在池中的线​​程数

package test2;

public class Board extends JFrame{


    public static int boardWidth = 800;
    public static int boardHeight = 800;

    public static void main(String[] args){
        new Board();
    }
    public Board() {

        this.setSize(boardWidth, boardHeight);
        this.setTitle("Ball");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        GameBoard gb = new GameBoard();

        this.add(gb, BorderLayout.CENTER);

        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5);

        executor.scheduleAtFixedRate(new RepaintTheBoard(this), 0L, 20L, TimeUnit.MILLISECONDS); 

        this.setVisible(true);
    }

}

class RepaintTheBoard implements Runnable{

    Board theBoard;

    public RepaintTheBoard(Board theBoard){
        this.theBoard = theBoard;
    }

    @Override
    public void run() {

        // Redraws the game board

        theBoard.repaint();

    }

}

@SuppressWarnings("serial")

//GameDrawingPanel is what we are drawing on

class GameBoard extends JComponent { 

    Random rnd=new Random();

    public ArrayList<Ball> balls = new ArrayList<Ball>();

    int width = Board.boardWidth;
    int height = Board.boardHeight;

    public GameBoard(){
        for(int i=0; i<50; i++){

            int randomStartXPos = (int) (Math.random() * (Board.boardWidth - 40) + 1);
            int randomStartYPos = (int) (Math.random() * (Board.boardHeight - 40) + 1);

            balls.add(new Ball(randomStartXPos,randomStartYPos,30));
        }
    }



    public void paint(Graphics g) { 


        // Allows me to make many settings changes in regards to graphics

        Graphics2D g2d = (Graphics2D)g; 
        g2d.setColor(Color.BLACK);
        g2d.fillRect(0, 0, getWidth(), getHeight());



        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        g2d.setPaint(new Color(rnd.nextInt(255),rnd.nextInt(255),rnd.nextInt(255)));


        for(Ball ball : balls){
            ball.move();

            g2d.draw(ball);

        }



    }

}

this ball class and i think , i have problem in move() class 这个球类,我认为move()类有问题

package test2;

import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;

public class Ball extends Ellipse2D{

    int uLeftXPos, uLeftYPos;

    int xDirection = 1;
    int yDirection = 1;

    int diameter;
    int width = Board.boardWidth;
    int height = Board.boardHeight;

    public Ball(int randomStartXPos, int randomStartYPos, int Diam) {
        super();

        this.xDirection = (int) (Math.random() * 4 + 1);

        this.yDirection = (int) (Math.random() * 4 + 1);

        // Holds the starting x & y position for the Rock

        this.uLeftXPos = randomStartXPos;

        this.uLeftYPos = randomStartYPos;
        this.diameter = Diam;

    }
    public void move(){
        if (uLeftXPos + xDirection < 0)
            xDirection = 1;
        if (uLeftXPos + xDirection > width - diameter)
            xDirection = -1;
        if (uLeftYPos + yDirection < 0)
            yDirection = 1;
        if (uLeftYPos + yDirection > height - diameter)
            yDirection = -1;

        uLeftXPos = uLeftXPos + xDirection;
        uLeftYPos = uLeftYPos + yDirection;

    }
    @Override
    public Rectangle2D getBounds2D() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public double getX() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public double getY() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public double getWidth() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public double getHeight() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public boolean isEmpty() {
        // TODO Auto-generated method stub
        return false;
    }
    @Override
    public void setFrame(double x, double y, double w, double h) {
        // TODO Auto-generated method stub

    }
}

Your main problem is that your Ball class extends a Shape object, Ellipse2D and does so incompletely, preventing full Ellipse2D/Shape behavior. 您的主要问题是Ball类扩展了Shape对象Ellipse2D并没有完全这样做,从而阻止了完整的Ellipse2D / Shape行为。 I think that you'd be far better off not using inheritance but rather using composition -- have Ball contain a valid and complete Ellipse2D object, one that it uses to help it draw itself. 我认为您最好不要使用继承,而是使用合成-让Ball包含有效且完整的Ellipse2D对象,该对象用于帮助其绘制自身。

Other issues: 其他事宜:

  • Your JComponent should have paintComponent overridden, not paint 您的JComponent应该重写paintComponent,而不是paint
  • You should always call the super's painting method within your override 您应该始终在替代中调用上级的绘画方法
  • It's not a good idea to have program logic within a painting method, as you can never fully control this method, nor do you want to. 在绘画方法中包含程序逻辑不是一个好主意,因为您永远也无法完全控制此方法。 Better to have your move method separate and have the painting method do one thing -- paint the state of the component, and that's it. 最好将移动方法分开,使绘画方法做一件事-绘画组件的状态,仅此而已。
  • Your code is skirting danger with Swing threading. 您的代码正在使用Swing线程规避危险。 Consider using a Swing Timer and not a scheduled executor service. 考虑使用Swing计时器而不是计划的执行程序服务。
  • Start your GUI on the Swing thread using SwingUtilities.invokeLater(...) 使用SwingUtilities.invokeLater(...)在Swing线程上启动GUI

  • Since your Ball object uses default overrides for most of the Ellipse2D methods, no movement will occur since its these method returns that determine the location of the Shape. 由于您的Ball对象对大多数Ellipse2D方法都使用默认替代,因此不会发生任何运动,因为其这些方法返回的结果决定了Shape的位置。

  • But again, you don't want to really override this object, but instead use composition. 但同样,您不想真正覆盖此对象,而是使用合成。

Something like: 就像是:

class Ball {
    private static final double ELLIPSE_W = 20;
    private static final double ELLIPSE_H = ELLIPSE_W;
    private int x = 0;
    private int y = 0;
    private Ellipse2D ellipse = new Ellipse2D.Double(x, y, ELLIPSE_W, ELLIPSE_H);
    int uLeftXPos, uLeftYPos;
    int xDirection = 1;
    int yDirection = 1;
    int diameter;
    int width = Board.boardWidth;
    int height = Board.boardHeight;

    public Ball(int randomStartXPos, int randomStartYPos, int Diam) {
        super();
        this.xDirection = (int) (Math.random() * 4 + 1);
        this.yDirection = (int) (Math.random() * 4 + 1);
        // Holds the starting x & y position for the Rock
        this.uLeftXPos = randomStartXPos;
        this.uLeftYPos = randomStartYPos;
        this.diameter = Diam;

        x = uLeftXPos;
        y = uLeftYPos;
        ellipse = new Ellipse2D.Double(x, y, ELLIPSE_W, ELLIPSE_H);
    }

    public Ellipse2D getEllipse() {
        return ellipse;
    }

    public void move() {
        if (uLeftXPos + xDirection < 0)
            xDirection = 1;
        if (uLeftXPos + xDirection > width - diameter)
            xDirection = -1;
        if (uLeftYPos + yDirection < 0)
            yDirection = 1;
        if (uLeftYPos + yDirection > height - diameter)
            yDirection = -1;
        uLeftXPos = uLeftXPos + xDirection;
        uLeftYPos = uLeftYPos + yDirection;
        x = uLeftXPos;
        y = uLeftYPos;
        ellipse = new Ellipse2D.Double(x, y, ELLIPSE_W, ELLIPSE_H);
    }
}

And in the game board: 在游戏板中:

class GameBoard extends JComponent {
    Random rnd = new Random();
    public ArrayList<Ball> balls = new ArrayList<Ball>();
    int width = Board.boardWidth;
    int height = Board.boardHeight;

    public GameBoard() {
        for (int i = 0; i < 50; i++) {
            int randomStartXPos = (int) (Math.random() * (Board.boardWidth - 40) + 1);
            int randomStartYPos = (int) (Math.random() * (Board.boardHeight - 40) + 1);
            balls.add(new Ball(randomStartXPos, randomStartYPos, 30));
        }
    }

    public void move() {
        for (Ball ball : balls) {
            ball.move();
        }
    }

    @Override
    protected void paintComponent(java.awt.Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.BLACK);
        g2d.fillRect(0, 0, getWidth(), getHeight());
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setPaint(new Color(rnd.nextInt(255), rnd.nextInt(255), rnd.nextInt(255)));
        for (Ball ball : balls) {
            // ball.move();
            g2d.draw(ball.getEllipse());
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM