我想有一个背景图像绘制,然后有超过它的字符平局。 我的代码是工作,直到我说睡觉我没有得到1500帧。
package sylvyrfysh.screen;
import javax.swing.*;
import java.awt.*;
import game.infos.Information;
public class ImageLoadDraw extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
public static void main(){
DisplayMode dm=new DisplayMode(Information.sX,Information.sY,16,DisplayMode.REFRESH_RATE_UNKNOWN);
ImageLoadDraw i = new ImageLoadDraw();
i.run(dm);
}
public void run(DisplayMode dm){
setBackground(Color.PINK);
setForeground(Color.WHITE);
setFont(new Font("Arial",Font.PLAIN,24));
s=new Screen();
try{
loadpics();
s.setFullScreen(dm,this);
try{
Thread.sleep(10000);
}finally{
doRun=false;
s.restoreScreen();
}
}catch(Exception e){
e.printStackTrace();
}
}
private void loadpics() {
bg=new ImageIcon("src/sylvyrfysh/screen/maze_icon.png").getImage();
chara=new ImageIcon("src/sylvyrfysh/screen/char.png").getImage();
repaint();
}
public void paint(Graphics g){
if(g instanceof Graphics2D){
Graphics2D g2=(Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
while(true&&doRun){
g.drawImage(bg,0,0,null);
g.drawImage(bg,0,480,null);
g.drawImage(bg,360,0,null);
g.drawImage(bg,360,480,null);
g.drawImage(bg,720,0,null);
g.drawImage(bg,720,480,null);
g.drawImage(chara,imgX,imgY,null);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private Screen s;
public static int imgX=0;
private int imgY=525;
private Image bg,chara;
private Boolean doRun=true;
}
什么任何想法是造成它,以及如何解决它? 就像我说的,没有睡眠正常工作。
摆动是一个单线程框架。 这是所有UI交互,预计修改要在事件调度线程,包括重绘请求的内容内执行。
凡是停止,阻断或阻止此线程运行将防止从美国东部时间处理新的事件,包括重绘请求。 这种意志,本质上,使它看起来你程序挂起(或停止响应),因为它有。
在你的run
方法,则需要调用Thread.sleep
。 这可能是从处理新的事件停止EDT,而是因为你实际上已经从“主”线程调用的方法,它实际上可能不过工作,...
在你paint
法,你有一个无限循环和A Thread.sleep
调用。 这些都将停止运行的EDT,因为paint
是从美国东部时间范围内调用。
绘画并不总是立即发生,在某些系统上,直到paint
方法返回时,它可能不会被推到输出设备,因此,在循环内连想法paint
,不管事实,这将导致问题在EDT,是一个坏主意的任何方式。
不像一些其他的UI框架,你并不需要实现一个“主循环”,摇摆负责为你处理。
相反,在你的paint
方法,你应该简单地画你需要画在那个周期和退出的东西。
相反,你应该这样做...
public void paint(Graphics g){
// Painting is a complex series of chained methods, failing to call super.paint
// to cause significant issues
super.paint(g);
// Graphics is guaranteed to be an instance of Graphics2D since I think 1.4
// You should create a copy, so any changes you make are not carried onto the
// next component, Graphics is shared between all the components being painted
// in this paint cycle.
Graphics2D g2=(Graphics2D)g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawImage(bg,0,0,null);
g2.drawImage(bg,0,480,null);
g2.drawImage(bg,360,0,null);
g2.drawImage(bg,360,480,null);
g2.drawImage(bg,720,0,null);
g2.drawImage(bg,720,480,null);
g2.drawImage(chara,imgX,imgY,null);
// If you create, you should dispose of it...
g2.dispose();
}
...代替
代替Thread.sleep
你应该利用的类似javax.swing.Timer
,例如...
s=new Screen();
try{
loadpics();
s.setFullScreen(dm,this);
Timer timer = new Timer(10000, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
s.restoreScreen();
}
});
timer.setRepeats(false);
timer.start();
}catch(Exception e){
e.printStackTrace();
}
看看并发秋千了解更多详情。
你也应该避免覆盖顶层容器,特别是压倒一切的paint
。 绘画一系列复杂的链式方法调用,每一个执行特定的工作,在彼此的顶部建立以产生最终结果。
相反,你应该用某种类型的自定义组件开始,从扩展JPanel
例如,并覆盖它的paintComponent
方法,确保您拨打super.paintComponent
你做任何你自己的绘画之前。
看看演出风俗绘画更多细节
嗯,这一个Thread.sleep(10000);
关闭所有10秒。 这是不是你想要的。 即使这样做了30毫秒为单位(这是〜30帧/秒)是不是你想要的,因为它甚至停止输入等。
您应该使用定时器。 它运行在另一个线程时间,而且睡觉,醒来只,对于以毫秒为单位的给定数量的自动线,所以它不会影响你的程序,它只能30milisec例如后调用它。
仍然有很好的应用,这个计时器应该具有低价值,你应该怎么算长时间穿过System.nanoTime()
和例如重绘每一次30milisec,但是读取输入的每个5milisec等。
我认为- >这是因为你需要调用loadpics()
平行,试试这个
public void run(DisplayMode dm){
setBackground(Color.PINK);
setForeground(Color.WHITE);
setFont(new Font("Arial",Font.PLAIN,24));
s=new Screen();
loadpics();
s.setFullScreen(dm,this);
try{
new Thread(new Runnable() {
@Override
public void run() {try {Thread.sleep(1000);doRun=false;s.restoreScreen();} catch (Exception e) {}
}
}).start();
}
还设置doRun
挥发性。 private Boolean doRun=true;