2017-01-28 9 views
0

私はJavaFXの中で大学のプロジェクトに取り組んでいます:スペースInvaders.Iのようなゲームは、ParallelTransitionで各OVNIのアニメーションを作成しようとしていた、タイムラインを作成しますのアニメーションを作成し、それをそれぞれのParallelTransitionに追加して、それぞれのEventHandlerを管理して、X位置のovniを移動し、ウィンドウの左境界に来るときYを移動します。問題はiアニメーションを再生しているとき、最初の行だけがx位置に正しく移動しますが、他の行は移動しません。言い換えれば、他の行がx位置にある距離移動すると、それらはリジッド境界上で動きを終了しませんが、代わりにY位置に移動します。モーションの問題

これは、 buildOvniに:第二に

public Shape buildOvni(){ 
    Arc arcCuerpo=new Arc(Constantes.POS_CUERPO_OVNI_X,Constantes.POS_CUERPO_OVNI_Y,Constantes.ANCHO_CUERPO_OVNI,Constantes.ALTO_CUERPO_OVNI,0,180); 
    Arc arcL=new Arc(Constantes.POS_ARC_IZQ_X,Constantes.POS_ARC_IZQ_Y,Constantes.ANCHO_ARC_IZQ,Constantes.ALTO_ARC_IZQ,180,180); 
    Arc arcCentro=new Arc(Constantes.POS_ARC_CTR_X,Constantes.POS_ARC_CTR_Y,Constantes.ANCHO_ARC_CTR,Constantes.ALTO_ARC_CTR,180,180); 
    Arc arcD=new Arc(Constantes.POS_ARC_DER_X,Constantes.POS_ARC_DER_Y,Constantes.ANCHO_ARC_DER,Constantes.ALTO_ARC_DER,180,180); 
    Shape union1=Shape.union(arcCuerpo, arcL); 
    Shape union2=Shape.union(union1, arcCentro); 
    Shape union3=Shape.union(union2, arcD); 

    return union3; 
} 

、私はovnisための2つの行列宣言している:各ovni's形状が含まれていますペインのための1つを、その他にはovniオブジェクトが含まれます。

public Juego(){ 
    lab=new Label(); 
    transicionEnY=new ParallelTransition(); 
    dir=new File(Constantes.GAME_BACKGROUND); 
    Pane navePane=new Pane(); 
    paneOvnis=new Pane[3][6]; //the panes for each ovni´s shape 
    nave=new Nave(navePane); 
    gameContainer=new Pane(); 
    gameContainer.getChildren().addAll(navePane); 
    background=new Image(dir.toURI().toString()); 
    pane=new BorderPane(); 
    pane.setCenter(gameContainer); 
    pane.setBackground(new Background(new BackgroundImage(background,null,null,null,new BackgroundSize(Constantes.MAXIMUM_WIDHT,Constantes.MAXIMUM_HEIGTH,false,false,false,true)))); 
    //playMusic(); 
    agregarOvnis(); 
    moverOvnis(); 
    pane.setBottom(lab); 
} 

各マトリックスを移入するための方法:

public void agregarOvnis(){ 
    this.ovnis=new Ovni[paneOvnis.length][paneOvnis[0].length]; 
    for(int i=0;i<paneOvnis.length;i++){ 
     for(int j=0;j<paneOvnis[0].length;j++){  
      Pane paneOvni=new Pane(); 
      Ovni ovni=new OvniGris(paneOvni); 
      ovni.setLocation(Constantes.POS_OVNI_X+Constantes.OVNI_SPACING_X*j,Constantes.POS_OVNI_Y+Constantes.OVNI_SPACING_Y*i); 
      this.gameContainer.getChildren().add(paneOvni); 
      this.paneOvnis[i][j]=paneOvni; 
      this.ovnis[i][j]=ovni; 
     } 
    } 
} 

ParallelTransitionを宣言し、各OVNIのタイムラインアニメーションを作成する方法を:

public void moverOvnis(){ 
    ParallelTransition animaciones=new ParallelTransition(); 
    for(int i=0;i<ovnis.length;i++){ 
     for(int j=0;j<ovnis[i].length;j++){ 
      Timeline animacionOvnis=new Timeline(); 
      KeyFrame kf=new KeyFrame(Duration.millis(900),new ManejadorMovimientos(i,j)); 
      animacionOvnis.getKeyFrames().add(kf); 
      animacionOvnis.setCycleCount(Timeline.INDEFINITE); 
      animacionOvnis.setAutoReverse(false); 
      animaciones.getChildren().add(animacionOvnis); 
     } 
    } 
    animaciones.play(); 
} 

最後に、このタイムラインのEventHandlerありますクラスごとにovniの動きを作る:

private class ManejadorMovimientos implements EventHandler<ActionEvent>{ 

    int i; 
    int j; 
    int orientacion=1; 

    public ManejadorMovimientos(int i, int j){ 
     this.i=i; 
     this.j=j; 
    } 

    @Override 
    public void handle(ActionEvent event) { 
     double distanciaMaxDer=maxDistanceRight(); 
     double distanciaMaxIzq=maxDistanceLeft(); 
     lab.setText(""+distanciaMaxDer+","+ovnis[0][5].getXLocation()); 
     if(orientacion==1) 
      if(distanciaMaxDer-30>0){ 
      ovnis[i][j].setLocation(ovnis[i][j].getXLocation()+30,ovnis[i][j].getYLocation()); 
      } 
      else{ 
      ovnis[i][j].setLocation(ovnis[i][j].getXLocation(),ovnis[i][j].getYLocation()+20); 
      orientacion=-1;     
      } 
     else{ 
      if(distanciaMaxIzq-30>30){ 
      ovnis[i][j].setLocation(ovnis[i][j].getXLocation()-30,ovnis[i][j].getYLocation()); 
      } 
      else{ 
      ovnis[i][j].setLocation(ovnis[i][j].getXLocation(),ovnis[i][j].getYLocation()+20); 
      orientacion=1; 
      } 
     } 

    } 

    private double maxDistanceRight(){ 
     int j=ovnis[0].length-1; 
     while(j>=0){ 
      for(int i=0;i<ovnis.length;i++){ 
       if(ovnis[i][j]!=null){ 
        return 1.25*Constantes.MAXIMUM_WIDHT-ovnis[i][j].getXLocation(); 
       } 
      } 
      j--; 
     } 
     return -1; 
    } 

    private double maxDistanceLeft(){ 
     int j=0; 
     while(j<ovnis[0].length){ 
      for(int i=0;i<ovnis.length;i++){ 
       if(ovnis[i][j]!=null){ 
        return ovnis[i][j].getXLocation()-30; 
       } 
      } 
      j++; 
     } 
     return -1; 
    } 

} 

は、私はより多くの情報については、それぞれ、ここでは定数、OVNIやゲームクラスを残す(スペイン語でいくつかの単語のため申し訳ありませんが、私のプロジェクトのrequerimentsの一部をit's。)

定数クラスを

public class Constantes { //PARAMETROS GENERALES DEL JUEGO public static final double MENU_HEIGTH= 600; public static final double MENU_WIDTH= 500; public static final double MAXIMUM_HEIGTH = 800; public static final double MAXIMUM_WIDHT= 640; public static final String MAIN_LOGO="src/backgrounds/logo.png"; public static final String MAIN_BACKGROUND="src/backgrounds/mainbackground2.jpg"; public static final String GAME_BACKGROUND="src/backgrounds/gamebackground2.jpg"; public static final String GAME_BACKGROUND_MUSIC="src/sounds/game.mp3"; public static final String MAIN_BACKGROUND_MUSIC="src/sounds/main.mp3"; //PARAMETROS DE CONSTRUCCION DE LA NAVE public static final double POS_NAVE_X=MAXIMUM_WIDHT/2; public static final double POS_NAVE_Y=MAXIMUM_HEIGTH-295; public static final double ANCHO_REC_A=50; public static final double ALTO_REC_A=18; public static final double POS_REC_A_X=(POS_NAVE_X/4)-(ANCHO_REC_A/2); public static final double POS_REC_A_Y=POS_NAVE_Y-400; public static final double ANCHO_REC_B=ANCHO_REC_A*0.66667; public static final double ALTO_REC_B=10; public static final double POS_REC_B_X=POS_REC_A_X+ANCHO_REC_B/4; public static final double POS_REC_B_Y=POS_NAVE_Y-405; public static final double ANCHO_REC_C=ANCHO_REC_B*0.225; public static final double ALTO_REC_C=10; public static final double POS_REC_C_X=POS_REC_B_X+ANCHO_REC_B/2; public static final double POS_REC_C_Y=POS_REC_B_Y; public static final double ANCHO_REC_D=ANCHO_REC_C*0.45; public static final double ALTO_REC_D=10; public static final double POS_REC_D_X=POS_REC_C_X-1; public static final double POS_REC_D_Y=POS_REC_C_Y-ALTO_REC_C-ALTO_REC_D+ALTO_REC_C/2; //PARAMETROS DE CONSTRUCCION DEL OVNI public static final double POS_OVNI_X=70; public static final double POS_OVNI_Y=40; public static final double POS_CUERPO_OVNI_X=0; public static final double POS_CUERPO_OVNI_Y=0; public static final double ANCHO_CUERPO_OVNI=23; public static final double ALTO_CUERPO_OVNI=15; public static final double ANCHO_ARC_IZQ=ANCHO_CUERPO_OVNI*0.22; public static final double ALTO_ARC_IZQ=ALTO_CUERPO_OVNI*0.55; public static final double POS_ARC_IZQ_X=POS_CUERPO_OVNI_X - ANCHO_CUERPO_OVNI * 0.80 + ANCHO_ARC_IZQ/2; public static final double POS_ARC_IZQ_Y=POS_CUERPO_OVNI_Y; public static final double ANCHO_ARC_CTR=ANCHO_CUERPO_OVNI*0.35; public static final double ALTO_ARC_CTR=ALTO_CUERPO_OVNI*0.30; public static final double POS_ARC_CTR_X=POS_CUERPO_OVNI_X; public static final double POS_ARC_CTR_Y=POS_CUERPO_OVNI_Y; public static final double ANCHO_ARC_DER=ANCHO_CUERPO_OVNI*0.22; public static final double ALTO_ARC_DER=ALTO_CUERPO_OVNI*0.55; public static final double POS_ARC_DER_X=POS_CUERPO_OVNI_X + ANCHO_CUERPO_OVNI * 0.60 + ANCHO_ARC_DER/2; public static final double POS_ARC_DER_Y=POS_CUERPO_OVNI_Y; public static final double POS_OVNI_WINDOW_X=POS_CUERPO_OVNI_X - ANCHO_CUERPO_OVNI * 0.80; public static final double POS_OVNI_WINDOW_Y=POS_CUERPO_OVNI_Y - ANCHO_CUERPO_OVNI/2; public static final double OVNI_SPACING_X=70; public static final double OVNI_SPACING_Y=30; //PARAMETROS DE MOVIMIENTO NAVE public static final double MOVIMIENTO_NAVE=2; //PARAMETROS DE MOVIMIENTO OVNI 

}

OVNIクラス

public abstract class Ovni { 
protected Shape ovni; 

public Ovni(Pane pane){ 
    ovni=buildOvni(); 
    pane.getChildren().add(ovni); 
} 

public void setLocation(double x,double y){ 
    ovni.setLayoutX(x); 
    ovni.setLayoutY(y); 
} 

public double getXLocation(){ 
    return ovni.getLayoutX(); 
} 

public double getYLocation(){ 
    return ovni.getLayoutY(); 
} 

public Shape getOvni() { 
    return ovni; 
} 

public void setOvni(Shape ovni) { 
    this.ovni = ovni; 
} 

public Shape buildOvni(){ 
    Arc arcCuerpo=new Arc(Constantes.POS_CUERPO_OVNI_X,Constantes.POS_CUERPO_OVNI_Y,Constantes.ANCHO_CUERPO_OVNI,Constantes.ALTO_CUERPO_OVNI,0,180); 
    Arc arcL=new Arc(Constantes.POS_ARC_IZQ_X,Constantes.POS_ARC_IZQ_Y,Constantes.ANCHO_ARC_IZQ,Constantes.ALTO_ARC_IZQ,180,180); 
    Arc arcCentro=new Arc(Constantes.POS_ARC_CTR_X,Constantes.POS_ARC_CTR_Y,Constantes.ANCHO_ARC_CTR,Constantes.ALTO_ARC_CTR,180,180); 
    Arc arcD=new Arc(Constantes.POS_ARC_DER_X,Constantes.POS_ARC_DER_Y,Constantes.ANCHO_ARC_DER,Constantes.ALTO_ARC_DER,180,180); 
    Shape union1=Shape.union(arcCuerpo, arcL); 
    Shape union2=Shape.union(union1, arcCentro); 
    Shape union3=Shape.union(union2, arcD); 

    return union3; 
} 

}

GAMEクラス

public class Juego { 
private BorderPane pane; 
private Pane gameContainer; 
private File dir; 
private Image background; 
private MediaPlayer player; 
private Nave nave; 
private Pane[][] paneOvnis; 
private Ovni[][] ovnis; 
private final ParallelTransition transicionEnY; 
Label lab; 
/** 
* 
*/ 
public Juego(){ 
    lab=new Label(); 
    transicionEnY=new ParallelTransition(); 
    dir=new File(Constantes.GAME_BACKGROUND); 
    Pane navePane=new Pane(); 
    paneOvnis=new Pane[3][6]; 
    nave=new Nave(navePane); 
    gameContainer=new Pane(); 
    gameContainer.getChildren().addAll(navePane); 
    background=new Image(dir.toURI().toString()); 
    pane=new BorderPane(); 
    pane.setCenter(gameContainer); 
    pane.setBackground(new Background(new BackgroundImage(background,null,null,null,new BackgroundSize(Constantes.MAXIMUM_WIDHT,Constantes.MAXIMUM_HEIGTH,false,false,false,true)))); 
    //playMusic(); 
    agregarOvnis(); 
    moverOvnis(); 
    pane.setBottom(lab); 
} 

/** 
* 
* @return 
*/ 
public BorderPane getRoot(){ 
    return pane; 
} 

/** 
* 
*/ 
public void playMusic(){ 
    File dir=new File(Constantes.GAME_BACKGROUND_MUSIC); 
    Media music=new Media(dir.toURI().toString()); 
    player=new MediaPlayer(music); 
    player.setOnEndOfMedia(new Runnable() { 
    @Override 
     public void run() { 
      player.seek(Duration.ZERO); 
     } 
    }); 
    player.play(); 
} 

public void agregarOvnis(){ 
    this.ovnis=new Ovni[paneOvnis.length][paneOvnis[0].length]; 
    for(int i=0;i<paneOvnis.length;i++){ 
     for(int j=0;j<paneOvnis[0].length;j++){  
      Pane paneOvni=new Pane(); 
      Ovni ovni=new OvniGris(paneOvni); 
      ovni.setLocation(Constantes.POS_OVNI_X+Constantes.OVNI_SPACING_X*j,Constantes.POS_OVNI_Y+Constantes.OVNI_SPACING_Y*i); 
      this.gameContainer.getChildren().add(paneOvni); 
      this.paneOvnis[i][j]=paneOvni; 
      this.ovnis[i][j]=ovni; 
     } 
    } 
} 

/** 
* 
* @param e 
*/ 
public void moverNave(Event e){ 
    ManejadorTeclas manager=new ManejadorTeclas(); 
    manager.handle((KeyEvent) e); 
} 

public void moverOvnis(){ 
    ParallelTransition animaciones=new ParallelTransition(); 
    for(int i=0;i<ovnis.length;i++){ 
     for(int j=0;j<ovnis[i].length;j++){ 
      Timeline animacionOvnis=new Timeline(); 
      KeyFrame kf=new KeyFrame(Duration.millis(900),new ManejadorMovimientos(i,j)); 
      animacionOvnis.getKeyFrames().add(kf); 
      animacionOvnis.setCycleCount(Timeline.INDEFINITE); 
      animacionOvnis.setAutoReverse(false); 
      animaciones.getChildren().add(animacionOvnis); 
     } 
    } 
    animaciones.play(); 
} 

private class ManejadorTeclas implements EventHandler<KeyEvent>{ 

    @Override 
    public void handle(KeyEvent event) { 
     double movimiento=Constantes.MOVIMIENTO_NAVE; 
     if(event.getCode()==KeyCode.RIGHT && nave.getLocationX()+Constantes.MOVIMIENTO_NAVE<Constantes.MAXIMUM_WIDHT) 
      nave.setLocationX(nave.getLocationX()+3); 
     else if(event.getCode()==KeyCode.LEFT && nave.getLocationX()-Constantes.MOVIMIENTO_NAVE>0) 
      nave.setLocationX(nave.getLocationX()-3); 
     else if(event.getCode()==KeyCode.ESCAPE){ 
      pane.getScene().getWindow().hide(); 
     } 
    } 
} 

private class ManejadorMovimientos implements EventHandler<ActionEvent>{ 

    int i; 
    int j; 
    int orientacion=1; 

    public ManejadorMovimientos(int i, int j){ 
     this.i=i; 
     this.j=j; 
    } 

    @Override 
    public void handle(ActionEvent event) { 
     double distanciaMaxDer=maxDistanceRight(); 
     double distanciaMaxIzq=maxDistanceLeft(); 
     lab.setText(""+distanciaMaxDer+","+ovnis[0][5].getXLocation()); 
     if(orientacion==1) 
      if(distanciaMaxDer-30>0){ 
      ovnis[i][j].setLocation(ovnis[i][j].getXLocation()+30,ovnis[i][j].getYLocation()); 
      } 
      else{ 
      ovnis[i][j].setLocation(ovnis[i][j].getXLocation(),ovnis[i][j].getYLocation()+20); 
      orientacion=-1;     
      } 
     else{ 
      if(distanciaMaxIzq-30>30){ 
      ovnis[i][j].setLocation(ovnis[i][j].getXLocation()-30,ovnis[i][j].getYLocation()); 
      } 
      else{ 
      ovnis[i][j].setLocation(ovnis[i][j].getXLocation(),ovnis[i][j].getYLocation()+20); 
      orientacion=1; 
      } 
     } 

    } 

    private double maxDistanceRight(){ 
     int j=ovnis[0].length-1; 
     while(j>=0){ 
      for(int i=0;i<ovnis.length;i++){ 
       if(ovnis[i][j]!=null){ 
        return 1.25*Constantes.MAXIMUM_WIDHT-ovnis[i][j].getXLocation(); 
       } 
      } 
      j--; 
     } 
     return -1; 
    } 

    private double maxDistanceLeft(){ 
     int j=0; 
     while(j<ovnis[0].length){ 
      for(int i=0;i<ovnis.length;i++){ 
       if(ovnis[i][j]!=null){ 
        return ovnis[i][j].getXLocation()-30; 
       } 
      } 
      j++; 
     } 
     return -1; 
    } 

} 

}

+0

これは、それが結果方法です: http://imgur.com/a/jFObp –

+1

[MCVE] – miken32

答えて

0

あなたはラインによって位置ラインを更新し、右端の位置を毎回再計算しています。 ParallelTransitionTimelineを追加した順番で、右下のouviが更新され、下側のouvisが更新されます。つまり、ouvisは右端の1つの「フレーム」に到達すると見なします。問題。

その他の注意事項:単一TimelineはすべてKeyFrame Sを扱うことができるので、

ParallelTransitionを使用して、この場合は、非効率的な/不要です。さらにouvisはすべて同時に更新され、いくつかの値でさえが再利用されるため、複数のKeyFrameも不要です。

次の例では、動き回るシンプルなオブジェクト:

private Rectangle[][] rects = new Rectangle[3][3]; 

private void moveDown() { 
    for (Rectangle[] column : rects) { 
     for (Rectangle r : column) { 
      if (r != null) { 
       r.setY(r.getY() + 5); 
      } 
     } 
    } 
} 

@Override 
public void start(Stage primaryStage) { 
    Pane root = new Pane(); 
    for (int j = 0; j < rects.length; j++) { 
     Rectangle[] column = rects[j]; 
     for (int i = 0; i < column.length; i++) { 
      Rectangle rect = new Rectangle(20, 20); 
      rect.setX(j * 25); 
      rect.setY(i * 25); 
      root.getChildren().add(rect); 
      column[i] = rect; 
     } 
    } 
    Timeline timeline = new Timeline(new KeyFrame(Duration.millis(500), new EventHandler<ActionEvent>() { 

     boolean movingRight = true; 

     @Override 
     public void handle(ActionEvent event) { 
      double maxX = Double.NEGATIVE_INFINITY; 
      double minX = Double.POSITIVE_INFINITY; 
      outer: 
      for (int i = rects.length - 1; i >= 0; i--) { 
       for (Rectangle r : rects[i]) { 
        if (r != null) { 
         maxX = r.getX() + r.getWidth(); 
         break outer; 
        } 
       } 
      } 
      outer: 
      for (Rectangle[] col : rects) { 
       for (Rectangle r : col) { 
        if (r != null) { 
         minX = r.getX(); 
         break outer; 
        } 
       } 
      } 
      if (movingRight) { 
       if (maxX + 5 > 150) { 
        moveDown(); 
        movingRight = false; 
        return; 
       } 
      } else { 
       if (minX - 5 < 0) { 
        moveDown(); 
        movingRight = true; 
        return; 
       } 
      } 
      double dx = movingRight ? 5 : -5; 
      for (Rectangle[] column : rects) { 
       for (Rectangle r : column) { 
        if (r != null) { 
         r.setX(r.getX() + dx); 
        } 
       } 
      } 
     } 

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

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

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
+0

感謝を作成する方法をお読みください私を助けるための多くの!!!!!この例は私のプロジェクトでうまく動作します。 –

関連する問題