目录
前言
找不同游戏是一种在移动应用程序中非常普遍的游戏体验。这种游戏可以在简单的用户界面下提供寻找游戏中不同点的乐趣。并且,这种游戏对于锻炼观察能力、提高认知能力都非常有帮助。因此,我们可以通过基于Android Studio 开发一个找不同游戏App,来提供这种乐趣和帮助用户提高认知能力。
视频演示:
Android studio期末设计大作业~找不同App
一、项目概述
1、构成以及功能设计
①.用户登录/注册功能
②主页面功能
- 关卡选择按钮
- 游戏描述按钮(show按钮)
- 历史分数和排名按钮
- 控制背景音乐的播放按钮
③ 关卡选择页面功能
- 三个级别的游戏
- 开始游戏
④ 游戏功能
- 计时器
- 五个不同之处
- 结果判断和按钮控制
- 自定义评价标准
⑤历史数据和排行榜页面
- 显示最近的游戏分数
- 显示历史上的最高和最低得分
- 分享按钮,分享结果、时间和地点的详细信息
二、开发环境
我的开发环境如下,大家的AS版本不需要和我相同,只要是近两年从官网下载的版本,都是比4.0.0高的,是可以满足运行和开发要求的。
三、准备工具
-
选择自己喜欢的找不同背景
-
选择一首你喜欢的音乐
四、详细设计
1、新建工程
-
首先打开Android Studio,并新建一个工程,File——>New——>New Project——>Empty Project,工程名称叫做Game,可以根据自己喜好设置名称。
-
包名自己随意设定,这里博主用的是com.example,一般是com.example;工程文件的保存路径要修改一下,不要放在C盘,我这里选择的是放在H盘,养成项目统一放在英文路径下的好习惯。
-
最后选择API 24:Android 7.0,因为这样它就拥有了96.3%的跨平台性(兼容性非常好),因为它版本很低,基本上模拟器API版本都是高于20的,所以这个软件可以运行其他各种设备上。点击Finish完成创建。
2、搭建注册登陆面
设计一个app的时候,一定要先设计layout文件,再设计java文件
,因为布局有了,才能在上面进行代码的编写。我们来看一下activity_register和activity_login布局文件。
注册页面完整代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#afddf4"
tools:context=".Register.RegisterActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="201dp"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/login" />
<EditText
android:id="@+id/password_edittext"
android:layout_width="236dp"
android:layout_height="42dp"
android:layout_marginTop="24dp"
android:hint="请输入密码"
android:inputType="textPassword"
app:layout_constraintEnd_toEndOf="@+id/username_edittext"
app:layout_constraintStart_toStartOf="@+id/username_edittext"
app:layout_constraintTop_toBottomOf="@+id/username_edittext" />
<Button
android:id="@+id/register_button"
android:layout_width="228dp"
android:layout_height="44dp"
android:layout_marginTop="32dp"
android:textColor="#fff"
android:textSize="20sp"
android:background="@drawable/login_view"
android:text="注 册"
app:layout_constraintEnd_toEndOf="@+id/password_edittext"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/password_edittext"
app:layout_constraintTop_toBottomOf="@+id/password_edittext" />
<EditText
android:id="@+id/username_edittext"
android:layout_width="236dp"
android:layout_height="42dp"
android:layout_marginTop="32dp"
android:hint="请输入账号"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
登陆页面完整代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#afddf4"
tools:context=".Login.LoginActivity">
<ImageView
android:id="@+id/imageView5"
android:layout_width="0dp"
android:layout_height="201dp"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/login" />
<EditText
android:id="@+id/username_edittext"
android:layout_width="236dp"
android:layout_height="42dp"
android:layout_marginTop="32dp"
android:hint="请输入账号"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView5" />
<Button
android:id="@+id/login_button"
android:layout_width="228dp"
android:layout_height="43dp"
android:layout_marginTop="40dp"
android:background="@drawable/login_view"
android:text="登 陆"
android:textColor="#fff"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.472"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password_edittext" />
<EditText
android:id="@+id/password_edittext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:hint="请输入密码"
android:inputType="textPassword"
app:layout_constraintEnd_toEndOf="@+id/username_edittext"
app:layout_constraintStart_toStartOf="@+id/username_edittext"
app:layout_constraintTop_toBottomOf="@+id/username_edittext" />
<Button
android:id="@+id/register_button"
android:layout_width="228dp"
android:layout_height="43dp"
android:layout_marginTop="24dp"
android:background="@drawable/login_view"
android:text="注 册"
android:textColor="#fff"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="@+id/login_button"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@+id/login_button"
app:layout_constraintTop_toBottomOf="@+id/login_button" />
</androidx.constraintlayout.widget.ConstraintLayout>
然后回到我们的Activity文件。首先创建需要用到的控件,然后绑定控件,再设置监听器等。
注册页面代码如下:
package com.example.game.Register;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.game.Login.LoginActivity;
import com.example.game.R;
import com.example.game.Data.DatabaseHelper;
public class RegisterActivity extends AppCompatActivity {
private EditText mUserNameEditText;
private EditText mPasswordEditText;
private DatabaseHelper mDatabaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
mUserNameEditText = findViewById(R.id.username_edittext);
mPasswordEditText = findViewById(R.id.password_edittext);
mDatabaseHelper = new DatabaseHelper(this);
Button registerButton = findViewById(R.id.register_button);
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = mUserNameEditText.getText().toString().trim();
String password = mPasswordEditText.getText().toString().trim();
if (username.isEmpty() || password.isEmpty()) {
Toast.makeText(getApplicationContext(), "请输入账号或密码", Toast.LENGTH_SHORT).show();
return;
}
boolean result = mDatabaseHelper.insertData(username, password);
if (result) {
Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
finish();
} else {
Toast.makeText(getApplicationContext(), "注册失败", Toast.LENGTH_SHORT).show();
}
}
});
}
}
登陆页面代码如下:
package com.example.game.Login;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.example.game.MainActivity;
import com.example.game.R;
import com.example.game.Register.RegisterActivity;
import com.example.game.Data.DatabaseHelper;
public class LoginActivity extends AppCompatActivity {
private EditText mUserNameEditText;
private EditText mPasswordEditText;
private Button mLoginButton, rEgisterButton;
private DatabaseHelper mDatabaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mUserNameEditText = findViewById(R.id.username_edittext);
mPasswordEditText = findViewById(R.id.password_edittext);
mLoginButton = findViewById(R.id.login_button);
rEgisterButton = findViewById(R.id.register_button);
mDatabaseHelper = new DatabaseHelper(this);
rEgisterButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(intent);
}
});
mLoginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = mUserNameEditText.getText().toString().trim();
String password = mPasswordEditText.getText().toString().trim();
if (username.isEmpty() || password.isEmpty()) {
Toast.makeText(getApplicationContext(), "请输入账号或密码", Toast.LENGTH_SHORT).show();
return;
}
boolean result = mDatabaseHelper.checkUser(username, password);
if (result) {
Toast.makeText(getApplicationContext(), "登陆成功", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), "账号或密码错误", Toast.LENGTH_SHORT).show();
}
}
});
}
}
3、搭建首页界面
主页主要实现每个按钮的点击事件进行对应页面的跳转
首页页面布局代码如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#afddf4"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView6"
android:layout_width="match_parent"
android:layout_height="250dp"
app:srcCompat="@drawable/login" />
<Button
android:id="@+id/button_select_level"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#03A9F4"
android:text="选择关卡"
android:textColor="#fff"
android:textSize="18sp" />
<Button
android:id="@+id/button_game_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#03A9F4"
android:text="游戏描述"
android:textColor="#fff"
android:textSize="18sp" />
<Button
android:id="@+id/button_history_score"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#03A9F4"
android:text="历史分数及排名"
android:textColor="#fff"
android:textSize="18sp" />
<Button
android:id="@+id/button_music_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#03A9F4"
android:text="播放音乐"
android:textColor="#fff"
android:textSize="18sp" />
</LinearLayout>
首页JAVA代码如下所示:
package com.example.game;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.media.MediaPlayer;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.example.game.Game.EasyActivity;
import com.example.game.Game.HardActivity;
import com.example.game.Game.NormalActivity;
import com.example.game.Grade.GradeActivity;
import com.example.game.Show.ShowActivity;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private MediaPlayer mediaPlayer;
private Button buttonMusicControl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonSelectLevel = findViewById(R.id.button_select_level);
Button buttonGameDescription = findViewById(R.id.button_game_description);
Button buttonHistoryScore = findViewById(R.id.button_history_score);
buttonMusicControl = findViewById(R.id.button_music_control);
buttonSelectLevel.setOnClickListener(this);
buttonGameDescription.setOnClickListener(this);
buttonHistoryScore.setOnClickListener(this);
buttonMusicControl.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_music_control:
toggleMusic();
break;
case R.id.button_select_level:
showSelectionDialog();
break;
case R.id.button_game_description:
showAlertDialog();
break;
case R.id.button_history_score:
grade();
break;
}
}
private void grade() {
Intent intent = new Intent(MainActivity.this, GradeActivity.class);
startActivity(intent);
}
private void showSelectionDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
final String[] options = {"简单", "一般", "困难"};
builder.setTitle("选择合适的关卡:");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (options[which]) {
case "简单":
Intent intent = new Intent(MainActivity.this, EasyActivity.class);
startActivity(intent);
break;
case "一般":
Intent intent2 = new Intent(MainActivity.this, NormalActivity.class);
startActivity(intent2);
break;
case "困难":
Intent intent3 = new Intent(MainActivity.this, HardActivity.class);
startActivity(intent3);
break;
}
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
private void showAlertDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("找不同游戏规则如下:");
builder.setMessage("1. 游戏开始后,会出现两张看似相同的图片,实际上有几处细微的差别。\n" +
"\n" +
"2. 玩家需要在规定的时间内,找出这些差别。\n" +
"\n" +
"3. 可以通过点击差异位置的方式来标出发现的差别。\n" +
"\n" +
"4. 游戏一般分为多个关卡,每个关卡的难度逐渐加大。\n" +
"\n" +
"5. 玩家需要在规定的时间内找到所有不同之处,才能晋级到下一个关卡。\n" +
"\n" +
"6. 如果时间到了但是还没有找完,游戏就会结束。\n" +
"\n" +
"7. 如果玩家成功通过关卡,则可以解锁下一个更难的关卡,在游戏中积累高分,以期打败其他玩家。\n" +
"\n" +
"找不同游戏的难点在于玩家需要有较强的观察力、反应力和记忆力,而且需要快速判断不同之处,在有限的时间内完成任务。因此,找不同游戏会不断考验玩家的能力,让玩家在娱乐的同时也可以锻炼自己的大脑。");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 处理确定按钮的点击事件
Toast.makeText(getApplicationContext(), "已知晓", Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton("show", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(MainActivity.this, ShowActivity.class);
startActivity(intent);
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
private void toggleMusic() {
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
buttonMusicControl.setText("播放音乐");
} else {
mediaPlayer.start();
buttonMusicControl.setText("暂停音乐");
}
} else {
mediaPlayer = MediaPlayer.create(this, R.raw.music0);
mediaPlayer.start();
buttonMusicControl.setText("暂停音乐");
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
}
4、搭建游戏界面
在这里我们创建EasyActivity文件然后在activity_easy.xml文件编辑页面代码,三个游戏难度代码几乎一致,以下为简单游戏。
1. `btn()` 方法用于处理活动中的按钮点击。
2. 在 `btn()` 方法内,有两个按钮点击监听器:
- 第一个适用于标识为 `btnChong倒计时器(`mCountDownTimer`),创建一个新意图以重新启动当前活动(`EasyActivity`),启动新活动,并结束当前活动。
- 第二个适用于标识为 `btnEsc` 的按钮。当点击该按钮时,会取消倒计时器,创建一个新意图以启动 `MainActivity`,启动新活动,并结束当前活动。
3. `play()` 方法负责启动一个倒计时器(`mCountDownTimer`),其持续时间为10秒,间隔为1秒。在计时器的 `onTick()` 方法内,剩余时间将显示在一个<TextView>(`mTextView`)上。
4. 在计时器的 `onFinish()` 方法内,当倒计时结束时执行一些操作:
- 从一个编辑文本框 (`grade`) 中获取得分(以字符串表示)。
- 使用 `Log.d()` 将得分记录到控制台。
- 获取 SharedPreferences 对象以存储分数列表。
- 从 SharedPreferences 中获取先前的分数列表,并向列表添加新的分数。
- 将修改后的分数列表保存回 SharedPreferences。
- 如果得分为 "简单关卡得分:5"(表示简单级别得分为5),则显示一个提示消息表明挑战成功。否则,隐藏某些视图,并显示一个提示消息表示挑战失败。
- 创建一个意图以启动 `GradeActivity` 并启动新活动。最后,结束当前活动。
5. `onClick(View view)` 方法处理活动中各种视图的点击事件。根据所点击视图的ID,它执行不同的操作以更新分数并显示或隐藏某些视图。
activity_easy.xml如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#afddf4"
tools:context=".Game.EasyActivity">
<Button
android:id="@+id/btn_chongxinkaishi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="52dp"
android:background="#00BCD4"
android:text="重新开始"
android:textColor="#fff"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/img1"
android:layout_width="414dp"
android:layout_height="440dp"
android:layout_marginTop="32dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.666"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_esc"
app:srcCompat="@drawable/easy" />
<View
android:id="@+id/dif_11"
android:layout_width="69dp"
android:layout_height="52dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="144dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<View
android:id="@+id/dif_01"
android:layout_width="69dp"
android:layout_height="52dp"
android:layout_marginEnd="144dp"
android:layout_marginBottom="140dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/img1"
app:layout_constraintEnd_toEndOf="parent" />
<View
android:id="@+id/dif_22"
android:layout_width="60dp"
android:layout_height="41dp"
android:layout_marginStart="120dp"
android:layout_marginTop="40dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<View
android:id="@+id/dif_02"
android:layout_width="56dp"
android:layout_height="30dp"
android:layout_marginStart="124dp"
android:layout_marginBottom="140dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/img1"
app:layout_constraintStart_toStartOf="@+id/img1" />
<View
android:id="@+id/dif_33"
android:layout_width="55dp"
android:layout_height="27dp"
android:layout_marginStart="124dp"
android:layout_marginTop="112dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<View
android:id="@+id/dif_03"
android:layout_width="55dp"
android:layout_height="27dp"
android:layout_marginStart="124dp"
android:layout_marginBottom="76dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/img1"
app:layout_constraintStart_toStartOf="@+id/img1" />
<View
android:id="@+id/dif_4"
android:layout_width="39dp"
android:layout_height="29dp"
android:layout_marginTop="96dp"
android:layout_marginEnd="124dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<View
android:id="@+id/dif_04"
android:layout_width="32dp"
android:layout_height="25dp"
android:layout_marginEnd="128dp"
android:layout_marginBottom="88dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/img1"
app:layout_constraintEnd_toEndOf="parent" />
<View
android:id="@+id/dif_5"
android:layout_width="45dp"
android:layout_height="34dp"
android:layout_marginTop="172dp"
android:layout_marginEnd="92dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<View
android:id="@+id/dif_05"
android:layout_width="45dp"
android:layout_height="34dp"
android:layout_marginEnd="92dp"
android:layout_marginBottom="8dp"
android:background="@drawable/view"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/img1"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="@+id/btn_esc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="#00BCD4"
android:text="退出"
android:textColor="#fff"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@+id/btn_chongxinkaishi"
app:layout_constraintTop_toBottomOf="@+id/btn_chongxinkaishi" />
<View
android:id="@+id/y_02"
android:layout_width="57dp"
android:layout_height="35dp"
android:layout_marginStart="120dp"
android:layout_marginTop="44dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<View
android:id="@+id/y_01"
android:layout_width="78dp"
android:layout_height="47dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="140dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<View
android:id="@+id/y_04"
android:layout_width="49dp"
android:layout_height="32dp"
android:layout_marginTop="96dp"
android:layout_marginEnd="120dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<View
android:id="@+id/y_05"
android:layout_width="49dp"
android:layout_height="32dp"
android:layout_marginTop="172dp"
android:layout_marginEnd="88dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<View
android:id="@+id/y_03"
android:layout_width="67dp"
android:layout_height="24dp"
android:layout_marginStart="120dp"
android:layout_marginTop="112dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/img1" />
<TextView
android:id="@+id/grade"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="简单关卡得分:0"
android:textColor="#fff"
android:textSize="30sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/mTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="1"
android:textColor="#fff"
android:textSize="30sp"
app:layout_constraintStart_toStartOf="@+id/grade"
app:layout_constraintTop_toBottomOf="@+id/grade" />
</androidx.constraintlayout.widget.ConstraintLayout>
接下来是对应java文件代码:
这段代码是一个简单的Android游戏活动(EasyActivity),它实现了一个倒计时功能和一些游戏逻辑。
1. **导入和变量声明**:
- 代码一开始导入了一些必要的Android库和其他类。
- 声明了一系列的View对象、TextView、Button、ImageView等,用来处理游戏界面的各个元素。
2. **onCreate方法**:
- 在Activity创建时调用,设置布局文件为R.layout.activity_easy,并初始化界面和调用play()方法开始游戏。
3. **btn()方法**:
- 设置了两个按钮的点击事件:
- `btnChongxinkaishi`:重新开始按钮,点击后取消当前的倒计时并重新启动EasyActivity。
- `btnEsc`:退出按钮,点击后取消当前的倒计时并跳转到MainActivity。
4. **play()方法**:
- 创建了一个CountDownTimer对象,进行了10秒的倒计时。
- 每秒更新一次剩余时间的TextView(mTextView)。
- 当倒计时结束时,根据得分显示Toast消息和处理逻辑:
- 如果得分为5(通过grade.getText().toString()获取),显示挑战成功的消息,并将得分保存到SharedPreferences中。
- 否则,隐藏游戏中的一些元素(y01至y05),显示挑战失败的消息,并提示重新开始游戏。
- 最后跳转到GradeActivity显示成绩列表,并结束当前Activity。
5. **initView()方法**:
- 初始化所有的View对象,包括游戏中的难题(dif1至dif5)和答案(y01至y05),以及其他界面元素(grade、mTextView、btnChongxinkaishi等)。
这段代码实现了一个简单的倒计时游戏,玩家需要在规定时间内完成某些任务,并根据完成情况显示不同的结果和消息。同时,它还展示了如何使用SharedPreferences来存储和读取游戏成绩,以及如何通过Intent在不同的Activity之间进行跳转。
package com.example.game.Game;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.game.Grade.GradeActivity;
import com.example.game.MainActivity;
import com.example.game.R;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
public class EasyActivity extends AppCompatActivity implements View.OnClickListener {
private View dif1;
private View dif01;
private View dif2;
private View dif02;
private View dif3;
private View dif03;
private View dif4;
private View dif04;
private View dif5;
private View dif05;
private View y02;
private View y01;
private View y04;
private View y05;
private View y03;
private TextView grade;
private int count;
private TextView mTextView;
private Button btnChongxinkaishi;
private ImageView imageView;
private Button btnEsc;
private TextView textView2;
private CountDownTimer mCountDownTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_easy);
initView();
play();
btn();
}
private void btn() {
// 重新开始按钮
btnChongxinkaishi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
Intent intent = new Intent(EasyActivity.this, EasyActivity.class);
startActivity(intent);
finish();
}
});
// 退出到主页按钮
btnEsc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
Intent intent = new Intent(EasyActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
});
}
private void play() {
mCountDownTimer =new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
// 这里可以更新显示剩余时间的TextView
mTextView.setText("剩余时间: " + millisUntilFinished / 1000);
}
public void onFinish() {
String grades = grade.getText().toString();
// 打印当前得分到控制台
Log.d("play", "当前得分为:" + grades);
// 获取 SharedPreferences 对象
SharedPreferences sharedPreferences = getSharedPreferences("grades", MODE_PRIVATE);
// 获取原有的分数列表
Gson gson = new Gson();
String gradesListString = sharedPreferences.getString("grades_list", "");
ArrayList<String> gradesList = new ArrayList<>();
if (!TextUtils.isEmpty(gradesListString)) {
gradesList = gson.fromJson(gradesListString, new TypeToken<ArrayList<String>>() {}.getType());
}
// 将新的分数添加到列表中
gradesList.add(grades);
// 保存成绩列表到 SharedPreferences 中
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("grades_list", gson.toJson(gradesList));
editor.apply();
// 倒计时结束后,判断得分是否为5,是则弹出对话框
if (grades.equals("简单关卡得分:5")) {
Toast.makeText(EasyActivity.this, "挑战成功," + grades, Toast.LENGTH_SHORT).show();
} else {
y01.setVisibility(View.GONE);
y02.setVisibility(View.GONE);
y03.setVisibility(View.GONE);
y04.setVisibility(View.GONE);
y05.setVisibility(View.GONE);
Toast.makeText(EasyActivity.this, "时间到,挑战失败," + grades + " 请重新开始!", Toast.LENGTH_SHORT).show();
}
// 跳转到成绩列表页面
Intent intent = new Intent(EasyActivity.this, GradeActivity.class);
startActivity(intent);
finish();
}
}.start();
}
private void initView() {
dif1 = (View) findViewById(R.id.dif_11);
dif01 = (View) findViewById(R.id.dif_01);
dif2 = (View) findViewById(R.id.dif_22);
dif02 = (View) findViewById(R.id.dif_02);
dif3 = (View) findViewById(R.id.dif_33);
dif03 = (View) findViewById(R.id.dif_03);
dif4 = (View) findViewById(R.id.dif_4);
dif04 = (View) findViewById(R.id.dif_04);
dif5 = (View) findViewById(R.id.dif_5);
dif05 = (View) findViewById(R.id.dif_05);
y02 = (View) findViewById(R.id.y_02);
y01 = (View) findViewById(R.id.y_01);
y04 = (View) findViewById(R.id.y_04);
y05 = (View) findViewById(R.id.y_05);
y03 = (View) findViewById(R.id.y_03);
y01.setOnClickListener(this);
y02.setOnClickListener(this);
y03.setOnClickListener(this);
y04.setOnClickListener(this);
y05.setOnClickListener(this);
grade = (TextView) findViewById(R.id.grade);
mTextView = (TextView) findViewById(R.id.mTextView);
btnChongxinkaishi = (Button) findViewById(R.id.btn_chongxinkaishi);
imageView = (ImageView) findViewById(R.id.img1);
btnEsc = (Button) findViewById(R.id.btn_esc);
textView2 = (TextView) findViewById(R.id.textView2);
}
}
至此,完整的找不同游戏项目创建完成。
五、项目运行
1.图片演示
(1)运行app到模拟器上,显示登陆面:
(2)点击注册跳转到注册页面:
(3)注册账号后进行登陆然乎进入首页:
(4)点击选择关卡选择对应的难度进行游戏:
(5)点击历史分数及排名:
运行效果和功能很完整,至此就完成了非常简单的找不同游戏。大家可以跟着动手做一下,放上自己喜欢的图片,还有喜欢的歌,体验感真的不要太好!
六、项目总结
在本设计中重点是:
1. 实现登录页面和注册页面,以及用户名和密码的验证和本地数据库的操作;
2. 实现主页面,包含关卡选择的按钮、关于游戏描述的按钮、历史分数和排名的按钮、背景音乐的控制按钮;
3. 实现关卡选择页面,定义三个游戏级别,启动游戏;
4. 实现游戏功能,包括计时器、不同之处的寻找、游戏结果的判断和按钮控制、自定义评价标准;
5. 实现历史数据和排行榜页面,显示最近的游戏分数、历史上的最高和最低得分。
Get 项目模板源码
👇👇👇快捷获取方式👇👇👇