国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現瘋狂連連看游戲之開發游戲界面(二)

2019-10-23 18:32:52
字體:
來源:轉載
供稿:網友

連連看的游戲界面十分簡單,大致可以分為兩個區域:
--游戲主界面區
--控制按鈕和數據顯示區

1、開發界面布局

本程序使用一個RelativeLayout作為整體的界面布局元素,界面布局上面是一個自定義組件,下面是一個水平排列的LinearLayout。

下面是本程序的布局文件:/res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="fill_parent" android:layout_height="fill_parent"  android:background="@drawable/room">  <!-- 游戲主界面的自定義組件 -->  <cn.oyp.link.view.GameView  android:id="@+id/gameView" android:layout_width="fill_parent"  android:layout_height="fill_parent" />  <!-- 水平排列的LinearLayout -->  <LinearLayout android:layout_width="fill_parent"  android:layout_height="fill_parent" android:orientation="horizontal"  android:layout_marginTop="380px" android:background="#1e72bb"  android:gravity="center">  <!-- 控制游戲開始的按鈕,該按鈕的背景圖片可以根據按鈕的狀態改變 -->  <Button android:id="@+id/startButton" android:layout_width="wrap_content"  android:layout_height="wrap_content" android:background="@drawable/button_selector" />  <!-- 顯示游戲剩余時間的文本框 -->  <TextView android:id="@+id/timeText" android:layout_width="wrap_content"  android:layout_height="wrap_content" android:gravity="center"  android:textSize="20dip" android:width="150px" android:textColor="#ff9" />  </LinearLayout> </RelativeLayout> 

其中指定按鈕背景色使用了@drawable/button_selector,這是在res/drawable目錄下配置的StateListDrawable對象,配置文件代碼如下:res/drawable/button_selector.xml

<?xml version="1.0" encoding="UTF-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android">  <!-- 指定按鈕按下時的圖片 -->  <item android:state_pressed="true" android:drawable="@drawable/start_down" />  <!-- 指定按鈕松開時的圖片 -->  <item android:state_pressed="false" android:drawable="@drawable/start" /> </selector> 

2、開發游戲界面組件

本游戲采用了一個自定義View:GameView,它從View的基類派生出來,這個自定義View的功能就是根據游戲狀態來描繪游戲界面上的全部方塊。

為了開發這個GameView,本程序還提供了一個Piece類,一個Piece對象代表游戲界面中的一個方塊,它除了封裝了方塊上的圖片之外,還需要封裝該方塊代表二維數組中的那個元素,也需要封裝它的左上角在游戲界面中的X、Y坐標,這X、Y坐標可以決定方塊的繪制位置,GameView根據這兩個坐標值繪制全部方塊即可。

下面是Piece類的代碼:cn/oyp/link/view/Piece.java

package cn.oyp.link.view;  import android.graphics.Point;  /**  * 連連看游戲中的方塊對象 <br/>  * <br/>  * 關于本代碼介紹可以參考一下博客: 歐陽鵬的CSDN博客</a> <br/>  */ public class Piece {  /**  * 保存方塊對象的所對應的圖片  */  private PieceImage pieceImage;  /**  * 該方塊的左上角的x坐標  */  private int beginX;  /**  * 該方塊的左上角的y座標  */  private int beginY;  /**  * 該對象在Piece[][]數組中第一維的索引值  */  private int indexX;  /**  * 該對象在Piece[][]數組中第二維的索引值  */  private int indexY;   /**  * 設置該Piece對象在數組中的索引值  *  * @param indexX  * 該方塊的左上角的x坐標  * @param indexY  * 該方塊的左上角的y座標  */  public Piece(int indexX, int indexY) {  this.indexX = indexX;  this.indexY = indexY;  }   /**  * 獲取該Piece的中心位置  *  * @return 中心點的坐標對象Point  */  public Point getCenter() {  return new Point(getBeginX() + getPieceImage().getImage().getWidth()  / 2, getBeginY() + getPieceImage().getImage().getHeight() / 2);  }   /**  * 判斷兩個Piece上的圖片是否相同  *  * @param otherPieceImage  * 另外的一個Piece對象  * @return 是否相同  */  public boolean isSameImage(Piece otherPieceImage) {  if (pieceImage == null) {  if (otherPieceImage.pieceImage != null)  return false;  }  // 當兩個Piece封裝圖片資源ID相同時,即可認為這兩個Piece上的圖片相同。  return pieceImage.getImageId() == otherPieceImage.pieceImage  .getImageId();  }   /**  * @return 該方塊的左上角的X坐標  */  public int getBeginX() {  return beginX;  }   /**  * 設置該方塊的左上角的X坐標  *  * @param beginX  */  public void setBeginX(int beginX) {  this.beginX = beginX;  }   /**  * @return 該方塊的左上角的Y座標  */  public int getBeginY() {  return beginY;  }   /**  * 設置該方塊的左上角的Y坐標  *  * @param beginY  */  public void setBeginY(int beginY) {  this.beginY = beginY;  }   /**  * @return 該對象在Piece[][]數組中第一維的索引值  */  public int getIndexX() {  return indexX;  }   /**  * 設置該對象在Piece[][]數組中第一維的索引值  *  * @param indexX  */  public void setIndexX(int indexX) {  this.indexX = indexX;  }   /**  * @return 該對象在Piece[][]數組中第二維的索引值  */  public int getIndexY() {  return indexY;  }   /**  * 設置該對象在Piece[][]數組中第二維的索引值  *  * @param indexY  */  public void setIndexY(int indexY) {  this.indexY = indexY;  }   /**  * @return 保存方塊對象的所對應的圖片  */  public PieceImage getPieceImage() {  return pieceImage;  }   /**  * 設置保存方塊對象的所對應的圖片  *  * @param pieceImage  */  public void setPieceImage(PieceImage pieceImage) {  this.pieceImage = pieceImage;  } } 

上面Piece類中封裝的PieceImage代表了該方塊上的圖片,它封裝了兩個信息:Bitmap對象和圖片資源ID。其中Bitmap對象用于在游戲界面上繪制方塊;而圖片資源ID則表示該Piece對象的標識,當兩個Piece所封裝的圖片資源ID相等時,即可認為這兩個Piece上的圖片相同。

下面是PieceImage的代碼:cn/oyp/link/view/PieceImage.java

package cn.oyp.link.view;  import android.graphics.Bitmap;  /**  * 封裝圖片ID與圖片本身的工具類 <br/>  * <br/>  * 關于本代碼介紹可以參考一下博客: 歐陽鵬的CSDN博客 <br/>  */ public class PieceImage {  /**  * 圖片  */  private Bitmap image;  /**  * 圖片資源ID  */  private int imageId;   /**  * 構造函數  *  * @param image  * 圖片  * @param imageId  * 圖片ID  */  public PieceImage(Bitmap image, int imageId) {  super();  this.image = image;  this.imageId = imageId;  }   /**  * @return 圖片  */  public Bitmap getImage() {  return image;  }   /**  * 設置圖片  *  * @param image  */  public void setImage(Bitmap image) {  this.image = image;  }   /**  * @return 圖片ID  */  public int getImageId() {  return imageId;  }   /**  * 設置圖片ID  *  * @param imageId  */  public void setImageId(int imageId) {  this.imageId = imageId;  } } 

GameView主要就是根據游戲的狀態來繪制界面上的方塊,GameView繼承了View組件,重寫了View組件上的onDraw(Canvas canvas)方法,重寫該方法主要就是繪制游戲里剩余的方塊,除此之外,它還復雜繪制連接方塊的連接線。GameView的代碼如下:cn/oyp/link/view/GameView.java

package cn.oyp.link.view;  import java.util.List;  import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.util.AttributeSet; import android.view.View; import cn.oyp.link.board.GameService; import cn.oyp.link.utils.ImageUtil; import cn.oyp.link.utils.LinkInfo;  /**  * 連連看游戲中的游戲主界面 <br/>  * <br/>  * 關于本代碼介紹可以參考一下博客:歐陽鵬的CSDN博客</a> <br/>  */ public class GameView extends View {  /**  * 游戲邏輯的實現類  */  private GameService gameService;  /**  * 保存當前已經被選中的方塊  */  private Piece selectedPiece;  /**  * 連接信息對象  */  private LinkInfo linkInfo;  /**  * 畫筆Paint  */  private Paint paint;  /**  * 選中標識的圖片對象  */  private Bitmap selectImage;   /**  * 構造方法  *  * @param context  * @param attrs  */  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);  }   /**  * 設置連接信息對象  *  * @param linkInfo  */  public void setLinkInfo(LinkInfo linkInfo) {  this.linkInfo = linkInfo;  }   /**  * 設置當前選中方塊  *  * @param piece  */  public void setSelectedPiece(Piece piece) {  this.selectedPiece = piece;  }   /**  * 設置游戲邏輯的實現類  *  * @param gameService  */  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.getPieceImage().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繪制連接線的方法。  *  * @param linkInfo  * 連接信息對象  * @param canvas  * 畫布  */  private void drawLine(LinkInfo linkInfo, Canvas canvas) {  // 獲取LinkInfo中封裝的所有連接點  List<Point> 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 startGame() {  this.gameService.start();  this.postInvalidate();  } } 

LinkInfo是一個非常簡單的工具類,它用于封裝兩個方塊之間的連接信息:其實就是封裝了一個List,List里面保存了連接線所需要經過的點。兩個方塊之間最多只能用3條線段相連,也就是說最多只能2個拐點,加上這兩個方塊的中心,方塊的連接信息最多只需要4個連接點。因此,LinkInfo最多需要封裝4個連接點,最少需要封裝2個連接點。
下面是LinkInfo的代碼:cn/oyp/link/utils.LinkInfo.java

package cn.oyp.link.utils;  import java.util.List; import java.util.ArrayList;  import android.graphics.Point;  /**  * 連接信息類<br/>  * <br/>  * 關于本代碼介紹可以參考一下博客: 歐陽鵬的CSDN博客</a> <br/>  */ public class LinkInfo {  /**  * 創建一個集合用于保存連接點  */  private List<Point> points = new ArrayList<Point>();   /**  * 提供第一個構造器, 表示兩個Point可以直接相連, 沒有轉折點  * @param p1  * @param p2  */  public LinkInfo(Point p1, Point p2) {  // 加到集合中去  points.add(p1);  points.add(p2);  }   /**  * 提供第二個構造器, 表示三個Point可以相連, p2是p1與p3之間的轉折點  * @param p1  * @param p2  * @param p3  */  public LinkInfo(Point p1, Point p2, Point p3) {  points.add(p1);  points.add(p2);  points.add(p3);  }   /**  * 提供第三個構造器, 表示四個Point可以相連, p2, p3是p1與p4的轉折點  * @param p1  * @param p2  * @param p3  * @param p4  */  public LinkInfo(Point p1, Point p2, Point p3, Point p4) {  points.add(p1);  points.add(p2);  points.add(p3);  points.add(p4);  }   /**  * @return 連接集合  */  public List<Point> getLinkPoints() {  return points;  } } 

關于具體的實現步驟,請參考下面的鏈接:

我的Android進階之旅------>Android瘋狂連連看游戲的實現之游戲效果預覽(一)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 瓮安县| 云和县| 东平县| 武宣县| 凤台县| 沁源县| 图木舒克市| 资中县| 佳木斯市| 清徐县| 东港市| 沈阳市| 柳河县| 孝义市| 巴楚县| 略阳县| 凤阳县| 英吉沙县| 凤冈县| 邵阳县| 兴国县| 陆良县| 孙吴县| 弥勒县| 广饶县| 旬邑县| 达拉特旗| 仪陇县| 都匀市| 古浪县| 台中市| 乌鲁木齐县| 婺源县| 潞城市| 垫江县| 宣城市| 扶风县| 广灵县| 高邮市| 新邵县| 凤山县|