Android移動拼圖小遊戲

XMl佈局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    >
    <GridLayout 
        android:id="@+id/jigsaw"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:columnCount="5"
        android:rowCount="3"/>
</RelativeLayout>

MainActivity代碼:

public class MainActivity extends Activity {

	private boolean isAnimRun = false;
	/**判斷遊戲是否開始*/
	private boolean isGameStart = false;
	/**利用二維數組創建若干個遊戲小方塊**/
	private ImageView[][] iv_game_arr = new ImageView[3][5];
	/**遊戲主界面**/
	private GridLayout gl_game;
	/**當前空方塊的實例保存*/
	private ImageView iv_null;
	/**當前手勢*/
	private GestureDetector mDetector;
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		return mDetector.onTouchEvent(event);
	}
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		mDetector.onTouchEvent(ev);
		return super.dispatchTouchEvent(ev);
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mDetector = new GestureDetector(this, new OnGestureListener() {
			
			@Override
			public boolean onSingleTapUp(MotionEvent e) {
				// TODO Auto-generated method stub
				return false;
			}
			
			@Override
			public void onShowPress(MotionEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
				// TODO Auto-generated method stub
				return false;
			}
			
			@Override
			public void onLongPress(MotionEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
				// TODO Auto-generated method stub
				Log.d("TAG", ""+getDirByGes(e1.getX(), e1.getY(), e2.getX(), e2.getY()));
				int type = getDirByGes(e1.getX(), e1.getY(), e2.getX(), e2.getY());
				changeByDir(type);
				return false;
			}
			
			@Override
			public boolean onDown(MotionEvent e) {
				// TODO Auto-generated method stub
				return false;
			}
		});
		/*初始化遊戲的若干個小方塊*/
		//獲取一張大圖
		Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.pic1)).getBitmap();
		int wh = bitmap.getWidth()/5;
		//小方塊的寬高是整個屏幕的寬除以5
		int ivWH = getWindow().getWindowManager().getDefaultDisplay().getWidth()/5;
		for(int i = 0;i<iv_game_arr.length;i++){
			for(int j = 0;j<iv_game_arr[0].length;j++){
				//根據行和列來切成若干個遊戲小圖片
				Bitmap bm = Bitmap.createBitmap(bitmap,j*wh,i*wh,wh,wh);
				iv_game_arr[i][j] = new ImageView(this);
				iv_game_arr[i][j].setImageBitmap(bm);//設置每個小方塊的圖案
				
				iv_game_arr[i][j].setLayoutParams(new RelativeLayout.LayoutParams(ivWH,ivWH));
				iv_game_arr[i][j].setPadding(2, 2, 2, 2);//設置方塊之間的間距
				iv_game_arr[i][j].setTag(new GameData(i, j, bm));//綁定自定義的數據
			
				iv_game_arr[i][j].setOnClickListener(new OnClickListener() {
					
					@Override
					public void onClick(View v) {
						// TODO Auto-generated method stub
						boolean flag = isHasByNullImage((ImageView)v);
						if(flag){
							changeDataByImage((ImageView)v);
						}
					}
				});
			}
		}
		/*初始化遊戲主界面,並添加若干個小方塊*/
		gl_game = (GridLayout) findViewById(R.id.jigsaw);
		for(int i = 0;i<iv_game_arr.length;i++){
			for(int j = 0;j<iv_game_arr[0].length;j++){
				gl_game.addView(iv_game_arr[i][j]);
			}
		}
		/*設置最後一個方塊爲空方塊*/
		setNullImage(iv_game_arr[2][4]);
		randomOrder();
		isGameStart = true;
	}
	
	/**
	 * 根據手勢的方向,獲取空方塊相應的相鄰位置,如果存在方塊,則進行數據狡猾
	 * 
	 * @param type 1:上 2:下 3:左 4:右
	 */
	public void changeByDir(int type){
		changeByDir(type, true);
	}
	
	/**
	 * 根據手勢的方向,獲取空方塊相應的相鄰位置,如果存在方塊,則進行數據狡猾
	 * 
	 * @param type 1:上 2:下 3:左 4:右
	 * @param isAnim true:有動畫 false:無動畫
	 */
	public void changeByDir(int type,boolean isAnim){
		//獲取當前空方塊的位置
		GameData mNullGameData = (GameData) iv_null.getTag();
		//根據方向,設置相應的相鄰位置的座標
		int new_x = mNullGameData.x;
		int new_y = mNullGameData.y;
		if(type==1){//要移動的方塊在當前空方塊的下面
			new_x++;
		}else if(type==2){
			new_x--;
		}else if(type==3){
			new_y++;
		}else if(type==4){
			new_y--;
		}
		//判斷這個新座標,是否存在
		if(new_x>=0 && new_x<iv_game_arr.length && new_y>=0 && new_y<iv_game_arr[0].length){
			//存在的話開始移動
			if(isAnim){
				changeDataByImage(iv_game_arr[new_x][new_y]);
			}else{
				changeDataByImage(iv_game_arr[new_x][new_y],false);
			}
		}else{
			//什麼也不做
		}
	}
	
	/***
	 * 判斷遊戲結束
	 */
	public void isGameOver(){
		boolean isOver = true;
		//要遍歷每個遊戲小方塊
		for(int i = 0;i<iv_game_arr.length;i++){
			for(int j =0;j<iv_game_arr[0].length;j++){
				//爲空的方塊數據不判斷跳過
				if(iv_game_arr[i][j] == iv_null){
					continue;
				}
				GameData mGameData = (GameData) iv_game_arr[i][j].getTag();
				if(!mGameData.isTrue()){
					isOver = false;
					break;
				}
		}
		}
		//根據一個開關變量決定遊戲是否結束,結束時給提示
		if(isOver){
			Toast.makeText(MainActivity.this, "GameOver", Toast.LENGTH_LONG).show();
		}
	}
	
	/**
	 * 手勢判斷
	 * @param start_x 手勢起始點x
	 * @param start_y 手勢起始點y
	 * @param end_x 手勢終止點x
	 * @param end_y 手勢終止點y
	 * @return 1:上 2:下 3:左 4:右
	 */
	public int getDirByGes(float start_x,float start_y,float end_x,float end_y){
		boolean isLeftOrRight = (Math.abs(start_x - end_x) > Math.abs(start_y - end_y)) ? true:false;//判斷左右
		if(isLeftOrRight){//左右
			boolean isLeft = start_x - end_x > 0 ? true : false;
			if(isLeft){
				return 3;
			}else{
				return 4;
			}
		}else{//上下
			boolean isUp = start_y - end_y > 0 ? true : false;
			if(isUp){
				return 1;
			}else{
				return 2;
			}
		}
	}
	
	/**
	 * 隨機打亂順序
	 */
	public void randomOrder(){
		//打亂的次數
		for (int i = 0; i < 100; i++) {
			//根據手勢開始交換,無動畫
			int type = (int)(Math.random()*4)+1;
			changeByDir(type, false);
		}
	}
	
	public void changeDataByImage(final ImageView mImageView){
		changeDataByImage(mImageView, true);
	}
	
	/**
	 * 利用動畫結束之後,交換亮給方塊的數據
	 * @param mImageView 點擊的方塊
	 * @param isAnim true:有動畫 false:無動畫
	 */
	public void changeDataByImage(final ImageView mImageView,boolean isAnim){
		if(isAnimRun)
			return;
		if(!isAnim){
			GameData mGameData = (GameData) mImageView.getTag();
			iv_null.setImageBitmap(mGameData.bitmap);
			
			GameData mNullGameData = (GameData) iv_null.getTag();
			mNullGameData.bitmap = mGameData.bitmap;
			mNullGameData.p_x = mGameData.p_x;
			mNullGameData.p_y = mGameData.p_y;
			iv_null.setTag(mNullGameData);
			
			//設置當前點擊的是空方塊
			setNullImage(mImageView);
			return;
		}
		//創建一個動畫,設置好方向,移動的距離
		TranslateAnimation translateAnimation = null;
		if(mImageView.getX()>iv_null.getX()){//當前點擊方塊在空方塊的下面
			//往上移動
			translateAnimation = new TranslateAnimation(0.1f, -mImageView.getWidth(), 0.1f, 0.1f);
		}else if(mImageView.getX()<iv_null.getX()){//當前點擊方塊在空方塊的上面
			//往下移動
			translateAnimation = new TranslateAnimation(0.1f, mImageView.getWidth(), 0.1f, 0.1f);
		}else if(mImageView.getY()>iv_null.getY()){//當前點擊方塊在空方塊的右面
			//往左移動
			translateAnimation = new TranslateAnimation(0.1f, 0.1f, 0.1f, -mImageView.getWidth());
		}else if(mImageView.getY()<iv_null.getY()){//當前點擊方塊在空方塊的左面
			//往右移動
			translateAnimation = new TranslateAnimation(0.1f,0.1f, 0.1f, mImageView.getWidth());
		}
		//設置動畫的時長
		translateAnimation.setDuration(70);
		//設置動畫結束之後是否停留
		translateAnimation.setFillAfter(true);
		//設置動畫結束之後要真正的把數據交換了
		translateAnimation.setAnimationListener(new AnimationListener() {
			
			@Override
			public void onAnimationStart(Animation animation) {
				// TODO Auto-generated method stub
				isAnimRun = true;
			}
			
			@Override
			public void onAnimationRepeat(Animation animation) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onAnimationEnd(Animation animation) {
				// TODO Auto-generated method stub
				isAnimRun = false;
				mImageView.clearAnimation();
				GameData mGameData = (GameData) mImageView.getTag();
				iv_null.setImageBitmap(mGameData.bitmap);
				
				GameData mNullGameData = (GameData) iv_null.getTag();
				mNullGameData.bitmap = mGameData.bitmap;
				mNullGameData.p_x = mGameData.p_x;
				mNullGameData.p_y = mGameData.p_y;
				iv_null.setTag(mNullGameData);
				
				//設置當前點擊的是空方塊
				setNullImage(mImageView);
				if(isGameStart){
					isGameOver();//成功時會彈出一個Toas
				}
			}
		});
		//執行動畫
		mImageView.startAnimation(translateAnimation);
	}
	
	/**
	 * 設置某個空方塊
	 * mImageView當前要設置空方塊的實例
	 */
	public void setNullImage(ImageView mImageView){
		mImageView.setImageBitmap(null);
		iv_null = mImageView;
	}
	
	/**
	 * 判斷當前點擊的方塊,是否與空方塊的位置關係爲相鄰關係
	 * @param mImageView 所點擊的方塊
	 * @return true:相鄰 false:不相鄰
	 */
	public boolean isHasByNullImage(ImageView mImageView){
		//分別獲取當前空方塊的位置與點擊方塊的位置,通過x與y兩邊都差1的方式判斷
		GameData mNullGameData = (GameData) iv_null.getTag();
		GameData mGameData = (GameData) mImageView.getTag();
		if(mNullGameData.y==mGameData.y&&mGameData.x+1==mNullGameData.x){//當前點擊的方塊在空方塊的上邊
			return true;
		}else if(mNullGameData.y==mGameData.y&&mGameData.x-1==mNullGameData.x){//當前點擊的方塊在空方塊的下邊
			return true;
		}else if(mNullGameData.y==mGameData.y+1&&mGameData.x==mNullGameData.x){//當前點擊的方塊在空方塊的左邊
			return true;
		}else if(mNullGameData.y==mGameData.y-1&&mGameData.x==mNullGameData.x){//當前點擊的方塊在空方塊的右邊
			return true;
		}
		
		return false;
	}
	/**每個遊戲小方塊上要綁定的數據*/
	class GameData{
		/**每個小方塊的實際位置x*/
		public int x;
		/**每個小方塊的實際位置y*/
		public int y;
		/**每個小方塊的圖片*/
		public Bitmap bitmap;
		/**每個小方塊的圖片的位置x*/
		public int p_x;
		/**每個小方塊的圖片的位置y*/
		public int p_y;
		public GameData(int x, int y, Bitmap bitmap) {
			super();
			this.x = x;
			this.y = y;
			this.bitmap = bitmap;
			this.p_x = x;
			this.p_y = y;
		}
		
		public boolean isTrue(){
			if(x==p_x && y==p_y){
				return true;
			}
			return false;
		}
		
	}
}
源碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章