分享

Android拼图游戏开发全纪录5

 水与火604 2016-03-13

今天我们终于可以把这个项目给结束掉啦,有了前几天的准备,相信最后一天还是比较轻松的,国际惯例:


最后要完成的就是我们的主要功能--拼图界面。

布局比较简单,在前几天就已经做好了,现在我们要做的是以下几件事情:

1、计时记步:这个是游戏基本都有的功能,其实也比较简单,记录成功移动的步数、显示一个计时器就行了。

2、处理图片,调整为合适的大小比例:这个方法在前几天已经实现了

3、点击GridView后移动图片:是否能移动的方法已经在前几天实现了

4、判断是否拼图完成:唉,也已经实现了

5、点击原图按钮:显示原图:只要显示一个ImageView就可以了

6、点击重置按钮:将传进来的这张图片重新处理一遍流程

基本思路写完了,看来很复杂的事情,是不是梳理下就觉得很简单了,很多准备工作做好了,会让我们的思路变的更清晰。


  1. package com.xys.xpuzzle.activity;  
  2.   
  3. import java.io.File;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6. import java.util.Timer;  
  7. import java.util.TimerTask;  
  8.   
  9. import android.app.Activity;  
  10. import android.graphics.Bitmap;  
  11. import android.graphics.BitmapFactory;  
  12. import android.os.Bundle;  
  13. import android.os.Handler;  
  14. import android.os.Message;  
  15. import android.view.View;  
  16. import android.view.View.OnClickListener;  
  17. import android.view.animation.Animation;  
  18. import android.view.animation.AnimationUtils;  
  19. import android.widget.AdapterView;  
  20. import android.widget.AdapterView.OnItemClickListener;  
  21. import android.widget.Button;  
  22. import android.widget.GridView;  
  23. import android.widget.ImageView;  
  24. import android.widget.RelativeLayout;  
  25. import android.widget.RelativeLayout.LayoutParams;  
  26. import android.widget.TextView;  
  27. import android.widget.Toast;  
  28.   
  29. import com.xys.xpuzzle.R;  
  30. import com.xys.xpuzzle.adapter.GridItemsAdapter;  
  31. import com.xys.xpuzzle.bean.ItemBean;  
  32. import com.xys.xpuzzle.util.GameUtil;  
  33. import com.xys.xpuzzle.util.ImagesUtil;  
  34. import com.xys.xpuzzle.util.ScreenUtil;  
  35.   
  36. /** 
  37.  * 拼图逻辑主界面:面板显示 
  38.  *  
  39.  * @author xys 
  40.  *  
  41.  */  
  42. public class PuzzleMain extends Activity implements OnClickListener {  
  43.   
  44.     // 选择的图片  
  45.     private Bitmap picSelected;  
  46.     // 拼图完成时显示的最后一个图片  
  47.     public static Bitmap lastBitmap;  
  48.     // PuzzlePanel  
  49.     private GridView gv_puzzle_main_detail;  
  50.     private int resId;  
  51.     private String picPath;  
  52.     private ImageView imageView;  
  53.     // Button  
  54.     private Button btnBack;  
  55.     private Button btnImage;  
  56.     private Button btnRestart;  
  57.     // 显示步数  
  58.     private TextView tv_puzzle_main_counts;  
  59.     // 计时器  
  60.     private TextView tv_Timer;  
  61.     // 切图后的图片  
  62.     private List<Bitmap> bitmapItemLists = new ArrayList<Bitmap>();  
  63.     // GridView适配器  
  64.     private GridItemsAdapter adapter;  
  65.     // 设置为N*N显示  
  66.     public static int type = 2;  
  67.     // Flag 是否已显示原图  
  68.     private boolean isShowImg;  
  69.     // 步数显示  
  70.     public static int countIndex = 0;  
  71.     // 计时显示  
  72.     public static int timerIndex = 0;  
  73.     // 计时器类  
  74.     private Timer timer;  
  75.   
  76.     /** 
  77.      * UI更新Handler 
  78.      */  
  79.     private Handler handler = new Handler() {  
  80.   
  81.     @Override  
  82.     public void handleMessage(Message msg) {  
  83.         switch (msg.what) {  
  84.         case 1:  
  85.         // 更新计时器  
  86.         timerIndex++;  
  87.         tv_Timer.setText("" + timerIndex);  
  88.         break;  
  89.         default:  
  90.         break;  
  91.         }  
  92.     }  
  93.     };  
  94.   
  95.     /** 
  96.      * 计时器线程 
  97.      */  
  98.     private TimerTask timerTask;  
  99.   
  100.     @Override  
  101.     protected void onCreate(Bundle savedInstanceState) {  
  102.     super.onCreate(savedInstanceState);  
  103.     setContentView(R.layout.xpuzzle_puzzle_detail_main);  
  104.     // 获取选择的图片  
  105.     Bitmap picSelectedTemp;  
  106.     // 选择默认图片还是自定义图片  
  107.     resId = getIntent().getExtras().getInt("picSelectedID");  
  108.     picPath = getIntent().getExtras().getString("picPath");  
  109.     if (resId != 0) {  
  110.         picSelectedTemp = BitmapFactory.decodeResource(getResources(), resId);  
  111.     } else {  
  112.         picSelectedTemp = BitmapFactory.decodeFile(picPath);  
  113.     }  
  114.     type = getIntent().getExtras().getInt("type", 2);  
  115.     // 对图片处理  
  116.     handlerImage(picSelectedTemp);  
  117.     // 初始化Views  
  118.     initViews();  
  119.     // 生成游戏数据  
  120.     generateGame();  
  121.     // GridView点击事件  
  122.     gv_puzzle_main_detail.setOnItemClickListener(new OnItemClickListener() {  
  123.   
  124.         @Override  
  125.         public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {  
  126.         // 判断是否可移动  
  127.         if (GameUtil.isMoveable(position)) {  
  128.             // 交换点击Item与空格的位置  
  129.             GameUtil.swapItems(GameUtil.itemBeans.get(position), GameUtil.blankItemBean);  
  130.             // 重新获取图片  
  131.             recreateData();  
  132.             // 通知GridView更改UI  
  133.             adapter.notifyDataSetChanged();  
  134.             // 更新步数  
  135.             countIndex++;  
  136.             tv_puzzle_main_counts.setText("" + countIndex);  
  137.             // 判断是否成功  
  138.             if (GameUtil.isSuccess()) {  
  139.             // 将最后一张图显示完整  
  140.             recreateData();  
  141.             bitmapItemLists.remove(type * type - 1);  
  142.             bitmapItemLists.add(lastBitmap);  
  143.             // 通知GridView更改UI  
  144.             adapter.notifyDataSetChanged();  
  145.             Toast.makeText(PuzzleMain.this, "拼图成功!", Toast.LENGTH_LONG).show();  
  146.             gv_puzzle_main_detail.setEnabled(false);  
  147.             timer.cancel();  
  148.             timerTask.cancel();  
  149.             }  
  150.         }  
  151.         }  
  152.     });  
  153.     // 返回按钮点击事件  
  154.     btnBack.setOnClickListener(this);  
  155.     // 显示原图按钮点击事件  
  156.     btnImage.setOnClickListener(this);  
  157.     // 重置按钮点击事件  
  158.     btnRestart.setOnClickListener(this);  
  159.     }  
  160.   
  161.     /** 
  162.      * Button点击事件 
  163.      */  
  164.     @Override  
  165.     public void onClick(View v) {  
  166.     switch (v.getId()) {  
  167.     // 返回按钮点击事件  
  168.     case R.id.btn_puzzle_main_back:  
  169.         PuzzleMain.this.finish();  
  170.         break;  
  171.     // 显示原图按钮点击事件  
  172.     case R.id.btn_puzzle_main_img:  
  173.         Animation animShow = AnimationUtils.loadAnimation(PuzzleMain.this, R.anim.image_show_anim);  
  174.         Animation animHide = AnimationUtils.loadAnimation(PuzzleMain.this, R.anim.image_hide_anim);  
  175.         if (isShowImg) {  
  176.         imageView.startAnimation(animHide);  
  177.         imageView.setVisibility(View.GONE);  
  178.         isShowImg = false;  
  179.         } else {  
  180.         imageView.startAnimation(animShow);  
  181.         imageView.setVisibility(View.VISIBLE);  
  182.         isShowImg = true;  
  183.         }  
  184.         break;  
  185.     // 重置按钮点击事件  
  186.     case R.id.btn_puzzle_main_restart:  
  187.         cleanConfig();  
  188.         generateGame();  
  189.         recreateData();  
  190.         // 通知GridView更改UI  
  191.         tv_puzzle_main_counts.setText("" + countIndex);  
  192.         adapter.notifyDataSetChanged();  
  193.         gv_puzzle_main_detail.setEnabled(true);  
  194.         break;  
  195.     default:  
  196.         break;  
  197.     }  
  198.     }  
  199.   
  200.     /** 
  201.      * 生成游戏数据 
  202.      */  
  203.     private void generateGame() {  
  204.     // 切图 获取初始拼图数据 正常顺序  
  205.     new ImagesUtil().createInitBitmaps(type, picSelected, PuzzleMain.this);  
  206.     // 生成随机数据  
  207.     GameUtil.getPuzzleGenerator();  
  208.     // 获取Bitmap集合  
  209.     for (ItemBean temp : GameUtil.itemBeans) {  
  210.         bitmapItemLists.add(temp.getBitmap());  
  211.     }  
  212.   
  213.     // 数据适配器  
  214.     adapter = new GridItemsAdapter(this, bitmapItemLists);  
  215.     gv_puzzle_main_detail.setAdapter(adapter);  
  216.   
  217.     // 启用计时器  
  218.     timer = new Timer(true);  
  219.     // 计时器线程  
  220.     timerTask = new TimerTask() {  
  221.   
  222.         @Override  
  223.         public void run() {  
  224.         Message msg = new Message();  
  225.         msg.what = 1;  
  226.         handler.sendMessage(msg);  
  227.         }  
  228.     };  
  229.     // 每1000ms执行 延迟0s  
  230.     timer.schedule(timerTask, 0, 1000);  
  231.     }  
  232.   
  233.     /** 
  234.      * 添加显示原图的View 
  235.      */  
  236.     private void addImgView() {  
  237.     RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rl_puzzle_main_main_layout);  
  238.     imageView = new ImageView(PuzzleMain.this);  
  239.     imageView.setImageBitmap(picSelected);  
  240.     int x = (int) (picSelected.getWidth() * 0.9F);  
  241.     int y = (int) (picSelected.getHeight() * 0.9F);  
  242.     LayoutParams params = new LayoutParams(x, y);  
  243.     params.addRule(RelativeLayout.CENTER_IN_PARENT);  
  244.     imageView.setLayoutParams(params);  
  245.     relativeLayout.addView(imageView);  
  246.     imageView.setVisibility(View.GONE);  
  247.     }  
  248.   
  249.     /** 
  250.      * 返回时调用 
  251.      */  
  252.     @Override  
  253.     protected void onStop() {  
  254.     super.onStop();  
  255.     // 清空相关参数设置  
  256.     cleanConfig();  
  257.     this.finish();  
  258.     }  
  259.   
  260.     /** 
  261.      * 清空相关参数设置 
  262.      */  
  263.     private void cleanConfig() {  
  264.     // 清空相关参数设置  
  265.     GameUtil.itemBeans.clear();  
  266.     // 停止计时器  
  267.     timer.cancel();  
  268.     timerTask.cancel();  
  269.     countIndex = 0;  
  270.     timerIndex = 0;  
  271.     // 清除拍摄的照片  
  272.     if (picPath != null) {  
  273.         // 删除照片  
  274.         File file = new File(MainActivity.TEMP_IMAGE_PATH);  
  275.         if (file.exists()) {  
  276.         file.delete();  
  277.         }  
  278.     }  
  279.     }  
  280.   
  281.     /** 
  282.      * 重新获取图片 
  283.      */  
  284.     private void recreateData() {  
  285.     bitmapItemLists.clear();  
  286.     for (ItemBean temp : GameUtil.itemBeans) {  
  287.         bitmapItemLists.add(temp.getBitmap());  
  288.     }  
  289.     }  
  290.   
  291.     /** 
  292.      * 对图片处理 自适应大小 
  293.      *  
  294.      * @param bitmap 
  295.      */  
  296.     private void handlerImage(Bitmap bitmap) {  
  297.     // 将图片放大到固定尺寸  
  298.     int screenWidth = ScreenUtil.getScreenSize(this).widthPixels;  
  299.     int screenHeigt = ScreenUtil.getScreenSize(this).heightPixels;  
  300.     picSelected = new ImagesUtil().resizeBitmap(screenWidth * 0.8f, screenHeigt * 0.6f, bitmap);  
  301.     }  
  302.   
  303.     /** 
  304.      * 初始化Views 
  305.      */  
  306.     private void initViews() {  
  307.     // Button  
  308.     btnBack = (Button) findViewById(R.id.btn_puzzle_main_back);  
  309.     btnImage = (Button) findViewById(R.id.btn_puzzle_main_img);  
  310.     btnRestart = (Button) findViewById(R.id.btn_puzzle_main_restart);  
  311.     // Flag 是否已显示原图  
  312.     isShowImg = false;  
  313.   
  314.     // GV  
  315.     gv_puzzle_main_detail = (GridView) findViewById(R.id.gv_puzzle_main_detail);  
  316.     // 设置为N*N显示  
  317.     gv_puzzle_main_detail.setNumColumns(type);  
  318.     LayoutParams gridParams = new RelativeLayout.LayoutParams(picSelected.getWidth(), picSelected.getHeight());  
  319.     // 水平居中  
  320.     gridParams.addRule(RelativeLayout.CENTER_HORIZONTAL);  
  321.     // 其他格式属性  
  322.     gridParams.addRule(RelativeLayout.BELOW, R.id.ll_puzzle_main_spinner);  
  323.     // Grid显示  
  324.     gv_puzzle_main_detail.setLayoutParams(gridParams);  
  325.     gv_puzzle_main_detail.setHorizontalSpacing(0);  
  326.     gv_puzzle_main_detail.setVerticalSpacing(0);  
  327.   
  328.     // TV步数  
  329.     tv_puzzle_main_counts = (TextView) findViewById(R.id.tv_puzzle_main_counts);  
  330.     tv_puzzle_main_counts.setText("" + countIndex);  
  331.     // TV计时器  
  332.     tv_Timer = (TextView) findViewById(R.id.tv_puzzle_main_time);  
  333.     tv_Timer.setText("0秒");  
  334.   
  335.     // 添加显示原图的View  
  336.     addImgView();  
  337.     }  
  338. }  

自认为注释、代码风格还是不错的,希望大家喜欢。

PS:需要源代码的朋友请留言,其实根据这个思路自己去实现下,对自己是有很大提高的,如果能优化我的代码,那就更好了,可以一起学习交流下。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多