代码之家  ›  专栏  ›  技术社区  ›  CodeF0x

蛇游戏-不能控制蛇

  •  2
  • CodeF0x  · 技术社区  · 7 年前

    贴底的实际问题!
    首先,我想解释一下我的问题。

    我正在写一个基本的蛇游戏,我让蛇自动移动。当您执行代码时,它会自动移动到窗口的右侧,就像预期的那样。但是,我不能按我想要的方向控制我的蛇,它根本不会改变方向。


    为了避免混淆, player 是类的实例 Snake .


    要解释蛇的运动:

    这个 对象具有 coordinates 属于ArrayList保留的属性 SnakePart 物体。各 蛇形零件 对象具有属性 x y . 使用这个数组列表,蛇通过在画布上绘制小矩形来移动。 X Y 画布Y轴和X轴上的属性。

    这个 对象还具有 dx 和A dy 属性,该属性将添加(或减去--取决于蛇的方向) X Y 性质 蛇形零件 使蛇向某个方向移动。


    在中更新arraylist Snake.java :

    public void move() {
      SnakePart head = new SnakePart(this.coordinates.get(0).x + this.dx, this.coordinates.get(0).y + this.dy);
    
      this.coordinates.add(0, head);
      this.coordinates.remove(this.coordinates.size() - 1);
    }
    

    在画布上画蛇 Board.java (部分原因是目前不需要其他方法):

    @Override
    public void paintComponent(Graphics g) {
      this.player.coordinates.forEach(snakePart -> {
        g.setColor(Color.BLUE);
        g.fillRect(snakePart.x, snakePart.y, 10, 10);
      });
    }
    

    为了控制蛇的方向,我想用箭头键。根据按下哪个箭头键,蛇的 X Y 修改坐标/属性( 爪哇岛 ):

    @Override
    public void keyPressed(KeyEvent event) {
      int keyCode = event.getKeyCode();
    
      if (keyCode == 37) {
        this.player.dx = -10;
        this.player.dy = 0;
      } else if (keyCode == 38) {
        this.player.dx = 0;
        this.player.dy = -10;
      } else if (keyCode == 39) {
        this.player.dx = 10;
        this.player.dy = 0;
      } else if (keyCode == 40) {
        this.player.dx = 0;
        this.player.dy = 10;
      }
    }
    

    完整代码:

    爪哇蛇 :

    package com.codef0x.snake;
    import java.util.ArrayList;
    
    public class Snake {
      ArrayList < SnakePart > coordinates;
      int dx = 10;
      int dy = 0;
    
      public Snake(ArrayList < SnakePart > coords) {
        this.coordinates = coords;
      }
    
      public void move() {
        SnakePart head = new SnakePart(this.coordinates.get(0).x + this.dx, this.coordinates.get(0).y + this.dy);
    
        this.coordinates.add(0, head);
        this.coordinates.remove(this.coordinates.size() - 1);
      }
    
      public void grow() {
        SnakePart newPart = new SnakePart(0, 0);
        newPart.x = this.coordinates.get(this.coordinates.size() - 1).x - 10;
        newPart.y = this.coordinates.get(this.coordinates.size() - 1).y;
    
        this.coordinates.add(this.coordinates.size() - 1, newPart);
      }
    }
    

    爪哇岛 (只显示相关部分,否则代码太多)

    package com.codef0x.snake;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.ArrayList;
    import java.util.Timer;
    import java.util.TimerTask;
    
    
    public class Board extends JPanel implements KeyListener {
      Snake player;
      ArrayList<SnakePart> snakeCoordinates;
    
      public Board() {
    
        this.snakeCoordinates = new ArrayList<>();
    
        snakeCoordinates.add(new SnakePart(150, 150));
        snakeCoordinates.add(new SnakePart(140, 150));
        snakeCoordinates.add(new SnakePart(130, 150));
        snakeCoordinates.add(new SnakePart(120, 150));
    
        this.player = new Snake(snakeCoordinates);
    
        this.food = new Food();
      }
    
      @Override
      public void paintComponent(Graphics g) {
        clear(g);
    
        this.player.coordinates.forEach(snakePart - > {
          g.setColor(Color.BLUE);
          g.fillRect(snakePart.x, snakePart.y, 10, 10);
        });
      }
    
      public void clear(Graphics g) {
        g.clearRect(0, 0, getHeight(), getWidth());
      }
    
      @Override
      public void update(Graphics g) {
        paintComponent(g);
      }
    
      @Override
      public void keyPressed(KeyEvent event) {
        int keyCode = event.getKeyCode();
    
        if (keyCode == 37) {
          this.player.dx = -10;
          this.player.dy = 0;
        } else if (keyCode == 38) {
          this.player.dx = 0;
          this.player.dy = -10;
        } else if (keyCode == 39) {
          this.player.dx = 10;
          this.player.dy = 0;
        } else if (keyCode == 40) {
          this.player.dx = 0;
          this.player.dy = 10;
        }
      }
    
      @Override
      public void keyTyped(KeyEvent event) {
        return;
      }
    
      @Override
      public void keyReleased(KeyEvent event) {
        return;
      }
    
      public void run(Board board) {
        Timer game = new Timer();
        game.schedule(new TimerTask() {
          boolean initiallySpawned = false;
          @Override
          public void run() {
            Graphics g = board.getGraphics();
    
            if (hitSomething()) { // removed method hitSomething, not relevant
              game.cancel();
              return;
            }
    
            player.move();
            update(g);
          }
        }, 0, 500);
      }
    }
    

    SnakePart.java :

    package com.codef0x.snake;
    
    public class SnakePart {
      int x;
      int y;
    
      public SnakePart(int x, int y) {
        this.x = x;
        this.y = y;
      }
    }
    

    我做错了什么?我需要做什么来正确地控制蛇?


    如果您仍然希望/需要将所有文件作为一个整体查看,可以在此处查看它们:

    Snake.java
    Board.java
    SnakePart.java
    Food.java <-不相关,但可以防止混淆 Food 对象

    1 回复  |  直到 7 年前
        1
  •  2
  •   minus    7 年前

    问题主要是。 你创造了一个 board 主办 你的游戏状态,并创建不同的一个来听键盘。

    public static void main(String[] args) {
    
        JFrame frame = new JFrame("Snake");
        frame.setDefaultCloseOperation(3);
    
        Board board = new Board();
        frame.add(board);
        frame.setSize(500, 500);
        frame.addKeyListener(new Board());
        frame.setVisible(true);
    
        board.run(board);
    }
    

    应该是:

    public static void main(String[] args) {
    
        JFrame frame = new JFrame("Snake");
        frame.setDefaultCloseOperation(3);
    
        Board board = new Board();
        frame.add(board);
        frame.setSize(500, 500);
        frame.addKeyListener(board);
        frame.setVisible(true);
    
    
        board.run(board);
    }
    

    阿尔索 board.run(board) 没有什么意义,在 run 方法,可以将板交换到 this (如此省略)

    推荐文章