Java小程序重新绘制一个圆形运动 [英] Java applet repaint a moving circle
问题描述
我刚刚搬了过来,从Pygame的所以Java 2D在一个applet是一个有点新的给我,特别是当它涉及到重绘屏幕。在pygame中你可以简单地做 display.fill([1,1,1])
,但我怎么做这在Java的一个小程序?据我所知)使用重绘(
但是,这并不清除屏幕 - 从屏幕上任何移动物体是不是'删除'所以你只能画一长排圆圈。
下面是我的code,我一直在与测试:
包圈;
进口java.applet.Applet中;
进口java.awt.Color中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口了java.util.Random;公共类圆形扩展的Applet实现Runnable {
私有静态最后的serialVersionUID长= -6945236773451552299L;
静态随机R =新随机(); 弦乐味精=点击播放!;
静态INT W = 800,H = 800; INT [] txtPos = {(W / 2)-50,(H / 2)-50};
INT [] = radiusRange {5,25};
INT []圈子;
静态INT [] POSRANGE; INT X = 0,Y = 0;
INT半径= 0;
INT cursorRadius = 10; 布尔游戏= FALSE; 公共静态INT [] POS(){
INT侧= r.nextInt(5-1)+ 1;
开关(侧){
情况1:
POSRANGE =新INT [] {1,r.nextInt(w)的,r.nextInt((H + 40)-h)+ H,r.nextInt(270-90)+90};
打破;
案例2:
POSRANGE =新INT [] {2,r.nextInt((W + 40)-w)+ W,r.nextInt(h)中,r.nextInt(270-90)+90};
打破;
案例3:
POSRANGE =新INT [] {3,r.nextInt(w)的,r.nextInt(40)-40,r.nextInt(180)};
打破;
情况4:
POSRANGE =新INT [] {4,r.nextInt(40)-40,r.nextInt(h)中,r.nextInt(180)};
打破;
}
的System.out.println(侧面);
返回POSRANGE;
}
公共无效的start(){
的setSize(500,500);
的setBackground(Color.BLACK);
新的Thread(本)。开始();
} 公共无效的run(){ }
公共无效更新(图形G){
油漆(G);
} 公共无效漆(图形E){
Graphics2D的G =(Graphics2D的)电子; 如果(System.currentTimeMillis的()%113 == 0){
X + = 1;
Y + = 1;
} g.setColor(Color.BLUE);
g.fillOval(X,Y,20,20); 重绘();
}
}
-
您需要调用
super.paint(G);
在油漆
方法,以不能离开油漆文物。 -
不要调用
重绘()
从油漆
方法内 -
不要显式调用
油漆
,如您在做的update()
,当你的意思调用reapaint()
-
刚刚更新
X
和是
从更新里面的值( )
方法,然后调用重绘()
-
您不必采取
A
图形
参数的update() -
您需要调用
更新()
某处反复循环,因为它更新X
和是
和reapint()
取值 -
如果你的类将是一个
的Runnable
,那么你应该放在运行一些code()
方法。这可能是你应该有你的循环
进口java.applet.Applet中;
进口java.awt.Color中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;公共类圆形扩展的Applet实现Runnable { INT X = 0,Y = 0; 公共无效的start(){
的setSize(500,500);
的setBackground(Color.BLACK);
新的Thread(本)。开始();
} 公共无效的run(){
而(真){
尝试{
更新();
视频下载(50); }赶上(InterruptedException的前){ }
}
} 公共无效更新(){
X + = 5;
Y + = 6;
重绘();
} 公共无效漆(图形E){
super.paint(E);
Graphics2D的G =(Graphics2D的)电子;
g.setColor(Color.BLUE);
g.fillOval(X,Y,20,20); }
}
旁注
- 为什么首先使用小程序。如果必须,为什么要使用AWT
Applet的
,而不是摇摆JApplet的
?时间升级。
下面是我怎么想的重做的Swing中的整个事情,使用Swing的定时
,而不是一个环和视频下载
,你应该做的。
进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.Graphics;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.SwingUtilities中;
进口javax.swing.Timer中;公共类圆继承JPanel {
私有静态最终诠释D_W = 500;
私有静态最终诠释D_H = 500; INT X = 0;
INT Y = 0;
公共圈(){
的setBackground(Color.BLACK); 定时器定时器=新定时器(50,新的ActionListener(){
公共无效的actionPerformed(ActionEvent的五){
X + = 5;
Y + = 5;
重绘();
}
});
timer.start();
} @覆盖
保护无效paintComponent(图形G){
super.paintComponent方法(G);
g.setColor(Color.BLUE);
g.fillOval(X,Y,20,20); } @覆盖
公共尺寸的get preferredSize(){
返回新的Dimension(D_W,D_H);
} 公共静态无效的主要(字串[] args){
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
JFrame的帧=新的JFrame();
frame.add(新圈());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(NULL);
frame.setVisible(真);
}
});
}
}
-
请参见如何使用Swing计时器
- 这里的更高级的例子的你来看待和思考。
更新
问题是,这是一个JPanel应用程序。我特别想打一个applet在网页上轻松使用。
块引用>您仍然可以使用它。只需使用的JPanel。取出的主要方法,而不是小程序,使用JApplet的,只是添加的JPanel你的小程序。简单的作为。
进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.Graphics;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口javax.swing.JApplet中;
进口javax.swing.JPanel中;
进口javax.swing.Timer中;公共类CircleApplet扩展JApplet的{ @覆盖
公共无效的init(){
添加(新圈());
} 公共类圆继承JPanel { 私有静态最终诠释D_W = 500;
私有静态最终诠释D_H = 500; INT X = 0;
INT Y = 0; 公共圈(){
的setBackground(Color.BLACK); 定时器定时器=新定时器(50,新的ActionListener(){
公共无效的actionPerformed(ActionEvent的五){
X + = 5;
Y + = 5;
重绘();
}
});
timer.start();
} @覆盖
保护无效paintComponent(图形G){
super.paintComponent方法(G);
g.setColor(Color.BLUE);
g.fillOval(X,Y,20,20); } @覆盖
公共尺寸的get preferredSize(){
返回新的Dimension(D_W,D_H);
} }
}I've just moved over from Pygame so Java 2D in an applet is a little new to me, especially when it comes to repainting the screen. In pygame you can simply do
display.fill([1,1,1])
but how do I do this in an applet in Java? I understand the use ofrepaint()
but that doesn't clear the screen - any moving object is not 'removed' from the screen so you just get a long line of painted circles.Here's my code that I've been testing with:
package circles; import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Random; public class circles extends Applet implements Runnable { private static final long serialVersionUID = -6945236773451552299L; static Random r = new Random(); String msg = "Click to play!"; static int w = 800, h = 800; int[] txtPos = { (w/2)-50,(h/2)-50 }; int[] radiusRange = { 5,25 }; int[] circles; static int[] posRange; int x = 0, y = 0; int radius = 0; int cursorRadius = 10; boolean game = false; public static int[] pos() { int side = r.nextInt(5-1)+1; switch(side) { case 1: posRange = new int[]{ 1,r.nextInt(w),r.nextInt((h+40)-h)+h,r.nextInt(270-90)+90 }; break; case 2: posRange = new int[]{ 2,r.nextInt((w+40)-w)+w,r.nextInt(h),r.nextInt(270-90)+90 }; break; case 3: posRange = new int[]{ 3,r.nextInt(w),r.nextInt(40)-40,r.nextInt(180) }; break; case 4: posRange = new int[]{ 4,r.nextInt(40)-40,r.nextInt(h),r.nextInt(180) }; break; } System.out.println(side); return posRange; } public void start() { setSize(500,500); setBackground(Color.BLACK); new Thread(this).start(); } public void run() { } public void update(Graphics g) { paint(g); } public void paint(Graphics e) { Graphics2D g = (Graphics2D) e; if(System.currentTimeMillis()%113==0) { x+=1; y+=1; } g.setColor(Color.BLUE); g.fillOval(x,y,20,20); repaint(); } }
解决方案
You need to call
super.paint(g);
in yourpaint
method, as to not leave paint artifacts.Never call
repaint()
from inside thepaint
methodDon't explicitly call
paint
, as you do inupdate()
, when you mean to callreapaint()
just update the
x
andy
values from inside theupdate()
method, then callrepaint()
You don't need to take a
Graphics
argument inupdate()
You need to call
update()
somewhere repeatedly in a loop, as it updates thex
andy
andreapint()
sIf your class is going to be a
Runnable
, then you should put some code in therun()
method. That's probably where you should have your loop
import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; public class circles extends Applet implements Runnable { int x = 0, y = 0; public void start() { setSize(500, 500); setBackground(Color.BLACK); new Thread(this).start(); } public void run() { while (true) { try { update(); Thread.sleep(50); } catch (InterruptedException ex) { } } } public void update() { x += 5; y += 6; repaint(); } public void paint(Graphics e) { super.paint(e); Graphics2D g = (Graphics2D) e; g.setColor(Color.BLUE); g.fillOval(x, y, 20, 20); } }
Side Notes
- Why use Applets in the first place. If you must, why use AWT
Applet
and not SwingJApplet
? Time for an upgrade.Here's how I'd redo the whole thing in Swing, using a Swing
Timer
instead of a loop andThread.sleep
, as you should be doing.import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; public class Circle extends JPanel{ private static final int D_W = 500; private static final int D_H = 500; int x = 0; int y = 0; public Circle() { setBackground(Color.BLACK); Timer timer = new Timer(50, new ActionListener(){ public void actionPerformed(ActionEvent e) { x += 5; y += 5; repaint(); } }); timer.start(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); g.fillOval(x, y, 20, 20); } @Override public Dimension getPreferredSize() { return new Dimension(D_W, D_H); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame frame = new JFrame(); frame.add(new Circle()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } }
- Here's more advanced example for you to look at and ponder.
UPDATE
"Problem is, that's a JPANEL application. I specifically want to make an applet easily usable on a web page. "
You can still use it. Just use the JPanel. Take out the main method, and instead of Applet, use a JApplet and just add the JPanel to your applet. Easy as that.
import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JApplet; import javax.swing.JPanel; import javax.swing.Timer; public class CircleApplet extends JApplet { @Override public void init() { add(new Circle()); } public class Circle extends JPanel { private static final int D_W = 500; private static final int D_H = 500; int x = 0; int y = 0; public Circle() { setBackground(Color.BLACK); Timer timer = new Timer(50, new ActionListener() { public void actionPerformed(ActionEvent e) { x += 5; y += 5; repaint(); } }); timer.start(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); g.fillOval(x, y, 20, 20); } @Override public Dimension getPreferredSize() { return new Dimension(D_W, D_H); } } }
这篇关于Java小程序重新绘制一个圆形运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!