贪吃蛇游戏

闲暇之余,学习前辈经验,再利用线程和窗体自己做了个贪吃蛇小游戏。

游戏带有加速功能,能显示游戏分数。

借鉴的朋友们后期还可以在此基础上增加其他功能。

下面给大家显示游戏代码,以及详细注解

一、bean类

/**
 * 蛇和食物的构造基础,
 * 
 * @author Deng
 *
 */
public class Node {
/** 基础图标的x、y 坐标 */
private int nodeX, nodeY;
/** 基础图标方向 */
private int nodeDir;
public int getNodeX() {
return nodeX;
}
public Node(int nodeX, int nodeY, int nodeDir) {
super();
this.nodeX = nodeX;
this.nodeY = nodeY;
this.nodeDir = nodeDir;
}
public Node() {
super();
// TODO Auto-generated constructor stub
}
public void setNodeX(int nodeX) {
this.nodeX = nodeX;
}
public int getNodeY() {
return nodeY;
}
public void setNodeY(int nodeY) {
this.nodeY = nodeY;
}
public int getNodeDir() {
return nodeDir;
}
public void setNodeDir(int nodeDir) {
this.nodeDir = nodeDir;
}

}

二、JPlanel类

用来构建游戏界面

**
 * 创建一个继承JPanel的子类,实现键盘监听和线程接口
 * 
 * @author Deng
 *
 */
public class Mypanle extends JPanel implements KeyListener, Runnable {
public boolean isGamestart() {
return gamestart;
}
public int getGrade() {
return grade;
}
//分数属性
private int grade;
//蛇的初始移动速度,0.1秒移动一次
private int speed=500;
// 蛇头属性
private Node snakeHead = new Node(100, 100, FIRST_DIR);



// 食物属性
private Node food = new Node(20, 60, STOP);


// 蛇的身体
Vector<Node> snakeBody = new Vector<Node>();



// 初始化蛇的移动方向
// 开始游戏标志
private boolean gamestart = true;
// 设置方向常量
private static final int FIRST_DIR = 4;
private static final int TURN_UP = 1;
private static final int TURN_DOWN = 2;
private static final int TURN_LEFT = 3;
private static final int TURN_RIGHT = 4;
private static final int STOP = -1;


public Mypanle(int x, int y, Container c) {
this.setLayout(null);
this.addKeyListener(this);
this.setBounds(x, y, 400, 500);
// 给窗口增加一个黑色边框
Border b = BorderFactory.createLineBorder(Color.BLACK);
this.setBorder(b);
c.add(this);
}


// 绘制图画
@Override
public void paint(Graphics g) {
super.paint(g);
// 设置颜色
// g.setColor(Color.BLUE);
// // 绘制行的直线
// for (int row = 20; row <=400; row += 20) {
// g.drawLine(0, row, 400, row);
// }
// // 绘制列的直线
// for (int col = 20; col <=400; col += 20) {
// g.drawLine(col, 0, col, 400);
// }
// 绘制蛇头
g.setColor(Color.BLUE);
g.fillOval(snakeHead.getNodeX(), snakeHead.getNodeY(), 20, 20);


// 绘制蛇身
g.setColor(Color.BLUE);
for (Node node : snakeBody) {
g.fillRect(node.getNodeX(), node.getNodeY(), 20, 20);
}


// 绘制食物
g.setColor(Color.RED);
g.fillOval(food.getNodeX(), food.getNodeY(), 20, 20);
requestFocusInWindow();


}
   
@Override
public void run() {
// TODO Auto-generated method stub
while (gamestart) {
try {
//判断是否碰撞边界
if (!judgeBoder()) {
JOptionPane.showMessageDialog(null, "再接再厉啊!");
return;
}
// 判断是否吃到自己
if(eatSelf()){
JOptionPane.showMessageDialog(null, "再接再厉啊!");
return;
}
//
if (judgeEat()) {
foodCreat();
changeSpeed();
}
// 蛇开始移动
move();
bodyMove();


// 重画
repaint();
Thread.sleep(this.speed);
}


catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}


}


/**
*  蛇头移动
*/
public void move() {
switch (snakeHead.getNodeDir()) {
case TURN_UP:
snakeHead.setNodeY(snakeHead.getNodeY() - 20);
break;
case TURN_DOWN:
snakeHead.setNodeY(snakeHead.getNodeY() + 20);
break;
case TURN_LEFT:
snakeHead.setNodeX(snakeHead.getNodeX() - 20);
break;
case TURN_RIGHT:
snakeHead.setNodeX(snakeHead.getNodeX() + 20);
break;


}


}


@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub


}


/**
* 实现按钮监听,完成转向功能
*/
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int key = e.getKeyCode();
if (key == KeyEvent.VK_DOWN) {
if (snakeHead.getNodeDir() == TURN_UP) {
return;
}
snakeHead.setNodeDir(TURN_DOWN);


} else if (key == KeyEvent.VK_UP) {
if (snakeHead.getNodeDir() == TURN_DOWN) {
return;
}
snakeHead.setNodeDir(TURN_UP);


} else if (key == KeyEvent.VK_LEFT) {
if (snakeHead.getNodeDir() == TURN_RIGHT) {
return;
}
snakeHead.setNodeDir(TURN_LEFT);


} else if (key == KeyEvent.VK_RIGHT) {
if (snakeHead.getNodeDir() == TURN_LEFT) {
return;
}
snakeHead.setNodeDir(TURN_RIGHT);


}
}


@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
/**
* 判断蛇是否超出边界

* @return
*/
public boolean judgeBoder() {
boolean temp = true;
if (snakeHead.getNodeX() == 380 && snakeHead.getNodeDir() == TURN_RIGHT) {
temp = false;
} else if (snakeHead.getNodeX() == 0 && snakeHead.getNodeDir() == TURN_LEFT) {
temp = false;
} else if (snakeHead.getNodeY() == 0 && snakeHead.getNodeDir() == TURN_UP) {
temp = false;
} else if (snakeHead.getNodeY() == 480 && snakeHead.getNodeDir() == TURN_DOWN) {
temp = false;
}


return temp;
}


/*
* 产生食物
*/
public void foodCreat() {
int x, y;


x = (int) (Math.random() * 20) * 20;
y = (int) (Math.random() * 25) * 20;
food.setNodeX(x);
food.setNodeY(y);
}
/**
* 食物与蛇碰撞检测

* @return  碰撞结果
*/
public boolean judgeEat() {
int dir;
if (snakeHead.getNodeX() == food.getNodeX() && snakeHead.getNodeY() == food.getNodeY()) {
// 记录蛇头的方向
Node body = new Node();
//吃一个食物增加五十分;
grade+=10;
if (snakeBody.isEmpty()) {
body.setNodeX(food.getNodeX());
body.setNodeY(food.getNodeY());
dir = snakeHead.getNodeDir();
} else {
Node lastBody = snakeBody.lastElement();
dir = lastBody.getNodeDir();
body.setNodeX(lastBody.getNodeX());
body.setNodeY(lastBody.getNodeY());
}

snakeBody.add(body);
return true;
}
return false;
}


/**
*  移动蛇身
*/
public void bodyMove() {

//当前蛇身移动方向
int dir;
//记录蛇头方向
int headDir =snakeHead.getNodeDir();
// 使用迭代器遍历蛇头
Iterator<Node> it = snakeBody.iterator();
while (it.hasNext()) {
Node body = it.next();
// 取出第一个身体的方向,根据方向判断移动
int bodyDir=body.getNodeDir();

switch (bodyDir) {
case TURN_UP:

body.setNodeY(body.getNodeY() - 20);
break;
case TURN_DOWN:
body.setNodeY(body.getNodeY() + 20);
break;
case TURN_LEFT:
body.setNodeX(body.getNodeX() - 20);
break;
case TURN_RIGHT:
body.setNodeX(body.getNodeX() + 20);
break;
}
//记录第一个蛇身的方向
dir=bodyDir;
// 把蛇头的方向赋值给第一个蛇身
bodyDir = headDir;
//将蛇头的方向给第一个身体
body.setNodeDir(bodyDir);
//把第一个身体的方向当做蛇头方向,
headDir=dir;
}


}
/**
* 判断蛇是不是吃到自己的身体。
* 蛇身体遍历,蛇头与任何蛇身碰撞游戏结束
* @return
*/
public boolean eatSelf(){
for (Node node : snakeBody) {
if(node.getNodeX()==snakeHead.getNodeX()&&node.getNodeY()==snakeHead.getNodeY()){
return true;
}

}

return false;
}
/**
* 根据分数改变蛇的移动速度
*/
public void changeSpeed(){

if(this.grade%100==0){
this.speed=this.speed/2;
}

}

}

三、封装的Jlable,用来显示成绩

public class MyLabel extends JLabel{
public MyLabel(int x,int y ,Container c){
this.setBounds(x, y, 120, 30);
this.setFont(new Font("华文云彩", Font.BOLD, 20));
c.add(this);
}
}

四、JFrame窗体,用来记录成绩,显示整个游戏界面

public class Begin extends JFrame implements Runnable{
//当前成绩
private String g="分数:  ";
private MyLabel  gameLable=new MyLabel(10, 10, this);
private  Mypanle gamePanle=new Mypanle(30, 50, this);
public Begin(){
this.setLayout(null);
this.setVisible(true);
this.setSize(500, 600);
gameLable.setText(g);
new Thread(this.gamePanle).start();
new Thread(this).start();
this.addKeyListener(this.gamePanle);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
}
public static void main(String[] args) {
Begin b=new Begin();

}
@Override
public void run() {
// TODO Auto-generated method stub
   while(true){
    int grade=gamePanle.getGrade();
       gameLable.setText(g+grade);
   }

}
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现移动,吃食变长游戏把子上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。[3] 二、“贪吃蛇”游戏的发展编辑 改变此款游戏的特别多。比如在蛋的方面,可能放上带道具的蛋,使蛇吃完后具有保护,穿墙等特种功能,而且难度逐渐变难,游戏制作的精细度和画面的质量也随着版本的提高而不断提高,且有单人及团队联机对战版本陆续推出。 参考资料游戏把子上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。[3] 二、“贪吃蛇”游戏的发展编辑 改变此款游戏的特别多。比如在蛋的方面,可能放上带道具的蛋,使蛇吃完后具有保护,穿墙等特种功能,而且难度逐渐变难,游戏制作的精细度和画面的质量也随着版本的提高而不断提高,且有单人及团队联机对战版本陆续推出。 游戏把子上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。[3] 二、“贪吃蛇”游戏的发展编辑 改变此款游戏的特别多。比如在蛋的方面,可能放上带道具的蛋,使蛇吃完后具有保护,穿墙等特种功能,而且难度逐渐变难,游戏制作的精细度和画面的质量也随着版本的提高而不断提高,且有单人及团队联机对战版本陆续推出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值