观察者模式 (模仿贪吃蛇) UML与代码
之前学习了23种模式,就找了个相关的案例,模仿贪吃蛇的。
三. 各个角色描述与UML图示
1.观察者-蛇(判断蛇有无吃到食物的isEat函数,判断蛇是否超过界限的isOut函数,判断蛇的头是否碰到自己的身体的isPitch函数,还有一个蛇死亡之后退出程序的dead函数。)
2.与蛇关联的对象-食物(构造函数初始化x,y坐标和flag标志,当蛇的头部碰到食物,也就是蛇的头或者身体的坐标和事物的坐标一样时,就表示食物被吃掉了。)
3.被观察者和地图-窗口组件与键盘事件 (MyPanel类)(paint函数为蛇的头部,身体,食物填充颜色,调用的是Graphics类中的fillRect 和setColor函数; keyPressed、这里用到了两次监听器,第一次把按键事件转化成蛇头的表示方向的改变,第二次把蛇头的表示方向的改变转化为蛇头实际方向的改变)
4.主函数-应用 (GreedySnake类)(初始化蛇头的位置,初始化食物的位置,初始化线程,然后添加了参数是mp的键盘监听器,设置了一些控制面板的相关内容)
UML类图如下图所示:Food关联Snake类,MyPanel类关联Food、Snake类,GreedySnake类关联Food类,Snake类,MyPanel类
四. 程序完整源代码
package snake;
0.引入一些需要用到的包
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Color;
import java.awt.Container;
import java.util.Random;
import java.util.List;
import java.util.LinkedList;
import javax.swing.JPanel;
import javax.swing.JFrame;
1.观察者-蛇
类的属性:蛇的正方体的边长size,蛇身体的正方体个数length,以及蛇的移动方向表示dir,边长越长,蛇的身体也就越粗壮;个数越多,蛇的身体也就越长;蛇的移动方向有上下左右四个,通过坐标点point(x,y)中x++,x--,y++,y--来实现蛇移动方向的控制。还有表示头部位置和身体位置flag的坐标
类的方法:判断蛇有无吃到食物的isEat函数,判断蛇是否超过界限的isOut函数,判断蛇的头是否碰到自己的身体的isPitch函数,还有一个蛇死亡之后退出程序的dead函数。前三个函数都是通过蛇头部的坐标点位置,身体的坐标位置,食物的坐标点位置,边界的坐标之间的大小比较来实现的。
class Snake{
int size,length,dir;
List
Point head;
Snake(Point head){
size = 15;
length = 6;
dir = 3;
this.head = head;
body = new LinkedList
for(int i=0;i<length-1;i++){
Point p = new Point(head.x,head.y+1+i);
body.add(p);
}
}
boolean isEat(Food food){//判断是否吃到食物的函数
if(head.x==food.x && head.y==food.y) return true;
return false;
}
boolean isOut(){//判断是否出界的函数
if(head.x<0 || head.y<0 || head.x>=40 || head.y>=40)
return true;
return false;
}
boolean isPitch(){//判断是否碰到自己身体的函数
for(Point it:body)
if(head.x==it.x && head.y==it.y){
dead(1);
return true;
}
return false;
}
void dead(int way){
System.exit(way);//0为正常退出,其他都是非正常
}
}