开发者

Java Paint() issues

first post here ever so forgive me if I am totally ignorant of all the rules.

I have some issues, I am relatively new to Java and have read and got some help from this community before.

I am having issues at the moment paint multiple balls on a JFrame, I have some solutions from other students but to no success. One student has got it working now but by painting everything within the Frame class which I don't feel is correct and putting repaint() within paint() which also feels wrong. if anyone could point me in the right direction I would be extremely appreciative.

Daniel

Code: 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.开发者_StackOverflowgeom.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);
    }

    }

This is my terrible code, I have gotten around the errors but no animation atm.

Thanks guys!! your insight is invaluable


"and putting repaint() within paint()" sounds dangerous!

repaint() method causes a call to this component's paint method as soon as possible. You may elaborate how you are trying to draw "multiple" balls on the frame. If nothing special, your answer may be here


OK some general observations based on the code you posted.

  1. You need to throttle your move() method so that it's not updating millions of times per second. I see you have a Thread.sleep() in your Game.move method. I think what you were trying to do was something like this:

    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. Since Ball.move() won't loop anymore, don't have Ball extend Thread at all. Get rid of the run() method. Your main game loop will be managed centrally by Game.

  3. From your main method or whoever starts the game running, call Game.run() either in that thread or in a new thread like this:

      public void main(String[] args) {
          Game game /* = new Game(...)*/;
          Thread gameThread = new Thread(game);
          gameThread.start();
      }
    
  4. Is there a good reason for getPosition() to exist? This is probably better off as encapsulated state.


Yes it is indeed very bad practice. Calling repaint() in paint() will cause a StackOverflow Error. Take a look at the game engine Bonsai from Ivo Wetzel. I like it a lot.

And indeed: You should create a JComponent which overrides the paintComponent(Graphics g) method. Add that JComponent to the JFrame. But you don't have to care about this. This will do the Bonsai game engine automatically.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜