Java 球不动为什么?
我已经做了一个程序来弹起两个球,但在运行程序时,它只是显示两个球,它们没有移动,我无法理解问题是什么? runnable的开始有什么问题吗?因为当我只运行一个球时,它运行时并没有实现runnable接口,但它不能运行两个球。为什么Java 球不动为什么?,java,Java,我已经做了一个程序来弹起两个球,但在运行程序时,它只是显示两个球,它们没有移动,我无法理解问题是什么? runnable的开始有什么问题吗?因为当我只运行一个球时,它运行时并没有实现runnable接口,但它不能运行两个球。为什么 import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHi
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Jpanel extends JPanel implements Runnable{
Thread t1;
Thread t2;
JFrame frame;
Jpanel jp;
int x=0;
int y=0;
Ball ball=new Ball(this);
Ball1 ball1=new Ball1(this);
void move1(){
ball.move();
}
void move2(){
ball1.move();
}
public void paint(Graphics g){
super.paint(g);
setBackground(Color.black);
Graphics2D g2d=(Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g);
ball1.paint(g);
//super.paint(g);//agar yaha to puri screen pehle jaisi saaf ho jaegi
}
public static void main(String args[]) throws InterruptedException{
Jpanel jp=new Jpanel();
JFrame frame =new JFrame("Chota Bheem");
frame.add(jp);
frame.setBackground(Color.BLACK);
frame.setSize(500,500);
frame.setVisible(true);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
Jpanel t1=new Jpanel();
Jpanel t2=new Jpanel();
t1.start();
t2.start();
}
public void start() {
System.out.println("inside start");
// TODO Auto-generated method stub
if(t1==null){
t1=new Thread(this,"first");
t1.start();
}
if(t2==null){
t2=new Thread(this,"second");
t2.start();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("inside run");
while(true){
jp.move1();
jp.repaint();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true){
jp.move2();
jp.repaint();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Ball1{
Jpanel jps;
int x=0,y=0,xs=-1,ys=-1;
public Ball1(Jpanel jpanel) {
// TODO Auto-generated constructor stub
this.jps=jpanel;
}
public void move(){
if(x+xs<0){xs=1;}
else if(y+ys<0){y=-1;}
else if(x+xs>jps.getWidth()-30){xs=-1;}
else if(y+ys>jps.getHeight()-30){ys=-1;}
x=x+xs;
y=y+ys;
}
void paint(Graphics g){
g.setColor(Color.darkGray);
g.fillOval(x, y, 60, 60);
}
}
class Ball{
int x=0;
int xs=-1,ys=-1;
int y=0;
JPanel jpn;
Ball(JPanel jpn){
this.jpn=jpn;
}
public void move() {
if(x+xs<0){
xs=1;
}
else if(y+ys<0){
ys=1;
}
else if(x+xs>jpn.getWidth()-30){
xs=-1;
}
else if(y+ys>jpn.getHeight()-30){
ys=-1;
}
x=x+xs;
y=y+ys;
}
public void paint(Graphics g) {
jpn.setBackground(Color.black);
g.setColor(Color.blue);
g.fillOval(x, y, 50, 50);
}
}
}
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.RenderingHints;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类Jpanel扩展Jpanel实现可运行{
螺纹t1;
螺纹t2;
JFrame框架;
Jpanel jp,;
int x=0;
int y=0;
球=新球(此);
Ball1 Ball1=新Ball1(本);
void move1(){
ball.move();
}
void move2(){
ball1.move();
}
公共空间涂料(图g){
超级油漆(g);
挫折背景(颜色:黑色);
Graphics2D g2d=(Graphics2D)g;
g2d.setRenderingHint(RenderingHits.KEY\u ANTIALIASING,RenderingHits.VALUE\u ANTIALIAS\u ON);
球形涂料(g);
1.油漆(g);
//super.paint(g);//agar yaha到puri屏幕pehle jaisi saaf ho jaegi
}
公共静态void main(字符串args[])引发InterruptedException{
Jpanel jp=新的Jpanel();
JFrame=新JFrame(“Chota Bheem”);
帧。添加(jp);
框架.立根背景(颜色.黑色);
框架。设置尺寸(500500);
frame.setVisible(true);
frame.setDefaultCloseOperation(关闭时退出frame);
Jpanel t1=新的Jpanel();
Jpanel t2=新的Jpanel();
t1.start();
t2.start();
}
公开作废开始(){
System.out.println(“内部启动”);
//TODO自动生成的方法存根
如果(t1==null){
t1=新螺纹(此“第一”);
t1.start();
}
如果(t2==null){
t2=新螺纹(此“第二”);
t2.start();
}
}
@凌驾
公开募捐{
//TODO自动生成的方法存根
System.out.println(“内部运行”);
while(true){
jp.move1();
jp.repaint();
试一试{
睡眠(1);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
while(true){
jp.move2();
jp.repaint();
试一试{
睡眠(1);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
}
一级{
Jpanel jps;
int x=0,y=0,xs=-1,ys=-1;
公共舞会1(Jpanel Jpanel){
//TODO自动生成的构造函数存根
this.jps=jpanel;
}
公开作废动议(){
如果(x+xsjps.getHeight()-30){ys=-1;}
x=x+xs;
y=y+ys;
}
空心漆(图形g){
g、 setColor(Color.darkGray);
g、 椭圆形(x,y,60,60);
}
}
班级舞会{
int x=0;
intxs=-1,ys=-1;
int y=0;
JPanel jpn;
鲍尔(JPanel jpn){
this.jpn=jpn;
}
公开作废动议(){
if(x+xsjpn.getHeight()-30){
ys=-1;
}
x=x+xs;
y=y+ys;
}
公共空间涂料(图g){
jpn.挫折背景(颜色:黑色);
g、 setColor(Color.blue);
g、 椭圆形(x,y,50,50);
}
}
}
Jpanel
类(即可运行的不是正确的方法。您需要做的是让Ball
类可以运行,并以一种与屏幕上的绘图内容完全分离的方式更新其位置。混合渲染和移动并不能很好地分离关注点。只要让你的球担心它在哪里,它在哪里移动,让UI担心它在哪里画
Jpanel
类中声明的线程
实例甚至没有被使用Thread.sleep(1)
是毫无意义的。如果你在屏幕上画球,而你只需要在球移动之间等待大约1毫秒,那为什么还要睡觉呢?如果你没有使用多个线程,你可以睡一段合理的时间(比如说,大约1/60秒),或者你可以一直全速运行由于只有一根线,单球跑得不稳。我不明白你为什么要创建Ball1。此外,线程的标题令人难以置信地误导:)为什么您有三个Jpanel和四个线程?最好将Jpanel和Runnable分开,让程序的每个部分对所有其他部分的暴露量最低,否则您将无法很快看穿自己的代码。只需将Balls/JPanel作为参数提供给Runnables,我只需要使用一个Swing计时器并去掉线程。我也会在JPanel的
paintComponent
方法中绘制,而不是在其paint
方法中绘制,并且我不会从绘制方法中调用setBackground(…)
。在构造函数中这样做一次。他不会直接调用paint(…)