Java Draw не движется змея - PullRequest
0 голосов
/ 24 июня 2019

Я пытаюсь создать клона змеи просто в качестве практики.Я нарисовал змею и добавил шаблоны движения, но змея ест ее самостоятельно, когда я нажимаю любую клавишу, чтобы двигаться.но это не движется.Массив втягивает свои реактивы в начальную точку и ничего не делает.

вот мой класс змей, я удалил свои комментарии, так как они больше, чем код и система публикации, не позволяли мне публиковать

Редактировать

Если вам нужно что-нибудь из других классов, пожалуйста, дайте мне знать.но я думаю, что моя ошибка где-то здесь

РЕДАКТИРОВАТЬ 2

Добавлен весь код, вы можете просто скопировать вставить внутри нового проекта, и вы будете воспроизводить мою ошибку.

public class Snake {

    List<Point> sPoints;
    int xDir,yDir;
    boolean isMoving,addTail;
    final int sSize = 20, startX = 150 , startY = 150;
    public Snake(){

        sPoints = new ArrayList<Point>();

        xDir = 0;
        yDir = 0;

        isMoving = false;

        addTail = false;
        sPoints.add(new Point(startX,startY));

        for(int i=1; i<sSize; i++) {


            sPoints.add(new Point(startX - i * 4,startY));
        }
    }

    public void draw(Graphics g){

        g.setColor(Color.white);

        for(Point p : sPoints) {

            g.fillRect(p.getX(),p.getY(),4,4);
        }
    }

    public void move(){
        if (isMoving) {
            Point temp = sPoints.get(0);
            Point last = sPoints.get(sPoints.size() - 1);

            Point newstart = new Point(temp.getX() + xDir * 4, temp.getY() + yDir * 4);


            for (int i = sPoints.size() - 1; i >= 1; i--) {

                sPoints.set(i, sPoints.get(i - 1));
            }

            sPoints.set(0, newstart);
        }
    }

    public int getxDir() {
        return xDir;
    }

    public void setxDir(int x) {
        this.xDir = xDir;
    }

    public int getyDir() {
        return yDir;
    }

    public void setyDir(int y) {
        this.yDir = yDir;
    }

    public  int getX(){
        return sPoints.get(0).getX();
    }

    public int getY(){
        return sPoints.get(0).getY();
    }

    public boolean isMoving() {
        return isMoving;
    }

    public void setIsMoving(boolean b) {
        isMoving = b;
    }
}

Ниже приведен класс точек.только некоторые методы получения геттеров для точек, для тех, кто использовал IntelliJ для их автоматической генерации .. (снова я удалил комментарии)

public class Point {

    private  int x,y;

    public Point() {

        x = 0;
        y = 0;
    }


      public Point(int x, int y) {

          this.x =x;
          this.y =y;
      }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }


}

и, наконец, мой основной класс под названием игра.здесь я создаю свой апплет и задаю ему цвет фона.создать мою угрозу для запуска.а также добавьте шаблоны движения для вверх / вправо / вниз / влево ... и используйте несколько классов, чтобы обновить мои шаблоны рисования, чтобы он мог имитировать движение, обновляя каждое из состояний моего прямоугольного списка.

import java.applet.Applet;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Game extends Applet implements Runnable, KeyListener {

    //setting up double buffering.
    Graphics graphics;
    Image img;
    Thread thread;
    Snake snake;
    public void init() {
        //setting the size of our Applet
        this.resize(400,400);
        //we gonna create the image just the same size as our applet.
        img = createImage(400,400);
        //this represents our offscreen image that we will draw
        graphics = img.getGraphics();
       this.addKeyListener(this);
        snake = new Snake();
        thread = new Thread(this);
        thread.start();
    }

    public void paint(Graphics g) {
        //Setting the background of our applet to black
        graphics.setColor(Color.black);
        //Fill rectangle 0 , 0 (starts from) for top left corner and then 400,400 to fill our entire background to black
        graphics.fillRect(0,0,400,400);
        snake.draw(graphics);
        //painting the entire image
        g.drawImage(img,0,0,null);
    }

    //Update will call on Paint(g)
    public void update(Graphics g){
        paint(g);
    }
    //Repaint will call on Paint(g)
    public  void repaint(Graphics g){
        paint(g);
    }


    public void run() {
        //infinite loop
        for(;;) {
            snake.move();
            //drawing snake
            this.repaint();
        //Creating a time delay
            try {
                Thread.sleep(40);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }


    public void keyTyped(KeyEvent keyEvent) {


    }

    public void keyPressed(KeyEvent keyEvent) {
        if(!snake.isMoving()){ //this will allow the snake to start moving, but will disable LEFT for just the 1st move
            if(keyEvent.getKeyCode() == KeyEvent.VK_UP || keyEvent.getKeyCode() == KeyEvent.VK_RIGHT ||
                    keyEvent.getKeyCode() == KeyEvent.VK_DOWN ) {
                snake.setIsMoving(true);
            }
        }

        //setting up Key mapping so when the user presses UP,RIGHT,DOWN,LEFT. the Snake will move accordingly
        if(keyEvent.getKeyCode() == KeyEvent.VK_UP) {
            if (snake.getyDir() != 1) {
                snake.setyDir(-1);
                snake.setxDir(0);
            }
        }
        if(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
            if (snake.getxDir() != -1) {
                snake.setxDir(1);
                snake.setyDir(0);
            }
        }
        if(keyEvent.getKeyCode() == KeyEvent.VK_DOWN) {
            if (snake.getyDir() != -1) {
                snake.setyDir(1);
                snake.setxDir(0);
            }
        }
        if(keyEvent.getKeyCode() == KeyEvent.VK_LEFT) {
            if (snake.getxDir() != 1) {
                snake.setxDir(-1);
                snake.setyDir(0);
            }
        }

    }

    public void keyReleased(KeyEvent keyEvent) {

    }
}

Ответы [ 2 ]

1 голос
/ 25 июня 2019

Вот мнение, что я читаю ваш код.

  1. Причина, по которой ваша змея не будет двигаться, в том, что ваши snake.setyDir() и snake.setxDir() не принял ввод для перезаписи xDir и yDir. Они присваивают себе.
  2. В JDK
  3. При перемещении змеи, вам просто нужно убрать хвост и добавить один еще блок перед головой. Вы можете держать тело плотно (в соответствии с насколько мне известно, змея). enter image description here Рассмотрим левую змею в форме буквы L, нижний конец - голова, и в данный момент она движется направо. Чтобы переместить змею, уберите хвост (зеленый блок) и добавьте еще один к голове в соответствии с ее направлением (красный блок). Это окончательное состояние змеи справа. LinkedList удовлетворить потребности.
  4. При использовании двух int (xDir и yDir) для управления направлением змеи сбивает с толку, вы можете помочь себе, создав enum. Те -1, 0, 1 с x и y может сбить вас с толку.
  5. Объявите константу вместо магического числа. например ширина блока 4, размер изображения 400
  6. Является ли Snake.addTail ненужным?
  7. Атрибут должен иметь модификатор доступности

Конечный результат:

enter image description here

Game.java

import java.applet.Applet;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Arrays;

public class Game extends Applet implements Runnable, KeyListener {

    private final int GAMEBOARD_WIDTH = 400;

    // setting up double buffering.
    private Graphics graphics;
    private Image img;
    private Thread thread;
    private Snake snake;

    public void init() {
        // setting the size of our Applet
        this.resize(GAMEBOARD_WIDTH, GAMEBOARD_WIDTH);
        // we gonna create the image just the same size as our applet.
        img = createImage(GAMEBOARD_WIDTH, GAMEBOARD_WIDTH);
        // this represents our offscreen image that we will draw
        graphics = img.getGraphics();
        this.addKeyListener(this);
        snake = new Snake();
        thread = new Thread(this);
        thread.start();
    }

    public void paint(Graphics g) {
        // Setting the background of our applet to black
        graphics.setColor(Color.BLACK);
        // Fill rectangle 0 , 0 (starts from) for top left corner and then 400,400 to
        // fill our entire background to black
        graphics.fillRect(0, 0, GAMEBOARD_WIDTH, GAMEBOARD_WIDTH);
        snake.draw(graphics);
        // painting the entire image
        g.drawImage(img, 0, 0, null);
    }

    // Update will call on Paint(g)
    public void update(Graphics g) {
        paint(g);
    }

    // Repaint will call on Paint(g)
    public void repaint(Graphics g) {
        paint(g);
    }

    public void run() {
        // infinite loop
        for (;;) {
            snake.move();
            // drawing snake
            this.repaint();
            // Creating a time delay
            try {
                Thread.sleep(40);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    public void keyTyped(KeyEvent keyEvent) {

    }

    public void keyPressed(KeyEvent keyEvent) {

        int keyCode = keyEvent.getKeyCode();

        if (!snake.isMoving()) {
            // this will allow the snake to start moving, but will disable LEFT for just the
            // 1st move
            if (matchKey(keyCode, KeyEvent.VK_UP, KeyEvent.VK_RIGHT, KeyEvent.VK_DOWN)) {
                snake.setIsMoving(true);
            }
        }

        // setting up Key mapping so when the user presses UP,RIGHT,DOWN,LEFT. the Snake
        // will move accordingly
        if (matchKey(keyCode, KeyEvent.VK_UP)) {
            snake.setDirection(Direction.UP);
        }
        if (matchKey(keyCode, KeyEvent.VK_RIGHT)) {
            snake.setDirection(Direction.RIGHT);
        }
        if (matchKey(keyCode, KeyEvent.VK_DOWN)) {
            snake.setDirection(Direction.DOWN);
        }
        if (matchKey(keyCode, KeyEvent.VK_LEFT)) {
            snake.setDirection(Direction.LEFT);
        }

    }

    // return true if targetKey contains the provided keyCode
    private boolean matchKey(int keyCode, int... targetKey) {
        return Arrays.stream(targetKey).anyMatch(i -> i == keyCode);
    }

    public void keyReleased(KeyEvent keyEvent) {

    }
}

Snake.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.Point2D;
import java.util.LinkedList;

public class Snake {

    private final int sSize = 20, startX = 150, startY = 150;
    private final int BLOCK_WIDTH = 4;

    private LinkedList<Point2D.Float> sPoints;

    private boolean isMoving;

    private Direction direction;

    public Snake() {

        sPoints = new LinkedList<Point2D.Float>();

        isMoving = false;

        sPoints.add(new Point2D.Float(startX, startY));

        for (int i = 1; i < sSize; i++) {
            sPoints.add(new Point2D.Float(startX - i * BLOCK_WIDTH, startY));
        }
    }

    public void draw(Graphics g) {

        g.setColor(Color.white);
        for (Point2D p : sPoints) {
            g.fillRect((int) p.getX(), (int) p.getY(), BLOCK_WIDTH, BLOCK_WIDTH);
        }
    }

    public void move() {
        if (isMoving) {
            sPoints.removeLast();
            steer(sPoints.getFirst());
        }
    }

    private void steer(Point2D head) {

        Point2D.Float newHead = new Point2D.Float();
        switch (this.getDirection()) {
        case UP:
            newHead.setLocation(head.getX(), head.getY() - BLOCK_WIDTH);
            break;
        case DOWN:
            newHead.setLocation(head.getX(), head.getY() + BLOCK_WIDTH);
            break;
        case LEFT:
            newHead.setLocation(head.getX() - BLOCK_WIDTH, head.getY());
            break;
        case RIGHT:
            newHead.setLocation(head.getX() + BLOCK_WIDTH, head.getY());
            break;
        }

        this.sPoints.addFirst(newHead);

    }

    public int getX() {
        return (int) sPoints.get(0).getX();
    }

    public int getY() {
        return (int) sPoints.get(0).getY();
    }

    public boolean isMoving() {
        return isMoving;
    }

    public void setIsMoving(boolean b) {
        isMoving = b;
    }

    public Direction getDirection() {
        return direction;
    }

    public void setDirection(Direction d) {
        if (this.getDirection() == null) {
            this.direction = d;
        } else if (!this.getDirection().isOpposite(d)) {
            this.direction = d;
        }
    }
}

Direction.java

public enum Direction {
    UP(-1), DOWN(1), LEFT(-2), RIGHT(2);

    int vector;

    Direction(int i) {
        this.vector = i;
    }

    public boolean isOpposite(Direction d) {
        return this.vector + d.vector == 0;
    }

}
0 голосов
/ 24 июня 2019

Snack.java

import java.awt.EventQueue;
import javax.swing.JFrame;

public class Snake extends JFrame {

    public Snake() {

        initUI();
    }

    private void initUI() {

        add(new Board());

        setResizable(false);
        pack();

        setTitle("Snake");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }


    public static void main(String[] args) {

        EventQueue.invokeLater(() -> {
            JFrame ex = new Snake();
            ex.setVisible(true);
        });
    }
}

Board.java

enter image description here

enter image description here enter image description here enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Board extends JPanel implements ActionListener {

    private final int B_WIDTH = 300;
    private final int B_HEIGHT = 300;
    private final int DOT_SIZE = 10;
    private final int ALL_DOTS = 900;
    private final int RAND_POS = 29;
    private final int DELAY = 140;

    private final int x\[\] = new int\[ALL_DOTS\];
    private final int y\[\] = new int\[ALL_DOTS\];

    private int dots;
    private int apple_x;
    private int apple_y;

    private boolean leftDirection = false;
    private boolean rightDirection = true;
    private boolean upDirection = false;
    private boolean downDirection = false;
    private boolean inGame = true;

    private Timer timer;
    private Image ball;
    private Image apple;
    private Image head;

    public Board() {

        initBoard();
    }

    private void initBoard() {

        addKeyListener(new TAdapter());
        setBackground(Color.black);
        setFocusable(true);

        setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
        loadImages();
        initGame();
    }

    private void loadImages() {

        ImageIcon iid = new ImageIcon("src/resources/dot.png");
        ball = iid.getImage();

        ImageIcon iia = new ImageIcon("src/resources/apple.png");
        apple = iia.getImage();

        ImageIcon iih = new ImageIcon("src/resources/head.png");
        head = iih.getImage();
    }

    private void initGame() {

        dots = 3;

        for (int z = 0; z < dots; z++) {
            x\[z\] = 50 - z * 10;
            y\[z\] = 50;
        }

        locateApple();

        timer = new Timer(DELAY, this);
        timer.start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        doDrawing(g);
    }

    private void doDrawing(Graphics g) {

        if (inGame) {

            g.drawImage(apple, apple_x, apple_y, this);

            for (int z = 0; z < dots; z++) {
                if (z == 0) {
                    g.drawImage(head, x\[z\], y\[z\], this);
                } else {
                    g.drawImage(ball, x\[z\], y\[z\], this);
                }
            }

            Toolkit.getDefaultToolkit().sync();

        } else {

            gameOver(g);
        }        
    }

    private void gameOver(Graphics g) {

        String msg = "Game Over";
        Font small = new Font("Helvetica", Font.BOLD, 14);
        FontMetrics metr = getFontMetrics(small);

        g.setColor(Color.white);
        g.setFont(small);
        g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2, B_HEIGHT / 2);
    }

    private void checkApple() {

        if ((x\[0\] == apple_x) && (y\[0\] == apple_y)) {

            dots++;
            locateApple();
        }
    }

    private void move() {

        for (int z = dots; z > 0; z--) {
            x\[z\] = x\[(z - 1)\];
            y\[z\] = y\[(z - 1)\];
        }

        if (leftDirection) {
            x\[0\] -= DOT_SIZE;
        }

        if (rightDirection) {
            x\[0\] += DOT_SIZE;
        }

        if (upDirection) {
            y\[0\] -= DOT_SIZE;
        }

        if (downDirection) {
            y\[0\] += DOT_SIZE;
        }
    }

    private void checkCollision() {

        for (int z = dots; z > 0; z--) {

            if ((z > 4) && (x\[0\] == x\[z\]) && (y\[0\] == y\[z\])) {
                inGame = false;
            }
        }

        if (y\[0\] >= B_HEIGHT) {
            inGame = false;
        }

        if (y\[0\] < 0) {
            inGame = false;
        }

        if (x\[0\] >= B_WIDTH) {
            inGame = false;
        }

        if (x\[0\] < 0) {
            inGame = false;
        }

        if (!inGame) {
            timer.stop();
        }
    }

    private void locateApple() {

        int r = (int) (Math.random() * RAND_POS);
        apple_x = ((r * DOT_SIZE));

        r = (int) (Math.random() * RAND_POS);
        apple_y = ((r * DOT_SIZE));
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if (inGame) {

            checkApple();
            checkCollision();
            move();
        }

        repaint();
    }

    private class TAdapter extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {

            int key = e.getKeyCode();

            if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
                leftDirection = true;
                upDirection = false;
                downDirection = false;
            }

            if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
                rightDirection = true;
                upDirection = false;
                downDirection = false;
            }

            if ((key == KeyEvent.VK_UP) && (!downDirection)) {
                upDirection = true;
                rightDirection = false;
                leftDirection = false;
            }

            if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
                downDirection = true;
                rightDirection = false;
                leftDirection = false;
            }
        }
    }
}

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...