学习JAVA也有一段时间了,之前看了翁恺老师的视频,跟着做了一个细胞自动机,粗浅地了解了一点MVC框架的知识,感觉获益匪浅。但是细胞自动机毕竟是跟着视频完成的,有很大程度上都是参考了视频里的代码,没有自己实践过,因此决定自己做一个贪吃蛇小程序,把MVC的结构运用到程序中来,并且也可以练习一下之前学过的一些知识。
一、MVC框架(Model View Controller)
首先简要的说明一下MVC框架,从其名称全写就能窥见其中含义。
- Model是模型,程序所有的数据都存放在模型中。
- View是视图,从模型中获取数据并将其输出出来。
- Controller是控制器,负责整个程序的业务逻辑,控制数据处理以及输出。
通过这样的框架结构将程序中的各个部分分离出来,使得整个程序的脉络变得清晰明了,能提高编程的效率,并且有效地降低了类与类之间的耦合,提升了程序的可扩展性。
二、贪吃蛇程序
作为一个贪吃蛇游戏小程序,肯定是需要一个场景一条蛇和一颗苹果的,否则无法正常完成程序。这些具体的游戏的构成元素都属于MVC框架中的Model。
Cell类:
在此之前受到细胞自动机的启发,我创建了一个Cell类作为游戏图形界面的最基本单元。通过这个Cell类的对象就可以构成这个游戏所需要的场景,蛇以及苹果了。
Cell类中包含私有成员变量x,y用以描述Cell的位置信息;其余私有成员变量isSnake、isApple和isWall用于判断Cell在这个程序中的真实属性。公有成员方法的用途通过方法名和代码注释应该不难理解,这里就不作过多赘述了,以下是Cell类的代码实现。
import java.awt.Color;
import java.awt.Graphics;
public class Cell {
private int x;
private int y;
private boolean isSnake; //是否为蛇的身体,以便打印时着色
private boolean isApple; //是否为苹果,以便打印时着色
private boolean isWall;
Cell(int x,int y) {
this.x = x;
this.y = y;
isSnake = false;
isApple = false;
isWall = false;
}
void toSnake() { //设置为蛇的身体
isSnake = true;
isApple = false;
}
void toApple() { //设置为苹果
isApple = true;
}
void toWall() { //设置为墙
isWall = true;
}
boolean isSnake() { //获取是否为蛇的身体的信息
return isSnake;
}
boolean isApple() { //获取是否为苹果的信息
return isApple;
}
boolean isWall() { //获取是否为墙的信息
return isWall;
}
void moveE() { //向东移动
x++;
}
void moveN() { //向北移动
y--;
}
void moveW() { //向西移动
x--;
}
void moveS() { //向南移动
y++;
}
int getX() {
return x;
}
int getY() {
return y;
}
void changeX(int x) { //改变Cell的X坐标
this.x = x;
}
void changeY(int y) { //改变Cell的Y坐标
this.y = y;
}
void draw(Graphics g,int CELL_SIZE){ //画出Cell
g.drawRect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE);
if(isSnake()){
g.fillRect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
if(isApple()) {
g.setColor(Color.PINK);
g.fillRect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE);
g.setColor(Color.BLACK);
}
if(isWall()) {
g.setColor(Color.lightGray);
g.fillRect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE);
g.setColor(Color.BLACK);
}
}
}
Wall类:
有了游戏图形界面的最基本的单元我们就可以开始构造游戏场景了。贪吃蛇游戏场景其实很简单,就是一道围墙包围住整个游戏区域。形成一道围墙需要很多Cell对象共同实现,因此Wall类的私有成员函数仅包含了一个Cell类的ArrayList容器用以存放若干形成围墙的Cell对象。以下是Wall类的代码实现。
import java.util.ArrayList;
public class Wall {
private ArrayList<Cell> Wall = new ArrayList<Cell>();
Wall