java实现贪吃蛇

package demo;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class MyPanel extends JPanel implements KeyListener, ActionListener {
    ImageIcon right = new ImageIcon("src/demo/right.png");
    ImageIcon body = new ImageIcon("src/demo/body.png");
    ImageIcon up = new ImageIcon("src/demo/up.png");
    ImageIcon down = new ImageIcon("src/demo/down.png");
    ImageIcon left = new ImageIcon("src/demo/left.png");

    //声明一个初始值,表示蛇的长度
    int len = 3;
    //两个数组表示x、y坐标
    int[] snakeX = new int[1008];
    int[] snakeY = new int[1008];
    Direction direction = Direction.right;
    Direction lastDirect = Direction.right;
    boolean isStart = false;
    //定时器对象
    Timer timer = new Timer(100, this);
    //食物位置
    int foodX;
    int foodY;
    //随机变量
    Random random = new Random();
    ImageIcon food = new ImageIcon("src/demo/food.png");
    public MyPanel() {
        //设定蛇的头部和身体初始位置
        snakeX[0] = 100;
        snakeY[0] = 100;

        snakeX[1] = 75;
        snakeY[1] = 100;
        snakeX[2] = 50;
        snakeY[2] = 100;
        //获取键盘事件
        this.setFocusable(true);
        //添加监听
        this.addKeyListener(this);
        //启动定时器
        timer.start();
        //生产食物坐标
        foodX = 25 + 25 * random.nextInt(20);
        foodY = 25 + 25 * random.nextInt(20);
    }
    //重写画组件方法
    @Override
    protected void paintComponent(Graphics g) {
        //调用父类方法做基本工作
        super.paintComponent(g);
        //设置背景颜色
        this.setBackground(Color.red);
        //在画布上添加游戏区域
        g.fillRect(0, 0, 700, 900);
        //根据枚举方向显示蛇头朝向
        switch (direction){
            case up:
                up.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
            case down:
                down.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
            case left:
                left.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
            case right:
                right.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
        }
        for (int i = 1; i < len; i++)
            body.paintIcon(this, g, snakeX[i], snakeY[i]);
        food.paintIcon(this, g, foodX, foodY);
        //判读那游戏是否开始
        if (!isStart){
            //开始提示信息
            g.setColor(Color.white);
            g.setFont(new Font("宋体", Font.BOLD, 50));
            g.drawString("请按空格键表示游戏开始!", 50, 500);
        }

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        lastDirect = direction;
        //判断 按空格键
        if (keyCode == 32){
            isStart = !isStart;
            //重画组件
            repaint();
        } else if (keyCode == KeyEvent.VK_UP) {
            direction = Direction.up;
            if (lastDirect == Direction.down)
                direction = lastDirect;
        } else if (keyCode == KeyEvent.VK_DOWN) {
            direction = Direction.down;
            if (lastDirect == Direction.up)
                direction = lastDirect;
        } else if (keyCode == KeyEvent.VK_LEFT) {
            direction = Direction.left;
            if (lastDirect == Direction.right)
                direction = lastDirect;
        } else if (keyCode == KeyEvent.VK_RIGHT) {
            direction = Direction.right;
            if (lastDirect == Direction.left)
                direction = lastDirect;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (isStart){
            //移动身体
            for (int i = len - 1; i > 0; i--){
                snakeX[i] = snakeX[i - 1];
                snakeY[i] = snakeY[i - 1];
            }
            switch (direction){
                case up:
                    snakeY[0] -= 25;
                    if (snakeY[0] < 0){
                        snakeY[0] = 825;
                    }
                    break;
                case down:
                    snakeY[0] += 25;
                    if (snakeY[0] >= 875){
                        snakeY[0] = 0;
                    }
                    break;
                case left:
                    snakeX[0] -= 25;
                    if (snakeX[0] < 0){
                        snakeX[0] = 675;
                    }
                    break;
                case right:
                    snakeX[0] += 25;
                    if (snakeX[0] >= 675){
                        snakeX[0] = 0;
                    }
                    break;
            }
            //蛇头坐标与食物一样则吃掉食物
            if (snakeX[0] == foodX && snakeY[0] == foodY){
                len++;
                //这样写新的身体不会闪一下
                snakeX[len-1] = -50;
                snakeY[len-1] = -50;
                foodX = 25 + 25 * random.nextInt(20);
                foodY = 25 + 25 * random.nextInt(20);
            }
            //判断蛇头碰到身体,则游戏结束
            for (int i = 1; i < len; i++){
                if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]){
                    len = 3;
                    isStart = false;
                }
            }
            repaint();
            timer.start();
        }
    }
}

一些蛇的数据结构和游戏场景

package demo;

import javax.swing.*;

public class MySnake {
    public static void main(String[] args) {
        //创建窗口
        JFrame frame  = new JFrame();
        //设置坐标大小
        frame.setBounds(600, 100, 700, 900);
        //不允许改变大小
        frame.setResizable(false);
        //点击关闭按钮,推出
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new MyPanel());
        //显示
        frame.setVisible(true);
    }
}
package demo;

public enum Direction {
    up, down, left, right;
}

游戏内图片

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.util.*; public class snate extends JFrame implements KeyListener,Runnable { JLabel j; Canvas j1; public static final int canvasWidth = 200; public static final int canvasHeight = 300; public static final int nodeWidth = 10; public static final int nodeHeight = 10; //SnakeModel se=null; //222222 // boolean[][] matrix; LinkedList nodeArray = new LinkedList();//表 Node food;//节点 int maxX; int maxY; int direction = 2; boolean running = false; int timeInterval = 200; double speedChangeRate = 0.75; boolean paused = false; int score = 0; int countMove = 0; // UP and DOWN should be even // RIGHT and LEFT should be odd public static final int UP = 2; public static final int DOWN = 4; public static final int LEFT = 1; public static final int RIGHT = 3; snate() { super(); //setSize(500,400); Container c=getContentPane(); j=new JLabel("Score:"); c.add(j,BorderLayout.NORTH); j1=new Canvas(); j1.setSize(canvasWidth+1,canvasHeight+1); j1.addKeyListener(this); c.add(j1,BorderLayout.CENTER); JPanel p1 = new JPanel(); p1.setLayout(new BorderLayout()); JLabel j2; j2 = new JLabel("PageUp, PageDown for speed;", JLabel.CENTER); p1.add(j2, BorderLayout.NORTH); j2 = new JLabel("ENTER or R or S for start;", JLabel.CENTER); p1.add(j2, BorderLayout.CENTER); j2 = new JLabel("SPACE or P for pause",JLabel.CENTER); p1.add(j2, BorderLayout.SOUTH); c.add(p1,BorderLayout.SOUTH); addKeyListener(this); pack(); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); // begin(); // //2222222 // this.gs = gs; this.maxX = maxX; this.maxY = maxY; // initial matirx matrix = new boolean[maxX][]; for(int i=0; i<maxX; ++i){ matrix[i] = new boolean[maxY]; Arrays.fill(matrix[i],false); } // initial the snake int initArrayLength = maxX > 20 ? 10 : maxX/2; for(int i = 0; i < initArrayLength; ++i){ int x = maxX/2+i; int y = maxY/2; nodeArray.addLast(new Node(x, y)); matrix[x][y] = true; } food = createFood(); matrix[food.x][food.y] = true; } public void keyPressed(KeyEvent e) { if(e.getKeyCode()==KeyEvent.VK_UP) { //se.changeDirection(SnakeModel.UP); } if(e.getKeyCode()==KeyEvent.VK_DOWN) { //se.changeDirection(SnakeModel.DOWN); } if(e.getKeyCode()==KeyEvent.VK_LEFT) { //se.changeDirection(SnakeModel.LEFT); } if(e.getKeyCode()==KeyEvent.VK_RIGHT) { //se.changeDirection(SnakeModel.RIGHT); } if(e.getKeyCode()==KeyEvent.VK_R||e.getKeyCode()==KeyEvent.VK_S||e.getKeyCode()==KeyEvent.VK_ENTER) { } } public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e) {} public void repaint() { Graphics g = j1.getGraphics(); //背景 g.setColor(Color.red); g.fillRect(0,0,canvasWidth,canvasHeight); //蛇 //g.setColor(Color.BLUE); } public void paint(Graphics g) { g.setColor(Color.red); g.fillRect(10,10,10,10); } // //222222 // public void changeDirection(int newDirection){ if (direction % 2 != newDirection % 2){ direction = newDirection; } } public boolean moveOn(){ Node n = (Node)nodeArray.getFirst(); int x = n.x; int y = n.y; switch(direction){ case UP: y--; break; case DOWN: y++; break; case LEFT: x--; break; case RIGHT: x++; break; } if ((0 <= x && x < maxX) && (0 <= y && y < maxY)){ if (matrix[x][y]){ if(x == food.x && y == food.y){ nodeArray.addFirst(food); int scoreGet = (10000 - 200 * countMove) / timeInterval; score += scoreGet > 0? scoreGet : 10; countMove = 0; food = createFood(); matrix[food.x][food.y] = true; return true; } else return false; } else{ nodeArray.addFirst(new Node(x,y)); matrix[x][y] = true; n = (Node)nodeArray.removeLast(); matrix[n.x][n.y] = false; countMove++; return true; } } return false; } public void run(){ running = true; while (running){ try{ Thread.sleep(timeInterval); } catch(Exception e){ break; } if(!paused){ if (moveOn()){ gs.repaint(); } else{ JOptionPane.showMessageDialog( null, "you failed", "Game Over", JOptionPane.INFORMATION_MESSAGE); break; } } } running = false; } private Node createFood(){ int x = 0; int y = 0; do{ Random r = new Random(); x = r.nextInt(maxX); y = r.nextInt(maxY); }while(matrix[x][y]); return new Node(x,y); } public void speedUp(){ timeInterval *= speedChangeRate; } public void speedDown(){ timeInterval /= speedChangeRate; } public void changePauseState(){ paused = !paused; } public String toString(){ String result = ""; for(int i=0; i<nodeArray.size(); ++i){ Node n = (Node)nodeArray.get(i); result += "[" + n.x + "," + n.y + "]"; } return result; } } class Node{ int x; int y; Node(int x, int y){ this.x = x; this.y = y; } } public static void main(String[] args) { //Graphics g=j1.getGraphics(); snate s=new snate(); //s.draw_something(g); //s.setVisible(true); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值