拼图APP结构梳理

来源:互联网 发布:手机淘宝排名规则 编辑:程序博客网 时间:2024/05/18 02:22

这个拼图是《Adnroid群英传》第13章的第一个例子,在github上的链接是拼图github链接,我花了几天弄懂,然后独立写了一个,现在写一个梳理和架构。

该项目的java文件包下有4个包,分别是activity,adapter,bean和util,先从工具包util说起。

util包下有3个类——GameUtil,ImagesUtil,ScreenUtil,先说屏幕工具类ScreenUtil。

ScreenUtil类下有2个方法:

public static DisplayMetrics getScreenSize(Context context)方法,该方法用于测量屏幕的宽和高。

public static float getDeviceDensity(Context context)方法,该方法用于测量屏幕density。


然后是图像工具类ImageUtil,该类有两个方法,用于实现图像的分割和自适应。

public void createInitBitmaps(int type, Bitmap picSelected,Context context),该方法用于切割图片并将图片初始化(按正常顺序),具体过程为——首先将传入Bitmap的长和宽等比切成Type份(Type为2,3,4,分别代表2*2,3*3,4*4难度),然后在一个二重循环中,每一次循环都创建一个长宽为原Bitmap的1/Type的小Bitmap(实际上就是将原图片一次切割成小块),然后将新创建的bitmap加载到bitmap列表bitmapItems中,再然后创建一个ItemBean(ItemBean为自定义的类,一会描述),将刚创建的ItemBean加载到GameUtil的ItemBean列表mItemBeans中。然后先保存最后一个图片以便在拼图完成时填充,再移除列表中最后一个图片(同时从bitmapItems和mItemBeans中移除),用一个blank图片来代替最后一个图片的位置(在两个列表中)。而blank所在的Bean的ItemId为type*type(代表最后一个图片),而BitmapId为0.

 public Bitmap resizeBitmap(float newWidth, float newHeight, Bitmap bitmap)方法,用于将指定Bitmap进行缩放。集体过程为通过矩阵Matrix进行缩放,然后创建新的Bitmap,该Bitmap以传入的Bitmap为基础,用矩阵进行缩放变换,最后返回该Bitmap。


最后是第三个工具类GameUtil,该类为拼图工具类,用于实现拼图的交换和生成算法。该类有一个静态公有的ItemBean列表mItenBeans,一个静态公有的ItemBean mBlankItemBean,有6个方法。

public static boolean isMoveable(int position) 方法,position为点击Item的ItemId,通过和blank的ItemId进行比较,来判断二者是否相邻。

public static void swapItems(ItemBean from, ItemBean blank)方法,该方法用于交换空格blank和点击的Item的方法,具体过程为先创建一个临时的ItenBean,然后借此将两个Item的Bitmap和BitmapId交换,然后设置好新的空格(注意:只是交换了图片和图片编号,位置编号ItemId并没有发生任何变化)。

public static int getInversions(List<Integer> data)方法,data为拼图数组数据,该方法用于计算该序列的倒置和。(随机生成的拼图有近一半不能复原,通过倒置和可以判断该拼图是否可以复原)

public static boolean canSolve(List<Integer> data)方法,data为拼图数组数据,该方法用于判断当前拼图是否有解,该方法中调用了public static int getInversions(List<Integer> data)方法。

public static void getPuzzleGenerator() 方法,具体商法是通过一个循环,在循环中生成随机数,用这个随机数来生产一个index,交换blank和该index的Item,然后调用public static boolean canSolve(List<Integer> data)方法判断是否有解,若无解,则再次调用该方法。

public static boolean isSuccess()方法,该方法用于判断拼图是否完成,具体过程为在遍历GameUtil.mItemBeans中的每一个ItemBean,若getBitmapId为0,则是blank,若不为0,则检查图片位置(BitmapId)和理论位置(ItemId)是否一致,若除blank以外都一致,则成功。

到此util包结束,下面是bean包。

bean包中只有一个类,就是ItemBean。

ItemBean有三个私有成员变量——int 型的mItemId(理论位置),mBitmapId(图片位置)和Bitmap型的mBitmap(图片)。该类有两个构造函数,一个无参数,一个有三个参数,此外还有6个方法,分别是以上三个变量的get和set方法。

到此bean包结束,下面是adapter包。

adapter包下有两个类——GridItemsAdapter,GridPicListAdapter。

GridItemsAdapter继承BaseAdapter,为拼图主界面适配器,该类有一个私有的Bitmap的list——mBitmapItemLists,一个Context——mContext,构造方法有两个参数。然后重写

public int getCount(),public Object getItem(int position),public long getItemId(int position)方法和public View getView(int position, View convertView, ViewGroup parent)方法,然后再最后一个方法中设置布局,图片和显示比例。

GridPicListAdapter同样继承自BaseAdapter,为程序主界面适配器。该类有一个私有的Bitmap的list——picList,一个私有Context——context,构造方法有两个参数。该类一样重写了public int getCount(),public Object getItem(int position),public long getItemId(int position)方法和public View getView(int position, View convertView, ViewGroup parent)方法。

至此adapter包结束,最后是activity包。

activity包有两个类,第一个类为——MainActivity(继承Activity并执行OnClickListener接口),该活动负责显示默认图片列表,自选图片按钮。

private void initViews()方法用来初始化Views,其中先找到的GridView,随后加载了所有默认图片的Id到数组,再然后根据这些Id在一个Bitmap数组中依次创建Bitmap,并将这些Bitmap加载到Bitmap的list。然后显示Type,然后找到3个显示不同Type的TextView,并设置点击事件。

private void popupShow(View view)用来显示pupup window.

然后重写了public void onClick(View v)方法,在该方法中,分别设置了mType的值并显示,最后用mPopupWindow.dismiss();方法取消popup Window。

重写了onCreate(Bundle savedInstanceState)方法,其中调用了initViews方法初始化View,设置了GridView点击事件来选择图片,设置了 mTvPuzzleMainTypeSelected的点击事件来选择难度,并用一个带有数据的intent来启动PuzzleMain活动。

第二个类——PuzzleMain(继承自Activity,实现了OnClickListener接口),该类用于拼图主界面的面板显示。

首先定义了一个Handler来更新计时器。

然后在onCreate方法中进行加载图片,设置点击事件,判断是否完成等工作。有三个按钮,重置,显示原图,并设置点击事件。在显示原图中调用了两个动画,隐藏和显示动画,代码分别为

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">    <translate        android:duration="1000"        android:fromYDelta="0%"        android:toYDelta="-200%" /></set>
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">    <translate        android:duration="1000"        android:fromYDelta="-200%"        android:toYDelta="0%" /></set>

之所以都是200%,是因为这个百分比是按图片本身大小来算的,而图片是小于屏幕的,如果只是100%,效果就是图片的底移动到顶边处然后消失,会显得很不自然。

在重写onClick方法中的重置按钮时调用了以下几个方法——cleanConfig()(清除已有数据),generateGame()(生成游戏数据),recreateData()(将重新生成后的Bitmap依次加载到Bitmap的list中),最后将list加载到GridView



0 0
原创粉丝点击