您的位置:首页 > 编程语言 > Java开发

java贪吃蛇小游戏源代码swing

2017-05-24 11:35 597 查看
//边界类

package greedysnake;

public class Bound {

// 定义贪吃蛇运动的边界范围(y的起点,y的终点,x的起点,x的终点)
public static final int XSTAR=20;
public static final int XEND=500;
public static final int YSTAR=20;
public static final int YEND=500;

// 定义贪吃蛇运动初始化第一个节点的位置
public static final int XSNAKE=100;
public static final int YSNAKE=100;
}

package greedysnake;

import java.util.Random;

import greedysnake.Bound;

//结点类

package greedysnake;

/*

 * 蛇身节点

 * 一个正方形 (x,y,width,height)

 */

public class Node {
int x;
int y;
public final static int HEIGHT=20;
public final static int WIDTH=20;

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

public Node(Node tmp) {

    x = tmp.getX(); 

    y = tmp.getY();

    }

public Node() {}

public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}

}

//蛇类

package greedysnake;

import java.util.LinkedList;

import java.util.Random;

import javax.swing.JOptionPane;

/*

 * 定义蛇身类

 * 属性:集合类-蛇身 

 *      方向

 *      初始节点数

 *      提示信息

 *      得分

 *      速度

 * 方法:构造函数Snake初始化一个蛇

 *      定义蛇头运动

 *      定义蛇的运动

 */

public class Snake {
private LinkedList<Node> snake = new LinkedList<Node>();//List存放结
private int curDir;
private int nodeNum=5;
private String snakeMessage="游戏开始";
static int score = 0;
static int speed = 50;

//初始化一个蛇 从(100,100)每间隔一个空格宽添加一个结点到蛇身 开始蛇身一共五个结点
public Snake() {

int x = Bound.XSNAKE;
int y = Bound.YSNAKE;
for (int i = 0; i < nodeNum; i++) {
Node st = new Node();
st.setX(x);
st.setY(y);

snake.add(st);
x = st.getX();
y = st.getY();
}
curDir = 1;

}

//蛇的方向
int getDir(){
return curDir;
}

//判断蛇是否吃到自己
boolean eatItself() {
Node tmp = snake.getFirst();
//定义移动后新的位置 20为小方格的边长
int x = tmp.getX() + (curDir % 10)*20;

int y = tmp.getY() + (curDir / 10)*20;
for(int i = 1; i < snake.size(); i++) {

            if((x<Bound.XEND&&y<Bound.YEND&&x>(Bound.XSTAR-20)&&y>(Bound.YSTAR-20))

            &&(snake.get(0).getX() == snake.get(i).getX() )&& (snake.get(0).getY() == snake.get(i).getY())) 

                return true;

        }

        return false;

    }

//蛇头移动
Node headMove(){
Node tmp = snake.getFirst();
//定义移动后新的位置 20为小方格的边长
int i = tmp.getX() + (curDir % 10)*20;

int j = tmp.getY() + (curDir / 10)*20;

        // 判断是否超过边界,没有则将蛇头添加到列表
if(i>=Bound.XEND||j>=Bound.YEND||i<=(Bound.XSTAR-20)||j<=(Bound.YSTAR-20))
{
snakeMessage="超出边界";

JOptionPane.showMessageDialog(null, "超出边界,游戏结束!","提示信息", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}else{

   tmp = new Node(i, j);
}
return tmp;
}

//蛇移动
void move()
   {
       //新建一个蛇头
   Node head = headMove();
   //新建一个食物
       Node newNode = new Node();
       boolean eat = false;
       if ((Math.abs(head.getX()) == SnakeJFrame.XSTART) && (Math.abs(head.getY()) == SnakeJFrame.YSTART)) {
           eat = true;
           newNode = new Node(snake.get(snake.size() - 1));
           Random rand=new Random();
           SnakeJFrame.XSTART=Bound.XSNAKE+rand.nextInt((Bound.XEND-Bound.XSTAR-Bound.XSNAKE)/20)*20;
           SnakeJFrame.YSTART=Bound.YSNAKE+rand.nextInt((Bound.YEND-Bound.YSTAR-Bound.YSNAKE)/20)*20;
       }
       for(int i = snake.size() - 1; i > 0; i--) {
       
snake.set(i, snake.get(i - 1));
       }
       snake.set(0, head);
       
       //吃到自己
       if(eatItself()) {
       
snakeMessage="吃到自己";
       
JOptionPane.showMessageDialog(null, "吃到自己,游戏结束!", "提示信息", JOptionPane.ERROR_MESSAGE);
           System.exit(1);
       }
       
       //吃到食物
       if(eat) {
       
snake.add(newNode);
           SnakeJFrame.score++;
           SnakeJFrame.speed++;
       }
   }
 
void changeDir(int dir) {
   this.curDir = dir;

}
 
public LinkedList<Node> getSnake() {
return snake;

     }

     public String getSnakeMessage() {
return snakeMessage;
}

public void setSnakeMessage(String snakeMessage) {
this.snakeMessage = snakeMessage;
}

}

//SnakeJFrame类

package greedysnake;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.util.Random;

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JPanel;

public class SnakeJFrame extends JPanel implements ActionListener, KeyListener {
static final int Up = -10 , Down = 10 , Left = -1 , Right = 1;
static int XSTART , YSTART;
static int score = 0 , speed = 1;
boolean startFlag = false;

    JButton startButton , stopButton , quitButton;

    Snake s;

    public SnakeJFrame() {

    //新建一条蛇

    s = new Snake();

    

        //随机获得食物

    Random rand=new Random();

        XSTART = Bound.XSNAKE+rand.nextInt((Bound.XEND-Bound.XSTAR-Bound.XSNAKE)/20)*20;

        YSTART = Bound.YSNAKE+rand.nextInt((Bound.YEND-Bound.YSTAR-Bound.YSNAKE)/20)*20;

        

        this.setLayout(null);//取消布局管理器设置

        startButton = new JButton("开始游戏");

        stopButton = new JButton("暂停游戏");

        quitButton = new JButton("退出游戏");

        startButton.setBounds(Bound.XEND+30, Bound.YSTAR+100, 100, 30);

    this.add(startButton);

    stopButton.setBounds(Bound.XEND+30, Bound.YSTAR+140, 100, 30);

    this.add(stopButton);

    quitButton.setBounds(Bound.XEND+30, Bound.YSTAR+180, 100, 30);

    this.add(quitButton);

    startButton.addActionListener(this);

        stopButton.addActionListener(this);

        quitButton.addActionListener(this);

        this.addKeyListener(this);

       

        //创建蛇移动的线程

        new Thread(new snackThread()).start(); 

    }

    

    public void paint(Graphics p) {
super.paint(p);
//游戏区域背景
p.drawImage(new ImageIcon("img/3.jpg").getImage(),20,20,480,480,this);

      // 一.蛇身-------------------------------------------------
//设定颜色
p.setColor(Color.RED);
for (int i = 0; i < s.getSnake().size(); i++) {
       //填充图形
p.fillRect(s.getSnake().get(i).getX(), s.getSnake().get(i).getY(), Node.WIDTH, Node.HEIGHT);
}

// 二.食物--------------------------------------------------
//设定颜色
p.setColor(Color.PINK);
//填充指定的图形
p.fillRect(XSTART, YSTART, Node.WIDTH, Node.HEIGHT);

// 三.边界--------------------------------------------------
//设定颜色
p.setColor(Color.BLACK);
   //设定字体{三个要素  1.字体 2.风格(加粗Font.BOLD、斜体Font.ITALIC、加粗斜体、普通) 3.大小)
p.setFont(new Font("TimesRoman", Font.BOLD, 80));

            //1.上下直线------------------------------------------------
for (int i = 0; i <=(Bound.YEND-Bound.YSTAR)/20; i++) {
//在此图形上下文的坐标系中,在点 (x1, y1) 和 (x2, y2) 之间画一条线
p.drawLine(Bound.XSTAR, Bound.YSTAR+i*20, Bound.XEND, Bound.YSTAR+i*20);
}
   //2.左右直线
------------------------------------------------------

for (int i = 0; i <=(Bound.XEND-Bound.XSTAR)/20; i++) {
p.drawLine(Bound.XSTAR+i*20, Bound.YSTAR, Bound.XSTAR+i*20, Bound.YEND);
}

//四.提示信息-------------------------------------------------
p.setColor(Color.BLUE);
p.setFont(new Font("楷体", Font.BOLD, 20));
p.drawString(s.getSnakeMessage(), Bound.XEND + 30, Bound.YSTAR + 20);

        
//五.分数-------------------------------------------------------
p.setColor(Color.BLACK);
p.setFont(new Font("楷体", Font.BOLD, 20));
//设定迭代器属性
p.drawString("分数:"+String.valueOf(score), Bound.XEND + 30, Bound.YSTAR + 60);

    }   

    

    class snackThread implements Runnable

    {

        public void run() {

            while(true) {

                try {

                    Thread.sleep(100 - speed >= 0 ? 100 - speed : 0);

                    repaint();

                    if(startFlag) {

                        s.move();

                    }

                }

                catch(InterruptedException e) {

                    e.printStackTrace();

                }

            }

        }

    }

@Override
public void keyTyped(KeyEvent e) {
// TODO 自动生成的方法存根

}

@Override
public void keyPressed(KeyEvent e) {
// TODO 自动生成的方法存根
if(!startFlag) return ;

        switch(e.getKeyCode()) {

        case KeyEvent.VK_UP:

            if(s.getDir() == Down) break;

            s.changeDir(Up);

            break;

        case KeyEvent.VK_DOWN:

            if(s.getDir() == Up) break;

            s.changeDir(Down);

            break;

        case KeyEvent.VK_LEFT:

            if(s.getDir() == Right) break;

            s.changeDir(Left);

            break;

        case KeyEvent.VK_RIGHT:

            if(s.getDir() == Left) break;

            s.changeDir(Right);

            break;

        }
}

@Override
public void keyReleased(KeyEvent e) {
// TODO 自动生成的方法存根

}

@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
if(e.getSource() == startButton) {
           startFlag = true;
           startButton.setEnabled(false);
           stopButton.setEnabled(true);
       }
       if(e.getSource() == stopButton) {
           startFlag = false;
           startButton.setEnabled(true);
           stopButton.setEnabled(false);
       }
       if(e.getSource() == quitButton) {
           System.exit(0);
       }
       this.requestFocus();
}

}

//JFrame类

package greedysnake;

import javax.swing.JFrame;

public class JF extends JFrame{
private SnakeJFrame jpanel = new SnakeJFrame();

public JF(){
super("GreedySncak");
}

void init(){

        
this.setBounds(320,100,700,550);
this.add(jpanel);
this.addKeyListener(jpanel);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

   }

   public static void main(String[] args) {
   JF j=new JF();
   j.init();

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java