4界面设计说明

4.1、程序描述   

主要功能:用于为玩家提供可视化的游戏界面,增加了游戏的可玩性。  

可扩展性:能够适应应用要求的变化和修改,具有灵活的可扩充性。

4.2、功能界面演示

1、生成游戏界面,生成进度条。如下图:

4.21

由此图可知:time 控制游戏的进度

连连看的主界面及变形(refresh)和求助 图标按钮。

2、下图为过关时的效果界面:

4.22 图中为“失败”界面

4.23图中为胜利过关信息界面:

图中有:关闭、重玩、下一关 等按钮选项

如上图4.24 为是否退出游戏提示框

4.3、算法   

 

 

 

  1.  
  2. //定义游戏视图类
  3. public class GameView extends View
  4. //存储素材图片
  5. public int[] p_w_picpathType
  6. //保存所有小格子中的图片
  7. public int[][] grid = new int[row][col];
  8. //初始化加载图片的类型
  9. public void initType() {
  10. //总共要加载的图片
  11. int size = (row-2)*(col-2); //64
  12. //每类图片加载的次数(张数) 要为偶数
  13. int count=size/p_w_picpathType.length; //p_w_picpathType.length=16 即,16种图片
  14. for(int i=0; i<p_w_picpathType.length; i++){
  15. for(int j=0; j<count;j++){
  16. type.add(p_w_picpathType[i]);
  17. }
  18. }
  19. }
  20. //初始化网格的设计
  21. private void initGrid() {
  22. Random r = new Random();
  23. for(int i=0; i<row;i++){
  24. for(int j=0; j<col;j++){
  25. if(i==0 || i==row-1 || j==0 ||j==col-1){
  26. grid[i][j]=0; //四周不设置图片
  27. }else{
  28. int index=r.nextInt(type.size());
  29. grid[i][j]=type.get(index);
  30. type.remove(index);
  31. }
  32. }
  33. }
  34. }
  35. //设置位图的大小
  36. private void ititmBitmap(Context context) {
  37. int typeLength=p_w_picpathType.length;
  38. p_w_picpath=new Bitmap[typeLength];
  39. //重新绘制
  40. for(int i=0;i<typeLength;i++){
  41. //创建一个Bitmap的对象
  42. Bitmap bitmap=Bitmap.createBitmap((int)width, (int)height, Bitmap.Config.ARGB_8888);
  43. //对Bitmap进行绘制
  44. Canvas canvas = new Canvas(bitmap);
  45. Drawable dwr = context.getResources().getDrawable(p_w_picpathType[i]);
  46. dwr.setBounds(1, 1, 30, 30);
  47. dwr.draw(canvas);
  48. p_w_picpath[i]=bitmap;
  49. }
  50. }
  51. //在OnDraw函数中画出框格,每次进行重绘操作
  52. //设置背景颜色:
  53. Paint backGround = new Paint();
  54. backGround.setColor(Color.WHITE);
  55. //画一个矩形
  56. canvas.drawRect(0, 0, getWidth(), getHeight(), backGround);
  57. //设置网格线条的颜色
  58. Paint higth= new Paint();
  59. higth.setColor(Color.BLUE);
  60. //画网格
  61. for(int i=0;i<10;i++){
  62. //画横线、纵线
  63. canvas.drawLine(0, height*i, getWidth(), height*i, higth);
  64. canvas.drawLine(width*i, 0, width*i, getHeight(), higth);
  65. }
  66. //画p_w_picpath图片
  67. boolean test=true; //检测图片是否肖完
  68. for(int i=0;i<row;i++){
  69. for(int j=0;j<col;j++){
  70. if(grid[i][j]!=0){
  71. canvas.drawBitmap(p_w_picpath[Arrays.binarySearch(p_w_picpathType, grid[i][j])],
  72. i*width, j*height, null);
  73. test=false; ////还有图片,说明未赢
  74. }
  75. }
  76. }

5主要显示及算法设计说明

5.1、程序描述   

主要功能:完成图片的消除功能,消除时画线功能,重新排列功能。  

可扩展性:能够适应应用要求的变化和修改,具有灵活的可扩充性。

 

5.2显示界面

 

 

5.3、算法   

5.3.1、图片的连接判断

对于选中的两个方块的销毁,们必须符合下面3个条件:

1选中的两个方块图案相同。

2选中的两个方块之间没有障碍物阻碍的情况下,可以用若干个垂直的直线线段连接起来。

3这些将它们连接起来的直线线段的折点不超过两个(连接线由x轴和y轴的平行线组成)。 

我们进行分情况分析:

无拐点、一个拐点、两个拐点,设置flag进行标记这三种情况。

以下是相关代码:

 

 

 

  1. //获得一个点可向上下左右走的范围
  2. public int[] extend(Point a){
  3. int i;
  4. int[] aLoc = new int[4];
  5. //向上
  6. for(i=a.y-1;i>=0 && grid[a.x][i]==0;i--){
  7. }
  8. aLoc[0]=i+1;
  9. //向下
  10. for(i=a.y+1;i<row && grid[a.x][i]==0;i++){
  11. }
  12. aLoc[1]=i-1;
  13. //向左
  14. for(i=a.x-1;i>=0 && grid[i][a.y]==0;i--){
  15. }
  16. aLoc[2]=i+1;
  17. //向右
  18. for(i=a.x+1;i<col && grid[i][a.y]==0;i++){
  19. }
  20. aLoc[3]=i-1;
  21. return aLoc;
  22. }
  23. //用于判断水平方向是否连通
  24. private boolean horizon(Point a, Point b){
  25. if(a.x == b.x && a.y == b.y) //如果点击的是同一个图案,直接返回false
  26. return false;
  27. int x_start = a.x <= b.x ? a.x : b.x;
  28. int x_end = a.x <= b.x ? b.x : a.x;
  29. for(int x = x_start + 1; x < x_end; x++)//只要一个不是-1,直接返回false
  30. if(grid[x][a.y] != 0){
  31. return false;
  32. }
  33. return true;
  34. }
  35. //用于判断垂直方向是否连通
  36. private boolean vertical(Point a, Point b){
  37. if(a.x == b.x && a.y == b.y)
  38. return false;
  39. int y_start = a.y <= b.y ? a.y : b.y;
  40. int y_end = a.y <= b.y ? b.y : a.y;
  41. for(int y = y_start + 1; y < y_end; y++)
  42. if(grid[a.x][y] != 0)
  43. return false;
  44. return true;
  45. }
  46.  //只有一个拐点的情况
  47. private boolean oneCorner(Point a, Point b){
  48. Point c = new Point(a.x, b.y);
  49. Point d = new Point(b.x, a.y);
  50. if(grid[c.x][c.y] == 0){
  51. boolean method1 = horizon(b, c) && vertical(a, c);
  52. if(method1){
  53. corner=new Point(c.x, c.y);
  54. }
  55. return method1;
  56. }
  57. if(grid[d.x][d.y] == 0){
  58. boolean method2 = horizon(a, d) && vertical(b, d);
  59. if(method2){
  60. corner=new Point(d.x, d.y);
  61. }
  62. return method2;
  63. }else{
  64. return false;
  65. }
  66. }
  67. //有两个拐点的情况
  68. private boolean twoCorner(Point a, Point b)
  69. {
  70. ll = scan(a, b);
  71. if(ll.isEmpty())
  72. return false;
  73. for(int index = 0; index < ll.size(); index++){
  74. Line line = (Line)ll.get(index);
  75. if(line.direct == 1){
  76. if(horizon(a, line.a) && horizon(b, line.b)){
  77. corner=new Point(line.a);
  78. corner2=new Point(line.b);
  79. return true;
  80. }
  81. } else{
  82. if(vertical(a, line.a) && vertical(b, line.b)){
  83. corner=new Point(line.a);
  84. corner2=new Point(line.b);
  85. return true;
  86. }
  87. }
  88. }
  89. return false;
  90. }
  91. //上面设计了一个类来判断两个拐点的情况
  92. //类的定义,构造函数如下
  93. class Line{
  94. public Point a;
  95. public Point b;
  96. public int direct;
  97. public Line(){
  98. a = new Point();
  99. b = new Point();
  100. }
  101. public Line(int direct, Point a, Point b){
  102. this.direct = direct;
  103. this.a = a;
  104. this.b = b;
  105. }
  106. }
  107. //对两个拐点的情况进行扫描,将扫描线放入Line类型的数组中
  108. private LinkedList scan(Point a, Point b){
  109. ll = new LinkedList<Line>();
  110. //Point c = new Point(a.x, b.y);
  111. //Point d = new Point(b.x, a.y);
  112. for(int y = a.y; y >= 0; y--)
  113. if(grid[a.x][y] == 0 && grid[b.x][y] == 0 && horizon(new Point(a.x, y), new Point(b.x, y)))
  114. ll.add(new Line(0, new Point(a.x, y), new Point(b.x, y)));
  115. for(int y = a.y; y < row; y++)
  116. if(grid[a.x][y] == 0 && grid[b.x][y] == 0 && horizon(new Point(a.x, y), new Point(b.x, y)))
  117. ll.add(new Line(0, new Point(a.x, y), new Point(b.x, y)));
  118. for(int x = a.x; x >= 0; x--)
  119. if(grid[x][a.y] == 0 && grid[x][b.y] == 0 && vertical(new Point(x, a.y), new Point(x, b.y)))
  120. ll.add(new Line(1, new Point(x, a.y), new Point(x, b.y)));
  121. for(int x = a.x; x < col; x++)
  122. if(grid[x][a.y] == 0 && grid[x][b.y] == 0 && vertical(new Point(x, a.y), new Point(x, b.y)))
  123. ll.add(new Line(1, new Point(x, a.y), new Point(x, b.y)));
  124. return ll;
  125. }
  126. //最后做总体判断,flag表示拐点的数目
  127. public boolean checkLink(Point a,Point b){
  128. if(grid[a.x][a.y] != grid[b.x][b.y])//如果图案不同,直接为false
  129. return false;
  130. if(a.y == b.y && horizon(a, b)){
  131. flag=0;
  132. return true;
  133. }
  134. if(a.x == b.x && vertical(a, b)){
  135. flag=0;
  136. return true;
  137. }
  138. if(oneCorner(a, b)){
  139. flag=1;
  140. return true;
  141. }
  142. if(twoCorner(a, b)){
  143. flag=2;
  144. return true;
  145. }else{
  146. return false;
  147. }
  148. }

5.3.2、图片消除的画线

根据flag的值分情况分析:

Flag=0时,从起点到终点画一条线即可

Flag=1时,从起点到拐点,从拐点到终点画两条线

Flag=2时,从起点到拐点,从拐点到拐点,从拐点到终点画三条线。

在做连接判断时就将路径保存下来。

//画线操作写在OnDraw函数中,cornercorner2保存拐点坐标

//每次都sleep(50)后重绘

 

 

 

  1. switch(flag){
  2. case 0:
  3. canvas.drawLine(width*(former.x + 0.5f), height*(former.y+0.5f),
  4. width*(current.x+ 0.5f), height*(current.y + 0.5f), p);
  5. flag=-1;
  6. SystemClock.sleep(50);
  7. invalidate();
  8. break;
  9. case 1:
  10. canvas.drawLine(width*(former.x + 0.5f), height*(former.y+0.5f),
  11. width*(corner.x+ 0.5f), height*(corner.y + 0.5f), p);
  12. canvas.drawLine(width*(corner.x + 0.5f), height*(corner.y+0.5f),
  13. width*(current.x+ 0.5f), height*(current.y + 0.5f), p);
  14. flag=-1;
  15. SystemClock.sleep(50);
  16. invalidate();
  17. break;
  18. case 2:
  19. canvas.drawLine(width*(former.x + 0.5f), height*(former.y+0.5f),
  20. width*(corner.x + 0.5f), height*(corner.y + 0.5f), p);
  21. canvas.drawLine(width*(corner.x + 0.5f), height*(corner.y+0.5f),
  22. width*(corner2.x+ 0.5f), height*(corner2.y + 0.5f), p);
  23. canvas.drawLine(width*(corner2.x + 0.5f), height*(corner2.y+0.5f),
  24. width*(current.x+ 0.5f), height*(current.y + 0.5f), p);
  25. flag=-1;
  26. SystemClock.sleep(50);
  27. invalidate();
  28. break;
  29. default:
  30. break;
  31. }

5.3.3、重新排列

隔一段时间后,将原有的排列随机打乱,进行重新排列

//对当前界面中的图片进行重新排列

  1. public void reDraw(){
  2. Random r = new Random();
  3. type= new ArrayList<Integer>();
  4. for(int i=0;i<row; i++){
  5. for(int j=0; j <col;j++){
  6. if(grid[i][j]!=0){
  7. type.add(grid[i][j]);
  8. }
  9. }
  10. }
  11. for(int i=0;i<row; i++){
  12. for(int j=0; j <col;j++){
  13. if(grid[i][j]!=0){
  14. int index = r.nextInt(type.size());
  15. grid[i][j] = type.get(index);
  16. type.remove(index);
  17. }
  18. }
  19. }
  20. former_i=former_j=0;
  21. former.x=former.y=0;
  22. invalidate();
  23. }
  24. //重新排列界面中的图片
  25. private void reStart() {
  26. GameActivity.refresh=true;
  27. initType();
  28. initGrid();
  29. invalidate();
  30. }