zoukankan      html  css  js  c++  java
  • Java贪吃蛇游戏(坐标方法)

    最近研究一个大大的贪吃蛇代码,自己开始试着写了写,已经对贪吃蛇的移动及规则方面的算法了解,主要是绘图方面有很大的困难,因为贪吃蛇的代码中将蛇的身体定义成多个坐标点,所以在绘图的过程中就必须要把这样的点给放大,与此同时蛇的移动范围又要在panel面板尺寸的基础上进行缩小,这样才使得游戏中设的移动不出问题。废话不说,上代码

    Snake.java

    import java.util.*;
    import javax.swing.*;
    public class Snake {
    int len,wid;
    static int up=1;
    static int down=3;
    static int left=2;
    static int right=4;
    int direction=4;
    LinkedList snakeList = new LinkedList();
    Node food;
    Snakepanel pane;
    boolean al[][];
    static boolean run=true;
    public Snake(Snakepanel pane,int x,int y)
    {
    len=x;
    wid=y;
    this.pane=pane;
    al=new boolean[x][y];
    for(int i=0;i<x;i++)
    {
    for(int j=0;j<y;j++)
    al[i][j]=false;
    }//设定边界,除蛇身以及食物以外的地方布尔值为false,
    int length = len > 20 ? 10 : len / 2;
    for(int i=0;i<length;i++)
    {
    int a=x/10+i;
    int b=y/10;
    snakeList.addFirst(new Node(a,b));//设置蛇身,蛇头朝右方向
    }
    food=createfood();
    al[food.x][food.y]=true;
    };
    public void move(){
    Node n=(Node)snakeList.getFirst();
    int x=n.x;
    int y=n.y;
    if(direction==4)
    x++;
    if(direction==2)
    x--;
    if(direction==3)
    y++;
    if(direction==1)
    y--;
    if((0<=x&&x<=pane.len/15-1)&&(0<=y&&y<=pane.wid/15-2))

    {
    if(al[x][y])
    {
    if(x==food.x&&y==food.y)
    {
    snakeList.addFirst(food);
    food =createfood();
    al[food.x][food.y] = true;
    }
    else 
    {
    JOptionPane.showMessageDialog(null, "GameOver");
    System.exit(0);
    }
    }
    else 
    {
    snakeList.addFirst(new Node(x,y));
    al[x][y]=true;
    Node l=(Node)snakeList.getLast();
    snakeList.removeLast();
    al[l.x][l.y]=false;//蛇身移动,队头增加,队尾删除
    }
    }
    else
    {
    JOptionPane.showMessageDialog(null, "GameOver");
    System.exit(0);
    }
    pane.repaint();//重绘组件
    }
    public Node createfood()
    {
    int x=0,y=0;
    do {
    Random r = new Random();
    x = r.nextInt(len-10);
    y = r.nextInt(wid-10);


    } while (al[x][y]);//排除食物产生在蛇身的可能
    return new Node(x, y);
    }
    public void changeDirection(int newdirection)
    {
    if(direction%2!=newdirection%2)
    {
    direction=newdirection;
    }//保证蛇不能回头
    }

    }


    Node.java

    public class Node {
    int x,y;
    public Node(int x,int y)
    {
    this.x=x;
    this.y=y;

    }
    }


    Snakepanel.java

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    public class Snakepanel extends JPanel implements KeyListener {//键盘事件接口
    int len=400;
    int wid=500;
    int rectx=15;
    int recty=15;//倍数设置
    int count=1;
    Snake snake;
    Node n;
    public Snakepanel()
    {
    snake=new Snake(this,len/rectx,wid/recty);
    setBackground(Color.BLACK);
    setSize(len,wid);
    setFocusable(true);
    addKeyListener(this);
    }
    public void paintComponent(Graphics g) {
    super.paintComponent(g);//打印容器中每个组件
    LinkedList list = snake.snakeList;
    Iterator it = list.iterator();
    g.setColor(Color.white);
    while (it.hasNext()) {
    n = (Node) it.next();
    drawNode(g, n);//调用迭代器并绘制蛇身颜色
    }
    g.setColor(Color.WHITE);
    Node f = snake.food;
    drawNode(g, f);//绘制食物颜色
    }
    public void keyPressed(KeyEvent e) {
    int keycode = e.getKeyCode();
    if (keycode == KeyEvent.VK_ENTER) {
    begin();
    } else if (keycode == KeyEvent.VK_UP) {
    snake.changeDirection(Snake.up);
    } else if (keycode == KeyEvent.VK_DOWN) {
    snake.changeDirection(Snake.down);
    } else if (keycode == KeyEvent.VK_LEFT) {
    snake.changeDirection(Snake.left);
    } else if (keycode == KeyEvent.VK_RIGHT) {
    snake.changeDirection(Snake.right);

    }


    public void keyReleased(KeyEvent e) {
    }


    public void keyTyped(KeyEvent e) {
    }//上述两种方法不需要实现,但必须空处理


    public void drawNode(Graphics g, Node n) {
    g.fillRect(n.x*rectx , n.y*recty , rectx-2, recty-2);
    }//定义绘制方法
    public void begin() {
    if(count==1)
    {
    Snake.run = true;
    SnakeThread thread = new SnakeThread(snake);
    thread.start();
    count++;
    }//调用线程实现蛇体移动,已经修正按回车加速的BUG
    }
    }



    SnakeThread.java
    public class SnakeThread extends Thread {
    Snake snake;


    public SnakeThread(Snake s) {
    snake = s;
    }


    public void run() {
    Snake.run = true;


    while (Snake.run) {
    try {
    snake.move();
    sleep(150);//休眠时间,影响游戏速度
    } catch (InterruptedException e) {
    }
    }
    }
    }

    Snakeframe.java

    import javax.swing.*;
    import java.awt.*;
    public class Snakeframe extends JFrame{
    public Snakeframe() {
    setSize(400, 505);
    setTitle("贪吃蛇");
    this.setLocation(360, 150);
    Snakepanel panel = new Snakepanel();
    add(panel, BorderLayout.CENTER);
    }
    }

    Play.java

    import javax.swing.*;
    public class Play {
    public static void main(String args[]) {
    Snakeframe frame = new Snakeframe();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);//窗口是否可以改变大小
    frame.setVisible(true);//显示窗口
    JOptionPane.showMessageDialog(null, "回车键开始\n上,下,左,右控制蛇的方向");
    }
    }



  • 相关阅读:
    bzoj 3226 [Sdoi2008]校门外的区间(线段树)
    bzoj 1513 [POI2006]Tet-Tetris 3D(二维线段树)
    cf293E Close Vertices(树分治+BIT)
    点分治练习:不虚就是要AK
    点分治练习: boatherds
    bzoj 4016 [FJOI2014]最短路径树问题(最短路径树+树分治)
    bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)
    464 整数排序Ⅱ
    445 余弦相似度
    488 快乐数
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3019661.html
Copyright © 2011-2022 走看看