android开发分享Android自定义View实现拼图小游戏

本文实例为大家分享了android拼图小游戏的具体代码,供大家参考,具体内容如下 1、效果图: 运行时: 结束时: 2、puzzlelayoutview: p

android开发分享Android自定义View实现拼图小游戏实例为大家分享了android拼图小游戏的具体代码,供大家参考,具体内容如下

1、效果图:

运行时:

Android自定义View实现拼图小游戏

结束时:

Android自定义View实现拼图小游戏

2、puzzlelayoutview:

  public class puzzlelayoutview extends relativelayout implements view.onclicklistener {      //表示将其切成2*2拼图(默认4块)    private int mcolumn = 2;    //容器的内边距    private int mpadding;    //每个块块的边距(横,纵  3:表示间距为3dp)    private int mmargin = 3;    //存储imageview    private imageview[] mgamepintuitems;    //item的宽度(一致)    private int mitemwidth;    //游戏的图片    private bitmap mbitmap;    //切图后的存储    private list<imagepiecebean> mitembitmaps;    //操作次数    private boolean once;    //容器宽度(游戏面板 高宽一致)    private int mwidth;    //设置游戏是否成功    private boolean isgamesuccess;    //设置游戏是否失败    private boolean isgameover;      public gamepintulistner mlistner;      public puzzlelayoutview(context context) {      this(context, null);    }      public puzzlelayoutview(context context, attributeset attrs) {      this(context, attrs, 0);    }      public puzzlelayoutview(context context, attributeset attrs, int defstyle) {      super(context, attrs, defstyle);      init();    }      private void init() {      mmargin = (int) typedvalue.applydimension(typedvalue.complex_unit_dip, 3,          getresources().getdisplaymetrics());//将dp转化为px,或xp转化为px      mpadding = min(getpaddingleft(), getpaddingright(), getpaddingtop(), getpaddingbottom());    }      //接口方法    public interface gamepintulistner {        void nextlevel(int nextlevel);//下一关        void timechanged(int currenttime);//关卡时间        void gameover();//游戏结束    }      public void setongamepintulistner(gamepintulistner mlistner) {      this.mlistner = mlistner;    }      private int level = 1;    private static final int time_changed = 0x123;    private static final int next_level = 0x124;        private handler handler = new handler() {      public void handlemessage(android.os.message msg) {        switch (msg.what) {          case time_changed:            if (isgamesuccess || isgameover)              return;            if (mlistner != null) {              mlistner.timechanged(mtime);              //时间结束后,游戏结束              if (mtime == 0) {                isgameover = true;                mlistner.gameover();              }            }            mtime--;            //延迟1秒发送            handler.sendemptymessagedelayed(time_changed, 1000);            break;          case next_level:            level = level + 1;//切换到下一关            if (mlistner != null) {              mlistner.nextlevel(level);            } else {              nextlevel();            }          default:            break;        }      }    };        private boolean istimeenabled = false;    private int mtime;      /**     * 设置是否启动时间  (默认不启动)     *     * @param istimeenabled     */    public void settimeenabled(boolean istimeenabled) {      this.istimeenabled = istimeenabled;    }      /**     * 获取当前布局的大小(正方形)     */    protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {      super.onmeasure(widthmeasurespec, heightmeasurespec);      //取宽和高中的最小值      mwidth = math.min(getmeasuredheight(), getmeasuredwidth());      if (!once) {        //调用进行切图,以及排序(方法)        initbitmap();        //调用设置imageview(item)的宽高等属性(方法)        inititem();        //判断是否开启时间(方法调用)        checktimeenable();        once = true;      }      setmeasureddimension(mwidth, mwidth);//强制调用使面板为正方形    }      /**     * 判断是否开启时间     */    private void checktimeenable() {      if (istimeenabled) {        //根据当前等级设置时间        counttimebaselevel();        //通知线程更新关卡时间        handler.sendemptymessage(time_changed);      }      }      private void counttimebaselevel() {      mtime = (int) math.pow(2, level) * 60;//第一关120秒 第二关:240 第三关:480    }      /**     * 进行切图,以及排序方法     */    private void initbitmap() {      //将图片引入      if (mbitmap == null) {        mbitmap = bitmapfactory.decoderesource(getresources(), r.drawable.pic_view);//注意此处的导包      }      mitembitmaps = imagesplitterutil.sqlitimage(mbitmap, mcolumn);//返回长度为4 (2*2)      //使用sort进行乱排序      collections.sort(mitembitmaps, new comparator<imagepiecebean>() {        public int compare(imagepiecebean a, imagepiecebean b) {//注意此处的a,b          //是否大于0.5具有不确定性          return math.random() > 0.5 ? 1 : -1;        }      });    }      /**     * 设置imageview(item)的宽高等属性方法     */    private void inititem() {      //容器的宽度-item内边距 =所有小块块加起来的/item个数(宽度)  2:左边和右边边距      mitemwidth = (mwidth - mpadding * 2 - mmargin * (mcolumn - 1)) / mcolumn;      mgamepintuitems = new imageview[mcolumn * mcolumn];//界面块块个数相*      //生成我们的item,设置rule(item间的关系,高矮等)      for (int i = 0; i < mgamepintuitems.length; i++) {        imageview item = new imageview(getcontext());        /**         * item点击事件         */        item.setonclicklistener(this);        item.setimagebitmap(mitembitmaps.get(i).getbitmap());//此前以进行过乱排序        mgamepintuitems[i] = item;//保存item        item.setid(i + 1);        //在item的tag中存储了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());        }        //如果不是第一行,设置topmargin和rule        if (i + 1 > mcolumn) {          lp.topmargin = mmargin;          lp.addrule(relativelayout.below, mgamepintuitems[i - mcolumn].getid());        }        addview(item, lp);//添加到relativelayout中      }    }      /**     * 当过关失败,时间停止时调用此方法(重新开始此关卡)     */    public void restart() {      isgameover = false;//重置当前关卡      mcolumn--;      nextlevel();    }      public void nextlevel() {      this.removeallviews();//移除当前所有view      manimlayout = null;      mcolumn++;//由2*2 变为3*3游戏面版      isgamesuccess = false;//游戏未成功(新的开始)      checktimeenable();//下一关时间重新计算      initbitmap();      inititem();    }      /**     * 获取多个参数的最小值     */    private int min(int... params) {//...传多个参数      int min = params[0];//获取最小的      for (int param : params) {//发现最小的则赋值        if (param < min) {          min = param;        }      }      return min;    }      /**     * 点击事件     */    private imageview mfirst;//点击的iitem    private imageview msecond;      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("#5551c4d4"));//设置选中item时的颜色(55为半透明)      } else {        msecond = (imageview) v;        //交换我们的item        exchangeview();      }    }      /**     * 动画层     */    private relativelayout manimlayout;    //设置图片进行切换时用户疯狂点击    private boolean isaniming;      /**     * 交换我们的item     */    private void exchangeview() {      mfirst.setcolorfilter(null);//去除颜色状态(高亮)      //调用构造我们的动画层方法      setupanimlayout();      //进行图片的交换      imageview first = new imageview(getcontext());      final bitmap firstbitmap = mitembitmaps.get(getimageidbytag((string) mfirst.gettag())).getbitmap();      first.setimagebitmap(firstbitmap);      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 secondbitmap = mitembitmaps.get(getimageidbytag((string) msecond.gettag())).getbitmap();      second.setimagebitmap(secondbitmap);      layoutparams lp2 = new layoutparams(mitemwidth, mitemwidth);      lp2.leftmargin = msecond.getleft() - mpadding;      lp2.topmargin = msecond.gettop() - mpadding;      second.setlayoutparams(lp2);      manimlayout.addview(second);//添加至动画层        //设置动画      translateanimation animfirst = new translateanimation(0, msecond.getleft() - mfirst.getleft(),          0, msecond.gettop() - mfirst.gettop());      animfirst.setduration(500);//设置动画时间      animfirst.setfillafter(true);//设置动画结束的位置      first.startanimation(animfirst);//启动动画        translateanimation animsecond = new translateanimation(0, -msecond.getleft() + mfirst.getleft(),          0, -msecond.gettop() + mfirst.gettop());      animsecond.setduration(500);//设置动画时间      animsecond.setfillafter(true);//设置动画结束的位置      second.startanimation(animsecond);//启动动画        /**       * 监听动画事件       */      animfirst.setanimationlistener(new animation.animationlistener() {        public void onanimationstart(animation animation) {          mfirst.setvisibility(view.invisible);//隐藏动画          msecond.setvisibility(view.invisible);          isaniming = true;        }          public void onanimationrepeat(animation animation) {        }          public void onanimationend(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);          //此处为空,并不是将对象设置为null 而是将mfirst与bitmap对象链接的线断开          mfirst = msecond = null;//回到初始状态          manimlayout.removeallviews();//移除动画层的两个view          //调用判断游戏成功时的方法          checksuccess();          isaniming = false;        }      });    }      /**     * 判断游戏是否成功     */    private void checksuccess() {        boolean issuccess = true;      for (int i = 0; i < mgamepintuitems.length; i++) {        imageview imageview = mgamepintuitems[i];        //getimageindex:上面的方法名(注意此处方法名)        if (getimageindex((string) imageview.gettag()) != i) {          issuccess = false;        }      }      if (issuccess) {        isgamesuccess = true;        handler.removemessages(time_changed);//进入下一关时的时间        log.e("tag", "success");        toast.maketext(getcontext(), "success,level up 游戏升级!!!", toast.length_long).show();        handler.sendemptymessage(next_level);      }    }      /**     * 根据tag获取id     */    public int getimageidbytag(string tag) {      string[] split = tag.split("_");      return integer.parseint(split[0]);//拿id    }      public int getimageindex(string tag) {      string[] split = tag.split("_");      return integer.parseint(split[1]);//拿id    }      /**     * 构造我们的动画层     */    private void setupanimlayout() {      if (manimlayout == null) {        manimlayout = new relativelayout(getcontext());        addview(manimlayout);//添加到游戏面板中      }    }  }

工具类:imagesplitterutil

  public class imagesplitterutil {      /**     * 传入bitmap,切成piece*piece块     */    public static list<imagepiecebean> sqlitimage(bitmap bitmap, int piece) {      list<imagepiecebean> imagepiecebeans = new arraylist<>();        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++) {//循环切第二,三行          imagepiecebean imagepiecebean = new imagepiecebean();          imagepiecebean.setindex(j + i * piece);//第一次i为0,第0行 j++递增 0-6          int x = j * piecewidth;//第一次循环x,y为0          int y = i * piecewidth;          imagepiecebean.setbitmap(bitmap.createbitmap(bitmap, x, y, piecewidth, piecewidth));          imagepiecebeans.add(imagepiecebean);        }      }      return imagepiecebeans;    }  }

实体类:imagepiecebean

  public class imagepiecebean {      private int index;  //表示当前第几块    private bitmap bitmap;  //当前图片      public imagepiecebean() {    }      //快捷键构造方法 source 倒3    public imagepiecebean(int index, bitmap bitmap) {      this.index = index;      this.bitmap = bitmap;    }      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;    }      public string tostring() {      return "imagepiece [index=" + index + ", bitmap=" + bitmap + "]";    }  }

3、使用方法:gameactivity

  /**   * 总结:   * 1.自定义控件选择,九宫格,relativelayout, id+rule   * 2.切图   * 3.动画图层   * 4.pause resume restart   * 5.游戏时间 handler sendmessagedelayed() 延迟一秒发送线程   */  public class gameactivity extends appcompatactivity {      private puzzlelayoutview puzzlelayoutview;    private textview mlevel, mtime;      protected void oncreate(bundle savedinstancestate) {      super.oncreate(savedinstancestate);      requestwindowfeature(window.feature_no_title);      setcontentview(r.layout.activity_game);        mlevel = this.findviewbyid(r.id.id_level);      mtime = this.findviewbyid(r.id.id_time);      puzzlelayoutview = this.findviewbyid(r.id.puzzle_layout_view);      puzzlelayoutview.settimeenabled(true);      //监听事件      puzzlelayoutview.setongamepintulistner(new puzzlelayoutview.gamepintulistner() {        public void timechanged(int currenttime) {          //此处为int 注意加""          mtime.settext(currenttime + "秒");        }          public void nextlevel(final int nextlevel) {          //弹出提示框          new alertdialog.builder(gameactivity.this).settitle("游戏信息")              .setmessage("游戏升级").setpositivebutton("进入下一关",              new dialoginterface.onclicklistener() {                public void onclick(dialoginterface dialog, int which) {                  //游戏结束后,调用下一关                  puzzlelayoutview.nextlevel();                  mlevel.settext("第" + +nextlevel + "关");                }              }).show();        }          public void gameover() {          //弹出提示框          new alertdialog.builder(gameactivity.this).settitle("游戏信息")              .setmessage("游戏结束!").setpositivebutton("是否继续该关卡?",              new dialoginterface.onclicklistener() {                public void onclick(dialoginterface dialog, int which) {                  puzzlelayoutview.restart();//重新启动                }              }).setnegativebutton("是否放弃该游戏!", new dialoginterface.onclicklistener() {            public void onclick(dialoginterface dialog, int which) {              finish();            }          }).show();        }      });    }  }

对应布局:activity_game

  <linearlayout xmlns:android="https://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:layout_margin="10dp"    android:gravity="center_horizontal"    android:orientation="vertical">      <relativelayout      android:layout_width="match_parent"      android:layout_height="wrap_content">        <textview        android:id="@+id/id_level"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:gravity="center"        android:text="1"        android:textsize="25sp"        android:textstyle="bold" />        <textview        android:id="@+id/id_time"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignparentright="true"        android:gravity="center"        android:text="120"        android:textcolor="#ea7821"        android:textsize="25sp"        android:textstyle="bold" />    </relativelayout>      <imageview      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginbottom="10dp"      android:src="@drawable/pic_view" />      <com.helloworld.game.utils.puzzlelayoutview      android:id="@+id/puzzle_layout_view"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:padding="3dp" />    </linearlayout>

注意:pic_view图片资源自行更换

以上就是android开发分享Android自定义View实现拼图小游戏的全部内容,希望对大家的学习有所帮助,也希望大家多多支持<计算机技术网(www.ctvol.com)!!>。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/899474.html

(0)
上一篇 2021年10月23日
下一篇 2021年10月23日

精彩推荐