2017-02-23 2 views
-1

J'utilise Javafx pour essayer de créer un jeu 2D où un joueur (classe de joueur) sera capable de déplacer une caisse (classe alimentaire) vers un certain endroit. Je peux amener le joueur à entrer en collision avec l'image que je veux déplacer, mais il ne bouge pas sur la grille. J'ai mis un message system.out pour agir comme un débogueur mais toujours pas de mouvement.Objets ne bougeant pas en collision

public class Game extends Application{ 
      Pane backgroundPane; 
      Pane playfieldLayer; 
      Pane scoreLayer; 

      Image playerImage; 
      Image foodImage; 

      List<Player> players = new ArrayList<>(); 
      List<Food> foods = new ArrayList<>(); 

      Text collisionText = new Text(); 
      boolean collision = false; 

      Scene scene; 

      @Override 

      public void start(Stage theStage) { 

       Group root = new Group(); 
       int columnAmount = 18; 
       int rowAmount = 18; 

       GridPane gameGrid = new GridPane(); 

       for (int i = 0; i < columnAmount; i++) { 
        ColumnConstraints columnn = new ColumnConstraints(45); 
        gameGrid.getColumnConstraints().add(columnn); 

       } 

       for (int i = 0; i < rowAmount; i++) { 
        RowConstraints row = new RowConstraints(45); 
        gameGrid.getRowConstraints().add(row); 
       } 

       gameGrid.setStyle("-fx-background-color: white; -fx-grid-lines-visible:true"); 


      root.getChildren().add(gameGrid); 
       // create layers 
       backgroundPane = new Pane(); 
       backgroundPane.setId("root"); 
       playfieldLayer = new Pane(); 
       scoreLayer = new Pane(); 

       root.getChildren().add(backgroundPane); 
       root.getChildren().add(playfieldLayer); 
       root.getChildren().add(scoreLayer); 

       scene = new Scene(root, Settings.SCENE_WIDTH, Settings.SCENE_HEIGHT); 
       backgroundPane.getStylesheets().addAll(this.getClass().getResource("application.css").toExternalForm()); 

       theStage.setResizable(false); 
       theStage.setScene(scene); 
       theStage.show(); 

       loadGame(); 
       createPlayers(); 

       AnimationTimer gameLoop = new AnimationTimer() { 

        @Override 
        public void handle(long now) { 

         // player input 
         players.forEach(sprite -> sprite.processInput()); 
         spawnFood(); 

         players.forEach(sprite -> sprite.move()); 
         foods.forEach(sprite -> sprite.move()); 


         checkCollisions(); 

         players.forEach(sprite -> sprite.updateUI()); 
         foods.forEach(sprite -> sprite.updateUI()); 
        } 
       }; 
       gameLoop.start(); 
      } 

      private void loadGame() { 
       playerImage = new Image(getClass().getResource("warehouse.png").toExternalForm()); 
       //enemyImage = new Image(getClass().getResource("enemy.png").toExternalForm()); 
       foodImage = new Image(getClass().getResource("food.png").toExternalForm()); 
      } 

      private void createPlayers() { 
       // player input 
       Input input = new Input(scene); 

       // register input listeners 
       input.addListeners(); // TODO: remove listeners on game over 

       Image image = playerImage; 

       // center horizontally, position at 70% vertically 
       double x = (Settings.SCENE_WIDTH - image.getWidth())/2.0; 
       double y = Settings.SCENE_HEIGHT * 0.7; 

       // create player 
       Player player = new Player(playfieldLayer, image, x, y, 0, 0, 0, Settings.PLAYER_SPEED, input); 

       // register player 
       players.add(player); 

      } 

      Input input = new Input(scene); 

     input.addListeners(); 


     Image image = foodImage; 

      double x = (Settings.SCENE_WIDTH - image.getWidth())/2.0; 
      double y = Settings.SCENE_HEIGHT * 0.2; 

     Food food = new Food(playfieldLayer, image, x,y,0,0, Settings.PLAYER_SHIP_SPEED, input); 

     foods.add(food); 

      private void checkCollisions() { 

       collision = false; 

       for(Player player: players) { 
        for(Food food: foods) { 
         if(player.collidesWith(food)) { 
          Food.collision = true; 
          food.updateUI(); 
          System.out.println("Collided"); 
         } 
        } 
       } 
      } 


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

    } 
    public abstract class SpriteBase { 
    public void move() { 
      if(!canMove) 
       return; 

      x += dx; 
      y += dy; 
     } 

    public void updateUI() { 
      imageView.relocate(x, y); 
    } 
    } 

public class Food extends SpriteBase { 
    double foodMinX; 
    double foodMaxX; 
    double foodMinY; 
    double foodMaxY; 
    double speed; 
    Input input; 

    static boolean collision; 

public Food(Pane layer, Image image, double x, double y, double dx, double dy, double speed, Input input) { 
     super(layer, image, x, y, dx, dy); 
     this.speed = speed; 
     this.input = input; 
     checkBounds1(); 
    } 

private void checkBounds1() { 
     // calculate movement bounds of the player ship 
     // allow half of the ship to be outside of the screen 
    foodMinX = 0 - image.getWidth()/2.0; 
    foodMaxX = Settings.SCENE_WIDTH - image.getWidth()/2.0; 
    foodMinY = 0 - image.getHeight()/2.0; 
    foodMaxY = Settings.SCENE_HEIGHT -image.getHeight()/2.0; 
    } 

public void processInput() { 
    if(input.isMoveUp() && collision != false) { 
     input.removeListeners(); 
     dy = -speed; 
     collision = false; 
     System.out.println("move up you bastard"); 
    } else if(input.isMoveDown() && collision != false) { 
     input.removeListeners(); 
     System.out.println("move up you bastard"); 
     dy = speed; 
     collision = false; 
    } else { 

     dy = 0d; 
    } 

    // horizontal direction 
    if(input.isMoveLeft() && collision == true) { 
     input.removeListeners(); 
     System.out.println("move up you bastard"); 
     collision = false; 
     dx = -speed; 
    } else if(input.isMoveRight() && collision == true) { 
     input.removeListeners(); 
     System.out.println("move up you bastard"); 
     collision = false; 
     dx = speed; 
    } else { 
     dx = 0d; 
    } 

    } 


@Override 
    public void move() { 
     super.move(); 
     // ensure the food can't move outside of the screen 
     checkBounds(); 
    } 

private void checkBounds() { 

     // vertical 
     if(Double.compare(y, foodMinY) < 0) { 
      y = foodMinY; 
     } else if(Double.compare(y, foodMaxY) > 0) { 
      y = foodMaxY; 
     } 

     // horizontal 
     if(Double.compare(x, foodMinX) < 0) { 
      x = foodMinX; 
     } else if(Double.compare(x, foodMaxX) > 0) { 
      x = foodMaxX; 
     } 
    } 
+2

Je soupçonne que vous avez publié beaucoup plus de code que la plupart des gens vont vouloir trawl à travers. Essayez de le réduire à un [mcve] – khelwood

+0

Lorsque vous configurez l'aliment, vous passez '0' à' dx' et 'dy'. Ainsi, la fonction 'move()' est appelée, elle ajoute simplement '0' à vos' x' et 'y'. Dans votre méthode 'spawnFoods'. –

+0

Je l'ai quelque peu réduit. Pensez-vous que cela a l'air mieux ou suggérez-vous de le réduire davantage? Merci pour la réponse Hypnic Jerk, très gentil de votre part. Que suggérez-vous de corriger cela? – callumSteven

Répondre

0

Suite du commentaire.

Lorsque vous appelez la méthode spawnFood(), vous faites new Food() avec un dx et dy valeur de 0. Donc, il n'a pas de vitesse à déplacer.

Food food = new Food(playfieldLayer, image, x,y,0,0); <--Here 

"Mais je fais la même chose sur la classe Player!" (Édité sur)

Player player = new Player(playfieldLayer, image, x, y, 0, 0, 0, Settings.PLAYER_SPEED, input);<-- Here 

Vous ne passez 0 pour dx,dy lorsque vous créez le Player aussi bien, sauf que vous passez aussi le Settings.PLAYER_SPEED, que vous définissez ensuite dans le constructeur. Vous ne faites pas cela dans la classe Food.

public Food(Pane layer, Image image, double x, double y, double dx, double dy) { 
     super(layer, image, x, y, dx, dy); 
     /***** NOT HERE ****/ 
     checkBounds1(); 

    } 

Je suggère de modifier les valeurs dx,dy dans votre méthode spawnFood(), à quelque chose d'autre, ou passer aussi le Settings.PLAYER_SPEED, puisque je suppose que vous voulez que la nourriture pour rester en face du personnage.

+0

Merci beaucoup pour la réponse. Je suis allé de l'avant et essayé d'entrer vos suggestions. Fondamentalement, j'ai changé la méthode spawnFood() et checkCollision() dans ma classe de jeu, en ajoutant un écouteur d'entrée et en passant à la vitesse du joueur et en faisant une variable bool statiques. De plus, dans ma classe alimentaire, j'ai ajouté une détection collison pour déplacer l'image en fonction de l'entrée du joueur (j'ai pensé que c'est assez raisonnable pour ce dont j'ai besoin). Mais je reçois ce problème étrange où l'image originale reste dans son point d'apparition et je ne peux que déplacer l'image d'une manière jusqu'à ce qu'elle atteigne le bord de l'écran. – callumSteven

+0

J'aurais dû mentionner les changements que j'ai faits sont dans le post original – callumSteven