1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > android实现九宫格拼图小游戏

android实现九宫格拼图小游戏

时间:2021-05-18 06:17:03

相关推荐

android实现九宫格拼图小游戏

贴一下效果图

接下来随便用一张图片就好

以下是全代码

自定义View

GameView类

importandroid.content.Context;importandroid.graphics.Bitmap;importandroid.graphics.BitmapFactory;importandroid.graphics.Color;importandroid.os.Handler;importandroid.os.Message;importandroid.util.AttributeSet;importandroid.util.Log;importandroid.util.TypedValue;importandroid.view.View;importandroid.view.animation.Animation;importandroid.view.animation.TranslateAnimation;importandroid.widget.ImageView;importandroid.widget.RelativeLayout;importandroid.widget.Toast;importjava.util.Collections;importparator;importjava.util.List;public classGameViewextendsRelativeLayoutimplementsView.OnClickListener { //默认3*3private intmColumn= 3; //容器的内边距private intmPadding; //小图的距离 dpprivate intmMagin= 3; //存储图片的,宽高 都是固定的,所以使用数组privateImageView[]mGameOintuItems; //宽度private intmItemWidth; //图片privateBitmapmBitmap; //切图后存储privateList<ImagePiece>mItemBitmaps; //标记private booleanonce; //记录时间private intmTime; //容器的一个宽度private intmWidth; //判断游戏是否成功private booleanisGameSuccess; //是否显示时间private booleanisTimeEnabled=false; /** * 动画层,覆盖在viewGroup中 */privateRelativeLayoutmAnimLayout;private booleanisGameOver; /** * 动画限制 */private booleanisAniming;private static final intTIME_CHANGED= 10;private static final intNEXT_LEVEL= 11; /** * 设置接口回调 * *@parammListener*/public voidsetOnGamemListener(GamePintuListener mListener) {this.mListener= mListener; }publicGamePintuListenermListener; /** * 关数 */private intlevel= 1; /** * 设置开启时间 * *@paramtimeEnabled*/public voidsetTimeEnabled(booleantimeEnabled) {isTimeEnabled= timeEnabled; } //接口public interfaceGamePintuListener { //关卡voidnextLevel(intnextLevel); //时间voidtimechanged(inttime); //游戏结束voidgameOver(); } //子线程操作privateHandlerhandler=newHandler() { @Overridepublic voidhandleMessage(Message msg) {switch(msg.what) {caseTIME_CHANGED:if(isGameSuccess||isGameOver||isPause) {return;}if(mListener!=null) {mListener.timechanged(mTime);if(mTime== 0) {isGameOver=true;mListener.gameOver();return; }}mTime--;handler.sendEmptyMessageDelayed(TIME_CHANGED, 1000);break;caseNEXT_LEVEL:level=level+ 1;if(mListener!=null) {mListener.nextLevel(level);}else{ nextLevel();}break; }super.handleMessage(msg); } };publicGameView(Context context) {this(context,null); }publicGameView(Context context, AttributeSet attrs) {this(context, attrs, 0); }publicGameView(Context context, AttributeSet attrs,intdefStyleAttr) {super(context, attrs, defStyleAttr); init(); } /** * 初始化 */private voidinit() { //单位转换——dp-pxmMagin= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics());mPadding= min(getPaddingLeft(), getPaddingRight(), getPaddingTop(), getPaddingBottom()); } /** * 确定当前布局的大小,我们要设置成正方形 * *@paramwidthMeasureSpec*@paramheightMeasureSpec*/ @Overrideprotected voidonMeasure(intwidthMeasureSpec,intheightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec); //拿到容器的高宽最小值mWidth= Math.min(getMeasuredHeight(), getMeasuredWidth());if(!once) { //进行切图和排序initBitmap(); //设置imageview(item)的宽高等属性initItem(); //根据关卡设置时间checkTimeEnable();once=true; } setMeasuredDimension(mWidth,mWidth); } /** * 是否显示时间 */private voidcheckTimeEnable() { //如果我们开启了if(isTimeEnabled) { countTimeBaseLevel();handler.sendEmptyMessage(TIME_CHANGED); } } /** * 根据当前等级设置时间 */private voidcountTimeBaseLevel() {mTime= (int) Math.pow(2,level) * 60; } /** * 进行切图和排序 */private voidinitBitmap() { //判断是否存在这张图片if(mBitmap==null) {mBitmap= BitmapFactory.decodeResource(getResources(), R.drawable.mm); } //进行裁剪mItemBitmaps= ImageSplitterUtil.splitImage(mBitmap,mColumn); //裁剪玩后需要进行顺序打乱sortCollections.sort(mItemBitmaps,newComparator<ImagePiece>() { @Overridepublic intcompare(ImagePiece lhs, ImagePiece rhs) {//生成随机数,如果》0.5返回1否则返回-1returnMath.random() > 0.5 ? 1 : -1; } }); } /** * 设置imageview(item)的宽高等属性 */private voidinitItem() { //( 容器的宽度 - 内边距 * 2 - 间距 ) / 裁剪的数量mItemWidth= (mWidth-mPadding* 2 -mMagin* (mColumn- 1)) /mColumn; //几 * 几mGameOintuItems=newImageView[mColumn*mColumn]; //开始排放for(inti = 0; i <mGameOintuItems.length; i++) { ImageView item =newImageView(getContext()); item.setOnClickListener(this); //设置图片item.setImageBitmap(mItemBitmaps.get(i).getBitmap()); //保存mGameOintuItems[i] = item; //设置IDitem.setId(i + 1); //设置Tagitem.setTag(i +"_"+mItemBitmaps.get(i).getIndex()); RelativeLayout.LayoutParams lp =newRelativeLayout.LayoutParams(mItemWidth,mItemWidth); //判断不是最后一列if(i + 1 %mColumn!= 0) {lp.rightMargin=mMagin; } //判断不是第一列if(i %mColumn!= 0) {lp.addRule(RelativeLayout.RIGHT_OF,mGameOintuItems[i - 1].getId()); } //判断如果不是第一行if((i + 1) >mColumn) {lp.topMargin=mMagin;lp.addRule(RelativeLayout.BELOW,mGameOintuItems[i -mColumn].getId()); } addView(item, lp); } } /** * 获取多个参数的最小值 */private intmin(int... params) {intmin = params[0]; //遍历for(intparam : params) {if(param < min) {min = param; } }returnmin; } /** * 点击的第一张图和第二张图,他们进行交换 */privateImageViewmFirst;privateImageViewmSecond; /** * 点击事件 * *@paramv*/ @Overridepublic voidonClick(View v) { //如果点击了一次,你还点击,则无效if(isAniming) {return; } //重复点击if(mFirst== v) { //去掉颜色mFirst.setColorFilter(null);mFirst=null;return; }if(mFirst==null) {mFirst= (ImageView) v; //设置选中效果mFirst.setColorFilter(Color.parseColor("#55FF0000")); //第二次点击}else{mSecond= (ImageView) v; //交换exchangeView(); } } /** * 图片交换 */private voidexchangeView() {mFirst.setColorFilter(null); // 构造我们的动画层setUpAnimLayout(); ImageView first =newImageView(getContext());finalBitmap firstBitmap =mItemBitmaps.get(getImageIdByTag((String)mFirst.getTag())).getBitmap(); first.setImageBitmap(firstBitmap); LayoutParams lp =newLayoutParams(mItemWidth,mItemWidth); lp.leftMargin=mFirst.getLeft() -mPadding; lp.topMargin=mFirst.getTop() -mPadding; first.setLayoutParams(lp);mAnimLayout.addView(first); ImageView second =newImageView(getContext());finalBitmap secondBitmap =mItemBitmaps.get(getImageIdByTag((String)mSecond.getTag())).getBitmap(); second.setImageBitmap(secondBitmap); LayoutParams lp2 =newLayoutParams(mItemWidth,mItemWidth); lp2.leftMargin=mSecond.getLeft() -mPadding; lp2.topMargin=mSecond.getTop() -mPadding; second.setLayoutParams(lp2);mAnimLayout.addView(second); // 设置动画TranslateAnimation anim =newTranslateAnimation(0,mSecond.getLeft()-mFirst.getLeft(), 0,mSecond.getTop() -mFirst.getTop()); anim.setDuration(300); anim.setFillAfter(true); first.startAnimation(anim); TranslateAnimation animSecond =newTranslateAnimation(0,-mSecond.getLeft() +mFirst.getLeft(), 0, -mSecond.getTop()+mFirst.getTop()); animSecond.setDuration(300); animSecond.setFillAfter(true); second.startAnimation(animSecond); // 监听动画anim.setAnimationListener(newAnimation.AnimationListener() { @Overridepublic voidonAnimationStart(Animation animation) {mFirst.setVisibility(View.INVISIBLE);mSecond.setVisibility(View.INVISIBLE);isAniming=true; } @Overridepublic voidonAnimationRepeat(Animation animation) {//TODO Auto-generated method stub} @Overridepublic voidonAnimationEnd(Animation animation) {String firstTag = (String)mFirst.getTag();String secondTag = (String)mSecond.getTag();mFirst.setImageBitmap(secondBitmap);mSecond.setImageBitmap(firstBitmap);mFirst.setTag(secondTag);mSecond.setTag(firstTag);mFirst.setVisibility(View.VISIBLE);mSecond.setVisibility(View.VISIBLE);mFirst=mSecond=null;mAnimLayout.removeAllViews();//每次移动完成判断是否过关 checkSuccess();isAniming=false; } }); } /** * 判断是否过关 */private voidcheckSuccess() {booleanisSuccess =true;for(inti = 0; i <mGameOintuItems.length; i++) { //拿到所有的图片ImageView imageView =mGameOintuItems[i];if(getImageIndex((String) imageView.getTag()) != i) {isSuccess =false; } }if(isSuccess) {isGameSuccess=true;handler.removeMessages(TIME_CHANGED); Log.i("tag","成功"); Toast.makeText(getContext(),"成功,进入下一关!", Toast.LENGTH_LONG).show();handler.sendEmptyMessage(NEXT_LEVEL); } } /** * 获取tag * *@paramtag*@return*/public intgetImageIdByTag(String tag) { String[] split = tag.split("_");returnInteger.parseInt(split[0]); } /** * 获取图片的tag * *@paramtag*@return*/public intgetImageIndex(String tag) { String[] split = tag.split("_");returnInteger.parseInt(split[1]); } /** * 交互动画 */private voidsetUpAnimLayout() {if(mAnimLayout==null) {mAnimLayout=newRelativeLayout(getContext()); //添加到整体addView(mAnimLayout); } } /** * 下一关 */public voidnextLevel() {this.removeAllViews();mAnimLayout=null;mColumn++;isGameSuccess=false; checkTimeEnable(); initBitmap(); initItem(); } /** * 重新开始 */public voidrestartGame() {isGameOver=false;mColumn--; nextLevel(); } //暂停状态private booleanisPause; /** * 暂停 */public voidpauseGame() {isPause=true;handler.removeMessages(TIME_CHANGED); } /** * 恢复 */public voidresumeGame() {if(isPause) {isPause=false;handler.sendEmptyMessage(TIME_CHANGED); } }}

ImagePiece类

importandroid.graphics.Bitmap;public classImagePiece {private intindex;privateBitmapbitmap; //构造方法publicImagePiece() { } //有参构造方法publicImagePiece(intindex, Bitmap bitmap) {this.index= index;this.bitmap= bitmap; }public intgetIndex() {returnindex; }public voidsetIndex(intindex) {this.index= index; }publicBitmap getBitmap() {returnbitmap; }public voidsetBitmap(Bitmap bitmap) {this.bitmap= bitmap; }}

ImageSplitterUtil工具类

importandroid.graphics.Bitmap;importjava.util.ArrayList;importjava.util.List;public classImageSplitterUtil { /** * 静态方法 * 传递bitmap切成piece*piece块,返回List<imagepiece> * *@parambitmap*@parampiece*@return*/public staticList<ImagePiece> splitImage(Bitmap bitmap,intpiece) { //作为返回值传递List<ImagePiece> imagePieces =newArrayList<>(); //获取图片的宽高intwidth = bitmap.getWidth();intheight = bitmap.getHeight(); //根据宽高取最小值达到正方形intpieceWidth = Math.min(width, height) / piece; //进行切割for(inti = 0; i < piece; i++) {for(intj = 0; j < piece; j++) {ImagePiece imagePiece =newImagePiece();imagePiece.setIndex(j + i * piece);intx = j * pieceWidth;inty = i * pieceWidth;//第一次循环为0,0, imagePiece.setBitmap(Bitmap.createBitmap(bitmap, x, y, pieceWidth, pieceWidth));/*** 保存到list中进行返回*/ imagePieces.add(imagePiece); } }returnimagePieces; }}

MainActivity类

packagecom.example.pintu;importandroid.content.DialogInterface;importandroid.os.Bundle;importandroid.support.v7.app.AlertDialog;importandroid.support.v7.app.AppCompatActivity;importandroid.widget.TextView;public classMainActivityextendsAppCompatActivity {privateGameViewgameview;privateTextViewtv_level,tv_time; @Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);tv_level= (TextView) findViewById(R.id.tv_level);tv_time= (TextView) findViewById(R.id.tv_time);gameview= (GameView) findViewById(R.id.gameview); //显示时间gameview.setTimeEnabled(true);gameview.setOnGamemListener(newGameView.GamePintuListener() { @Overridepublic voidnextLevel(final intnextLevel) {newAlertDialog.Builder(MainActivity.this).setTitle("拼图完成").setMessage("美女抱回家").setPositiveButton("下一关",newDialogInterface.OnClickListener() {@Overridepublic voidonClick(DialogInterface dialog,intwhich) {gameview.nextLevel();tv_level.setText("当前关卡"+ nextLevel);}}).show(); } @Overridepublic voidtimechanged(inttime) {//设置时间tv_time.setText("倒计时:"+ time); } @Overridepublic voidgameOver() {newAlertDialog.Builder(MainActivity.this).setTitle("游戏结束").setMessage("很遗憾没有成功抱到美女!").setPositiveButton("重新开始",newDialogInterface.OnClickListener() {@Overridepublic voidonClick(DialogInterface dialog,intwhich) {gameview.restartGame();}}).setNegativeButton("退出",newDialogInterface.OnClickListener() {@Overridepublic voidonClick(DialogInterface dialog,intwhich) { finish();}}).show(); } }); } @Overrideprotected voidonPause() {super.onPause();gameview.pauseGame(); } @Overrideprotected voidonResume() {super.onResume();gameview.resumeGame(); }}

activity_main.xml布局文件

<?xml version="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.example.pintu.MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:id="@+id/tv_level"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:id="@+id/tv_time"android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout><com.example.pintu.GameViewandroid:id="@+id/gameview"android:layout_width="500dp"android:layout_height="500dp"></com.example.pintu.GameView></LinearLayout>

最后不要忘记修改布局文件中的GameView为自己的包名

这里没有做适配.大家可以根据实际效果改一下高度和宽度.........

好了.九宫格拼图小游戏就可以运行啦

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。