我想添加ArrayList
Thread
个代表带有(x,y)协调球的球,move()
方法代表新球{{1}每5秒钟。
因此,Thread
实施了JPanel
,并在那里向Runnable
添加了一个新球ArrayList
。
在Thread
方法中,我使用paintComponent()
循环来迭代球foreach
的{{1}}并启动他们移动它们的ArrayList
并呼叫Thread
。问题是我根本没有看到任何绘图(只有玩家绘图)。
MyPanel.java :
Thread
Ball.java :
repaint()
我省略了一个简单的public class MyPanel extends JPanel implements KeyListener,Runnable
{
private static final long serialVersionUID = 1L;
private static final Color BACKGROUND_COLOR = Color.WHITE;
private static final Color NPC_BALLS_COLOR = Color.RED;
// The player is an oval
private int playerRadius = 20;
private int playerX;
private int playerY;
// True - first player position, false - otherwise
private boolean playerPosition = true;
// Array of all the balls threads
private ArrayList<BallThread> balls = new ArrayList<BallThread>();
private Thread generateBallsThread;
public MyPanel()
{
this.setBackground(MyPanel.BACKGROUND_COLOR);
this.setFocusable(true);
this.addKeyListener(this);
this.generateBallsThread = new Thread();
generateBallsThread.start();
}
// Drawing
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
final double PANEL_WIDTH = this.getWidth();
final double PANEL_HEIGHT = this.getHeight();
if (this.playerPosition)
{
this.playerX = (int)(PANEL_WIDTH / 2 - this.playerRadius);
this.playerY = (int)(PANEL_HEIGHT / 2 - this.playerRadius);
this.playerPosition = false;
}
// Drawing the player
g.setColor(Color.BLACK);
g.fillOval(playerX,playerY, this.playerRadius * 2, this.playerRadius * 2);
// Drawing npc's balls
g.setColor(MyPanel.NPC_BALLS_COLOR);
for (BallThread ball: this.balls)
{
ball.start();
g.fillOval(ball.getBall().getX(), ball.getBall().getY(),
ball.getBall().radius, ball.getBall().radius);
repaint();
}
}
// Keyboard listeners
@Override
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_W: // Up
{
this.playerY -= 5;
repaint();
break;
}
case KeyEvent.VK_S: // Down
{
this.playerY += 5;
repaint();
break;
}
case KeyEvent.VK_D: // Right
{
this.playerX += 5;
repaint();
break;
}
case KeyEvent.VK_A: // Left
{
this.playerX -= 5;
repaint();
break;
}
}
}
@Override
public void keyReleased(KeyEvent e)
{
}
@Override
public void keyTyped(KeyEvent e)
{
}
public int getBallXStartingPositionFromTop()
{
return (int) Math.random() * 101; // 0 - 100
}
//public int getBallYStartingPositionFromLeft()
//{
// return (int) Math.random() * 101; // 0 - 100
//}
/**
*
*
*
* Class for the balls threads.
*
*/
public class BallThread extends Thread
{
private Ball ball;
public BallThread(Ball ball)
{
this.ball.setX(ball.getX());
this.ball.setY(ball.getY());
}
@Override
public void run()
{
try
{
this.ball.move();
Thread.sleep(4000);
repaint(); // Execute paintComponent() method
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public Ball getBall()
{
return this.ball;
}
public void setBall(Ball ball)
{
this.ball = ball;
}
}
@Override
public void run()
{
try
{
Thread.sleep(5000); // 5 seconds
this.balls.add(new BallThread(new Ball(20,20)));
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
} // End of MyPanel class
类和一个public class Ball
{
int x;
int y;
int velocity = 1;
public int radius = 10;
public boolean directionX = true; // True - right, false - left
public boolean directionY = false; // True - up, false - down
public static final int Y_STARTING_POSITION_FROM_TOP = 0;
public Ball(int x, int y)
{
this.x = x;
this.y = y;
}
public Ball()
{
}
public int getX()
{
return this.x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return this.y;
}
public void setY(int y)
{
this.y = y;
}
public void move()
{
if (this.directionX) // Right
{
this.x += this.velocity;
}
else // Left
{
this.x -= this.velocity;
}
if (this.directionY) // Up
{
this.y -= this.velocity;
}
else
{
this.y += this.velocity;
}
}
}
,他们生成了JFrame
并添加了main()
。
任何想法为什么我都不能看到球的绘制JFrame
?
答案 0 :(得分:5)
this.generateBallsThread = new Thread();
generateBallsThread.start();
这没有任何作用。它是一个没有逻辑的空线程。
我想你想要
this.generateBallsThread = new BallsThread();
generateBallThread.start();
此外,您不应该使用Thread进行动画制作。您应该使用Swing Timer
。任何更新Swing组件状态的逻辑都应该在Event Dispatch Thread上执行。有关详细信息,请阅读Concurrency上Swing教程中的部分。本教程还有一个关于How to Use Swing Timers
的部分。