Java Paint()问题

时间:2011-07-11 19:56:21

标签: java

如果我完全不了解所有规则,请先在这里发帖,请原谅我。

我有一些问题,我对Java比较陌生,之前已经阅读并从这个社区获得了一些帮助。

我现在遇到的问题是在JFrame上绘制多个球,我有其他学生的一些解决方案,但没有成功。一个学生现在已经开始工作,但是通过在Frame类中绘制一些我认为不正确的东西,并将paint()放在paint()中,这也感觉不对。如果有人能指出我正确的方向,我将非常感激。

丹尼尔

代码: 的 Gamejava

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package myanimie;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 *
 * @author Dan
 */
public class Game extends JFrame implements Runnable {


    private Ball myBall = new Ball();
    private Paddle myPad = new Paddle();
    final JPanel jp = new JPanel();
    final JPanel jp1 = new JPanel();
    final JPanel jp2 = new JPanel();



    public Game()
    {
        setVisible(true);        
        setResizable(false);
        setTitle("First Test Animation");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setAlwaysOnTop(true);
        setSize(640,480);


    }

public void run()
    {
    move();
    }

    public void paint(Graphics g)
    {
        super.paint(g);
        myBall.paint(g);
    }

    public void move()
    {

      myBall.start();
      repaint();

        try
        {
            Thread.sleep(50);
        }
        catch (InterruptedException e)
        {
            System.exit(0);
        }
    }
    }

Ball.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package myanimie;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.geom.Ellipse2D;

/**
 *
 * @author Dan
 */
public class Ball  extends Thread  {

    Point pos;
    Color ballColor = Color.red;
    Color[] ts = {Color.CYAN,Color.green,Color.black};
    private int yChange = 2;
    private int xChange = 1;



    public Ball()
    {
    pos = new Point();
    pos.x = (int)(Math.random() * (500 - 100)) + 10 ;
    pos.y = (int)(Math.random() * (500/2 - 100)) + 10;

    }




    @Override
    public void run()
    {
     while(true)
    {
       move();

    }
    }

    public void paint(Graphics g)
    {
       g.setColor(ballColor);
       g.fillOval(pos.x - 10, pos.y - 10, 60,60);     

    }


    public void move()
    {
//        System.out.println("y " + pos.y);
//        System.out.println("x " + pos.x);

        if(pos.y < 20)
        {            
            yChange = -yChange;            
            System.out.println("T");
            ballColor = Color.BLUE;
        }
        if(pos.x < 20)
        {
            xChange = -xChange;
            System.out.println("L");
            ballColor = Color.MAGENTA;
        }
        if(pos.x > 620 - 20)
        {
        xChange = -xChange;
        System.out.println("R");
        ballColor = Color.GREEN;
        }
        if(pos.y > 430 - 20)
        {
            yChange = -yChange;
            System.out.println("B");
            ballColor = Color.PINK;
        }
        if(pos.y < 640 - 20)
        {
            pos.translate(xChange, yChange);           
        }
        if(pos.x < 480 - 20 || pos.x > 460)
        {
            pos.translate(xChange, yChange);           
        }   
        }


    public Point getPosition()
    {
        return pos;
    }



    public Ellipse2D area()
    {
        return new Ellipse2D.Double(pos.x, pos.y,60,60);
    }

    }

这是我可怕的代码,我已经解决了错误,但没有动画atm。

谢谢你们!您的见解非常宝贵

3 个答案:

答案 0 :(得分:1)

“并将paint()放在paint()中”听起来很危险!

repaint()方法会尽快调用此组件的paint方法。 您可以详细说明如何在框架上绘制“多个”球。如果没有什么特别的,您的答案可能是here

答案 1 :(得分:0)

是的,这确实是非常糟糕的做法。在repaint()中拨打paint()会导致StackOverflow错误。 从Bonsai查看游戏引擎Ivo Wetzel。我很喜欢它。

确实:您应该创建一个覆盖paintComponent(Graphics g)方法的JComponent。将该JComponent添加到JFrame。但你不必关心这个。这将自动进行盆景游戏引擎。

答案 2 :(得分:0)

根据您发布的代码确定一些一般性观察结果。

  1. 您需要限制move()方法,使其每秒更新数百万次。我看到您的Thread.sleep()方法中有Game.move。我想你要做的是这样的事情:

    public void run() {
        while(true) {
            //change the game state
            move();
    
            //draw the changes to the state that I just made
            repaint();
    
            //wait before moving to the next "frame"
            try {
               Thread.sleep(50);
            } catch ( InterruptedException ie ) {
            }
        }
    }
    
    private void move() {
        myBall.move();
    }
    
  2. 由于Ball.move()不再循环,因此根本没有Ball扩展Thread。摆脱run()方法。您的主要游戏循环将由Game集中管理。

  3. 从您的main方法或开始运行游戏的任何人,请在该主题或新主题中调用Game.run()

      public void main(String[] args) {
          Game game /* = new Game(...)*/;
          Thread gameThread = new Thread(game);
          gameThread.start();
      }
    
  4. getPosition()是否有充分理由存在?这可能比encapsulated state更好。