Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
快速移动时的JavaFX图像重影_Java_Image_Swing_Javafx 8 - Fatal编程技术网

快速移动时的JavaFX图像重影

快速移动时的JavaFX图像重影,java,image,swing,javafx-8,Java,Image,Swing,Javafx 8,我偶然发现了一个问题:如果图像在屏幕上高速移动,它会被错误地渲染,从而产生重影效果。我想我们可以排除我的显示器的问题,因为这种类型的运动是完美的摇摆(以相同的帧率) 看起来像: 代码(从3个类中合并): 导入javafx.animation.AnimationTimer; 导入javafx.application.application; 导入javafx.event.EventHandler; 导入javafx.scene.Group; 导入javafx.scene.scene; 导入java

我偶然发现了一个问题:如果图像在屏幕上高速移动,它会被错误地渲染,从而产生重影效果。我想我们可以排除我的显示器的问题,因为这种类型的运动是完美的摇摆(以相同的帧率)

看起来像:

代码(从3个类中合并):

导入javafx.animation.AnimationTimer;
导入javafx.application.application;
导入javafx.event.EventHandler;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.input.KeyCode;
导入javafx.scene.input.KeyEvent;
导入javafx.scene.paint.Color;
导入javafx.stage.stage;
导入javafx.stage.StageStyle;
导入java.awt.Dimension;
导入java.awt.Toolkit;
公共类构造函数扩展应用程序{
图像播放器,镜头;
静态维度屏幕=新维度(Toolkit.getDefaultToolkit().getScreenSize());
静态int wid=屏幕宽度;
静态int hei=屏幕高度;
静态布尔向上、向下、左、右、左、右;
静态双x=(wid/2)-109;
静态双y=(hei/1.5)-132;
静态双velx=0,Fly=0,velx2=0,vely2=0;
静态双前速度=0,侧速度=0;
静态整数旋转=0;
公共空荷载(){
player=新图像(“res/sprite.png”);
}
@凌驾
public void start(最终阶段帧)引发异常{
加载();
frame.setTitle(“默认”);
框架。初始样式(舞台样式。未装饰);
组根=新组();
最终ImageView发货=新ImageView();
ship.setImage(播放器);
root.getChildren().add(ship);
frame.setScene(新场景(root、wid、hei、Color.BLACK));
frame.addEventHandler(按下KeyEvent.KEY_,新建EventHandler()){
公共无效句柄(KeyEvent密钥){
if(key.getCode()==KeyCode.W)
向上=真;
if(key.getCode()==KeyCode.S)
向下=真;
if(key.getCode()==KeyCode.Q)
左=真;
if(key.getCode()==KeyCode.E)
右=真;
if(key.getCode()==KeyCode.A)
左=真;
if(key.getCode()==KeyCode.D)
右=真;
}
});
frame.addEventHandler(KeyEvent.KEY_已发布,新的EventHandler(){
公共无效句柄(KeyEvent密钥){
if(key.getCode()==KeyCode.ESCAPE)
{
frame.close();
系统出口(0);
}
if(key.getCode()==KeyCode.W)
向上=错误;
if(key.getCode()==KeyCode.S)
向下=假;
if(key.getCode()==KeyCode.Q)
左=假;
if(key.getCode()==KeyCode.E)
右=假;
if(key.getCode()==KeyCode.A)
左=假;
if(key.getCode()==KeyCode.D)
右=假;
}
});
frame.setAlwaysOnTop(真);
帧设置高度(hei);
帧设置宽度(wid);
frame.setresizeable(false);
frame.setFullScreen(真);
frame.show();
新的AnimationTimer(){
@凌驾
公共无效句柄(长){
gameloop();
ship.setTranslateX(x);
船舶。setTranslateY(y);
ship.setRotate(旋转);
}
}.start();
}
公共静态void gameloop(){
if(Shared.up)
速度+=1;
if(Shared.down)
速度-=1;
if(Shared.right)
侧速度+=1;
if(Shared.left)
侧速度-=1;
if(Shared.rotlight)
旋转-=3;
if(Shared.rotright)
rotat+=3;
velx=数学常数cos(数学常数toRadians(rotat-90))*速度+数学常数cos(数学常数toRadians(rotat))*侧速度;
vely=Math.sin(Math.toRadians(rotat-90))*速度+Math.sin(Math.toRadians(rotat))*侧速度;
如果(!Shared.up&&!Shared.down)
{
如果(速度>0时)
速度-=0.2;
否则如果(速度<0时)
速度+=0.2;
}
如果(!Shared.right&&!Shared.left)
{
如果(侧速度>0)
侧速度-=0.2;
否则,如果(侧速度<0)
侧速度+=0.2;
}
x+=velx;
y+=0;
筛检结肠炎();
}
私有静态无效屏幕合并(){
//左右
if(x<0)
{
x=0;
侧速度=0;
}
else if(x+218>Shared.wid)
{
x=共享的wid-218;
侧速度=0;
}
//上下
if(y<0)
{
y=0;
forspeed=0;
}
否则如果(y+164>共享.hei)
{
y=共享。hei-164;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import java.awt.Dimension;
import java.awt.Toolkit;


public class Constructor extends Application{

        Image player, shot;
        static Dimension screen = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());
        static int wid = screen.width;
        static int hei = screen.height;
        static boolean up, down, left, right, rotleft , rotright;
        static double x = (wid/2)-109;
        static double y = (hei/1.5)-132;
        static double velx = 0, vely = 0, velx2 = 0, vely2 = 0;
        static double forspeed = 0, sidespeed = 0;
        static int rotat = 0;

        public void load(){
                player = new Image("res/sprite.png");
        }

        @Override
        public void start(final Stage frame) throws Exception{

                load();

                frame.setTitle("DEFAULT");
                frame.initStyle(StageStyle.UNDECORATED);

                Group root = new Group();              
                final ImageView ship = new ImageView();
                ship.setImage(player); 
                root.getChildren().add(ship);

            frame.setScene(new Scene(root,  wid,  hei, Color.BLACK));

                frame.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>(){
                        public void handle(KeyEvent key) {
                          if(key.getCode()==KeyCode.W)
                                   up = true;
                          if(key.getCode()==KeyCode.S)
                                   down = true;
                          if(key.getCode()==KeyCode.Q)
                                   left = true;
                          if(key.getCode()==KeyCode.E)
                                   right = true;
                          if(key.getCode()==KeyCode.A)
                                   rotleft = true;
                          if(key.getCode()==KeyCode.D)
                                   rotright = true;

                        }
                });
                frame.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>(){
                        public void handle(KeyEvent key) {
                          if(key.getCode()==KeyCode.ESCAPE)
                          {
                              frame.close();
                                  System.exit(0);  
                          }
                          if(key.getCode()==KeyCode.W)
                                   up = false;
                          if(key.getCode()==KeyCode.S)
                                   down = false;
                          if(key.getCode()==KeyCode.Q)
                                   left = false;
                          if(key.getCode()==KeyCode.E)
                                   right = false;
                          if(key.getCode()==KeyCode.A)
                                   rotleft = false;
                          if(key.getCode()==KeyCode.D)
                                   rotright = false;

                        }
                });
                frame.setAlwaysOnTop(true);
                frame.setHeight(hei);
                frame.setWidth(wid);
                frame.setResizable(false);
                frame.setFullScreen(true);
                frame.show();

                 new AnimationTimer() {
                    @Override
                    public void handle(long now) {

                        gameloop();
                        ship.setTranslateX(x);
                        ship.setTranslateY(y);
                        ship.setRotate(rotat);
                    }
                }.start();
        }

        public static void gameloop(){
        if(Shared.up)
                forspeed += 1;
        if(Shared.down)
                forspeed -= 1;
        if(Shared.right)
                sidespeed += 1;
        if(Shared.left)
                sidespeed -= 1;

        if(Shared.rotleft)
                rotat -=3;
        if(Shared.rotright)
                rotat +=3;

        velx = Math.cos(Math.toRadians(rotat-90))*forspeed + Math.cos(Math.toRadians(rotat))*sidespeed;
        vely = Math.sin(Math.toRadians(rotat-90))*forspeed + Math.sin(Math.toRadians(rotat))*sidespeed;

        if(!Shared.up && !Shared.down)
        {
                if(forspeed > 0)
                        forspeed -= 0.2;
                else if (forspeed < 0)
                        forspeed += 0.2;
        }
        if(!Shared.right && !Shared.left)
        {
                if(sidespeed > 0)
                        sidespeed -= 0.2;
                else if (sidespeed < 0)
                        sidespeed += 0.2;
        }

        x += velx;
        y += vely;

        screencolisions();
        }

        private static void screencolisions() {
                // LEFT RIGHT
                if(x < 0)
            {
                x = 0;
                sidespeed = 0;
            }
            else if (x+218 > Shared.wid)
            {
                x = Shared.wid-218;
                sidespeed = 0;
            }

                // UP DOWN
            if(y < 0)
            {
                y = 0;
                forspeed = 0;
            }
            else if (y+164 > Shared.hei)
            {
                y = Shared.hei-164;
                forspeed = 0;
            }

        }

        public static void main(String[] args){
                Application.launch(args);
    }
}
Screen screen = Screen.getPrimary();
wid = screen.getBounds().getWidth();
hei = screen.getBounds().getHeight();
// Visual bounds will be different depending on OS and native toolbars etc..
// think of it as desktop bounds vs whole screen
public class ScreenBounds extends Application {

    @Override
    public void start(Stage primaryStage) {
        Screen screen = Screen.getPrimary();
        System.out.println("ScreenBounds : " + screen.getBounds() + "\nVisualBounds : " +   screen.getVisualBounds());
        Platform.exit();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}
compile-single:
run-single:
ScreenBounds : Rectangle2D [minX = 0.0, minY=0.0, maxX=1680.0, maxY=1050.0, width=1680.0, height=1050.0]
VisualBounds : Rectangle2D [minX = 0.0, minY=40.0, maxX=1680.0, maxY=1050.0, width=1680.0, height=1010.0]
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.util.Duration;

/**
 *
 * @author jdub1581
 */
public class NanoTimer extends ScheduledService<Void> {

    private final long ONE_NANO = 1000000000L;
    private final double ONE_NANO_INV = 1f / 1000000000L;

    private long startTime, previousTime;
    private double frameRate, deltaTime;
    private final NanoThreadFactory tf = new NanoThreadFactory();

    public NanoTimer() {
        super();
        this.setPeriod(Duration.millis(16));// equivalent to 60 fps
        this.setExecutor(Executors.newCachedThreadPool(tf));
    }

    public double getTimeAsSeconds() {
        return getTime() * ONE_NANO_INV;
    }

    public long getTime() {
        return System.nanoTime() - startTime;
    }

    public long getOneSecondAsNano() {
        return ONE_NANO;
    }

    public double getFrameRate() {
        return frameRate;
    }

    public double getDeltaTime() {
        return deltaTime;
    }

    private void updateTimer() {
        deltaTime = (getTime() - previousTime) * (1.0f / ONE_NANO);
        frameRate = 1.0f / deltaTime;
        previousTime = getTime();

    }

    @Override
    public void start() {
        super.start();
        if (startTime <= 0) {
            startTime = System.nanoTime();
        }
     }

    @Override
    public void reset() {
        super.reset();
        startTime = System.nanoTime();
        previousTime = getTime();
    }
    private boolean init = true;

    @Override
    protected Task<Void> createTask() {
        return new Task<Void>() {
            @Override
            protected Void call() throws Exception {                
                updateTimer();
                // perform NON UI calculations here

                return null;
            }
        };
    }

    @Override
    protected void succeeded() {
        super.succeeded();
        //update the UI here
    }

    @Override
    protected void failed() {
        getException().printStackTrace(System.err);

    }

    @Override
    public String toString() {
        return "ElapsedTime: " + getTime() + "\nTime in seconds: " + getTimeAsSeconds()
            + "\nFrame Rate: " + getFrameRate()
            + "\nDeltaTime: " + getDeltaTime();
    }

    /*==========================================================================
        creates a daemon thread for use
    */
    private class NanoThreadFactory implements ThreadFactory {

        public NanoThreadFactory() {
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, "NanoTimerThread");
            t.setDaemon(true);
            return t;
        }

    }
}//=============================================================================