用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

贪吃蛇游戏

2017-03-11 作者: 陆痴举报

[java]代码库

11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
package game.mysanek.entities;

import game.mysanek.listener.SnakeListener;
import game.mysanek.util.Global;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

public class Snake {
	public static final int UP= -1;
	public static final int DOWN=1;
	public static final int LEFT=2;
	public static final int RIGHT= -2;
	
	//设置两个变量来存放原来的蛇头坐标--和--键盘输入的最后一次控制蛇的方向
	private int oldDirection, newDirection;
	//这个变量用来存放蛇的尾部,当蛇吃掉食物后身体边长。则在蛇的身体添加body.addLast(oldTail),节点的位置坐标
	private Point oldTail;	
	
	//存放蛇的节点位置坐标。
	private LinkedList<Point> body = new LinkedList<Point>();
	private Set<SnakeListener> listeners = new HashSet<SnakeListener>();
	
	public boolean life;	//这个变量用来判断蛇是否死亡(结速进程)
	
	/**
	 * 构造方法初始化蛇的body身体、蛇头oldDirection和newDirection运行的方向
	 */
	public Snake(){	
		init();
	}
	public void init(){
		//取一个节点作为蛇头的位置坐标
		int x=Global.WIDTH/2;	
		int y=Global.HEIGHt/2;
		//蛇的长度初始化为--5个节点的长度
		for(int i=0; i<5; i++){
			body.addLast(new Point(x--, y));
		}
		oldDirection = newDirection = RIGHT;	//蛇头方向初始化
		life=true;	//蛇是活的,
	}
	
	
	/**
	 * 蛇移动
	 */
	public void move(){
		System.out.println("Snake's move");
		
		//1.去尾
		oldTail=body.removeLast(); //记录每次去尾时,尾巴的x,y坐标
		
		//获取蛇的蛇头坐标想x,y
		int x = body.getFirst().x;
		int y = body.getFirst().y;
		
		//当蛇的原来方向oldDirection和键盘输入的最后一个方向newDirection不相反时,再传递蛇最新的方式值
		if(!(oldDirection + newDirection ==0)){
			oldDirection = newDirection;
		}
		
		switch(oldDirection){
		case UP:
			y--;
			if(y <0){	//使蛇在GamePanel的范围内运动
				y =Global.HEIGHt - 1;
			}
			break;
		case DOWN:
			y++;
			if( y > Global.HEIGHt-1){	//使蛇在GamePanel的范围内运动
				y = 0;
			}
			break;
		case LEFT:
			x--;
			if( x<0 ){	//使蛇在GamePanel的范围内运动
				x=Global.WIDTH-1;
			}
			break;
		case RIGHT:
			x++;
			if(x> Global.WIDTH-1){	//使蛇在GamePanel的范围内运动
				x=0;
			}
			break;
		}
		//蛇变化方向后,蛇头的坐标位置
		Point newHead = new Point(x, y);
		
		//2.加头
		body.addFirst(newHead);
		
	}
	
	/**
	 * 蛇改变方向
	 * @param direction
	 */
	public void changeDirection(int direction){
			newDirection=direction;
	}
	
	/**
	 * 蛇吃食物
	 * 蛇吃到食物后身体变长
	 */
	public void eatFood(){
		System.out.println("Snake's eatFood");
		
		body.addLast(oldTail); //蛇吃到食物后身体变长
		
	}
	
	/**
	 * 判断蛇是否吃到了自己的身体,吃到身体蛇死亡(即结束SankeDriver线程)
	 * @return
	 */
	public boolean isEatBody(){
		System.out.println("Sanek's isEatBody");
		
		//i=0表示蛇头,所以i要从1,2,3。。。开始
		for(int i=1; i<body.size(); i++){
			//判断蛇头与身体的其中一个坐标是否重贴
			if(body.get(i).equals(this.getHead())){
				return true;
			}
		}
		return false;
	}
	
	
	/**
	 * 绘制蛇的图像
	 * @param g
	 */
	public void drawMe(Graphics g){
		System.out.println("Snake's drawMe");
		
		g.setColor(Color.BLUE);		//设置蛇头颜色
		for(Point p :body){
			g.fill3DRect(p.x * Global.cell_size, p.y * Global.cell_size,
					Global.cell_size, Global.cell_size, true);
			
			if(p==body.getFirst()){	//设置蛇的身体颜色
				g.setColor(Color.MAGENTA);
			}
		}
	}
	
	//获取蛇头方向
	public Point getHead(){
		return body.getFirst();
		
	}
	
	/**
	 * 蛇死亡,即结束进程的方法
	 */
	public void die(){
		life=false;
	}
	
	
	
	/**
	 * SnakeDirver类,控制蛇的进程
	 * @author Administrator
	 *
	 */
	public class SnakeDriver implements Runnable{

		@Override
		public void run() {
			// TODO 自动生成的方法存根
			while(life){
				move();		//蛇运动
				//绘制图像--图像显示
				for(SnakeListener l : listeners){
					l.snakeMoved();
				}
				try {
					//设置线程休息时间
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
				System.out.println("##########################################");
			}
		}
		
	}
	
	/**
	 * start()方法是启动线程的方法
	 */
	public void start(){
		new Thread(new SnakeDriver()).start();
	}
	
	/**
	 * 往listens中添加 Snake类、Food类、Ground类、GamePnael类的-------类地址
	 * @param l
	 */
	public void addSnakeListener(SnakeListener l){
		if(l != null){
			this.listeners.add(l);
		}
	}
	
}

2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
package game.mysanek.entities;

import game.mysanek.util.Global;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

public class Food extends Point{
	
	//设置食物的x,y坐标
	public void newFood(Point p){ //生成食物
		this.setLocation(p);		//设置食物的坐标
		System.out.println("-------------"+p);
	}
	
	//比坐标---当蛇头的坐标与食物的坐标重合,则表示食物被蛇吃掉了
	public boolean isSnakeEatFood(Snake snake){
		System.out.println("Food's isSnakeEatFood");
		return this.equals(snake.getHead());
//		return false;
	}
	
	
	/**
	 * 绘制食物的图像
	 * @param g
	 */
	public void drawMe(Graphics g){
		System.out.println("Food's drawMe");
	
		g.setColor(Color.CYAN);
		g.fill3DRect(x*Global.cell_size, y*Global.cell_size,
						Global.cell_size, Global.cell_size, true);
	}

}


333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

package game.mysanek.entities;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;

import game.mysanek.util.Global;

public class Ground {
	//用一个二维数组来存放rocks(障碍物)的坐标
	//大小为GamePanel的长宽的小格子数WIDTH和HEIGHT;
	private int[][] rocks= new int[Global.WIDTH][Global.HEIGHt];
	
	public Ground(){
		for(int x=0; x<Global.WIDTH; x++){
			//第一行和最后一行---为rocks(障碍物)
			rocks[x][0]=1;					
			rocks[x][Global.HEIGHt-1]=1;
		}
	}
	
	//随机生成---newFood()食物的x,y坐标
	//而且不能使newFood(食物)的坐标和rocks(障碍物)坐标重合
	public Point getPoint(){
		Random random =new Random();
		int x,y;
		//newFood的坐标和rocks坐标重叠,则继续生成新的坐标---直到不重合
		do{
			x=random.nextInt(Global.WIDTH);
			y=random.nextInt(Global.HEIGHt);
		}while(rocks[x][y]==1);
			return new Point(x,y);
		
	}
	
	/**
	 * 蛇是否吃到石头(障碍物)
	 * @param snake
	 * @return
	 */
	public boolean isSnakeEatRock(Snake snake){
		System.out.println("Ground's isSnakeEatRock");
		
		//判断snake(蛇)是否吃到了rocks(障碍物)
		for(int x=0; x<Global.WIDTH; x++){
			for(int y=0; y<Global.HEIGHt; y++){
				if(rocks[x][y]==1 && 
					(x==snake.getHead().x && y==snake.getHead().y) ){//getHead()方法可以获得蛇头的坐标
						return true;
				}
			}
		}
		
		return false;
	}
	
	
	/**
	 * 当rocks[x][y]==1时,绘制石头(障碍物)
	 * @param g
	 */
	public void drawMe(Graphics g){
		System.out.println("Ground's drawMe");
		
		g.setColor(Color.gray);
		for(int x=0; x<Global.WIDTH; x++){
			for(int y=0; y<Global.HEIGHt; y++){
				if(rocks[x][y] ==1 ){
					g.fill3DRect(x*Global.cell_size, y*Global.cell_size,
									Global.cell_size, Global.cell_size, true);
				}
			}
		}
		
	}
}


1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111


package game.mysanek.view;

import game.mysanek.entities.Food;
import game.mysanek.entities.Ground;
import game.mysanek.entities.Snake;
import game.mysanek.util.Global;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;

public class GamePanel extends JPanel{
	private Snake snake;
	private Food food;
	private Ground ground;
	
	
	/**
	 * 将蛇、食物、石头(障碍物)显示出来
	 *snake、food、ground---传递的都是Snaek类、Food类、Ground类的***地址。
	 * @param snake 		传递地址
	 * @param food
	 * @param ground
	 */
	public void display(Snake snake, Food food, Ground ground){//传递各个class的地址
		System.out.println("GamePanel's display");
		this.snake=snake;
		this.food=food;
		this.ground=ground;
		
		//绘图----调用下方的--画图功能
		this.repaint();
	}
	@Override
	protected void paintComponent(Graphics g) {
		// TODO 自动生成的方法存根
		//显示
		g.setColor(new Color(0xcfcfcf));
		//绘制一个GamePnanl大小的--矩形--遮盖掉前一个时间的蛇、食物、石头(障碍物),---相当于橡皮差
		g.fillRect(0, 0, Global.WIDTH * Global.cell_size, 
				                   Global.HEIGHt *Global.cell_size);
		
		//当snake、food、ground字段----都有对应的Snake类、Food类、Ground类的地址时---画图
		if(snake != null && food != null && ground !=null){
			this.ground.drawMe(g);
			this.snake.drawMe(g);
			this.food.drawMe(g);
		}
		
	}
}


1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111


package game.mysanek.controller;

import game.mysanek.entities.Food;
import game.mysanek.entities.Ground;
import game.mysanek.entities.Snake;
import game.mysanek.listener.SnakeListener;
import game.mysanek.util.Global;
import game.mysanek.view.GamePanel;

import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;

public class Controller extends KeyAdapter implements SnakeListener{
	
	//------这时的snake只是个字段,它的值为--null。 没有Snake类的地址
	private Snake snake;
	private Food food;
	private Ground ground;
	private GamePanel gamePanel;
	
	
	/**
	 * Controller 构造方法----传递Snaek类、Food类、Ground类、GamePanel类--的***地址。
	 * @param snake
	 * @param food
	 * @param ground
	 * @param gamePanel
	 */
	public Controller(Snake snake, Food food, Ground ground, GamePanel gamePanel) {
		//传递各个class的地址
		this.snake = snake;
		this.food = food;
		this.ground = ground;
		this.gamePanel = gamePanel;
	}

	
	/**
	 * 键盘控制-------实现键盘控制-蛇-的方向移动。
	 */
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO 自动生成的方法存根
		switch(e.getKeyCode()){
		case KeyEvent.VK_UP:
			snake.changeDirection(Snake.UP);
			break;
		case KeyEvent.VK_DOWN:
			snake.changeDirection(Snake.DOWN);
			break;
		case KeyEvent.VK_LEFT:
			snake.changeDirection(Snake.LEFT);
			break;
		case KeyEvent.VK_RIGHT:
			snake.changeDirection(Snake.RIGHT);
			break;
		}
	}

	
	/**
	 * 实现SnakeLisener接口中的方法。
	 */
	@Override
	public void snakeMoved() {
		
		//判断食物是否被蛇吃掉,吃掉后产生新的---新食物
		if(food.isSnakeEatFood(snake)){
			snake.eatFood();	//蛇吃掉食物
			food.newFood(ground.getPoint()); 	//产生新的食物
		}
		
		//判断蛇头的位置与石头的位置是否重合---蛇是否吃到石头
		if(ground.isSnakeEatRock(snake)){  
			snake.die();	//蛇蛇死亡---结束SnakeDriver线程
		}
		
		//判断蛇是否吃到了自己的身体
		if(snake.isEatBody()){
			snake.die();	//蛇蛇死亡---结束SnakeDriver线程
		}
		
		
		//绘图-------在GamePanel的面板上绘制蛇、食物、石头(障碍物)。
		//snake、food、ground---传递的都是Snaek类、Food类、Ground类的***地址。
		gamePanel.display(snake, food, ground);//传递各个class的地址
		
	}
	
//	//随机生成---食物的x,y坐标
//	public Point getPoint(){
//		Random random =new Random();
//		int x=random.nextInt(Global.WIDTH);
//		int y=random.nextInt(Global.HEIGHt);
//		return new Point(x,y);
//	}

	/**
	 * 将Snake类中的start()方法,放在在Controller中
	 * 逻辑控制
	 */
	public void newGame(){
		snake.start();
		food.newFood(ground.getPoint());
	}

}


1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111


package game.mysanek.listener;

/**
 * 设置一个借口----用来存放(Snake snake, Food food, Ground ground) 的类的地址
 * @author Administrator
 *
 */
public interface SnakeListener {
	
	public void snakeMoved();
}


111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111


package game.mysanek.util;

public class Global {
	//贪吃蛇中的每个小方格的边长--20
	public static final int cell_size=20;
	//设置游戏界面GameJPanel的大小
	public static final int WIDTH=40;	//宽度为40个小方格
	public static final int HEIGHt =25;		//高度为25个小方格
}


11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111


package game.mysanek.game;

import java.awt.BorderLayout;

import game.mysanek.controller.Controller;
import game.mysanek.entities.Food;
import game.mysanek.entities.Ground;
import game.mysanek.entities.Snake;
import game.mysanek.util.Global;
import game.mysanek.view.GamePanel;

import javax.swing.JFrame;

public class Game {
	
	public static void main(String[] args) {
		Snake snake = new Snake();
		Food food = new Food();
		Ground ground = new Ground();
		GamePanel gamePanel = new GamePanel();
		
		//传递各个class的地址
		Controller controller = new Controller(snake, food, ground, gamePanel);
		
		JFrame frame = new JFrame("贪吃蛇游戏");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gamePanel.setSize(Global.WIDTH * Global.cell_size, 
				                          Global.HEIGHt * Global.cell_size);
		frame.setSize(Global.WIDTH * Global.cell_size +10, 
				                     Global.HEIGHt * Global.cell_size+35);
		frame.add(gamePanel, BorderLayout.CENTER);
		frame.setLocationRelativeTo(null);
		
		gamePanel.addKeyListener(controller);
		snake.addSnakeListener(controller);
		
		frame.addKeyListener(controller);
		
		frame.setVisible(true);
		controller.newGame();
	}
}




[代码运行效果截图]


贪吃蛇游戏


网友评论    (发表评论)

共3 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...