安卓拼图游戏(一)

本文详细介绍了游戏拼图的交互与布局实现过程,包括主类定义、图片切片、布局切开与动画效果应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

完成了拼图的切换和动画效果,熟悉了View的用法,总体来说还是感觉很张见识的。。


主类

package com.innoc.game.pintu;

import com.example.first.R;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


   
    
}



图片的属性,包括bitmap和自己的实际顺序index,


package com.innoc.game.utils;

import android.graphics.Bitmap;

public class ImagePiece {

	private int index;
	
	public ImagePiece(int index) {
		super();
		this.index = index;
	}

	private Bitmap bitmap;
	
	public ImagePiece(Bitmap bitmap) {
		super();
		this.bitmap = bitmap;
	}


	public ImagePiece(int index, Bitmap bitmap) {
		super();
		this.index = index;
		this.bitmap = bitmap;
	}
	
	
	public ImagePiece()
	{
		
	}
	public int getIndex() {
		return index;
	}
	public void setIndex(int index) {
		this.index = index;
	}
	public Bitmap getBitmap() {
		return bitmap;
	}
	public void setBitmap(Bitmap bitmap) {
		this.bitmap = bitmap;
	}
	
	@Override
	public String toString() {
		return "ImagePiece [index=" + index + ", bitmap=" + bitmap + "]";
	}
	
}

切出pieces*pieces块的纸片


package com.innoc.game.utils;


import java.util.ArrayList;
import java.util.List;

import android.graphics.Bitmap;

/**
 * 
 * @author YangPeiLin
 * 切出pieces*pieces块的纸片
 * 
 *  
 */



public class ImageSpiltterUtil {

	
	public static List<ImagePiece> splitImage(Bitmap bitmap,int piece)
	{
		
		List<ImagePiece> imagePieces=new ArrayList<ImagePiece>();
		
		int width=bitmap.getWidth();
		int height=bitmap.getHeight();
		int pieceWidth=Math.min(width, height)/piece;
		for(int i=0;i<piece;i++)
		{
			for(int j=0;j<piece;j++)
			{
			ImagePiece imagePiece=new ImagePiece();
			imagePiece.setIndex(j+i*piece);		
			int x=j*pieceWidth;
			int y=i*pieceWidth;
			imagePiece.setBitmap(Bitmap.createBitmap(bitmap, x, y, pieceWidth, pieceWidth));                        
			imagePieces.add(imagePiece);	
								
			}
			
		}
		
		return imagePieces;
	}
	
	
	
	
	
	
	
}


layout的切开和动画效果分布。。。。

package com.innoc.game.view;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.example.first.R;
import com.innoc.game.utils.ImagePiece;
import com.innoc.game.utils.ImageSpiltterUtil;
/**
 * 
 * @author YangPeiLin
 * 0 1 2
 * 3 4 5
 * 6 7 8
 * 
 * 
 * 
 */


public class GamepintuLayout extends RelativeLayout implements OnClickListener {
	
	
	private int mColumn=3;
	
	
	
	/*
	 * 游戏面板的宽度
	 */
	private int mWidth;
	
	
	
	/*
	 * 容器的内边距
	 * 
	 */
	private int mPadding;
	/*
	 * 
	 * 每张小图之间的距离 (heng,zong) dp
	 */
	private int mMargin=3;
	
	
	private List<ImageView> mItems=new ArrayList<ImageView>();
	private ImageView[] mGamepintuItems;
	
	private int mItemWidth;
	
	/*
	 * 游戏的拼图
	 * 
	 * 
	 */
	private Bitmap mBitmap;
	
	private List<ImagePiece> mItemBitmaps;
	
	private boolean once;
	
	public GamepintuLayout(Context context) {
		this(context,null);
		// TODO Auto-generated constructor stub
	}
	
	public GamepintuLayout(Context context, AttributeSet attrs) {
		this(context, attrs,0);
		// TODO Auto-generated constructor stub
	}


	public GamepintuLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		 init();
		
		
	}

	private void init() {
		// TODO Auto-generated method stub
		mMargin=(int) TypedValue.applyDimension
				(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics());
		
		/*
		 * 将sp换成dp,尽量不使用px
		 * 
		 */
		mPadding=min(getPaddingLeft(),getPaddingRight(),getPaddingTop(),getPaddingBottom());		
	
	}
	
   
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //取宽和高中的最小值 
        mWidth=Math.min(getMeasuredHeight(),getMeasuredWidth());
        if(!once)
        {
        	//进行切图,和排序
        	initBitmap();
        	//设置item的宽高属性
        	initItem();
        	once=true;
        }
        //设置为正方形
        setMeasuredDimension(mWidth, mWidth);
        
        
        
        
        
    }
	//进行切图,和排序
    private void initBitmap() {
		// TODO Auto-generated method stub
		if(mBitmap==null)
		{
			mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.image);
		}
		
		mItemBitmaps=ImageSpiltterUtil.splitImage(mBitmap, mColumn);
   	    
		//使用sort乱序
   	    Collections.sort(mItemBitmaps,new Comparator<ImagePiece>()
   	    {
			@Override
			public int compare(ImagePiece a, ImagePiece b) {

				return Math.random()>0.5?1:-1;
			} 	
   	     });
   	 
   	 
   	 
   	 
	}
	//设置ImageView(item)的宽高属性
	private void initItem() {
		// TODO Auto-generated method stub
		mItemWidth=(mWidth-mPadding*2-mMargin*(mColumn-1))/mColumn;
		
		mGamepintuItems= new ImageView[mColumn*mColumn];
		
		for(int i=0;i<mGamepintuItems.length;i++)
		{
			ImageView item=new ImageView(getContext());
			item.setOnClickListener(this);
			item.setImageBitmap(mItemBitmaps.get(i).getBitmap());
			mGamepintuItems[i]=item;
			item.setId(i+1);
			//在item的tag中存储了index,index是真正的顺序
			item.setTag(i+"_"+mItemBitmaps.get(i).getIndex());
			
			RelativeLayout.LayoutParams lp=
					new RelativeLayout.LayoutParams(mItemWidth, mItemWidth);
			
			//设置item间横向间隙,通过rightMargin
			//不是最后一列
			
			
			if((i+1)%mColumn!=0)
			{
				lp.rightMargin=mMargin;
			}
			//不是第一列
			if(i%mColumn!=0)
			{
				lp.addRule(RelativeLayout.RIGHT_OF, mGamepintuItems[i-1].getId());
			}
			//如果不是第一行
			if((i+1)>mColumn)
			{
				lp.topMargin=mMargin;
				lp.addRule(RelativeLayout.BELOW, mGamepintuItems[i-mColumn].getId());
			}
			addView(item,lp);
			
			
			
		}
		
		
		
	}



	/*
      * 
      * 获取多个参数的最小值
      */
	private int min(int...params) {
	
		int min=params[0];
		for(int param:params)
		{
			if(param<min)
			{
				min=param;
			}
			
		}
		
		
		
		return min;
	}
 
	private ImageView mFirst;
	private ImageView mSecond;
	
	
	private boolean isAniming;
	
	@Override
	public void onClick(View v) {
		
		
		/*
		 * 
		 * 
		 *防止正在动画的时候用户还在敲。。
		 *
		 */
		if(isAniming)
		return;
		//两次点击同一个item
		if(mFirst==v)
		{
			mFirst.setColorFilter(null);
			mFirst=null;
			return;
		}
		
		
		if(mFirst==null)
		{
			
			mFirst=(ImageView)v;
			mFirst.setColorFilter(Color.parseColor("#55FF0000"));
		}
		else
		{
		   /*交换我们的item*/
			mSecond=(ImageView)v;
			exchangeView();
		}
			
		
	}

	private void exchangeView() {
		// TODO Auto-generated method stub
		
		mFirst.setColorFilter(null);
		
		setUpAnimaLayout();
		
		
	    ImageView  first=new ImageView(getContext());
		final Bitmap firstBitmap1=mItemBitmaps.get(getImageIdByTag((String)mFirst.getTag())).getBitmap();
		first.setImageBitmap(firstBitmap1);
		RelativeLayout.LayoutParams lp=new  LayoutParams(mItemWidth,mItemWidth);
		lp.leftMargin=mFirst.getLeft()-mPadding;
		lp.topMargin=mFirst.getTop()-mPadding;
	    first.setLayoutParams(lp);
		mAnimLayout.addView(first);
		
		
		ImageView  second=new ImageView(getContext());
		final Bitmap secondBitmap1=mItemBitmaps.get(getImageIdByTag((String)mSecond.getTag())).getBitmap();
		second.setImageBitmap(secondBitmap1);
		RelativeLayout.LayoutParams lp2=new  LayoutParams(mItemWidth,mItemWidth);
		lp2.leftMargin=mSecond.getLeft()-mPadding;
		lp2.topMargin=mSecond.getTop()-mPadding;
	    second.setLayoutParams(lp2);
		mAnimLayout.addView(second);
		
		TranslateAnimation anim=new TranslateAnimation(0,
		mSecond.getLeft()-mFirst.getLeft(),0,mSecond.getTop()-
		mFirst.getTop());
		anim.setDuration(300);
		anim.setFillAfter(true);
		first.startAnimation(anim);
		
		TranslateAnimation Secondanim=new TranslateAnimation(0,
				-mSecond.getLeft()+mFirst.getLeft(),0,-mSecond.getTop()+
				mFirst.getTop());
		Secondanim.setDuration(300);
		Secondanim.setFillAfter(true);
		second.startAnimation(Secondanim);
		
		anim.setAnimationListener(new AnimationListener()
		{

			@Override
			public void onAnimationEnd(Animation arg0) {
				// TODO Auto-generated method stub
				
				String firstTag=(String)mFirst.getTag();
				String secondTag=(String)mSecond.getTag();
				//String[]firstParams=firstTag.split("_");
				//String[]secondParams=secondTag.split("_");
				
				
				
				
				
				//Bitmap firstBitmap=mItemBitmaps.get(Integer.parseInt(firstParams[0])).getBitmap();
				//Bitmap secondBitmap=mItemBitmaps.get(Integer.parseInt(secondParams[0])).getBitmap();
				
				mFirst.setImageBitmap(secondBitmap1);
				mSecond.setImageBitmap(firstBitmap1);
				mFirst.setTag(secondTag);
				mSecond.setTag(firstTag);
				mFirst.setVisibility(View.VISIBLE);
				mSecond.setVisibility(View.VISIBLE);
				
				mAnimLayout.removeAllViews();
				mFirst=mSecond=null;
				
				isAniming=false;
				
			}

			@Override
			public void onAnimationRepeat(Animation arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onAnimationStart(Animation arg0) {
				// TODO Auto-generated method stub
				mFirst.setVisibility(View.INVISIBLE);
				mSecond.setVisibility(View.INVISIBLE);
				isAniming=true;
				
			}
			
		});
		
		
		
		
	
	}
	/*
	 * 动画层
	 * 
	 */
     private RelativeLayout mAnimLayout;
     
	
     /*
 * 
 * 构造我们的动画层
 */
	private void setUpAnimaLayout() {
		// TODO Auto-generated method stub
		
		if(mAnimLayout==null)
		{
			mAnimLayout=new RelativeLayout(getContext());
			addView(mAnimLayout);
			
			
		}
		
		
	}
	/*
	 * 根据tag取出id
	 */
    public int getImageIdByTag(String tag)
    {
    	
    	String[] spilt=tag.split("_");
    	return Integer.parseInt(spilt[0]);
    	
    	
    }

    public int getImageIdIndex(String tag)
    {
    	
    	String[] spilt=tag.split("_");
    	return Integer.parseInt(spilt[1]);
    	
    	
    }

	
	
	
	
	
	
	
	
	
	
	
	
	
	
}



效果:::::



第二部分:点击打开链接

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值