技术开发 频道

Android游戏开发:初始化游戏状态数据

  【IT168技术】本文是Android游戏开发系列文章的第五篇,讲解了如何初始化游戏状态的数据。为了初始化游戏状态,程序需要创建一个Piece[][]数组,为此程序定义一个AbstractBoard抽象类,该抽象类的代码如下。

  程序清单:codes\18\Link\src\org\crazyit\link\board\AbstractBoard.java

public abstract class AbstractBoard
{
    
// 定义一个抽象方法, 让子类去实现
    protected abstract List
<Piece> createPieces(GameConf config,
        Piece[][] pieces);
    
public Piece[][] create(GameConf config)
    {
        
// 创建Piece[][]数组
        Piece[][] pieces
= new Piece[config.getXSize()][config.getYSize()];
        
// 返回非空的Piece集合, 该集合由子类去创建
        List
<Piece> notNullPieces = createPieces(config, pieces);      //
        
// 根据非空Piece对象的集合的大小来取图片
        List
<PieceImage> playImages = ImageUtil.getPlayImages(config.get
        Context(),
            notNullPieces.size());
        
// 所有图片的宽、高都是相同的
        
int imageWidth = playImages.get(0).getImage().getWidth();
        
int imageHeight = playImages.get(0).getImage().getHeight();
        
// 遍历非空的Piece集合
        
for (int i = 0; i < notNullPieces.size(); i++)
        {
            
// 依次获取每个Piece对象
            Piece piece
= notNullPieces.get(i);
            piece.setImage(playImages.get(i));
            
// 计算每个方块左上角的X、Y坐标
            piece.setBeginX(piece.getIndexX()
* imageWidth
                
+ config.getBeginImageX());
            piece.setBeginY(piece.getIndexY()
* imageHeight
                
+ config.getBeginImageY());
            
// 将该方块对象放入方块数组的相应位置处
            pieces[piece.getIndexX()][piece.getIndexY()]
= piece;
        }
        return pieces;
    }
}

  上面的程序中粗体字代码块用于初始化Piece[][]数组,初始化代码负责为各非空的Piece元素的beginX、beginY、image属性赋值,其中beginX、beginY根据该方块在二维数组中的位置动态计算得到。

  上面的程序中①号代码调用了createPieces(config, pieces)抽象方法来创建一个List集合,该抽象方法将会交给其子类去实现,这里是典型的“模板模式”的应用。AbstractBoard抽象基类完全可以根据Piece对象在二维数组中的位置动态地计算它的beginX、beginY,但AbstractBoard不确定Piece[][]数组的哪些元素是非空的。

  由于连连看游戏的初始状态可能有很多种——比如横向分布的方块、竖向分布的方块、矩阵排列的方块、随机分布的方块等,该程序为了考虑以后的扩展性,此处只是采用了模板模式:定义AbstractBoard抽象基类来完成通用的代码,而暂时无法确定、需要子类实现的方法定义成createPieces(GameConf config, Piece[][] pieces)抽象方法。

  上面的程序中还用到了一个ImageUtil工具类,它的作用是自动搜寻/res/drawable-mdpi目录下的图片,并根据需要随机地读取该目录下的图片。后面会详细介绍该工具类的用法。

  下面为该AbstractBoard实现3个子类。

  1.矩阵排列的方块

  矩阵排列的方块会填满二维数组的每个数组元素,只是把四周留空即可,该子类的代码如下。

  程序清单:codes\18\Link\src\org\crazyit\link\board\impl\FullBoard.java

public class FullBoard extends AbstractBoard
{
    @Override
    protected List
<Piece> createPieces(GameConf config,
        Piece[][] pieces)
    {
        
// 创建一个Piece集合, 该集合里面存放初始化游戏时所需的Piece对象
        List
<Piece> notNullPieces = new ArrayList<Piece>();
        
for (int i = 1; i < pieces.length - 1; i++)
        {
            
for (int j = 1; j < pieces[i].length - 1; j++)
            {
                
// 先构造一个Piece对象, 只设置它在Piece[][]数组中的索引值
                
// 所需要的PieceImage由其父类负责设置
                Piece piece
= new Piece(i, j);
                
// 添加到Piece集合中
                notNullPieces.add(piece);
            }
        }
        return notNullPieces;
    }
}

  该子类初始化的游戏界面如图18.7所示。


▲图18.7 矩阵排列的方块

  2.竖向排列的方块

  竖向排列的方块以垂直的空列分隔开,该子类的代码如下。

  程序清单:codes\18\Link\src\org\crazyit\link\board\impl\VerticalBoard. java

public class VerticalBoard extends AbstractBoard
{
    protected List
<Piece> createPieces(GameConf config,
        Piece[][] pieces)
    {
        
// 创建一个Piece集合, 该集合里面存放初始化游戏时所需的Piece对象
        List
<Piece> notNullPieces = new ArrayList<Piece>();
        
for (int i = 0; i < pieces.length; i++)
        {
            
for (int j = 0; j < pieces[i].length; j++)
            {
                
// 加入判断, 符合一定条件才去构造Piece对象, 并加到集合中
                
if (i % 2 == 0)
                {
                    
// 如果x能被2整除, 即单数列不会创建方块
                    
// 先构造一个Piece对象, 只设置它在Piece[][]数组中的索引值
                    
// 所需要的PieceImage由其父类负责设置
                    Piece piece
= new Piece(i, j);
                    
// 添加到Piece集合中
                    notNullPieces.add(piece);
                }
            }
        }
        return notNullPieces;
    }
}

  上面的程序中粗体字代码控制了只设置i % 2 == 0的列,也就是只设置索引为偶数的列,该子类初始化的游戏界面如图18.8所示。


▲图18.8 竖向排列的方块

  3.横向排列的方块

  竖向排列的方块以水平的空行分隔开,该子类的代码如下。

  程序清单:codes\18\Link\src\org\crazyit\link\board\impl\HorizontalBoard.java

public class HorizontalBoard extends AbstractBoard
{
    protected List
<Piece> createPieces(GameConf config,
        Piece[][] pieces)
    {
        
// 创建一个Piece集合, 该集合里面存放初始化游戏时所需的Piece对象
        List
<Piece> notNullPieces = new ArrayList<Piece>();
        
for (int i = 0; i < pieces.length; i++)
        {
            
for (int j = 0; j < pieces[i].length; j++)
            {
                
// 加入判断, 符合一定条件才去构造Piece对象, 并加到集合中
                
if (j % 2 == 0)
                {
                    
// 如果j能被2整除, 即单数行不会创建方块
                    
// 先构造一个Piece对象, 只设置它在Piece[][]数组中的索引值
                    
// 所需要的PieceImage由其父类负责设置
                    Piece piece
= new Piece(i, j);
                    
// 添加到Piece集合中
                    notNullPieces.add(piece);
                }
            }
        }
        return notNullPieces;
    }
}

  上面的程序中粗体字代码控制了只设置j % 2 == 0的行,也就是只设置索引为偶数的行,该子类初始化的游戏界面如图18.9所示。

0
相关文章