java贪吃蛇总结报告_java贪吃蛇开发总结

相信每一个java学者在成长的时候都编写过一些小游戏,我花了两天的时间编写了贪吃蛇,这其中当然也参考了别人的代码。对于学者来说,通过这个案例也成长了不少。

对于面向对象来说,贪吃蛇所包含的类应该有Snake类、Food类、Ground类、GamePanel类(继承JPanel),这些都是属于Entity(实体)类,所以把他们放到一个包下面,Controller类继承KeyAdapter(键盘事件监听类库)实现SnakeListener 接口,可以看出Controller是一个控制蛇和监听键盘事件的类。SnakeGameActivity类包含main函数,是游戏的入口。Global类用于定义面板格局。列入面板的长宽,格子的大小。

所有的包以及类

0f9ae16543756873f3187af1016c1a59.png

Controller负责控制游戏的开始、蛇的移动以及监听键盘,监听键盘调用了keyPressed键盘事件,判断键盘的输入。

820adce663c124ffe5f57d998d30b1a9.png

实体类蛇、食物、障碍物通过对象把他们抽象出来,声明它们所具有的属性和方法,比如说:蛇具有移动和改变方向的方法。

225062e40d02bce083866c94f57767e9.png

SnakeLiener(单词错误,是SnakeListener)负责监听蛇每次的移动,具体实现方法见Controller。

Global定义了窗口的宽高以及每块方格的大小。

d1506eb1937bb9a2e2eea197ec3d1333.png

整个项目很简单,但对于刚接触编程的人来说在这其中却能学到很多东西。

packagecom.Leekin.Entity;importjava.awt.Color;importjava.awt.Graphics;importjava.awt.Point;importjava.util.LinkedList;importcom.Leekin.Listener.SnakeLiener;importcom.Leekin.Util.Global;/*** Snake Class

*@authorLeekin

**/

public classSnake {//the Listener for Snake Move

privateSnakeLiener snakeListener;//LinkedList

private boolean life = true;private LinkedList body = new LinkedList();public static final int UP = 1;public static final int DOWN = -1;public static final int LEFT = 2;public static final int RIGHT = -2;private intoldDirection,newDirection;private Point tail; //储存尾巴

publicSnake(){

init();

}private voidinit() {int x = Global.WIDTH/2;int y = Global.HEIGHT/2;for(int i = 0;i < 3;i++){

body.add(new Point(x-1,y));

}this.oldDirection = newDirection=RIGHT;

}/*** eat mothd

* 去掉尾巴加头

*@paramfood*/

public voideatFood(Food food){

body.add(tail);

}/***

* 去尾加头*/

//move Method

public voidmove(){

tail=body.removeLast();int x =body.getFirst().x;int y=body.getFirst().y;/*** 获得新的头部

* 要判断方向才能确定头部

* 在初始化构造的时候默认的方向是向右

**/

if(this.oldDirection+newDirection != 0)this.oldDirection = this.newDirection;switch(oldDirection){caseUP:

y--;if(y<0)y=Global.HEIGHT - 1;break;caseDOWN:

y++;if(y >= Global.HEIGHT) y = 0;break;caseLEFT:

x--;if(x<0)x=Global.WIDTH-1;break;caseRIGHT:

x++;if(x>=Global.WIDTH) x=0;break;

}

body.addFirst(newPoint(x,y));

}//changedirection method

public void changeDirection(intdirection){this.newDirection =direction;//this.direction= direction;

}//DrawMe Method

public voidDrawMe(Graphics g){

g.setColor(Color.blue);for(Point p:body){

g.fill3DRect(p.x*Global.CELL_SIZE,p.y*Global.CELL_SIZE, Global.CELL_SIZE,Global.CELL_SIZE,true);

}

}//is eat self method

public booleanisEatSelf(){for(int i = 0; i < body.size();i++){if(body.get(i).equals(getHead())){return false;

}

}return false;

}public voidaddSnakeListener(SnakeLiener snakeLiener){if(snakeLiener != null)this.snakeListener =snakeLiener;

}public voidstart(){newSnakeDriver().start();

}//获得蛇头的方法

publicPoint getHead(){returnbody.getFirst();

}public void setlife(booleanlife){this.life =life;

}private class SnakeDriver extendsThread{

@Overridepublic voidrun() {while(life){

move();

snakeListener.snakeMoved(Snake.this);try{

Thread.sleep(300);

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

}

Snake实现逻辑,其中移动速度用线程来控制,Thread.sleep(300);(休眠0.3秒)

packagecom.Leekin.Entity;importjava.awt.Graphics;importjavax.swing.JPanel;/*** Ganme Panel class

*@authorLeekin

**/

public class GamePanel extendsJPanel {//Initialize object

privateSnake snake;privateFood food;privateGround ground;//show method

public voiddisPlay(Snake snake,Food food,Ground ground){this.snake =snake;this.food =food;this.ground =ground;

repaint();

}

@Overrideprotected voidpaintComponent(Graphics g) {super.paintComponent(g);if(snake!=null&&food!=null&&ground!=null){

snake.DrawMe(g);

food.DrawMe(g);

ground.DrawMe(g);

}

}

}

GamePanel类是JPanel的子类,复写父类的paintComponen方法,是游戏板面的对象。

packagecom.Leekin.Entity;importjava.awt.Color;importjava.awt.Graphics;importjava.awt.Point;importjava.util.Random;importcom.Leekin.Util.Global;/*** Ground class

*@authorLeekin

**/

public classGround {private int[][] rocks = new int[Global.WIDTH][Global.HEIGHT];publicGround(){for(int y = 0;y< Global.HEIGHT;y++){for(int x = 0;x

rocks[y][x]= 1;if(x==0||x==Global.HEIGHT-1){

rocks[y][x]= 1;

}

}

}

}//DrawMe

public voidDrawMe(Graphics g){

g.setColor(Color.orange);for(int y = 0;y

g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE,

Global.CELL_SIZE, Global.CELL_SIZE,true);

}

}

}

}/*** 设置食物点的位置

*@return

*/

publicPoint getPoint(){intx,y;do{

x= newRandom().nextInt(Global.WIDTH);

y= newRandom().nextInt(Global.HEIGHT);

}while(rocks[x][y]==1);return newPoint(x,y);

}//is eat by snake

public booleanisEatBySnake(Snake snake){

Point head=snake.getHead();for(int x = 0;x

}

}return false;

}

}

Ground类,数组rocks用于储存障碍物,便用镶套for循环遍历,在用if判断,符合条件的生成边框障碍物。当蛇头的点与障碍物重合时就判定为蛇撞到障碍物,调用gameover的方法。

packagecom.Leekin.Entity;importjava.awt.Color;importjava.awt.Graphics;importjava.awt.Point;importcom.Leekin.Util.Global;/*** Food class

*@authorLeekin

**/

public class Food extendsPoint {//DrawMe method

public voidDrawMe(Graphics g){

g.setColor(Color.green);

g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE,

Global.CELL_SIZE,Global.CELL_SIZE,true);

}/*** is eat by snak

* 只要判断蛇头的点是否和食物的点重合

* 得到蛇头

*@paramsnake

*@return

*/

public booleanisEatBySnak(Snake snake){

Point head=snake.getHead();if(this.equals(head))return true;return false;

}public voidaddFood(Point p){this.x =p.x;this.y=p.y;

}

}

Food类是point的子类,因为生成的food是一个点。判断是否被蛇吃到的方法是蛇头的点是否和食物的点重合。当吃到蛇就会增加一个方格,同时addFood方法生成新的食物。

整个布局是以左上角的点为(0,0)的坐标,但坐标点与坐标的位置相反,它排列了数组在上面。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值