主要的蛇的类

import java.awt.Color;
import java.awt.Graphics;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.Random; public class Snake { private Node head = null;
private Node tail = null;
int size = 0;
private boolean live = true; /**
* 判断蛇是否活着
* @return true则活着 false则死亡
*/
public boolean isLive() {
return live;
}
/**
* 设置蛇的生死
* @param live true则活着 false则死亡
*/
void setLive(boolean live){
this.live = live;
} private Yard y; Node n = new Node(15, 15, Dir.L);
/**
* 构造方法
* @param y
*/
public Snake(Yard y){
this.y = y;
head = n;
tail = n;
size++;
} /**
* 将一个结点添加到蛇的链表中
*/
void addToTail(){
Node node = null;
switch (tail.dir) {
case L:
node = new Node(tail.row, tail.col+1, tail.dir);
break;
case U:
node = new Node(tail.row+1, tail.col, tail.dir);
break;
case R:
node = new Node(tail.row, tail.col-1, tail.dir);
break;
case D:
node = new Node(tail.row-1, tail.col, tail.dir);
break;
}
tail.next = node;
node.prev = tail;
tail = node;
size++;
} /**
* 将一个结点从蛇的尾巴处删除
*/
void deleteFromTail(){
if(size == 0) return;
tail = tail.prev;
tail.next = null;
size--;
} /**
* 设置使蛇的位置向前移动一步
*/
void move(){
addToHead();
deleteFromTail();
checkDead();
}
/**
* 蛇的重画方法
* @param g
*/
void draw(Graphics g){
if(!isLive() || size == 0) {
return;
}
move();
for(Node node = head ; node != null ; node = node.next){
node.draw(g);
} }
/**
* 将一个结点加到蛇链表的头部
*/
void addToHead(){
Node node = null;
switch (head.dir) {
case L:
node = new Node(head.row, head.col-1, head.dir);
break;
case U:
node = new Node(head.row-1, head.col, head.dir);
break;
case R:
node = new Node(head.row, head.col+1, head.dir);
break;
case D:
node = new Node(head.row+1, head.col, head.dir);
break;
}
node.next = head;
head.prev = node ;
head = node ;
size++;
} /**
* 保存蛇单个结点信息的类
*/
private class Node{
int w = Yard.BLOCK_SIZE;
int h = Yard.BLOCK_SIZE;
Dir dir = Dir.L;
int row,col; Node next = null;
Node prev = null; public Node(int row,int col,Dir dir){
this.row = row;
this.col = col;
this.dir = dir;
}
//蛇单个节点的画法
public void draw(Graphics g){
Color c = g.getColor();
g.setColor(Color.BLACK);
g.fillRect(col*Yard.BLOCK_SIZE, row*Yard.BLOCK_SIZE, w, h);
g.setColor(c);
} }
/**
* 键盘监听
* @param e
*/
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key){
case KeyEvent.VK_LEFT:
if(head.dir != Dir.R) head.dir = Dir.L;
break;
case KeyEvent.VK_UP:
if(head.dir != Dir.D) head.dir = Dir.U;
break;
case KeyEvent.VK_RIGHT:
if(head.dir != Dir.L) head.dir = Dir.R;
break;
case KeyEvent.VK_DOWN:
if(head.dir != Dir.U) head.dir = Dir.D;
break;
case KeyEvent.VK_F2:
if(!this.isLive()){
y.snake = new Snake(y);
}
break;
}
} /**
* 吃食物
* @param f
*/
public void eatFood(Food f){
if(this.getRect().intersects(f.getRect())){
f.setPos();
y.setScore();
this.addToTail();
}
} /**
* 通过检测来设置蛇的生死
*/
public void checkDead(){
if(head.col < 0 || head.col > Yard.COLS || head.row < 3 || head.row > Yard.ROWS-1){
setLive(false);
}
if(size >= 4){
for(Node node = head.next;node != null ; node = node.next){
if(head.row == node.row && head.col == node.col){
setLive(false);
}
}
}
} public Rectangle getRect(){
return new Rectangle(head.col*Yard.BLOCK_SIZE,head.row*Yard.BLOCK_SIZE,Yard.BLOCK_SIZE,Yard.BLOCK_SIZE);
}
}

吃的食物的类

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random; public class Food {
int row,col;
int h = Yard.BLOCK_SIZE;
int w = Yard.BLOCK_SIZE;
private static Random rd = new Random();
int step = 0; public Food(int row ,int col) {
this.row = row;
this.col = col;
} public void draw(Graphics g){
Color c = g.getColor();
if(step == 0){
g.setColor(Color.RED);
step++;
}else if(step == 1){
g.setColor(Color.green);
step++;
}else {
g.setColor(Color.WHITE);
step = 0;
} g.fillOval(col*Yard.BLOCK_SIZE, row*Yard.BLOCK_SIZE, w, h);
g.setColor(c);
} public Rectangle getRect(){
return new Rectangle(col*Yard.BLOCK_SIZE, row*Yard.BLOCK_SIZE, w, h);
} void setPos(){
this.row = rd.nextInt(Yard.ROWS-3)+3;
this.col = rd.nextInt(Yard.COLS);
}
}

方向的枚举

public enum Dir {
L,U,R,D
}

主界面的类

import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; class Yard extends Frame{ PaintThread pt = null;
/**
* 速度 设置数字越大 越慢
*/
public static final int SPEED = 4;
/**
* 行数
*/
public static final int ROWS = 30;
/**
* 列数
*/
public static final int COLS = 30;
/**
* 行列的宽度
*/
public static final int BLOCK_SIZE = 15; /**
* 在游戏窗口中加入一条蛇
*/
public Snake snake = new Snake(this); /**
* 在游戏窗口中加入一个食物
*/
public Food food = new Food(10,10); private Font font = new Font("宋体", Font.BOLD,30 ); private Image offScreenImage = null; //分数
private int score = 0; public int getScore() {
return score;
} public void setScore() {
this.score += 5;
} /**
* 窗口构建函数
*/
public void launch(){ pt = new PaintThread();
this.setLocation(200, 200);
this.setSize(COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {
System.exit(0);
} }); this.setVisible(true);
this.addKeyListener(new KeyMonitor());
this.setResizable(false);
//开始重画线程
new Thread(pt).start(); } /**
* 主方法
* @param args
*/
public static void main(String[] args){
new Yard().launch();
} /**
* 重写的paint方法 用来画出各个元素
*/
@Override
public void paint(Graphics g) { Color c = g.getColor();
g.setColor(Color.GRAY);
g.fillRect(0, 0, COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
g.setColor(Color.DARK_GRAY); //画出横线
for(int i=1; i<ROWS; i++) {
g.drawLine(0, BLOCK_SIZE * i, COLS * BLOCK_SIZE, BLOCK_SIZE * i);
}
for(int i=1; i<COLS; i++) {
g.drawLine(BLOCK_SIZE * i, 0, BLOCK_SIZE * i, BLOCK_SIZE * ROWS);
} snake.eatFood(food);
g.setColor(Color.YELLOW);
g.drawString("score :" + score, 10, 50);
food.draw(g); if(snake.isLive()) {
snake.draw(g);
}else{
g.setColor(Color.YELLOW);
g.setFont(font);
g.drawString("Game Over!", 125, 225);
}
g.setColor(c); } /**
* 重写的update用来防止屏幕闪烁
*/
@Override
public void update(Graphics g) { if(offScreenImage == null){
offScreenImage = this.createImage(COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
}
Graphics graphics = offScreenImage.getGraphics();
paint(graphics); g.drawImage(offScreenImage, 0, 0, null);
} /**
* 重画线程
*/
private class PaintThread implements Runnable{
private boolean flag = true; private boolean pause = false;
@Override
public void run() {
while(flag){
if(!pause)
repaint();
try {
Thread.sleep(25*SPEED);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public void stopPaintThread(){
flag = !flag;
} public void pausePaintThread(){
pause = !pause;
}
} /**
* 键盘监听类
*/
private class KeyMonitor extends KeyAdapter{ @Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_SPACE){
pt.pausePaintThread();
}
snake.keyPressed(e);
} }
}

最新文章

  1. dedecms功能性函数封装(XSS过滤、编码、浏览器XSS hack、字符操作函数)
  2. Handlebars.js的学习
  3. vs2010 sql server 2008数据库管理界面安装
  4. membership 启用 roleManager 抛出异常:未能加载文件或程序集MySql.Web
  5. java中二进制和流的相互转换
  6. [LintCode] Reverse Nodes in k-Group 每k个一组翻转链表
  7. Objective-C基础
  8. java并发的理解
  9. 启动Eclipse 弹出“Failed to load the JNI shared library”错误的解决方法
  10. 电赛菜鸟营培训(二)&mdash;&mdash;STM32F103CB之中断控制
  11. 第七篇 Integration Services:中级工作流管理
  12. 如何限制textarea文本框的输入字数
  13. oracle 绿色版本 instantclient 使用说明
  14. SmartFoxServer 2x的pythonclient
  15. c#中使用easyUI的DataGrid组件
  16. Android中,粗暴的方式,修改字体
  17. 将JPA出参Iterable转为List
  18. QUIC:基于udp的传输新技术
  19. [Umbraco] xslt语言介绍及与umbraco的关系
  20. 微信小程序之顶部固定和底部固定

热门文章

  1. vs2013 error LNK2005 已经在***.obj中定义
  2. 模板, 保存&amp;发布
  3. 《FPGA全程进阶---实战演练》第七章 让按键恢复平静
  4. 用OpenGL实现动态的立体时钟
  5. JPA 不生成外键
  6. centos7 网络配置
  7. [GPU] DIY for Deep Learning Workstation
  8. chrome设置捕获异常时自动暂停js
  9. 【代码审计】大米CMS_V5.5.3 任意文件读取漏洞分析
  10. Linux设备驱动剖析之IIC(四)