制作的这个小游戏我称之为速度真夫君
这是一个九宫格3x3的还原图片的小游戏,当你运行程序时,计时器显示为0,当你点击第一个碎片开始计时,并且记载你的点击次数,相邻两个碎片可以互换,凌驾120秒游戏失败
1.class PuzzleView
代码如下:
- package com.example.gameapplication.Activity;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Paint;
- import android.os.Handler;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.View;
- import android.widget.Toast;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- public class PuzzleView extends View {
- private List<PuzzlePiece> pieces; // 存储拼图块的列表
- private int numColumns = 3; // 拼图的列数(3x3)
- private int pieceSize; // 原始拼图块大小
- private int scaledPieceSize; // 缩放后的拼图块大小
- private Paint paint; // 用于绘制拼图块的画笔
- private Paint textPaint; // 用于绘制文本的画笔
- private Integer firstSelectedIndex = null; // 记录第一个选中的拼图块索引
- private float scaleFactor = 1.5f; // 拼图块的缩放因子
- private int swapCount = 0; // 记录交换次数的计数器
- private long startTime ; // 计时开始时间,初始化为0
- private Handler handler = new Handler(); // 用于更新计时器的处理器
- private boolean isRunning = false; // 计时器是否在运行
- // 定义一个Runnable来定期更新计时器
- private Runnable timerRunnable = new Runnable() {
- @Override
- public void run() {
- if (isRunning) {
- long elapsedTime = (System.currentTimeMillis() - startTime) / 1000; // 计算经过的时间(秒)
- if (elapsedTime >= 120) {
- endGame("时间到,游戏结束!"); // 超过120秒,结束游戏
- return;
- }
- invalidate(); // 刷新视图以更新计时器
- handler.postDelayed(this, 1000); // 每秒更新一次
- }
- }
- };
- public PuzzleView(Context context, AttributeSet attrs) {
- super(context, attrs);
- paint = new Paint(); // 初始化绘图画笔
- textPaint = new Paint(); // 初始化文本画笔
- textPaint.setColor(0xFF000000); // 设置文本颜色为黑色
- textPaint.setTextSize(50); // 设置文本大小
- pieces = new ArrayList<>(); // 初始化拼图块列表
- }
- // 初始化拼图,分割图像为拼图块
- public void initializePuzzle(Bitmap bitmap) {
- pieceSize = bitmap.getWidth() / numColumns; // 计算原始拼图块大小
- scaledPieceSize = (int) (pieceSize * scaleFactor); // 计算缩放后的拼图块大小
- // 将图像分割为拼图块
- for (int i = 0; i < numColumns; i++) {
- for (int j = 0; j < numColumns; j++) {
- // 创建拼图块的Bitmap
- Bitmap pieceBitmap = Bitmap.createBitmap(bitmap, j * pieceSize, i * pieceSize, pieceSize, pieceSize);
- // 缩放拼图块
- pieceBitmap = Bitmap.createScaledBitmap(pieceBitmap, scaledPieceSize, scaledPieceSize, true);
- pieces.add(new PuzzlePiece(pieceBitmap, i * numColumns + j)); // 添加拼图块到列表
- }
- }
- shufflePuzzle(); // 打乱拼图
- invalidate(); // 刷新视图
- }
- // 打乱拼图块的顺序
- private void shufflePuzzle() {
- Collections.shuffle(pieces); // 随机打乱拼图块
- }
- // 启动计时器
- private void startTimer() {
- startTime = System.currentTimeMillis(); // 记录开始时间
- isRunning = true; // 设置计时器为运行状态
- handler.postDelayed(timerRunnable, 1000); // 每秒启动一次计时器
- }
- // 结束游戏并显示提示
- private void endGame(String message) {
- isRunning = false; // 停止计时器
- handler.removeCallbacks(timerRunnable); // 移除计时器回调
- // 计算总用时(秒),确保在游戏开始后才计算
- long totalTime = (isRunning ? (System.currentTimeMillis() - startTime) / 1000 : 0);
- Toast.makeText(getContext(), message + " 用时: " + totalTime + "秒", Toast.LENGTH_SHORT).show(); // 显示结束提示
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- // 计算拼图整体绘制的起始位置,使其居中
- int totalWidth = scaledPieceSize * numColumns;
- int totalHeight = scaledPieceSize * numColumns;
- int startX = (getWidth() - totalWidth) / 2; // 水平居中
- int startY = (getHeight() - totalHeight) / 2; // 垂直居中
- // 绘制拼图块
- for (int i = 0; i < pieces.size(); i++) {
- PuzzlePiece piece = pieces.get(i);
- int x = startX + (i % numColumns) * scaledPieceSize; // 计算水平坐标
- int y = startY + (i / numColumns) * scaledPieceSize; // 计算垂直坐标
- canvas.drawBitmap(piece.getBitmap(), x, y, paint); // 绘制拼图块
- }
- // 绘制交换次数文本
- canvas.drawText("交换次数: " + swapCount, startX, startY - 20, textPaint);
- // 计算经过的时间(秒)
- long elapsedTime = (isRunning ? (System.currentTimeMillis() - startTime) / 1000 : 0);
- // 将时间格式化为“mm:ss”
- String timeFormatted = String.format("%02d:%02d", elapsedTime / 60, elapsedTime % 60);
- canvas.drawText("时间: " + timeFormatted, startX, startY - 70, textPaint);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- // 计算点击的列和行
- int startX = (getWidth() - (scaledPieceSize * numColumns)) / 2; // 计算拼图的起始X坐标
- int startY = (getHeight() - (scaledPieceSize * numColumns)) / 2; // 计算拼图的起始Y坐标
- int x = (int) (event.getX() - startX) / scaledPieceSize; // 计算点击的列
- int y = (int) (event.getY() - startY) / scaledPieceSize; // 计算点击的行
- int clickedIndex = y * numColumns + x; // 计算点击的拼图块索引
- // 处理选中逻辑
- if (clickedIndex >= 0 && clickedIndex < pieces.size()) {
- if (!isRunning) {
- startTimer(); // 如果计时器未运行,则开始计时
- }
- handleSelection(clickedIndex); // 处理选中拼图块
- }
- invalidate(); // 刷新视图
- }
- return true; // 事件处理完成
- }
- private void handleSelection(int clickedIndex) {
- if (firstSelectedIndex == null) {
- // 第一次点击,记录索引
- firstSelectedIndex = clickedIndex;
- } else {
- // 第二次点击,检查是否可以交换
- if (isAdjacent(firstSelectedIndex, clickedIndex)) {
- swapPieces(firstSelectedIndex, clickedIndex); // 交换拼图块
- swapCount++; // 增加交换次数计数
- }
- firstSelectedIndex = null; // 重置选中状态
- }
- }
- // 交换拼图块
- private void swapPieces(int index1, int index2) {
- Collections.swap(pieces, index1, index2); // 交换拼图块
- checkCompletion(); // 检查拼图是否完成
- }
- // 检查两个拼图块是否相邻
- private boolean isAdjacent(int index1, int index2) {
- int row1 = index1 / numColumns;
- int col1 = index1 % numColumns;
- int row2 = index2 / numColumns;
- int col2 = index2 % numColumns;
- // 检查是否相邻(上下或左右)
- return (Math.abs(row1 - row2) + Math.abs(col1 - col2) == 1);
- }
- // 检查拼图是否完成
- private void checkCompletion() {
- boolean completed = true;
- for (int i = 0; i < pieces.size(); i++) {
- if (pieces.get(i).getPosition() != i) {
- completed = false; // 拼图尚未完成
- break;
- }
- }
- if (completed) {
- long totalTime = (System.currentTimeMillis() - startTime) / 1000; // 计算总用时(秒)
- endGame("拼图完成! 总交换次数: " + swapCount + ", 用时: " + totalTime + "秒"); // 游戏完成提示
- }
- }
- }
复制代码 2.class PuzzlePiece
代码如下:
- package com.example.gameapplication.Activity;
- import android.graphics.Bitmap;
- public class PuzzlePiece {
- private Bitmap bitmap;
- private int position; // 在拼图中的位置
- public PuzzlePiece(Bitmap bitmap, int position) {
- this.bitmap = bitmap;
- this.position = position;
- }
- public Bitmap getBitmap() {
- return bitmap;
- }
- public int getPosition() {
- return position;
- }
- public void setPosition(int position) {
- this.position = position;
- }
- }
复制代码 3.class MainActivity
- package com.example.gameapplication;
- import androidx.appcompat.app.AppCompatActivity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Bundle;
- import com.example.gameapplication.Activity.PuzzleView;
- public class MainActivity extends AppCompatActivity {
- private PuzzleView puzzleView;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- puzzleView = new PuzzleView(this, null);
- setContentView(puzzleView);
- Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.puzzle); // 替换为你的图片
- puzzleView.initializePuzzle(bitmap);
- }
- }
复制代码 4.activity_main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <!-- PuzzleView will be set programmatically in MainActivity -->
- </FrameLayout>
复制代码 最后自己找一张喜欢的图片放进去就可以了
总结,这个游戏没什么难度 但是重要在于图片的起始位置,判断点击的是哪个碎片,两个碎片是否相邻,时间的盘算。结束!!!!!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |