贪食蛇

贪吃蛇游戏: 一个游戏最核心的部分是游戏的业务逻辑代码。  

分析里面的有几个事物:
    1. 地图
    2. 蛇
    3. 食物

了解游戏规则: 
    1.蛇初始化的时候是三个节点,而且一开始蛇是出现在地图的中间位置。
    2. 蛇吃到东西会长长一节。 
    3. 蛇咬到自己会死,蛇撞墙也会死。
    4. 食物是随机生成的,食物不能长在石头上,食物可以长在蛇身上。

业务逻辑部分SnakeGame.java

package cn.itcast.snake;

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

import javax.swing.JButton;
import javax.swing.JFrame;

import cn.itcast.util.FrameUtil;

public class SnakeGame {
	
	//地图的宽(列数)
	public static final int WIDTH = 35;
	
	//地图高(行数)
	public static final int HEIGHT = 9;	
	
	
	//地图
	private char[][] background = new char[HEIGHT][WIDTH];
	
	//使用集合保存蛇节点的所有信息
	LinkedList<Point>  snake = new LinkedList<Point>(); 
	
	
	//食物
	Point	food;
	
	//使用四个常量表示四个方向
	public static final int UP_DIRECTION = 1;  //上
	
	public static final int DOWN_DIRECTION = -1;  //下
	
	public static final int LEFT_DIRECTION = 2;  //左
	
	public static final int RIGHT_DIRECTION =-2;  //右


	//蛇当前的方向
	int currentDrection = -2; // 蛇默认是向右行走
	
	
	//记录游戏是否结束
	static	boolean isGameOver = false; //默认游戏没有结束的。
	
	
	//蛇移动的方法
	public void move(){
		Point head = snake.getFirst();
		//蛇是根据当前的方向移动的
		switch (currentDrection) {
			case UP_DIRECTION:
				//添加新的蛇头
				snake.addFirst(new Point(head.x,head.y-1));
				break;
			case DOWN_DIRECTION:
				//添加新的蛇头
				snake.addFirst(new Point(head.x,head.y+1));
				break;
			case LEFT_DIRECTION:
				if(head.x==0){
					snake.addFirst(new Point(WIDTH-1,head.y));
				}else{
					//添加新的蛇头
					snake.addFirst(new Point(head.x-1,head.y));
				}
				break;
			case RIGHT_DIRECTION:
				if(head.x==WIDTH-1){
					snake.addFirst(new Point(0,head.y));
				}else{
					//添加新的蛇头
					snake.addFirst(new Point(head.x+1,head.y));
				}
				break;
			default:
				break;
		}
		
		if(eat()){
			//吃到了食物
			createFood();
		}else{
			//删除蛇尾
			snake.removeLast(); 		
		}
	}
	
	
	//改变当前方向的方法
	public  void changeDirection(int newDirection){
		//判断新方向是否与当前方向是否是相反方向,才允许其改变
		if(newDirection+currentDrection!=0){
			this.currentDrection = newDirection;
		}
	}
	
	
	
	

	//生成食物 
	public void createFood(){
		//创建一个随机数对象
		Random random = new Random();
		while(true){
			int x = random.nextInt(WIDTH); 
			int y = random.nextInt(HEIGHT);
			if(background[y][x]!='*'){
				food = new Point(x,y);
				break;
			}
		}
	}
	
	//显示食物
	public void showFood(){
		background[food.y][food.x] ='@';
	}
	

	
	//初始化蛇
	public void initSnake(){
		int x = WIDTH/2;
		int y = HEIGHT/2;
		snake.addFirst(new Point(x-1,y));
		snake.addFirst(new Point(x,y));
		snake.addFirst(new Point(x+1,y));
	}
	
	
	//显示蛇--->实际上就是将蛇节点 的坐标信息反馈到地图上,在地图上画上对应的字符而已
	public void showSnake(){
	
		//画蛇身
		for(int i =1; i<snake.size() ; i++ ){
			Point body = snake.get(i);
			background[body.y][body.x] = '#';
			
		}
		
		//取出蛇头
		Point head = snake.getFirst();
		background[head.y][head.x] = '$';
		
	}
	
	
	
	
	//初始化地图
	public void initBackground(){
		for(int rows = 0 ; rows<background.length ; rows++){
			for(int cols = 0  ; cols<background[rows].length ; cols++ ){
				if(rows==0||rows==(HEIGHT-1)){  //第一行、最后一行、 第一列与最后一列
					background[rows][cols] = '*';
				}else{
					background[rows][cols] = ' ';
				}
			}
		}
	}


	//显示地图的
	public void showBackground() {
		//打印二维数组
		for(int rows = 0 ; rows<background.length ; rows++){ // rows =0 
			for(int cols = 0  ; cols<background[rows].length ; cols++ ){
				System.out.print(background[rows][cols]);
			}
			System.out.println(); //换行
		}
	}
	
	//刷新游戏 的状态 
	public void refrash(){
		//清空游戏之前的所有状态信息
		initBackground();
		//把蛇最新的状态反馈到地图上
		showSnake();
		//把食物的信息反馈到地图婚丧。
		showFood();
		//显示当前地图的信息
		showBackground();
	}
	
	//吃食物
	public boolean eat(){
		//获取到原来的蛇头
		Point head = snake.getFirst();
		if(head.equals(food)){
			return true; 
		}
		return false;
	}
	
	
	//游戏结束的方法
	public void isGameOver(){
		//撞墙死亡
		Point head = snake.getFirst();
		if(background[head.y][head.x]=='*'){
			isGameOver = true;
		}
		
		//咬到自己  蛇身
		for(int i = 1; i<snake.size() ; i++){
			Point body = snake.get(i);
			if(head.equals(body)){
				isGameOver = true;
			}
		}
	}
	

	
	public static void main(String[] args) throws Exception {
		final SnakeGame snake = new SnakeGame();
		//初始化地图
		snake.initBackground();
		//初始化蛇
		snake.initSnake(); 
		//把蛇的信息反馈到地图上
		snake.showSnake();
		
		//初始化事物
		snake.createFood();
		//显示食物
		snake.showFood();
		snake.showBackground();
		
		
		JFrame frame = new JFrame("方向盘");
		frame.add(new JButton("↑"),BorderLayout.NORTH);
		frame.add(new JButton("↓"),BorderLayout.SOUTH);
		frame.add(new JButton("←"),BorderLayout.WEST);
		frame.add(new JButton("→"),BorderLayout.EAST);
		JButton button = new JButton("点击控制方向");
		frame.add(button);
		FrameUtil.initFrame(frame, 300, 300);
		
		//给按钮添加事件监听器
		button.addKeyListener(new KeyAdapter(){
			@Override
			public void keyPressed(KeyEvent e) {
				int code = e.getKeyCode();
				switch (code) {
					case KeyEvent.VK_UP:
						snake.changeDirection(UP_DIRECTION);
						break;
					case KeyEvent.VK_DOWN:
						snake.changeDirection(DOWN_DIRECTION);
						break;
					case KeyEvent.VK_LEFT:
						snake.changeDirection(LEFT_DIRECTION);
						break;
					case KeyEvent.VK_RIGHT:
						snake.changeDirection(RIGHT_DIRECTION);
						break;
					default:
						break;
				}
				snake.move();
				snake.isGameOver();//判断是否游戏结束
				snake.refrash();
				if(isGameOver){
					System.out.println("游戏结束了..");
					System.exit(0);
				}
			}
		});
		
		
		
		
		
	}

}

游戏窗口部分

1.初始化窗口FrameUtil.java

package cn.itcast.util;

import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JFrame;

//初始化窗体的工具类
public class FrameUtil {

	
	public static void initFrame(JFrame frame,int width , int height){
		Toolkit toolkit = Toolkit.getDefaultToolkit(); //获取一个与系统相关工具类对象
		//获取屏幕的分辨率
		Dimension d = toolkit.getScreenSize();
		int x = (int) d.getWidth();
		int y = (int) d.getHeight();
		frame.setBounds((x-width)/2, (y-height)/2, width, height);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

2.具体窗口设置 Demo1.java 

package cn.itcast.view;

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

import javax.swing.JFrame;
import javax.swing.JPanel;

import cn.itcast.util.FrameUtil;

public class Demo1 extends JPanel {  //Demo1 也是一个面板
	
	
	@Override
	public void paint(Graphics g) {  // Graphics g 画笔  使用该画笔可以画任何的东西。
		//设置画笔的颜色
		g.setColor(Color.GRAY);
		//画矩形
		g.fill3DRect(0, 0, 20, 20, true);
		g.fill3DRect(20, 0, 20, 20, true);
		g.setColor(Color.GREEN);
		g.fill3DRect(20,20, 20, 20, true);
		
		//写字
		g.setColor(Color.RED);
		//设置画笔 的字体
		g.setFont(new Font("宋体", Font.BOLD, 30));
		g.drawString("GAME OVER", 300, 200);
		
	}
	
	public static void main(String[] args) {
		JFrame frame = new JFrame("测试");
		Demo1 d = new Demo1();
		frame.add(d);
		FrameUtil.initFrame(frame,700, 500);
		
	}

	
	
	

}

 3.蛇设计

package cn.itcast.view;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;

import javax.swing.JFrame;
import javax.swing.JPanel;

import cn.itcast.util.FrameUtil;

public class SnakeView  extends JPanel{

	//地图的宽(列数)
	public static final int WIDTH = 40;
	
	//地图高(行数)
	public static final int HEIGHT = 30;	
	
	
	//格子宽
	public static final int CELLWIDTH = 20;
	
	//格子高
	public static final int CELLHEIGHT = 20;
	
	//地图
	private boolean[][] background = new boolean[HEIGHT][WIDTH];
	

	//使用集合保存蛇节点的所有信息
	LinkedList<Point>  snake = new LinkedList<Point>(); 
	
	
	//初始化蛇
	public void initSnake(){
		int x = WIDTH/2;
		int y = HEIGHT/2;
		snake.addFirst(new Point(x-1,y));
		snake.addFirst(new Point(x,y));
		snake.addFirst(new Point(x+1,y));
	}
		
	
	//向上移动
	public void moveUp(){
		//获取原来蛇头 
		Point head = snake.getFirst();
		//添加新的蛇头
		snake.addFirst(new Point(head.x,head.y-1));
		//删除蛇尾
		snake.removeLast();
	}
	
	
	//初始化地图
	public void initBackground(){
		for(int rows = 0 ; rows<background.length ; rows++){
			for(int cols = 0  ; cols<background[rows].length ; cols++ ){
				if(rows==0||rows==(HEIGHT-1)||cols==0||cols==(WIDTH-1)){  //第一行、最后一行、 第一列与最后一列
					background[rows][cols] = true;
				}
			}
		}
	}
		
	
	@Override
	public void paint(Graphics g) {
		//画地图		
		for(int rows = 0 ; rows<background.length ; rows++){ // rows =0 
			for(int cols = 0  ; cols<background[rows].length ; cols++ ){
				if(background[rows][cols]){
					//石头
					g.setColor(Color.GRAY);
				}else{
					//空地
					g.setColor(Color.WHITE);
				}
				//画矩形
				g.fill3DRect(cols*CELLWIDTH, rows*CELLHEIGHT, CELLWIDTH, CELLHEIGHT, true);
			}
		}
		
		//画蛇
		
		//取出蛇头
		Point head = snake.getFirst();
		g.setColor(Color.RED);
		g.fill3DRect(head.x*CELLWIDTH, head.y*CELLHEIGHT, CELLWIDTH, CELLHEIGHT, true);
		//画蛇身
		g.setColor(Color.GREEN);
		for(int i =1; i<snake.size() ; i++ ){
			Point body = snake.get(i);
			g.fill3DRect(body.x*CELLWIDTH, body.y*CELLHEIGHT, CELLWIDTH, CELLHEIGHT, true);
		}
		
		
		
	
	}
	
	public static void main(String[] args) {
		JFrame frame = new JFrame("贪吃蛇");
		final SnakeView snakeView = new SnakeView();
		snakeView.initBackground();
		snakeView.initSnake();
		frame.add(snakeView);
		FrameUtil.initFrame(frame, WIDTH*CELLWIDTH+20, HEIGHT*CELLHEIGHT+35);
		
		//给窗口添加事件监听
		frame.addKeyListener(new KeyAdapter() {

			@Override
			public void keyPressed(KeyEvent e) {
				int code = e.getKeyCode();
				switch (code) {
				case KeyEvent.VK_UP:
						snakeView.moveUp();
						//重画游戏
						snakeView.repaint(); //调用repaint方法的时候实际上就是调用了paint方法。
					break;

				default:
					break;
				}
				
				
			}
			
			
			
		});
		
		
		
		
		
	}
	
}

具体运行效果如下:

 

 


    

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值