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;
}
}
}
}
未完
学习笔记