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.
You need to throttle your
move()
method so that it's not updating millions of times per second. I see you have aThread.sleep()
in yourGame.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(); }
Since
Ball.move()
won't loop anymore, don't haveBall
extendThread
at all. Get rid of therun()
method. Your main game loop will be managed centrally byGame
.From your
main
method or whoever starts the game running, callGame.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(); }
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.
精彩评论