前面说的是创建了Piece0, Piece1,Piece2,Piece3,Piece4,Piece5,Piece6.其中变化的方块,由于游戏开始和下一个方块出现时是随机得到不同的大方块的,在定义Piece时用changes属性(Protectec List<List<Square>> changes = new ArrayList<<List<Square>>())来储存变化的方块,所以要想随机的到一个方块,在Piece提供了一个geDefault()方法,并提供了一个随机产生数字的想要得到的变化的随机数属性random(protected Random random = new Random(); )。
protected Random random = new Random();
public List<Square> getDefault() {
//从changes中随机得到其中一种变化
int defaultChange = random.nextInt(changes.size());
this.currentIndex = defaultChange;
return changes.get(defaultChange);
}
在Piece1,Piece2,Piece3,Piece4,Piece5,Piece6类里添加下面的语句super.setSquares(getDefault());
注意了前面只说了大方块和小方块的类。特别是小方块里的Image image属性且 前面创建了各个Piece的子类。每个子类都提供一个含有image构造器。只需从文件里读取图片就可以创建一个可以下降的大方块了。下面说说创建与显示大方块。新建一个PieceCreator接口专门用于创建大方块。(注:在这里我想不出书的作者为什么创建这个接口)并未接口提供了一个PieceCreatorImpl实现类
public interface PieceCreator {
/**
* 在x和y坐标中创建一个Square对象
*/
Piece createPiece(int x,int y);
/**
*返回一个Square对象
*/
Piece getPiece();
}
为了创建一个真正带有图片的物快,很明显需要考虑的因素是:必须得到图片,为此在PieceCreatorImpl类提供了getImge(int key)方法。(关于参数key的加入待会看了后面会明白)。从文件里得到图片要有文件的读取操作。为了不用每次都去文件里读取一个Image对象,在PieceCreatorImpl里提供了一个Map类存储读取过的image对象
Private Map<Integer,Image> images = new HashMap<Integer,Image>();
但是对于Map里的图片又是从哪里来的呢?当然是读取文件的来的。所以有设计了一个ImageUtil类来读取图片
public class ImageUtil {
public static BufferedImage getImage(String imagePath) {//注意是静态方法
try {
//使用ImageIO读取图片
return ImageIO.read(new File(imagePath));
} catch (IOException e) {
//读取图片发生异常,抛出GameException
throw new GameException("read image error");
}
}
}
//于是map中的图片就是下面代码得来的。从map中得到图片对象,如果map中没有对应的图片对象,则创建
private Image getImage(int key) {
if(this.images.get(key)==null) {
Image s = ImageUtil.getImage("images/square" + key+".jpg");
this.images.put(key,s);//
}
return this.images.get(key);
}
(个人认为把图片放入map应该单独定义一个方法)
得到了图片下面改创建把图片加入到Square里进而创建一个大方块了,注意由于文件里保留了七种不同颜色的图片(/
/总共有七种颜色的方块
private final static int COLOR_SIZE = 7;),
所以获得图片时也是提供一个在PieceCreatorImplement类里提供了random属性
(private Random random = new Random();)
来随机读取一张图片,
public Piece createPiece(int x, int y) {
//随机得到一张方块图片
Image image = getImage(random.nextInt(COLOR_SIZE));
Piece piece = initPiece(image);
return piece;
}
/**
* 初始化各个大方快,随机创建各个大方框
*/
public Piece initPiece(Image image) {
Piece piece = null;
int pieceType = random.nextInt(SQUARE_SIZE);
if(pieceType == 0) {
piece = new Piece0(image);
}else if(pieceType == 1) {
piece = new Piece1(image);
}else if(pieceType == 2) {
piece = new Piece0(image);
}else if(pieceType == 2) {
piece = new Piece3(image);
}else if(pieceType == 3) {
piece = new Piece4(image);
}else if(pieceType == 5) {
piece = new Piece5(image);
}else if(pieceType == 6) {
piece = new Piece6(image);
}
return piece;
}
需要注意的是,游戏中大方块出现的位置和移动的位置的实现是通过改变方块位置的纵横坐标来实现的,又由于实际上大方块是由小方块组成的,只要同时改变组成大方块的所有小方块的x和y 坐标就可以了,为此Piece提供了一以下方法
//让Piece对象中所有的Square对象的x坐标都加上参数x
public void setSquareXLocation(int x) {
for(int i = 0;i<this.changes.size();i++) {
//得到一个变化
List<Square> change = this.changes.get(i);
for(int j = 0;j<change.size();j++) {
Square s = change.get(j);
s.setBeginX(s.getBeginX()+x);
}
}
}
//让Piece对象中所有的Square对象的y坐标都加上参数y
public void setSquareYLocation(int y) {
for(int i = 0;i<this.changes.size();i++) {
//从变化容器里得到各个成有不同形状的大方块的容器
List<Square> change = this.changes.get(i);
for(int j = 0;j<change.size();j++) {
//得到容器里的小方块
Square s = change.get(j);
s.setBeginY(s.getBeginY()+y);