主要的蛇的类

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);
} }
}

贪吃蛇java版的更多相关文章

  1. 原生js写的贪吃蛇网页版游戏特效

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <bo ...

  2. c/c++ 贪吃蛇控制台版

    贪吃蛇控制台版(操作系统win7 64位:编译环境gcc, vs2017通过,其它环境未测试 不保证一定通过) 运行效果: #include <iomanip> #include < ...

  3. 贪吃蛇 Java实现(一)

    贪吃蛇  Java实现 1.面向对象思想 1.创建antition包它是包含sanke  Ground Food类 2.创建Controller包controller类 3.创建Game包有game类 ...

  4. js贪吃蛇-简单版

    分享个用原生js写的贪吃蛇,最近在学java,按照当年写的 js的思路,转换成java,换汤不换药 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1 ...

  5. 如何用python制作贪吃蛇以及AI版贪吃蛇

    用python制作普通贪吃蛇 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很 ...

  6. C语言 贪吃蛇

    贪吃蛇(单人版): 本人先来介绍一个函数 -- bioskey函数: int bioskey (int cmd) 参数 (cmd) 基本功能 0 返回下一个从键盘键入的值(若不键入任何值,则将等下一个 ...

  7. 原生JavaScript贪吃蛇

    在实例开发过程中还是能认识到很多不足的,并且加强了一些基础. 简单写一下制作过程: 1.创建画布 2.创建蛇和老鼠 坐标不能重叠 3.让蛇移动起来 4.添加死亡方法 5.添加转点坐标和方向 6.添加吃 ...

  8. 原生Js贪吃蛇游戏实战开发笔记

    前言 本课程是通过JavaScript结合WebAPI DOM实现的一版网页游戏---贪吃蛇的开发全过程,采用面向以象的思想设计开发.通过这个小游戏的开发, 不仅可以掌握JS的语法的应用,还可以学会D ...

  9. 用GUI实现java版贪吃蛇小游戏

    项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public static void main(String[] args) { JFrame jFr ...

随机推荐

  1. msyql同步的时候报错 : 错误代码: 1293 Incorrect table definition;there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

    场景,两个不同服务器上的数据库,进行数据库同步 但是执行之后,提示报错 错误代码: 1293 Incorrect table definition; there can be only one TIM ...

  2. Java之CountDownLatch使用

    CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 主要方法 public CountDownLatch(int count); pu ...

  3. Scala学习笔记——简化代码、柯里化、继承、特质

    1.简化代码 package com.scala.first import java.io.File import javax.management.Query /** * Created by co ...

  4. python通过input()函数输入的内容是什么类型

    说明: 通过input()函数,可以从标准输入读取内容,那么读到的内容是什么类型呢. 通过type()函数可以进行判断,另外,通过input()函数的官方解释,从标准输入读取一个字符串.所以,应该是字 ...

  5. golang net/http 包

    https://studygolang.com/articles/9467 https://www.jianshu.com/p/be3d9cdc680b 客户端: 用来发送请求, 并处理返回结果. 涉 ...

  6. Kubernetes部署SpringCloud(三) 使用 Ingress-nginx 暴露服务

    之前部署的zuul以及basic-info-api 都仅仅在于flannel 网络内可以访问. 现在来使用Ingress-nginx 对外暴露服务 以下用到的一些docker镜像,是存在我私有仓库的, ...

  7. Kubernetes – Ingress

    用户在 Kubernetes 上部署的服务一般运行于私有网络,Pod和Service 提供了 hostPort,NodePort等参数用于暴露这些服务端口到K8S节点上,供使用者访问.这样的方法有明显 ...

  8. linux命令之间的分号,&&, ||

    在用linux命令时候, 我们经常需要同时执行多条命令, 那么命令之间该如何分割呢? 分号: 顺序地独立执行各条命令, 彼此之间不关心是否失败, 所有命令都会执行. &&  : 顺序执 ...

  9. mui---子页面主动调用父页面的方法

    我们在做APP的时候,很多时候会有这样的功能需求,例如:登录,充值,如果登录成功,或充值成功后,需要更改当前页面以及父页面的状态信息,就会用到在子页面调用父页面的方法来实现:在子页面刷新父页面的功能. ...

  10. 版本控制 version control和团队协作

    这些技术你可能暂时不会用到,但是一旦软件体量变大,开发人数增加,这就带来质变,需要借助一些工具或者技术才能完成这些复杂的工程. 你可以从最简单的情况思考,你可以对任何类型的文件进行版本控制,比如一个p ...