博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android开发学习之路——连连看之游戏界面(一)
阅读量:4682 次
发布时间:2019-06-09

本文共 8693 字,大约阅读时间需要 28 分钟。

  学习了李刚老师的《疯狂Android讲义》,其中18章是介绍连连看的设计。从而学会了如何设计一个android小程序。

  这个游戏,难度适中,适合初学者学习。

  开发连连看游戏,除了需要理解游戏界面的数据模型外,程序开发者还需要判断两个方块是否可以相连,为了判断两个方块是否可以相连,开发者需要对两个方块所处的位置进行分类,然后针对不同的情况采用不同的判断算法进行判断,这需要开发者采用条理化的思维方式进行分析、处理,这也是这小程序需要重点掌握的能力。

  开发游戏界面

  连连看的游戏界面分为两个区域:

  ·游戏主界面区。

  ·控制按钮与数据显示区。

 

(一)开发界面布局

  本程序将会使用一个RelativeLayout作为整体的界面布局元素,界面布局的上面是一个自定义组件,下面是一个水平排列的LinearLayout。

  布局文件代码如下:res\layout\main.xml

1 
2
7
8
12
13 android:layout_width="fill_parent"14 android:layout_height="fill_parent"15 android:orientation="horizontal"16 android:layout_marginTop="380px"17 android:background="#le72bb"18 android:gravity="center">19
20
25
26
34 35

 

  这个界面布局很简单,指定按钮的背景色时使用了@drawable/button_selector,这是一个在res\drawable目录下配置的StateListDrawable对象。

  配置文件代码如下:res\drawable-mdpi\button_selector.xml

1 
2
3
4
6
7
9

 

(二) 开发游戏界面组件

    本游戏的界面组件采用了一个自定义View:GameView,它从View基类派出而出,这个自定义View的功能就是根据游戏状态来绘制游戏界面的全部方块。为了开发这个GameView,本程序还提供了一个Piece类,一个Piece对象代表游戏界面上的一个方块,它除了封装方块上的图片之外,还需要封装该方块代表二维数组中的哪个元素;也需要封装它的左上角在游戏界面中X、Y坐标。方块左上角的X、Y坐标可决定它的绘制位置,GameView根据这两个坐标绘制全部方块即可。

Piece类代码如下:src\org\crazyit\link\view\Piece.java

1 public class Piece 2 { 3     // 保存方块对象的所对应的图片 4     private PieceImage image; 5     // 该方块的左上角的x坐标 6     private int beginX; 7     // 该方块的左上角的y座标 8     private int beginY; 9     // 该对象在Piece[][]数组中第一维的索引值10     private int indexX;11     // 该对象在Piece[][]数组中第二维的索引值12     private int indexY;13 14     // 只设置该Piece对象在数组中的索引值15     public Piece(int indexX , int indexY)16     {17         this.indexX = indexX;18         this.indexY = indexY;19     }20 21     public int getBeginX()22     {23         return beginX;24     }25 26     public void setBeginX(int beginX)27     {28         this.beginX = beginX;29     }30 31     public int getBeginY()32     {33         return beginY;34     }35 36     public void setBeginY(int beginY)37     {38         this.beginY = beginY;39     }40 41     public int getIndexX()42     {43         return indexX;44     }45 46     public void setIndexX(int indexX)47     {48         this.indexX = indexX;49     }50 51     public int getIndexY()52     {53         return indexY;54     }55 56     public void setIndexY(int indexY)57     {58         this.indexY = indexY;59     }60     61 62     public PieceImage getImage()63     {64         return image;65     }66 67     public void setImage(PieceImage image)68     {69         this.image = image;70     }71 72     // 获取该Piece的中心73     public Point getCenter()74     {75         return new Point(getImage().getImage().getWidth() / 276             + getBeginX(), getBeginY()77             + getImage().getImage().getHeight() / 2);78     }    79     // 判断两个Piece上的图片是否相同80     public boolean isSameImage(Piece other)81     {82         if (image == null)83         {84             if (other.image != null)85                 return false;86         }87         // 只要Piece封装图片ID相同,即可认为两个Piece相等。88         return image.getImageId() == other.image.getImageId();89     }90 }

    上面的Piece类中封装的PieceImage代表了该方块上的图片,但此处并未直接使用Bitmap对象来代表方块上的图片——因为我们需要使用PieceImage来封装两个信息:

    ·Bitmap对象。

    ·图片资源的ID。

    其中Bitmap对象用于在游戏界面上绘制方块,而图片资源的ID则代表该Piece对象的标识,用于判断两个Piece上的图片是否相同。如前面代码所示。

    PieceImage类的代码如下:src\org\crazyit\link\view\PieceImage.java

1 public class PieceImage 2 { 3     private Bitmap image; 4     private int imageId; 5     // 有参数的构造器 6     public PieceImage(Bitmap image, int imageId) 7     { 8         super(); 9         this.image = image;10         this.imageId = imageId;11     }12     public Bitmap getImage()13     {14         return image;15     }16     public void setImage(Bitmap image)17     {18         this.image = image;19     }20     public int getImageId()21     {22         return imageId;23     }24     public void setImageId(int imageId)25     {26         this.imageId = imageId;27     }28 }

    GameView主要就是根据游戏的状态数据来绘制界面上的方块,GameView继承了View组件,重写了View组件上onDraw(Canvas canvas)方法,重写该方法主要就是绘制游戏里剩余的方块;除此之外,它还会负责绘制连接方块的连接线。

    GameView的代码如下:src\org\crazyit\link\view\GameView.java

1 public class GameView extends View  2 {  3     // 游戏逻辑的实现类  4     private GameService gameService;  5     // 保存当前已经被选中的方块  6     private Piece selectedPiece;  7     // 连接信息对象  8     private LinkInfo linkInfo;  9     private Paint paint; 10     // 选中标识的图片对象 11     private Bitmap selectImage; 12  13     public GameView(Context context, AttributeSet attrs) 14     { 15         super(context, attrs); 16         this.paint = new Paint(); 17         // 设置连接线的颜色 18         this.paint.setColor(Color.RED); 19         // 设置连接线的粗细 20         this.paint.setStrokeWidth(3); 21         this.selectImage = ImageUtil.getSelectImage(context); 22     } 23  24     public void setLinkInfo(LinkInfo linkInfo) 25     { 26         this.linkInfo = linkInfo; 27     } 28  29     public void setGameService(GameService gameService) 30     { 31         this.gameService = gameService; 32     } 33  34     @Override 35     protected void onDraw(Canvas canvas) 36     { 37         super.onDraw(canvas); 38         if (this.gameService == null) 39             return; 40         Piece[][] pieces = gameService.getPieces(); 41         if (pieces != null) 42         { 43             // 遍历pieces二维数组 44             for (int i = 0; i < pieces.length; i++) 45             { 46                 for (int j = 0; j < pieces[i].length; j++) 47                 { 48                     // 如果二维数组中该元素不为空(即有方块),将这个方块的图片画出来 49                     if (pieces[i][j] != null) 50                     { 51                         // 得到这个Piece对象 52                         Piece piece = pieces[i][j]; 53                         // 根据方块左上角X、Y座标绘制方块 54                         canvas.drawBitmap(piece.getImage().getImage(), 55                             piece.getBeginX(), piece.getBeginY(), null); 56                     } 57                 } 58             } 59         } 60         // 如果当前对象中有linkInfo对象, 即连接信息 61         if (this.linkInfo != null) 62         { 63             // 绘制连接线 64             drawLine(this.linkInfo, canvas); 65             // 处理完后清空linkInfo对象 66             this.linkInfo = null; 67         } 68         // 画选中标识的图片 69         if (this.selectedPiece != null) 70         { 71             canvas.drawBitmap(this.selectImage, this.selectedPiece.getBeginX(), 72                 this.selectedPiece.getBeginY(), null); 73         } 74     } 75  76     // 根据LinkInfo绘制连接线的方法。 77     private void drawLine(LinkInfo linkInfo, Canvas canvas) 78     { 79         // 获取LinkInfo中封装的所有连接点 80         List
points = linkInfo.getLinkPoints(); 81 // 依次遍历linkInfo中的每个连接点 82 for (int i = 0; i < points.size() - 1; i++) 83 { 84 // 获取当前连接点与下一个连接点 85 Point currentPoint = points.get(i); 86 Point nextPoint = points.get(i + 1); 87 // 绘制连线 88 canvas.drawLine(currentPoint.x , currentPoint.y, 89 nextPoint.x, nextPoint.y, this.paint); 90 } 91 } 92 93 // 设置当前选中方块的方法 94 public void setSelectedPiece(Piece piece) 95 { 96 this.selectedPiece = piece; 97 } 98 99 // 开始游戏方法100 public void startGame()101 {102 this.gameService.start();103 this.postInvalidate();104 }105 }

    GameView根据游戏的状态数据来绘制界面中的所有方块,根据LinkInfo来绘制两个方块间的连接线。上面的代码中定义了GameService对象,调用了GameService的getPiece()方法来获取游戏中剩余的方块,GameService是游戏的业务逻辑实现类。后面的篇幅会介绍()

 

(三)处理方块之间的连接线

    LinkInfo是一个非常简单的工具类,它用于封装两个方块之间的连接信息——其实就是封装一个List,List里保存了连接线需要经过的点。在实现LinkInfo对象之前,先分析两个方块可以相连的情形。两个方块之间最多只能用3条线段相连,也就是说最多只能有2个“拐点”,加上两个方块的中心,方块的连接信息最多只需要4个连接点。考虑到LinkInfo最多需要封装4个连接点,最少需要封装2个连接点,因此定义LinkInfo类的代码如下:src\org\crazyit\link\object\Linkinfo.java

1 public class LinkInfo 2 { 3     // 创建一个集合用于保存连接点 4     private List
points = new ArrayList
(); 5 6 // 提供第一个构造器, 表示两个Point可以直接相连, 没有转折点 7 public LinkInfo(Point p1, Point p2) 8 { 9 // 加到集合中去10 points.add(p1);11 points.add(p2);12 }13 14 // 提供第二个构造器, 表示三个Point可以相连, p2是p1与p3之间的转折点15 public LinkInfo(Point p1, Point p2, Point p3)16 {17 points.add(p1);18 points.add(p2);19 points.add(p3);20 }21 22 // 提供第三个构造器, 表示四个Point可以相连, p2, p3是p1与p4的转折点23 public LinkInfo(Point p1, Point p2, Point p3, Point p4)24 {25 points.add(p1);26 points.add(p2);27 points.add(p3);28 points.add(p4);29 }30 31 // 返回连接集合32 public List
getLinkPoints()33 {34 return points;35 }36 }

    LinkInfo中所用的Point代表一个点,程序直接使用了android.graphics.Point类,每个Point封装了该点的X,Y坐标。

 

具体实现步骤连接:

转载于:https://www.cnblogs.com/weilongfu/p/7366520.html

你可能感兴趣的文章
java有date类型吗_关于java中date类型的问题
查看>>
java中svg图片怎么用_svg如何使用
查看>>
java dart 官司_From Java to Dart
查看>>
java ftp 读取excel_从Excel文件读取数据表
查看>>
oracle 有哪些字典表,oracle 常用字典表
查看>>
linux c多进程多线程,linux下的C\C++多进程多线程编程简易例子
查看>>
linux 命令 考试,linux常用命令总结-第一次考试
查看>>
linux动态库编译多重依赖,Linux动态库多重依赖
查看>>
linux网卡缓冲区设置,【Linux】tcp缓冲区大小的默认值、最大值
查看>>
opus编译linux,Linux 下源码编译FFMEG
查看>>
linux 运行real basic,REALbasic 快速入门.pdf
查看>>
linux启动tomcat不停的触发gc,tomcat启动时就频繁gc和full gc
查看>>
linux uart串口驱动,X-017-KERNEL-串口驱动开发之uart driver框架
查看>>
关于sqoop导入数据的时候添加--split-by配置项对sqoop的导入速度的影响。
查看>>
nginx配置
查看>>
2014-11-9------- 设有一数据库,包括四个表:学生表(Student)、课程表(Course)、成绩表(Score)以及教师信息表(Teacher)。...
查看>>
python 魔法方法补充(__setattr__,__getattr__,__getattribute__)
查看>>
NOIP 2010 关押罪犯
查看>>
CentOS7.5删除旧的内核
查看>>
Java常用的非受检异常
查看>>