In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article will explain in detail how Android customizes View to achieve Mini Game puzzles. The editor thinks it is very practical, so I share it with you for reference. I hope you can get something after reading this article.
PuzzleLayoutView:
Public class PuzzleLayoutView extends RelativeLayout implements View.OnClickListener {/ / indicates that it is cut into 2x2 puzzles (default 4 pieces) private int mColumn = 2; / / the inner margin of the container private int mPadding; / / the margin of each block (horizontal, vertical 3: indicates the spacing is 3dp) private int mMargin = 3; / / stores the width of ImageView private ImageView [] mGamePintuItems; / / Item (consistent) private int mItemWidth; / / the picture private Bitmap mBitmap of the game / / Storage private List mItemBitmaps; / / number of operations private boolean once; / / Container width (the game panel is the same height and width) private int mWidth; / / set whether the game is successful private boolean isGameSuccess; / / set whether the game fails 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 ()); / / convert dp to px, or xp to px mPadding = min (getPaddingLeft (), getPaddingRight (), getPaddingTop (), getPaddingBottom ()) } / / Interface method public interface GamePintuListner {void nextLevel (int nextLevel); / / next level void timechanged (int currentTime); / / checkpoint time void gameover (); / / Game over} 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) / / after the end of the game, if (mTime = = 0) {isGameOver = true; mListner.gameover ();}} mTime--; / / delay 1 second to send handler.sendEmptyMessageDelayed (TIME_CHANGED, 1000); break Case NEXT_LEVEL: level = level + 1 level / switch to the next level if (mListner! = null) {mListner.nextLevel (level);} else {nextLevel ();} default: break;}; private boolean isTimeEnabled = false; private int mTime / * set whether the startup time (default is not enabled) * * @ param isTimeEnabled * / public void setTimeEnabled (boolean isTimeEnabled) {this.isTimeEnabled = isTimeEnabled;} / * get the size of the current layout (square) * / protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure (widthMeasureSpec, heightMeasureSpec) / / take the minimum values of width and high school mWidth = Math.min (getMeasuredHeight (), getMeasuredWidth ()); if (! once) {/ / call to cut the image and sort (method) initBitmap (); / / call to set the wide and high attribute (method) of ImageView (Item) initItem (); / / determine whether the opening time (method call) checkTimeEnable (); once = true } setMeasuredDimension (mWidth, mWidth); / / call to make the panel square} / * to determine whether the opening time is * / private void checkTimeEnable () {if (isTimeEnabled) {/ / set the time countTimeBaseLevel () according to the current level; / / notify the thread to update the level time handler.sendEmptyMessage (TIME_CHANGED) }} private void countTimeBaseLevel () {mTime = (int) Math.pow (2, level) * 60 mBitmap / first level 120s second level: 2403rd level: 480} / * to cut images, and sorting method * / private void initBitmap () {/ / introduce pictures into if (mBitmap = = null) {mBitmap = BitmapFactory.decodeResource (getResources (), R.drawable.pic_view) / / Note the guide package} mItemBitmaps = ImageSplitterUtil.sqlitImage (mBitmap, mColumn) here; / / return length is 4 (2x2) / / use sort to disorderly sort Collections.sort (mItemBitmaps, new Comparator () {public int compare (ImagePieceBean a, ImagePieceBean b) {/ / Note whether return Math.random () > 0. 5? 1:-1 is uncertain when aLead b / / is greater than 0. 5 }});} / * method for setting wide and high properties of ImageView (Item) * / private void initItem () {/ / container width-Item inner margin = total / Item of all small chunks (width) 2: left and right margins mItemWidth = (mWidth-mPadding * 2-mMargin * (mColumn-1)) / mColumn; mGamePintuItems = new ImageView [mColumn * mColumn] / / number of interface blocks * / / generate our Item, set Rule (relationship between Item, height, etc.) 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); / / add to RelativeLayout}} / * this method is called when clearance fails and the time stops (restart this level) * / public void restart () {isGameOver = false;// resets the current level mColumn-- NextLevel ();} public void nextLevel () {this.removeAllViews (); / / remove all current View mAnimLayout = null; mColumn++;// from 2x2 to 3x3 game facet isGameSuccess = false;// game failed (new start) checkTimeEnable (); / / the next pass time recalculates initBitmap (); initItem () } / * get the minimum value of multiple parameters * / private int min (int... Params) {/ /. Pass multiple parameters int min = params [0]; / / get the smallest for (int param: params) {/ / find the smallest and assign if (param < min) {min = param;}} return min;} / * * Click event * / IItem private ImageView mSecond; public void onClick (View v) {if (isAniming) return clicked by private ImageView mFirst;// / / Click the same Item if (mFirst = = v) {mFirst.setColorFilter (null); mFirst = null; return;} if (mFirst = = null) {mFirst = (ImageView) v; mFirst.setColorFilter (Color.parseColor ("# 5551c4d4")); / / set the color (55 is translucent)} else {mSecond = (ImageView) v when Item is selected / / swap our Item exchangeView ();}} / * Animation layer * / private RelativeLayout mAnimLayout; / / when setting the picture to switch, users frantically click private boolean isAniming; / * to exchange our Item * / private void exchangeView () {mFirst.setColorFilter (null) / / remove the color state (highlight) / / call the method setUpAnimLayout () to construct our animation layer; / / swap the image 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); / / add to animation layer 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); / / add to animation layer / / animate TranslateAnimation animFirst = new TranslateAnimation (0, mSecond.getLeft ()-mFirst.getLeft (), 0, mSecond.getTop ()-mFirst.getTop ()); animFirst.setDuration (500); / / animate animFirst.setFillAfter (true) / / set animation end position first.startAnimation (animFirst); / / start animation TranslateAnimation animSecond = new TranslateAnimation (0,-mSecond.getLeft () + mFirst.getLeft (), 0,-mSecond.getTop () + mFirst.getTop ()); animSecond.setDuration (500); / / set animation time animSecond.setFillAfter (true); / / set animation end position second.startAnimation (animSecond) / / start animation / * listen for animation events * / animFirst.setAnimationListener (new Animation.AnimationListener () {public void onAnimationStart (Animation animation) {mFirst.setVisibility (View.INVISIBLE); / / hide animation 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) / / Show the hidden picture mSecond.setVisibility (View.VISIBLE); / / empty here, instead of setting the object to null, disconnect the link between mFirst and Bitmap object mFirst = mSecond = null;// back to the original state mAnimLayout.removeAllViews (); / / remove two View / / from the animation layer to call the method checkSuccess () to judge the success of the game; isAniming = false }});} / * judge whether the game is successful or not * / private void checkSuccess () {boolean isSuccess = true; for (int I = 0; I < mGamePintuItems.length; iTunes +) {ImageView imageView = mGamePintuItems [I]; / / getImageIndex: the above method name (note here) if (getImageIndex ((String) imageView.getTag ())! = I) {isSuccess = false }} if (isSuccess) {isGameSuccess = true; handler.removeMessages (TIME_CHANGED); / / time to enter the next level Log.e ("TAG", "SUCCESS"); Toast.makeText (getContext (), "Success,level up Game upgrade!", Toast.LENGTH_LONG). Show (); handler.sendEmptyMessage (NEXT_LEVEL) }} / * obtain Id * / public int getImageIdByTag (String tag) {String [] split = tag.split ("_") according to tag; return Integer.parseInt (split [0]); / / take ID} public int getImageIndex (String tag) {String [] split = tag.split ("_"); return Integer.parseInt (split [1]) / / take ID} / * to construct our animation layer * / private void setUpAnimLayout () {if (mAnimLayout = = null) {mAnimLayout = new RelativeLayout (getContext ()); addView (mAnimLayout); / / add to the game panel}
Tool class: ImageSplitterUtil
Public class ImageSplitterUtil {/ * input bitmap and cut into piece*piece blocks * / public static List sqlitImage (Bitmap bitmap, int piece) {List ImagePieceBeans = new ArrayList (); int width = bitmap.getWidth (); / / get the width and height of the picture int height = bitmap.getHeight (); int pieceWidth = Math.min (width, height) / piece;// to get the width of each block for (int I = 0; I < piece ) {/ / cut the first line for (int j = 0; j < piece; jigsaw +) {/ / loop cut the second, three lines ImagePieceBean ImagePieceBean = new ImagePieceBean (); ImagePieceBean.setIndex (j + I * piece); / / the first I is 0, the 0th line is 0 int + increment 0-6 int x = j * pieceWidth;// the first cycle is 0 int y = I * pieceWidth ImagePieceBean.setBitmap (Bitmap.createBitmap (bitmap, x, y, pieceWidth, pieceWidth); ImagePieceBeans.add (ImagePieceBean);}} return ImagePieceBeans;}}
Entity class: ImagePieceBean
Public class ImagePieceBean {private int index; / / indicates the current number of private Bitmap bitmap; / / current picture public ImagePieceBean () {} / / shortcut key construction method Source inverted 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 + "]";}}
Usage: GameActivity
/ * Summary: * 1. Custom control selection, Nine Miyagi, RelativeLayout, id+Rule * 2. Cut the picture * 3. Animation layer * 4.pause resume restart * 5. Game time Handler sendMessageDelayed () delay one second sending thread * / 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); / / listen to the event puzzleLayoutView.setOnGamePintuListner (new PuzzleLayoutView.GamePintuListner () {public void timechanged (int currentTime) {/ / add "mTime.setText (currentTime +" seconds ") for int attention here) } public void nextLevel (final int nextLevel) {/ / pop-up prompt box new AlertDialog.Builder (GameActivity.this) .setTitle ("Game Information") .setMessage ("Game upgrade"). SetPositiveButton ("enter the next level", new DialogInterface.OnClickListener () {public void onClick (DialogInterface dialog, int which) {/ / after the game is over Call the next level puzzleLayoutView.nextLevel () MLevel.setText ("first" + nextLevel + "off");}}) .show () } public void gameover () {/ / pop-up prompt box new AlertDialog.Builder (GameActivity.this) .setTitle ("Game Information") .setMessage ("Game over!") .setPositiveButton ("do you want to continue this level?", new DialogInterface.OnClickListener () {public void onClick (DialogInterface dialog, int which) {puzzleLayoutView.restart () / / restart}}) .setNegativeButton ("whether to give up the game!", new DialogInterface.OnClickListener () {public void onClick (DialogInterface dialog, int which) {finish ();}) .show ();}});}}
Corresponding layout: activity_game
Note: pic_view image resources are replaced by themselves.
This is the end of the article on "Android how to customize the View puzzle Mini Game". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it out for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.