前回に引き続き、前回の記事でゲーム内のタイミングとプログラム片の自動ランダム配置を完了しましたが、この記事では残りの部分(片の動きとパズルの成功ロジック)を完了します。
実装プロセスは大まかに: 最後の写真はデフォルトでは表示されていませんが、実際には存在します. 空白領域で隣接する画像をクリックし (空白領域の画像のみがクリックされて有効になります)、その後の画像の動きを実現します.クリックして空白領域の交換. 2 番目の動きの後、最終的な合計画像の組み合わせが指定された最終画像と同じ場合、パズルの成功を示すプロンプト ボックスがポップアップ表示されます!
実際、要約は知識の配列です。配列の座標値交換で画像の交換を示し、画像の移動(配列数の交換)を数回使用して、取り込んだ最終的な指定画像(指定番号順)と同じかどうかをチェック!
具体的な実装方法: (コードのコメントはすでに非常に詳細であり、ロジックに従って段階的にコメントされているため、理解しやすい)
コメント領域で何かを理解できない場合, メッセージまたはプライベートメッセージを残すことができます. 記事にコードがある場合, ロジック, または不正確な書き込みエラー, 修正してください. 修正して時間内に学習します, ありがとう!
フラグメントをクリックした効果を得るには:
//指定した位置のボタンを移動し、画像を余白部分と入れ替える機能を 表します private void move(int imagebuttonId, int site) { //選択した画像がどの行と列にあるかを判定します。判定方法は残りのメソッド int sitex=site/imageX; int sitey=site%imageY; //空白領域の座標を取得します int blankx=blankSwap/imageX; int blanky=blankSwap%imageY; //画像が移動する 2 つの条件 // 1. 同じ行数と列数の減算の絶対値は 1; 2. 同じ列の行数の減算の絶対値は 1 int x=Math.abs(sitex- blankx); int y=Math.abs(sitey-blanky); if ((x == 0&&y==1)||(y==0&&x==1)){ //この可動ボタン ImageButton を id で見つける clickButton= findViewById(imagebuttonId); clickButton.setVisibility(View.INVISIBLE) ; // 空白領域を表示するボタン ImageButton blackButton=findViewById(blankImgid); //空白領域を画像に設定する blackButton.setImageResource(image[imageIndex[site]]); //移動間は非表示、移動後はコントロールを表示するように設定 blackButton.setVisibility(View . VISIBLE); //字幕を変更するプロセスを、画像の場所を格納する配列に記録します swap(site,blankSwap); //新しい空白領域の位置の更新は、受信したクリック ボタンの位置と同じ です blankSwap=site; blankImgid= imagebuttonId; }
破片が正常に移動したかどうかを数回後に判断することの論理的な効果を理解してください。
//パズルが成功したかどうかを判定し ます private voidudgerGameOver() { boolean loop=true;//フラグビットを定義します for(int i=0;i<imageIndex.length;i++) { if (imageIndex[i] != i ) { loop = false; break; } } if(loop){ //パズルが成功し、タイミングを停止する handler.removeMessages(1); //パズルが成功した後、プレイヤーはボタン ib00を動かし続けることを禁止される.setClickable(false); ib01.setClickable(false) ; ib02.setClickable(false); ib10.setClickable(false); ib11.setClickable(false); ib12.setClickable(false); ib20.setClickable(false); ib21.setClickable(false); ib22.setClickable(false); ib22.setImageResource(image[8]); ib22.setVisibility(View.VISIBLE); //ユーザー成功ダイアログをポップアップします AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setMessage("おめでとうございます。パズルは成功しました!あなたの時間は "+time+" 秒です").setPositiveButton("Confirm",null); builder.create().show( ) ; }
Java 総コード:
パッケージcom.example.jigsaw; import androidx.annotation.NonNull; androidx.appcompat.app.AlertDialog をインポートします。 androidx.appcompat.app.AppCompatActivity をインポートします。 android.annotation.SuppressLint をインポートします。 android.media.Image をインポートします。 android.os.Bundle をインポートします。 android.os.Handler をインポートします。 android.os.Message をインポートします。 android.text.AlteredCharSequence をインポートします。 android.view.View をインポートします。 android.widget.Button をインポートします。 android.widget.ImageButton をインポートします。 android.widget.TextView をインポートします。 public class MainActivity extends AppCompatActivity { ImageButton ib00,ib01,ib02,ib10,ib11,ib12,ib20,ib21,ib22; ボタン restartBtn; TextView timeTv; //一連の画像の個数を定義する private int imageX=3; private int imageY=3; //画像の総数 private int imgCount=imageX*imageY; //空白領域の位置 private int blankSwap=imgCount-1; //空白領域のボタン ID を初期化 private int blankImgid=R.id.pt_id_02x02; //時間変数を定義する int time = 0; //一元管理用フラグメントの配列を格納する private int[]image={R.drawable.pt_id_00x00,R.drawable.pt_id_00x01, R. drawable.pt_id_00x02 , R.drawable.pt_tv_01x00, R.drawable.pt_tv_01x01, R.drawable.pt_tv_01x02, R.drawable.p1, R.drawable.p2, R.drawable.p3}; //ピクチャ配列を宣言する 下付き配列,この配列をランダムに並べます private int[]imageIndex=new int[image.length]; Handler handler=new Handler(){ @Override public void handleMessage(@NonNull Message msg) { if (msg.what==1){ time++; timeTv.setText("Time: "+time+" seconds"); handler.sendEmptyMessageDelayed(1,1000); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView (); // フラグメント を中断し ます 。不規則な プライベート void をランダムに中断 します。の 破片 [i]=i; } //20回指定し、2つの添字に対応する値をランダムに選択して交換する int rand1,rand2; for(int j=0;j<20;j++){ //添字をランダムに生成し、値は 0 ~ 8 rand1=(int)(Math.random()*(imageIndex. length-1)); //ランダムに生成された 2 番目の添え字は、最初と同じにすることはできません do{ rand2=(int)(Math.random()*(imageIndex.length-1)); if(rand1! =rand2 ){ break; } }while (true); //2 つのコーナー マークの対応する値を交換します swap(rand1,rand2); } //指定されたコントロールにランダムに配置します ib00.setImageResource(image[imageIndex[0] ]); ib01.setImageResource(画像[画像インデックス[1]]); ib02.setImageResource(画像[画像インデックス[2]]); ib01=findViewById(R.id.pt_id_00x01); ib10.setImageResource(image[imageIndex[3]]); ib11.setImageResource(画像[画像インデックス[4]]); ib12.setImageResource(画像[画像インデックス[5]]); ib20.setImageResource(画像[画像インデックス[6]]); ib21.setImageResource(画像[画像インデックス[7]]); ib22.setImageResource(画像[画像インデックス[8]]); } //交換 プライベート void swap(int rand1, int rand2) { int temp=imageIndex[rand1]; imageIndex[rand1]=imageIndex[rand2]; imageIndex[rand2]=temp; } private void initView() { ib00=findViewById(R.id.pt_id_00x00); ib10=findViewById(R.id.pt_id_01x00); ib02=findViewById(R.id.pt_id_00x02); ib11=findViewById(R.id.pt_id_01x01); ib12=findViewById(R.id.pt_id_01x02); ib20=findViewById(R.id.pt_id_02x00); ib21=findViewById(R.id.pt_id_02x01); ib22=findViewById(R.id.pt_id_02x02); timeTv=findViewById(R.id.pt_tv_time); restartBtn=findViewById(R.id.pt_btn_restart); } public void onClick(View ビュー) { int id=view.getId(); switch (id){ case R.id.pt_id_00x00: move(R.id.pt_id_00x00,0); 壊す; ケース R.id.pt_id_00x01: move(R.id.pt_id_00x01,1); 壊す; 壊す; ケース R.id.pt_id_00x02: move(R.id.pt_id_00x02,2); 壊す; case R.id.pt_id_01x00: move(R.id.pt_id_01x00,3); 壊す; case R.id.pt_id_01x01: move(R.id.pt_id_01x01,4); 壊す; case R.id.pt_id_01x02: move(R.id.pt_id_01x02,5); 壊す; case R.id.pt_id_02x00: move(R.id.pt_id_02x00,6); 壊す; case R.id.pt_id_02x01: move(R.id.pt_id_02x01,7); case R.id.pt_id_02x02: move(R.id.pt_id_02x02,8); break; } } //指定した位置のボタンを移動し、画像を余白部分と入れ替える機能を 表します private void move(int imagebuttonId, int site) { //選択した画像がどの行と列にあるかを判定し、判定メソッドが渡される 剰余を求めるメソッド int sitex=site/imageX; int sitey=site%imageY; //空白領域の座標を取得する int blankx=blankSwap/imageX; int blanky=blankSwap%imageY; //2 つの条件for images to move // 1.同じ行で、列数の減算の絶対値は 1; 2.同じ列で、行数の減算の絶対値は 1 int x= Math.abs(sitex-blankx); int y=Math.abs(sitey-blanky); if((x == 0&&y==1)||(y==0&&x==1)){ clickButton.setVisibility(View.INVISIBLE); // この可動ボタンを ID で検索 ImageButton clickButton=findViewById(imagebuttonId); //空白領域にボタンを表示する ImageButton blackButton=findViewById(blankImgid); //空白領域を画像に設定する blackButton.setImageResource(image[imageIndex[site]]); //Invisible移動間、移動後、コントロールを可視状態に設定 blackButton.setVisibility(View.VISIBLE); //コーナーマークを変更する過程を画像位置を格納する配列に記録 swap(site,blankSwap); //更新クリックボタンの位置 blankSwap=site; blankImgid=imagebuttonId; } //移動終了後にジグソーパズルゲームが終了したかどうかを判断し ますudgerGameOver(); } //移動が終了したかどうかを判断しますジグソー パズルは成功し ます。 boolean loop=true;//フラグを定義する ib21.setClickable(false); for(int i=0;i <imageIndex.length; i++) { if (imageIndex[i] != i) { loop = false; break; } } if(loop){ //パズル成功、タイミング停止 handler.removeMessages(1); //パズル成功後、プレイヤーボタンを動かし続けることを禁止 ib00 .setClickable(false); ib01.setClickable(false); ib02.setClickable(false); ib10.setClickable(false); ib11.setClickable(false); ib12.setClickable(false); ib20.setClickable(false) ; setClickable(false); ib22.setImageResource(image[8]); ib22.setVisibility(View.VISIBLE); // ユーザー成功ダイアログ ボックスをポップアップしますAlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setMessage("おめでとう、パズルThe time is "+time+" seconds").setPositiveButton("Confirm",null); builder.create().show(); } // } } //ジグソーパズルの再起動 public void restart(View view ) { // ジグソー パズルが再開し、プレイヤーがピースを動かせる よう に なり ます ib10.setClickable(true); ib20.setClickable(true); ib21.setClickable(true); ib22.setClickable(true); // パズルの中断 interruptRandpm(); handler.removeMessages(1); // 時間が 0 に戻り、re⏲ time=0 ; timeTv.setText("Time: "+time+" seconds"); handler.sendEmptyMessageDelayed(1,1000); } } スクリーンショット効果: