亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java Draw不動蛇

Java Draw不動蛇

喵喔喔 2023-02-16 15:19:27
我正在嘗試創建一個蛇克隆作為練習。我畫了蛇并添加了運動模式,但是當我按任意鍵移動時蛇會自己吃掉它。但它不動。該陣列收回起點上的反應堆并且什么也不做。這是我的蛇類我已經刪除了我的評論,因為它們不僅僅是代碼而且發布系統不允許我發布編輯如果您需要其他班級的任何東西,請告訴我。但我認為我的錯誤就在這里編輯 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;    }}下面是點類。只是一些點的 getter setter,對于那些我使用 IntelliJ 自動生成它們的點..(我再次刪除了評論)
查看完整描述

2 回答

?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

這是我閱讀您的代碼的一些意見。

  1. 你的蛇不會移動的原因是因為你的snake.setyDir()and snake.setxDir()沒有接受輸入來覆蓋 xDirand yDir。他們正在分配給自己。

  2. JDK 中已經Point2D為你準備好了一個類

  3. 移動蛇時,只需要去掉尾巴,在蛇頭前多加一個方塊即可。你可以保持身體緊繃(據我對蛇的常識)。在此處輸入圖像描述 考慮左側的 L 形蛇,底端是頭部,它目前正向右移動。要移動蛇,請移除尾巴(綠色塊)并根據其方向(紅色塊)在頭部添加一條。它的最終狀態變成了右邊的蛇。LinkedList適合需要。

  4. 如果使用兩個 int(xDiryDir)來控制蛇的方向令人困惑,您可以通過創建一個enum. 那些帶有 x 和 y 的 -1、0、1 可能會讓您感到困惑。

  5. 聲明常量而不是幻數。例如塊 4 的寬度,圖像大小 400

  6. Snake.addTail不必要的嗎?

  7. 屬性應該有可訪問性修飾符

最終結果:

https://i.stack.imgur.com/IbbND.gif

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;

    }


}


查看完整回答
反對 回復 2023-02-16
?
慕碼人8056858

TA貢獻1803條經驗 獲得超6個贊

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

http://img1.sycdn.imooc.com//63edd93f0001bcc602360214.jpg

http://img1.sycdn.imooc.com//63edd94a0001b4c500490026.jpg

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;

            }

        }

    }

}

http://img1.sycdn.imooc.com//63edd95d000107ee03010324.jpg

查看完整回答
反對 回復 2023-02-16
  • 2 回答
  • 0 關注
  • 121 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號