疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

android开发—连连看开发技巧(2)


 

android游戏开发教程之连连看(2)

2.2 开发游戏界面组件

       本游戏的界面组件采用了一个自定义View:GameView,它从View基类派生而出,这个自定义View的功能就是根据游戏状态来绘制游戏界面上的全部方块。
       为了开发这个GameView,本程序还提供了一个Piece类,一个Piece对象代表游戏界面上的一个方块,它除了封装方块上的图片之外,还需要封装该方块代表二维数组中的哪个元素;也需要封装它的左上角在游戏界面中X、Y座标。图18.4示意了方块左上角的X、Y座标的作用:
方块的左上角X、Y座标
图18.4 方块的左上角
方块左上角的X、Y座标可决定它的绘制位置,GameView根据这两个座标值绘制全部方块即可。下面是该程序中Piece类的代码:
程序清单:codes18LinksrcorgcrazyitlinkviewPiece.java
public class Piece
{
// 保存方块对象的所对应的图片
private PieceImage image;
// 该方块的左上角的x座标
private int beginX;
// 该方块的左上角的y座标
private int beginY;
// 该对象在Piece[][]数组中第一维的索引值
private int indexX;
// 该对象在Piece[][]数组中第二维的索引值
private int indexY;
// 只设置该Piece对象在棋盘数组中的位置
public Piece(int indexX , int indexY)
{
this.indexX = indexX;
this.indexY = indexY;
}
public int getBeginX()
{
return beginX;
}
public void setBeginX(int beginX)
{
this.beginX = beginX;
}
// 下面省略了各属性的setter和getter方法
...
// 判断两个Piece上的图片是否相同
public boolean isSameImage(Piece other)
{
if (image == null)
{
if (other.image != null)
return false;
}
// 只要Piece封装图片ID相同,即可认为两个Piece相等。
return image.getImageId() == other.image.getImageId();
}
}

 

上面Piece类中封装的PieceImage代表了该方块上的图片,但此处并未直接使用Bitmap对象来代表方块上的图片——因为我们需要使用PieceImage来封装两个信息:
   Bitmap对象。
   图片资源的ID。
其中Bitmap对象用于在游戏界面上绘制方块;而图片资源的ID则代表了该Piece对象的标识,当两个Piece所封装的图片资源的ID相等时,即可认为这两个Piece上的图片相同。如上程序中粗体字代码所示。
下面是PieceImage类的代码:
程序清单:codes18LinksrcorgcrazyitlinkviewPieceImage.java
public class PieceImage
{
private Bitmap image;
private int imageId;
// 有参数的构造器
public PieceImage(Bitmap image, int imageId)
{
super();
this.image = image;
this.imageId = imageId;
}
// 省略了各属性的setter和getter方法
...
}
        GameView主要就是根据游戏的状态数据来绘制界面上的方块,GameView继承了View组件,重写了View组件上onDraw(Canvas canvas)方法,重写该方法主要就是绘制游戏里剩余的方块;除此之外,它还会负责绘制连接方块的连接线。
GamaView的代码如下:
程序清单:codes18LinksrcorgcrazyitlinkviewGameView.java
public class GameView extends View
{
// 游戏逻辑的实现类
private GameService gameService;//①
// 保存当前已经被选中的方块
private Piece selectedPiece;
// 连接信息对象
private LinkInfo linkInfo;
private Paint paint;
// 选中标识的图片对象
private Bitmap selectImage;
public GameView(Context context, AttributeSet attrs)
{
super(context, attrs);
this.paint = new Paint();
// 设置连接线的颜色
this.paint.setColor(Color.RED);
// 设置连接线的粗细
this.paint.setStrokeWidth(3);
this.selectImage = ImageUtil.getSelectImage(context);
}
public void setLinkInfo(LinkInfo linkInfo)
{
this.linkInfo = linkInfo;
}
public void setGameService(GameService gameService)
{
this.gameService = gameService;
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if (this.gameService == null)
return;
Piece[][] pieces = gameService.getPieces();//②
if (pieces != null)
{
// 遍历pieces二维数组
for (int i = 0; i < pieces.length; i++)
{
for (int j = 0; j < pieces[i].length; j++)
{
// 如果二维数组中该元素不为空(即有方块),将这个方块的图片画出来
if (pieces[i][j] != null)
{
// 得到这个Piece对象
Piece piece = pieces[i][j];
// 根据方块左上角X、Y座标绘制方块
canvas.drawBitmap(piece.getImage().getImage(),
piece.getBeginX(), piece.getBeginY(), null);
}
}
}
}
// 如果当前对象中有linkInfo对象, 即连接信息
if (this.linkInfo != null)
{
// 绘制连接线
drawLine(this.linkInfo, canvas);
// 处理完后清空linkInfo对象
this.linkInfo = null;
}
// 画选中标识的图片
if (this.selectedPiece != null)
{
canvas.drawBitmap(this.selectImage, this.selectedPiece.getBeginX(),
this.selectedPiece.getBeginY(), null);
}
}
// 根据LinkInfo绘制连接线的方法。
private void drawLine(LinkInfo linkInfo, Canvas canvas)
{
// 获取LinkInfo中封装的所有连接点
List points = linkInfo.getLinkPoints();
// 依次遍历linkInfo中的每个连接点
for (int i = 0; i < points.size() - 1; i++)
{
// 获取当前连接点与下一个连接点
Point currentPoint = points.get(i);
Point nextPoint = points.get(i + 1);
// 绘制连线
canvas.drawLine(currentPoint.x, currentPoint.y,
nextPoint.x, nextPoint.y, this.paint);
}
}
// 设置当前选中方块的方法
public void setSelectedPiece(Piece piece)
{
this.selectedPiece = piece;
}
// 开始游戏方法
public void startGame()
{
this.gameService.start();
this.postInvalidate();
}
}

      上面GameView中第一段粗体字代码用于根据游戏的状态数据来绘制界面中的所有方块,第二段粗体字代码则用于根据LinkInfo来绘制两个方块之间的连接线。

      上面程序中①号代码处定义了GameService对象,程序②号代码则调用了GameService的getPieces()方法来获取游戏中剩余的方块,GameService是游戏的业务逻辑实现类。后面会详细介绍该类的实现,此处暂不讲解。(未完.摘自[疯狂Android讲义].)