先分析有哪些对象:
蛇:
属性:节点,长度,颜色,运动的方向,生长的标记。
方法:构造一条蛇,移动,改变方向。
食物:
属性:颜色,位置(横纵坐标)
方法: 初始化一个食物,绘制
网格:
属性: 行,列,格子大小,背景的颜色。
方法:初始化网格
游戏
属性:蛇,食物,网格,蛇的移动速度,窗口,画布,绘画对象。
方法:初始化一个游戏;判断是否吃到食物,判断是否吃到自己,判断是否撞墙,画蛇,画食物,画网格
节点:行,列
蛇初始化: direction = down;color = green;
[{rows = 3,col = 5},{row = 3,col = 4},{row = 3,col = 3}]
蛇的移动,改变方向,生长,
网格初始化:rows = 25;Cols = 25;color = black;
游戏初始化:
初始化蛇,初始化食物,初始化网格,绘制蛇、食物、网格,开始游戏
定义网格:
public class Grid {
int rows;
int cols;
int size;
public Grid(int rows,int cols,int size ){
this.rows = rows;
this.cols = cols;
this.size = size;
}
}
定义食物:
public class Food {
Random rand = new Random();
int row = rand.nextInt(25);
int col = rand.nextInt(25);
Node node = new Node(row, col);
/**
* 食物的初始化
*/
public Node getFood() {
return node;
}
}
定义蛇:
public class Snake {
public static final byte LEFT = -1;
public static final byte RIGHT = 1;
public static final byte DOWN = 2;
public static final byte UP = -2;//定义方向
public int direction = RIGHT;
public byte direction1 = RIGHT;
public boolean grow_flag = false;
public int speed = 200;
public int cout = 0;
private LinkedList<Node> body =new LinkedList<>();//建立链表
/**
* 初始化蛇
* @param lenght
*/
public Snake(int lenght){
for (int col = lenght ;col>0;col--){
Node node = new Node(0,col);
body.add(node);
}//初始化蛇身,即填写链表
}
/**
* 改变蛇的方向同时不让他180度转向
* @param direction 新的方向
*/
public void changeDirection(byte direction){
if(direction + this.direction != 0){
this.direction=direction;
}
}
/**
* 蛇的移动
*/
public void move() {
Node n = new Node();//建立一个新节点
Node head = body.getFirst();//获取头部节点
//根据方向确定坐标
switch (direction) {
case LEFT:
n.row = head.row;
n.col = head.col - 1;
break;
case RIGHT:
n.row = head.row;
n.col = head.col + 1;
break;
case DOWN:
n.row = head.row + 1;
n.col = head.col;
break;
case UP:
n.row = head.row - 1;
n.col = head.col;
break;
}
body.addFirst(n);
if (grow_flag) {
grow_flag = false;
}
else {
body.removeLast();//删除链表尾节点
}
}
/**
* 蛇的生长
*/
public void grow(){
grow_flag= true;
}
/**
* 判断是否吃到自己
* @return false 没有 true 吃到了
*/
public boolean eatslif() {
Node head = body.getFirst();//获取头部节点
for (int i = 1; i < getbody().size(); i++) {
if (head.equal(body.get(i))) {
return true;
}
}
return false;
}
/**
* 判断撞墙
* @return true 撞了false没撞
*/
public boolean meetwall(){
Node head = body.getFirst();
if (head.row<25&&head.col<25&&head.row>=0&&head.col>=0){
return false;
}else{
return true;
}
}
/**
* 判断是否死亡
* @return true=死亡 false=没死
*/
public boolean die(){
if(meetwall()==false&&eatslif()==false){
return true;
}
else{
return false;
}
}
public LinkedList<Node> getbody(){
return body;
}
}
定义游戏:
public class Game {
private static final Color BLANK = Color.BLACK;
private static final Color GREEN = Color.GREEN;
private static final Color YELLOW = Color.YELLOW;
private static final Color BULE = Color.BLUE;
private static final Color RED = Color.RED;
private static final Color MAGENTA = Color.MAGENTA;
private static final Color CYAN = Color.CYAN;
public Frame frame;//建一个弹窗
public Canvas canvas;//建一个画布
public Graphics graphics;//建一个画笔
public Snake snake;
public Grid grid;
public Food food;
public Node node;
/**
* 定义游戏
* @param rows 界面的横坐标
* @param clos 界面的纵坐标
* @param size 表格大小
* @param length 蛇的长度
*/
public Game(int rows, int clos, int size, int length) {
grid = new Grid(rows, clos, size);
snake = new Snake(length);
food = new Food();
node = new Node();
JFrame frame = new JFrame("贪食蛇");//初始化弹窗并命名
frame.setSize(516, 558);//大小
canvas = new Canvas();//初始化画布
frame.add(canvas);
frame.setVisible(true);//设置可视
canvas.addKeyListener(new KeyAdapter() {//写按键事件
@Override
public void keyPressed(KeyEvent e) {
handleKeyPress(e.getKeyCode());
}
});
}
/**
* 监听按键
* @param e
*/
public void handleKeyPress(int e ){
switch (e) {
case 90:
snake.speed +=50;
break;
case 88:
snake.speed -=50;
break;
case 37:
snake.direction1 = Snake.LEFT;
break;
case 38:
snake.direction1 = Snake.UP;
break;
case 39:
snake.direction1 = Snake.RIGHT;
break;
case 40:
snake.direction1 = Snake.DOWN;
}
}
/**
* 画背景
*/
public void drawGrid(){
graphics = canvas.getGraphics();//获取绘画对象
graphics.setColor(Color.white);
graphics.fillRect(0,0,grid.rows*grid.size,grid.cols*grid.size);//画网格
}
/**
* 画线
*/
public void drawlines(){
graphics = canvas.getGraphics();//获取绘画对象
graphics.setColor(RED);
for (int i=0;i<=grid.rows;i++) {
graphics.drawLine(0,i*grid.size,grid.rows*grid.size,i*grid.size);
}
for (int i=0;i<=grid.cols;i++) {
graphics.drawLine(i*grid.size,0,i*grid.size,grid.rows*grid.size);
}
}
/**
* 画蛇
*/
public void drawSnake(){
graphics = canvas.getGraphics();//获取绘画对象
graphics.setColor(Color.pink);
int size = grid.size;
for (Node elment:snake.getbody()){
int x = elment.col*size;
int y = elment.row*size;
graphics.fillOval(x,y,grid.size,grid.size);
graphics.setColor(GREEN);
}
Node last = snake.getbody().getLast();
int i = snake.getbody().size();
Node second = snake.getbody().get(i-2);
drawhead(last,second);
}
/**
* 画食物
*/
public void drawFood(){
graphics = canvas.getGraphics();//获取绘画对象
int size = grid.size;
int x = food.node.col*size;
int y = food.node.row*size;
Image im = new ImageIcon("d:/im/1.jpg").getImage();
graphics.drawImage(im,x,y,size,size,null);
}
/**
* 画三角形蛇尾
* @param n 输入蛇尾节点和倒数第二个节点
*/
public void drawhead(Node n ,Node n1 ){
graphics = canvas.getGraphics();//获取绘画对象
graphics.setColor(Color.white);
int size=grid.size;
int a =n.col+1;
int b =n.row+1;
graphics.fillRect(n.col*size,n.row*size,size,size);
if(n.col == n1.col&&n.row-n1.row == 1){
graphics.setColor(BULE);
int [] x={a*size,(a-1)*size,a*size-size/2};
int [] y={(b-1)*size,(b-1)*size,b*size};
graphics.fillPolygon(x,y,3);
}
else if(n.col == n1.col&&n1.row-n.row == 1){
graphics.setColor(BULE);
int [] x={(a-1)*size,a*size,a*size-size/2};
int [] y={b*size,b*size,(b-1)*size};
graphics.fillPolygon(x,y,3);
}
else if(n1.col-n.col ==1&&n1.row == n.row){
graphics.setColor(BULE);
int [] x={a*size,a*size,(a-1)*size};
int [] y={(b-1)*size,b*size,b*size-size/2};
graphics.fillPolygon(x,y,3);
}
else {
graphics.setColor(BULE);
int [] x={(a-1)*size,(a-1)*size,a*size};
int [] y={(b-1)*size,b*size,b*size-size/2};
graphics.fillPolygon(x,y,3);
}
}
/**
* 画得分
*/
public void drawscout(){
graphics = canvas.getGraphics();//获取绘画对象
graphics.setColor(Color.CYAN);
graphics.fillRect(0,25*grid.size,grid.rows*grid.size,grid.size);
graphics.setColor(RED);
graphics.drawString("得分:"+snake.cout,0,518);
if(snake.cout >= 5&&snake.cout<10){
graphics.drawString("得到"+snake.cout+"分速度加1",100,518);
}
if(snake.cout >= 10&&snake.cout<20){
graphics.drawString("得到"+snake.cout+"分速度加2",100,518);
}
if(snake.cout >= 20){
graphics.drawString("得到"+snake.cout+"分速度加3",100,26*518);
}
}
/**
* 重新生成食物并且判断食物是否在蛇上
*/
private void resetFood() {
while (true) {
Node newFood = new Node();
int n = (int)(Math.random()*grid.cols*grid.rows);
newFood.col = n/grid.rows;
newFood.row = n/grid.cols;
LinkedList<Node> Body = snake.getbody();
boolean flag = true;
for (int i = 0;i<snake.getbody().size();i++){
if (newFood.equal(Body.get(i))){
flag = false;
break;
}
}if (flag){
food.node = newFood;
break;
}
}
}
/**
* 判断是否吃到食物
* @return false 没吃到 true 吃到
*/
public boolean meetfood(){
Node head = snake.getbody().getFirst();
return head.equal(food.node);
}
/**
* 一个让蛇随时间运动的线程
*/
public void start() {
new Thread() {
public void run() {
while (snake.die()) {
drawGrid();
drawSnake();
drawFood();
snake.changeDirection(snake.direction1);
snake.move();
drawlines();
drawscout();
if(meetfood()){
snake.grow();
resetFood();
drawFood();
drawscout();
snake.cout++;
if(snake.cout == 5){
snake.speed -=50;
}
if(snake.cout == 10){
snake.speed -=50;
}
if(snake.cout == 20){
snake.speed -=25;
}
}
try{
Thread.sleep( snake.speed);
}
catch(InterruptedException e){
e.printStackTrace();
}
}
JOptionPane.showMessageDialog(null, "Game Over", "警告", JOptionPane.ERROR_MESSAGE);
}
}.start();
}
public static void main(String[] args) {
Game game = new Game(25,25,20,3);
game.start();
}
}
实现截图: