Android拼图游戏开发全纪录4

今天我们主要实现我们的主界面:国际惯例:

界面我们已经在第一天做好了,今天我们就要实现这个界面的功能,

分析一下,这个界面包含以下几个功能:

1、显示游戏的难度:使用popupwindow,选择后改变显示的数字

2、显示默认的待拼图图片,包含一张选择自定义的图片:这个比较简单,只是GridView的最简单应用而已

3、自定义按钮功能:调用系统图册和相机

4、查看记录和了解更多:这个也是一般的应用需求,比较简单

package com.xys.xpuzzle.activity;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.xys.xpuzzle.R;
import com.xys.xpuzzle.adapter.GridPicListAdapter;

/**
 * 程序主界面:显示默认图片列表、自选图片按钮
 *
 * @author xys
 *
 */
public class MainActivity extends Activity implements OnClickListener {

    // 返回码:系统图库
    private static final int RESULT_IMAGE = 100;
    // 返回码:相机
    private static final int RESULT_CAMERA = 200;
    // Temp照片路径
    public static String TEMP_IMAGE_PATH;
    // IMAGE TYPE
    private static final String IMAGE_TYPE = "image/*";
    // GridView 显示图片
    private GridView gv_Pic_List;
    private List<Bitmap> picList;
    // 主页图片资源ID
    private int[] resPicId;
    // 显示Type
    private TextView tv_puzzle_main_type_selected;
    private LayoutInflater layoutInflater;
    private PopupWindow popupWindow;
    private View popupView;
    private TextView tvType2;
    private TextView tvType3;
    private TextView tvType4;
    // 游戏类型N*N
    private int type = 2;
    // 本地图册、相机选择
    private String[] customItems = new String[] { "本地图册", "相机拍照" };

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

	TEMP_IMAGE_PATH = Environment.getExternalStorageDirectory().getPath() + "/ttt.jpg";
	picList = new ArrayList<Bitmap>();
	// 初始化Views
	initViews();
	// 数据适配器
	gv_Pic_List.setAdapter(new GridPicListAdapter(MainActivity.this, picList));
	// Item点击监听
	gv_Pic_List.setOnItemClickListener(new OnItemClickListener() {

	    @Override
	    public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
		if (position == resPicId.length - 1) {
		    // 选择本地图库 相机
		    showDialogCustom();
		} else {
		    // 选择默认图片
		    Intent intent = new Intent(MainActivity.this, PuzzleMain.class);
		    intent.putExtra("picSelectedID", resPicId[position]);
		    intent.putExtra("type", type);
		    startActivity(intent);
		}
	    }
	});

	/**
	 * 显示难度Type
	 */
	tv_puzzle_main_type_selected.setOnClickListener(new OnClickListener() {

	    @Override
	    public void onClick(View v) {
		// 弹出popup window
		popupShow(v);
	    }
	});
    }

    // 显示选择系统图库 相机对话框
    private void showDialogCustom() {
	AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
	builder.setTitle("选择:");
	builder.setItems(customItems, new DialogInterface.OnClickListener() {

	    @Override
	    public void onClick(DialogInterface dialog, int which) {
		if (0 == which) {
		    // 本地相册
		    Intent intent = new Intent(Intent.ACTION_PICK, null);
		    intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_TYPE);
		    startActivityForResult(intent, RESULT_IMAGE);
		} else if (1 == which) {
		    // 系统相机
		    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		    Uri photoUri = Uri.fromFile(new File(TEMP_IMAGE_PATH));
		    intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
		    startActivityForResult(intent, RESULT_CAMERA);
		}
	    }
	});
	builder.create().show();
    }

    /**
     * 调用图库相机回调方法
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);
	if (resultCode == RESULT_OK) {
	    if (requestCode == RESULT_IMAGE && data != null) {
		// 相册
		Cursor cursor = this.getContentResolver().query(data.getData(), null, null, null, null);
		cursor.moveToFirst();
		String imagePath = cursor.getString(cursor.getColumnIndex("_data"));
		Intent intent = new Intent(MainActivity.this, PuzzleMain.class);
		intent.putExtra("picPath", imagePath);
		intent.putExtra("type", type);
		startActivity(intent);
	    } else if (requestCode == RESULT_CAMERA) {
		// 相机
		Intent intent = new Intent(MainActivity.this, PuzzleMain.class);
		intent.putExtra("picPath", TEMP_IMAGE_PATH);
		intent.putExtra("type", type);
		startActivity(intent);
	    }
	}
    }

    /**
     * 显示popup window
     *
     * @param view
     */
    private void popupShow(View view) {
	// 显示popup window
	popupWindow = new PopupWindow(popupView, 200, 50);
	popupWindow.setFocusable(true);
	popupWindow.setOutsideTouchable(true);
	// 透明背景
	Drawable transpent = new ColorDrawable(Color.TRANSPARENT);
	popupWindow.setBackgroundDrawable(transpent);
	// 获取位置
	int[] location = new int[2];
	view.getLocationOnScreen(location);
	popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0] - 40, location[1] + 50);
    }

    /**
     * 初始化Views
     */
    private void initViews() {
	gv_Pic_List = (GridView) findViewById(R.id.gv_xpuzzle_main_pic_list);
	// 初始化Bitmap数据
	resPicId = new int[] { R.drawable.pic1, R.drawable.pic2, R.drawable.pic3, R.drawable.pic4, R.drawable.pic5, R.drawable.pic6, R.drawable.pic7,
		R.drawable.pic8, R.drawable.pic9, R.drawable.pic10, R.drawable.pic11, R.drawable.pic12, R.drawable.pic13, R.drawable.pic14,
		R.drawable.pic15, R.drawable.plus };
	Bitmap[] bitmaps = new Bitmap[resPicId.length];
	for (int i = 0; i < bitmaps.length; i++) {
	    bitmaps[i] = BitmapFactory.decodeResource(getResources(), resPicId[i]);
	    picList.add(bitmaps[i]);
	}
	// 显示type
	tv_puzzle_main_type_selected = (TextView) findViewById(R.id.tv_puzzle_main_type_selected);
	layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
	// type view
	popupView = layoutInflater.inflate(R.layout.xpuzzle_main_type_selected, null);
	tvType2 = (TextView) popupView.findViewById(R.id.tv_main_type_2);
	tvType3 = (TextView) popupView.findViewById(R.id.tv_main_type_3);
	tvType4 = (TextView) popupView.findViewById(R.id.tv_main_type_4);

	// 监听事件
	tvType2.setOnClickListener(this);
	tvType3.setOnClickListener(this);
	tvType4.setOnClickListener(this);
    }

    /**
     * popup window item点击事件
     */
    @Override
    public void onClick(View v) {
	switch (v.getId()) {
	// Type
	case R.id.tv_main_type_2:
	    type = 2;
	    tv_puzzle_main_type_selected.setText("2 X 2");
	    break;
	case R.id.tv_main_type_3:
	    type = 3;
	    tv_puzzle_main_type_selected.setText("3 X 3");
	    break;
	case R.id.tv_main_type_4:
	    type = 4;
	    tv_puzzle_main_type_selected.setText("4 X 4");
	    break;
	default:
	    break;
	}
	popupWindow.dismiss();
    }
}

注释还是比较清晰的,相信大家都看得懂。

下面还有送一个数据适配器:

package com.xys.xpuzzle.adapter;

import java.util.List;

import android.R.color;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;

/**
 * 程序主界面数据适配器
 *
 * @author xys
 *
 */
public class GridPicListAdapter extends BaseAdapter {

    // 映射List
    private List<Bitmap> picList;
    private Context context;

    public GridPicListAdapter(Context context, List<Bitmap> picList) {
	this.context = context;
	this.picList = picList;
    }

    @Override
    public int getCount() {
	return picList.size();
    }

    @Override
    public Object getItem(int position) {
	return picList.get(position);
    }

    @Override
    public long getItemId(int position) {
	return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup arg2) {
	ImageView iv_pic_item = null;
	if (convertView == null) {
	    iv_pic_item = new ImageView(context);
	    // 设置布局 图片
	    iv_pic_item.setLayoutParams(new GridView.LayoutParams(80, 100));
	    // 设置显示比例类型
	    iv_pic_item.setScaleType(ImageView.ScaleType.FIT_XY);
	} else {
	    iv_pic_item = (ImageView) convertView;
	}
	iv_pic_item.setBackgroundColor(color.black);
	iv_pic_item.setImageBitmap(picList.get(position));
	return iv_pic_item;
    }
}

今天的难点在于调用系统图册和相机:

1、调用的Intent在代码中已经写清楚了

2、调用相机的时候,如果直接返回data,其实是返回的相机缩略图,如果要获得原始图片,就需要先保存在SD卡上,再去获取这张图片,希望大家注意。

时间: 2024-10-18 20:26:49

Android拼图游戏开发全纪录4的相关文章

Android拼图游戏开发全纪录0

最近刚完成一个Android的小项目--拼图游戏.项目并不复杂,但也是一个完整的项目,用到的知识点还是比较丰富的. 做完之后照例进行下总结: 需求定义: 1.选择图片后进入拼图界面,可以选择默认图片或者自定义图片,即从图库选择或者从相机拍照. 2.可以设置游戏的难度,即选择拼图为NXN结构. 3.自动打乱拼图的顺序,利用倒置和算法,确保生成的数据有解. 4.拼图过程中可以查看原图. 5.拼图具有计时.记步功能. 6.完成拼图后显示全部图片并提升拼图成功. 7.可以查看历史记录. *8.利用IDA

Android拼图游戏开发全纪录2

今天我们主要来讨论下拼图游戏的可行性解的问题,其实不要小看拼图游戏,他其实是人工智能算法中很著名的15puzzle问题,网上已经有很多关于这个问题的解释,我就做个搬运工好了. 随机生成的15puzzle大约有%50是无解的,本文将就随机生成的谜题的可解性加以讨论. 设有如下矩阵: 12 1 10 2 7 11 4 14 5 x 9 15 8 13 6 3 将其排成水平的,有:12,1,10,2,7,11,4,14,5,X,9,15,8,13,6,3.并记该序列为A 定义:"倒置变量值"

Android拼图游戏开发全纪录3

今天我们要继续开发Android游戏拼图,今天同样是做一些准备工作,昨天我们把界面的准备工作做好了,今天呢,我们想想,要完成一个拼图,我们还需要做哪些准备. 首先,我们需要一个工具类,去获取屏幕的相关信息,让我们的程序去自动适应不同分辨率大小的屏幕: package com.xys.xpuzzle.util; import android.content.Context; import android.util.DisplayMetrics; import android.view.Displa

Android拼图游戏开发全纪录5

今天我们终于可以把这个项目给结束掉啦,有了前几天的准备,相信最后一天还是比较轻松的,国际惯例: 最后要完成的就是我们的主要功能--拼图界面. 布局比较简单,在前几天就已经做好了,现在我们要做的是以下几件事情: 1.计时记步:这个是游戏基本都有的功能,其实也比较简单,记录成功移动的步数.显示一个计时器就行了. 2.处理图片,调整为合适的大小比例:这个方法在前几天已经实现了 3.点击GridView后移动图片:是否能移动的方法已经在前几天实现了 4.判断是否拼图完成:唉,也已经实现了 5.点击原图按

Android拼图游戏的设计逻辑,从切图到交互动画,从关卡到倒计时,实例提高!

Android拼图游戏的设计逻辑,从切图到交互动画,从关卡到倒计时,实例提高! 群英传的最后一章,我大致的看了一下这个例子,发现鸿洋大神也做过,就参考两个人的设计逻辑,感觉都差不多,就这样实现起来了 一.切图工具类 我们九宫格嘛,肯定要一个切图的工具,把一个图片给切成九张,那具体是怎么实现呢?我们先写一个bean来存储一切的状态 ImagePiece package com.lgl.ninegame.utils; import android.graphics.Bitmap; /** * * C

《Android 3D游戏开发技术宝典——OpenGL ES 2.0》——2.5节2D动画的开发

2.5 2D动画的开发 Android 3D游戏开发技术宝典--OpenGL ES 2.0 虽然本书是着重介绍3D的开发技术,但在大部分的3D应用中也需要有不少的2D界面,如菜单.帮助等.本节将介绍一般用于开发游戏中2D界面的SurfaceView类的使用.其继承自View类,但与View的不同之处在于,View更新画面必须是在UI线程中(也可以理解为主线程中),而SurfaceView更新画面可以在自定义线程中进行,大大方便了开发. 提示 关于Android下的多线程问题,读者可以参考笔者在人

《Android 3D游戏开发技术宝典——OpenGL ES 2.0》——1.5节Android应用程序运行的机制

1.5 Android应用程序运行的机制 Android 3D游戏开发技术宝典--OpenGL ES 2.0 上一节介绍了如何搭建Android开发环境.如何开发Hello Android应用程序以及Android应用程序的调试,接下来在本节中将简要地介绍Android应用程序的运行机制. 1.5.1 应用程序的系统架构 Android平台由应用程序.应用程序框架.Android运行时.系统库以及底层Linux内核构成,详细结构如图1-54所示. 说明 应用程序层里面包含的就是需要读者去发挥创意

《Android 3D游戏开发技术宝典——OpenGL ES 2.0》——1.4节Hello Android应用程序的开发

1.4 Hello Android应用程序的开发 Android 3D游戏开发技术宝典--OpenGL ES 2.0 本节首先将介绍如何在Eclipse中创建一个基于Android的Hello World应用程序,之后将简单介绍Android应用程序的调试,为读者以后学习高级开发铺平道路. 1.4.1 第一个Android应用程序 本小节将向读者介绍如何在Eclipse中创建一个基于Android的Hello World应用程序,基本步骤如下所列. (1)首先打开Eclipse,然后依次选择Fi

《Android 3D游戏开发技术宝典——OpenGL ES 2.0》——2.1节游戏中的音效

2.1 游戏中的音效 Android 3D游戏开发技术宝典--OpenGL ES 2.0 一款好游戏,除了具备优质的画面和较高的可玩性之外,还应该有出色的音效.音效一般指的是游戏中发生特定行为或进行特定操作时播放的效果音乐或为了渲染整体气氛播放的背景音,如远处隆隆的炮声.怪物死亡的惨叫声.由远而近的脚步声等. 通过开发人员精心准备的声音特效,结合游戏的场景,可以渲染出一种紧张刺激的氛围,使玩家产生身临其境的感觉.这就像电影中的声音特效一样,假如没有了合适的音效,那么游戏和电影一样,真实感会大打折