贪吃蛇小游戏(java)

Config

package com.hpe.config;

// import com.java.po.User;

//常量配置
public class Config {

	public static final int ROWS = 22;//行
	public static final int COLS = 35;//列
	public static final int SPAN = 20;//间距

	public static final String U = "u";//方向-上
	public static final String D = "d";//方向-下
	public static final String L = "l";//方向-左
	public static final String R = "r";//方向-右

	public static boolean islive = true;//死亡检测的标识
	public static int speed = 400;//速度,间隔多少毫秒移动一次
	public static boolean valid = false;//当前的 单位时间内 有无 有效按键事件false代表没有
	public static boolean isgone = true;//暂停 继续
	public static int score = 0;//得分

	//public static User user;//当前登陆人

	//控制条件初始化
	public static void reload() {
		islive = true;
		valid = false;
		score = 0;
		speed = 400;
		isgone = true;
	}
}

SnakeFrame

package com.hpe.frame;

import javax.swing.JFrame;

import com.hpe.panel.ButtonPanel;
import com.hpe.panel.SnakePanel;


public class SnakeFrame extends JFrame {
	
	private SnakePanel snakePanel = new SnakePanel();
	private ButtonPanel buttonPanel = new ButtonPanel(snakePanel);
	
	public SnakeFrame() {
		initFrame();
		addComponent();
		//显示
		this.setVisible(true);
	}
	
	//进行初始化设置
	private void initFrame() {
		//设置窗口的标题
		this.setTitle("贪吃蛇");
		//设置窗口的大小和坐标
		this.setBounds(70, 40, 706, 500);	
		//设置不能修改大小
		this.setResizable(false);
		//关闭之后的操作
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLayout(null);
		
		//让SnakePanel获得焦点,以便其捕获键盘点击事件
		this.snakePanel.setFocusable(true);
		this.snakePanel.requestFocus();
	}
	
	//添加其他组件
	private void addComponent() {
		this.add(snakePanel);
		this.add(buttonPanel);
		
	}
	
	public static void main(String[] args) {
		new SnakeFrame();
	}
	
}

SnakePanel

package com.hpe.panel;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;

import com.hpe.config.Config;
import com.hpe.po.Food;
import com.hpe.po.Snake;
/**
 * 监听--事件
 * 
 * 特定的事件发生以后,触发相应的动作(代码)
 * 
 * 
 *
 */
public class SnakePanel extends JPanel implements KeyListener{
	//食物
	private Food food = new Food();
	//蛇
	private Snake snake = new Snake(food);
	private SnakeThread snakeThread = new SnakeThread();
	//构造方法
	public SnakePanel() {
		initPanel();
		addComponent();
		//启动线程
		snakeThread.start();
	}

	//初始化操作
	private void initPanel() {
		//设置大小
		this.setSize(700, 440);
		//设置背景颜色
		this.setBackground(Color.GREEN);

		//绑定
		this.addKeyListener(this);
	}

	//重写父类中的方法
	@Override
	public void paint(Graphics g) {
		super.paint(g);

		//画笔
		g.setColor(Color.GRAY);
		//划线  横线
		for(int i = 0; i < Config.ROWS; i++) {
			g.drawLine(0, Config.SPAN * i, Config.SPAN * Config.COLS, Config.SPAN * i);
		}

		//竖线
		for(int i = 0; i < Config.COLS; i++) {
			g.drawLine(Config.SPAN * i, 0, Config.SPAN * i, Config.SPAN * Config.ROWS);
		}

		//画食物
		food.draw(g);
		//画蛇
		snake.draw(g);
		//蛇移动
		snake.move();
		//是否吃食物
		snake.eatOrNot();
		//死亡监测
        snake.deadCheck();
	}

	//添加其他组件
	private void addComponent() {

	}

	//内部类
	class SnakeThread extends Thread {
		@Override
		public void run() {
			super.run();

			while(Config.islive) {
				try {
					Thread.sleep(300); //延时400ms



				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				//重新绘制SnakePanel
				if(Config.isgone){
					repaint();
				}
			}
		}

	}

	@Override
	//点击键盘上的按钮调用的方法
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		//System.out.println("1111");
	}
	/**
	 * 点击键盘上的按键,就会触发该方法,并且将键盘点击事件以参数的形式传递到该方法中
	 * 
	 */
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		//点击w、s、a、d实现Snake上、下、左、右移动
		this.snake.dirControl(e);

	}

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

	}

}

ButtonPanel

package com.hpe.panel;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;

import com.hpe.config.Config;

//暂停 开始
public class ButtonPanel extends JPanel implements ActionListener {
	//四个按钮
	private JButton btn_pause = new JButton("暂停游戏");
	private JButton btn_continue = new JButton("继续游戏");
	private JButton btn_restart = new JButton("重新开始");
	private JButton btn_rank = new JButton("游戏排行");
	private SnakePanel snakePanel;
	
	
	//构造方法
	public ButtonPanel(SnakePanel snakePanel) {
		this.snakePanel = snakePanel;
		init();
		addComponent();
	}
	
	public void init() {
		this.setBounds(0, 440, 706, 60);
		
		btn_continue.addActionListener(this);
		btn_pause.addActionListener(this);
		btn_restart.addActionListener(this);
		btn_rank.addActionListener(this);
	}
	
	public void addComponent() {
		this.add(btn_pause);
		this.add(btn_continue);
		this.add(btn_restart);
		this.add(btn_rank);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		//暂停
		if(e.getSource() == btn_pause) {
			pauseGame();
		}
		//继续
		if(e.getSource() == btn_continue) {
			continueGame();
		}
	}
	
	//暂停
	public void pauseGame() {
		Config.isgone = false;
	}
	
	//继续
	public void continueGame() {
		Config.isgone = true;
		
		//重新让SnakePanel获取焦点
		this.snakePanel.setFocusable(true);
		this.snakePanel.requestFocus();
	}
}

Food

package com.hpe.po;

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

import com.hpe.config.Config;

//表示食物的类
/**
 * 随机生成
 * 随机数
 * 在一个方格内
 * @author Administrator
 *
 */
public class Food {
	//属性
	private int col;//列---横坐标
	private int row;//行---纵坐标

	//构造方法
	public Food(){
		this.reGen();
	}
	//重新生成食物
	public void reGen(){
		this.col = new Random().nextInt(Config.COLS);
		this.row = new Random().nextInt(Config.ROWS);

	}

	//方法
	public void draw(Graphics g) {
		// TODO Auto-generated method stub
		//设置食物为红色
		g.setColor(Color.RED);

		//矩形
		g.fillRect(col*Config.SPAN, row*Config.SPAN, Config.SPAN, Config.SPAN);

	}

	//获取食物所在的矩形
	public Rectangle getFoodRectangle(){
		return new Rectangle(
				this.col*Config.SPAN, 
				this.row*Config.SPAN,
				Config.SPAN,
				Config.SPAN);

	}

}

MyText

package com.hpe.po;

import java.util.Random;

public class MyTest {

	public static void main(String[] args) {
		//随机数
		/*
		 * 1.Math类在java.lang包下,不需要导入java.lang包是项目默认导入的包
		 * 		random() >=0.0 <1.0 0.0~0.999999
		 * 2.Random
		 * */
		//1~10
		//Math.random()  				0.0~0.99999999999999
		//Math.random() * 10 			0.0~9.99999999999999
		//Math.random() * 10 + 1 		1.0~10.9999999999999999
		//(int)(Math.random() * 10 + 1)	1~10
		for(int i = 0; i < 5; i++) {
			System.out.println((int)(Math.random() * 10) + 1);
		}
		System.out.println("------------------------------------------------------------");

		//1~4
		for(int i = 0; i < 50; i++) {
			System.out.println((int)(Math.random() * 4) + 1);
		}
		System.out.println("------------------------------------------------------------");

		//2~6  1~5
		for(int i = 0; i < 60; i++) {
			System.out.println((int)(Math.random() * 5) + 2);
		}

		System.out.println("*************************************************************");

		Random rd = new Random();
		for(int i = 0; i < 10; i++) {
			System.out.println(rd.nextInt(10));
		}
	}
}

Node

package com.hpe.po;

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

import com.hpe.config.Config;

//表示节点的类
public class Node {
	private int col; //节点所在的列---横坐标
	private int row; //节点所在的行---纵坐标
	private String dir; //方向
	public Node pre; //前一个元素
	public Node next;//后一个元素

	public Node(int col, int row, String dir) {
		super();
		this.col = col;
		this.row = row;
		this.dir = dir;
	}

	public int getCol() {
		return col;
	}

	public void setCol(int col) {
		this.col = col;
	}

	public int getRow() {
		return row;
	}

	public void setRow(int row) {
		this.row = row;
	}

	public String getDir() {
		return dir;
	}

	public void setDir(String dir) {
		this.dir = dir;
	}

	//画节点
	public void draw(Graphics g) {
		//判断是否的头节点
		if(this.pre == null) {
			g.setColor(Color.YELLOW);
		} else {
			g.setColor(Color.BLUE);
		}

		g.fillOval(col * Config.SPAN, row * Config.SPAN, Config.SPAN, Config.SPAN);
	}


}

Snake

package com.hpe.po;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;

import com.hpe.config.Config;

//双向链表
//表示蛇的类
public class Snake {
	private Node head; //头
	private Node body; //躯干
	private Node tail; //尾

	private Food food;
	//构造方S法

	public Snake(Food food) {
		this.food = food;
		//创建蛇初始的三个节点,让其在同一行
		head = new Node(17, 11, Config.R);
		body = new Node(16, 11, Config.R);
		tail = new Node(15, 11, Config.R);

		//让三个节点关联,创建一个双向链表
		head.pre = null;
		head.next = body;
		body.pre = head;
		body.next = tail;
		tail.pre = body;
		tail.next = null;
	}

	//画蛇
	public void draw(Graphics g) {
		for(Node n = head; n != null; n = n.next) {
			//画节点
			n.draw(g);
		}
	}

	public void move() {
		//添加头
		addHead();
		//删去尾
		removeTail();
	}

	//添加头
	public void addHead() {
		//判断当前往哪个方向走,然后头的相应的位置添加一个元素---->如何判断当前往哪个方向走---->头的移动方向
		Node node = null;

		//根据蛇当前移动的方向,创建要添加的节点
		switch(this.head.getDir()) {
		case Config.U:
			node = new Node(this.head.getCol(), this.head.getRow() - 1, this.head.getDir());
			break;
		case Config.D:
			node = new Node(this.head.getCol(), this.head.getRow() + 1, this.head.getDir());
			break;
		case Config.L:
			node = new Node(this.head.getCol() - 1, this.head.getRow(), this.head.getDir());
			break;
		case Config.R:
			node = new Node(this.head.getCol() + 1, this.head.getRow(), this.head.getDir());
			break;
		}

		node.pre = null;
		node.next = head;
		head.pre = node;
		head = node;
	}

	public void removeTail() {
		Node temp = tail;

		tail = tail.pre;
		tail.next = null;
		temp.pre = null;
	}

	public void dirControl(KeyEvent e) {
		// TODO Auto-generated method stub
		//不能向相反的方向转换方向
		switch(e.getKeyCode()){
//		case KeyEvent.VK_W:
//			if(!this.head.getDir().equals(Config.D)){
//				this.head.setDir(Config.U);
//			}
//			break;
//
//		case KeyEvent.VK_S:
//			if(!this.head.getDir().equals(Config.U)){
//				this.head.setDir(Config.D);
//			}
//			break;
//
//		case KeyEvent.VK_A:
//			if(!this.head.getDir().equals(Config.R)){
//				this.head.setDir(Config.L);
//			}
//			break;
//
//		case KeyEvent.VK_D:
//			if(!this.head.getDir().equals(Config.L)){
//				this.head.setDir(Config.R);
//			}
//			break;
			case KeyEvent.VK_UP:
			if(!this.head.getDir().equals(Config.D)){
					this.head.setDir(Config.U);
				}
				break;

			case KeyEvent.VK_DOWN:
				if(!this.head.getDir().equals(Config.U)){
					this.head.setDir(Config.D);
				}
				break;

			case KeyEvent.VK_LEFT:
				if(!this.head.getDir().equals(Config.R)){
					this.head.setDir(Config.L);
				}
				break;

			case KeyEvent.VK_RIGHT:
				if(!this.head.getDir().equals(Config.L)){
					this.head.setDir(Config.R);
				}
				break;
		default:
			break;

		}


		//通过键盘控制蛇的移动
	}
	/**
	 * 吃食物检测
	 * 
	 * 什么情况是吃到食物?---头和食物坐标重合---如何判断头和食物坐标重合
	 * 
	 * 
	 * 
	 */
	public void eatOrNot() {
		// TODO Auto-generated method stub
		//能够吃食物
		if(this.getHeadRectangle().contains(this.food.getFoodRectangle())){
			//添加头
			this.addHead();
			//重新生成食物
			this.food.reGen();
		}
	}
	//获取head所在矩形
	public Rectangle getHeadRectangle(){
		return new Rectangle(
				this.head.getCol()*Config.SPAN, 
				this.head.getRow()*Config.SPAN,
				Config.SPAN, 
				Config.SPAN);

	}
	//死亡监测
	public void deadCheck() {
		// TODO Auto-generated method stub
/**
 * 头碰到边界
 * 头碰到身体
 */
	//判断是否碰到边界
		if(this.head.getCol()<0||
				this.head.getCol()>Config.COLS||
				this.head.getRow()<0||
				this.head.getRow()>Config.ROWS){
			Config.islive=false;
			return;
		}
		//head碰到了body node表示头之后的所有的节点
		for(Node node =head.next;node !=null;node = node.next){
			Rectangle nodeRect =new Rectangle(
					node.getCol()*Config.SPAN,
					node.getRow()*Config.SPAN,
					Config.SPAN,
					Config.SPAN);
			if(this.getHeadRectangle().contains(nodeRect)){
				Config.islive=false;
				return;
			}
		}
	}
}

未完

学习笔记

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值