Android Studio制作简单拼图小游戏
制作的这个小游戏我称之为速度真夫君这是一个九宫格3x3的还原图片的小游戏,当你运行程序时,计时器显示为0,当你点击第一个碎片开始计时,并且记载你的点击次数,相邻两个碎片可以互换,凌驾120秒游戏失败
https://i-blog.csdnimg.cn/direct/4ee11ce7640b465782ab8524b336b042.png
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>
最后自己找一张喜欢的图片放进去就可以了
https://i-blog.csdnimg.cn/direct/c5d9756441534b0bbecd4a038b8fd614.png
总结,这个游戏没什么难度 但是重要在于图片的起始位置,判断点击的是哪个碎片,两个碎片是否相邻,时间的盘算。结束!!!!!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]