JavaFX游戏动画如何根据角度在X轴和Y轴上移动ImageView

时间:2018-11-06 10:52:51

标签: javafx javafx-8 game-physics

我希望子弹直接对准目标。我知道如何根据目标位置改变玩家的方向,我也知道我需要根据角度减小X轴和Y轴,但是..不知道如何?任何人都不知道我该怎么做。另外,目标将在x轴上向下移动,我希望目标飞船朝向玩家。同样的问题。我的数学不是很好,我不知道我需要采用哪种三角方法。

只有2个此类文件可以自己运行代码

enter image description here

Main.java

    package bullitsrunning;

import java.util.ArrayList;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.stage.Stage;
import javafx.util.Duration;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;


public class Main extends Application {

    private final int HEIGHT = 600, WIDTH = 600;

    public static Pane root  = new Pane();;

    ArrayList<ImageObject> rocket_list = new ArrayList<>();
    ArrayList<ImageObject> enemy_rocket_list = new ArrayList<>();


    boolean up = false,down = false,left = false,right = false, rotateLeft = false, rotateRight= false;

    ImageObject player = new ImageObject(300, 450, 100, 100, "alienship2.png");

    ImageObject enemy = new ImageObject(100, 10, 50, 50, "animemonster.png");



    @Override
    public void start(Stage stage) {
        try {



            Timeline tl = new Timeline(new KeyFrame(Duration.millis(5), e-> {


                playerUpdate();

                enemyUpdate();

                for(ImageObject rock : new ArrayList<ImageObject>(rocket_list)) {



                    rock.setLayoutY(rock.getLayoutY() - 2);     




                    if(rock.getLayoutY() < 0) {  

                        if(rock.getBound().intersects(enemy.getBound())) 
                        {
                            //enemy.delete();
                        }


                        System.out.println(rocket_list.size());
                        rock.delete();  
                        rocket_list.remove(rock);

                    }
                }


            }));
            tl.setCycleCount(Animation.INDEFINITE);
            tl.play();





            Scene scene = new Scene(root,600,600); 

            scene.setOnKeyPressed(new EventHandler<KeyEvent>() {

                @Override
                public void handle(KeyEvent e) 
                {

                    switch (e.getCode()) {
                    case W:
                        up = true;

                        break;
                    case S:

                        down = true;
                        break;
                    case A:

                        left = true;
                        break;
                    case D:

                        right = true;
                        break;

                    case LEFT:
                        System.out.println("Rotate Left");
                        rotateLeft = true;
                        break;

                    case RIGHT:
                        System.out.println("Rotate Right");
                        rotateRight = true;
                        break;


                    case SPACE:

                        ImageObject io = new ImageObject(player.getX() + 38, player.getY(), 25, 25, "blackbullet.png"); 
                        rocket_list.add(io);


                        break;


                    }
                }
            });



            scene.setOnKeyReleased(new EventHandler<KeyEvent>() {

                @Override
                public void handle(KeyEvent e) 
                {

                    switch (e.getCode()) {
                    case W:
                        up = false;

                        break;
                    case S:

                        down = false;
                        break;
                    case A:

                        left = false;
                        break;
                    case D:

                        right = false;
                        break;

                    case LEFT:
                        System.out.println("Rotate Left");
                        rotateLeft = false;
                        break;

                    case RIGHT:
                        System.out.println("Rotate Right");
                        rotateRight = false;
                        break;



                    }
                }
            });



            stage.setScene(scene);

            stage.show();


        } catch(Exception e) {
            e.printStackTrace();
        }
    }




    private void enemyUpdate() {




        for(ImageObject rock : new ArrayList<ImageObject>(enemy_rocket_list)) {
            rock.setLayoutY(rock.getLayoutY() + 2);     
            if(rock.getLayoutY() > HEIGHT) {  



                System.out.println(rocket_list.size());
                rock.delete();  
                rocket_list.remove(rock);

            }
        }


    }








    private void playerUpdate() {




        Point2D ene = new Point2D(enemy.getLayoutX(), enemy.getLayoutY());
        Point2D play = new Point2D(player.getLayoutX(), player.getLayoutY());
        Point2D p3 = play.subtract(ene);
        Point2D p4 = new Point2D(1, 0);

        System.out.println( "Point2D: " + p4.angle(p3));

        player.setRotate(p4.angle(p3) - 90);

        System.out.println(Math.sin(p4.angle(p3)));













        //So Player Can't move outside of the border
        if(player.getX() < 0 ) {
            player.setLayoutX(0);

        } else if(player.getX() > WIDTH- player.getWidth()) 
        {
            player.setLayoutX(WIDTH - player.getWidth());
        }else if(player.getY() < 0 ) 
        {
            player.setLayoutY(0);
        }else if(player.getY() > HEIGHT - player.getHeight()) 
        {
            player.setLayoutY(HEIGHT - player.getHeight());
        }else
        {

        //Player movement UP, DOWN, LEFT, RIGHT
            if(up) 
            {
                player.setLayoutY(player.getLayoutY() - 1);

            }
            if(down) 
            {
                player.setLayoutY(player.getLayoutY() + 1);
            }
            if(left)
            {
                player.setLayoutX(player.getLayoutX() - 1);
            }
            if(right)
            {
                player.setLayoutX(player.getLayoutX() + 1);

            }

            if(rotateLeft)
            {

                player.setRotate(120 - 90);


            }
            if(rotateLeft)
            {
                player.setRotate(60 - 90);


            }




        }



    }

    public static void main(String[] args) {
        launch(args);
    }
}

ImageObject.java

package bullitsrunning;

import javafx.geometry.Bounds;
import javafx.scene.image.ImageView;

public class ImageObject {

    private String folder_location ="File:Images/";
    private ImageView image_view;
    private boolean alive = true;
    public ImageObject(double x,double y,double w,double h,String image) 
    {


        image_view = new ImageView(folder_location+image);
        image_view.setCache(true); //help in performance

        image_view.setFitHeight(h );
        image_view.setFitWidth(w);

        image_view.setLayoutX(x);
        image_view.setLayoutY(y);

        image_view.setSmooth(true);



        Main.root.getChildren().add(image_view);

    }

    public double getX(){

        return image_view.getLayoutX();
    }

    public double getY() {
        return image_view.getLayoutY();
    }



    public void setRotate(double rot) {
        image_view.setRotate(rot);
    }

    public double getHeight() 
    {
        return image_view.getFitHeight();
    }


    public double getWidth() 
    {
        return image_view.getFitWidth();
    }

    public void setHeight(double h) 
    {
        image_view.setFitHeight(h);

    }
    public void setWidth(double w) 
    {
        image_view.setFitWidth(w);
    }

    public void setSize(double h,double w) 
    {
        image_view.setFitHeight(h);
        image_view.setFitWidth(w);
    }

    //Axis
    public double getLayoutX() 
    {
        return image_view.getLayoutX();
    }
    public double getLayoutY() 
    {
        return image_view.getLayoutY();
    }

    public void setLayoutX(double x) 
    {

        image_view.setLayoutX(x);
    }

    public void setLayoutY(double y) 
    {
        image_view.setLayoutY(y);
    }

    public void setPos(double x,double y) 
    {   image_view.setLayoutX(x);
        image_view.setLayoutY(y);
    }


    public Bounds getBound() 
    {
        return image_view.getBoundsInParent();

    }

    public ImageView getView() 
    {
        return image_view;
    }

    public void delete() 
    {
        Main.root.getChildren().remove(image_view);
    }


    public boolean isAlive() {
        return alive;
    }


    public void setAlive(boolean alive) {
        this.alive = alive;
    }


}

3 个答案:

答案 0 :(得分:4)

我不知道JavaFX,也不了解您的实现细节。但是核心思想如下:

您需要从源位置(当前玩家位置)到目的地(我想是敌人)创建一个direction矢量,

direction   = new Vector()
direction.x = des.x-src.x;
direction.y = des.y-src.y;

现在,您应该归一化矢量,如:

double direction_magnitude = Math.sqrt(direction.x*direction.x + direction.y*direction.y)
direction.x = direction.x/direction_magnitude;
direction.y = direction.y/direction_magnitude;

现在只需根据以下direction向量逐步更新玩家位置

void update(float deltaTime) {
  // recalculate `direction` if your destination is moving
  player.x = player.x + (direction.x * deltaTime);
  player.y = player.y + (direction.y * deltaTime);
  player.rotation = Math.atan2(direction.y, direction.x)
}

最后一行旋转面向目标玩家(了解有关此行here的更多信息)。

答案 1 :(得分:4)

只需使用节点的变换来确定镜头的方向:

给出图像坐标shotLocalXshotLocalY中的拍摄方向,只需执行

Point2D shotDirection = player.getLocalToParentTransform().deltaTransform(shotLocalX, shotLocalY);

shotDirection的{​​{1}}和x属性包含y坐标系中的射击方向。

关于计算将敌人直接移向玩家的移动方向:使用位置的差异并将其缩放到适当的长度

root

dx = targetX - startX dy = targetY - startY magnitude = Math.sqrt(dx * dx + dy *dy); directionX = dx / magnitude; directionY = dy / magnitude; directionX是从位置directionY(startX, startY)开始的标准化(长度1)移动方向。

答案 2 :(得分:0)

一种最好的方法

    Timeline frame = new Timeline(new KeyFrame(Duration.millis(100), new EventHandler<ActionEvent>() 
    {

        @Override
        public void handle(ActionEvent event) 
        {



            for (Bullet bul : new ArrayList<Bullet>(bullet_list)) 
            {
                Point2D ene = new Point2D(bot_list.get(selected_bot_id).getX(),bot_list.get(selected_bot_id).getY());
                Point2D play = new Point2D(Player.getCenterX(), Player.getCenterY());
                Point2D p3 = play.subtract(ene);
                Point2D p4 = new Point2D(1, 0);

                System.out.println("Bullet run");

                bul.setRotate(p4.angle(p3) - 90); 
                //*100 is multipl of speed u need
                bul.setTranslateX(bul.getTranslateX() - (Math.cos(Math.toRadians(p4.angle(p3))) *100 ));
                bul.setTranslateY(bul.getTranslateY() - (Math.sin(Math.toRadians(p4.angle(p3))) *100 ));

                if(bul.getTranslateX() < 0 ||bul.getTranslateX() > Constant.WIDTH ||bul.getTranslateY() < 0) {
                    System.out.println("Delecte");
                    bul.delete();

                }
            }




        }

    }));
    frame.setCycleCount(Animation.INDEFINITE);
    frame.play();