赞
踩
目录
通过自定义View实现Android飞机大战小游戏,游戏玩法很简单,可以锻炼玩家的反应能力。开启背景音乐进行新的游戏,控制飞机移动来消灭敌机获取更多的分数,在移动过程中避免与敌机发生碰撞。主界面可以查看自己的历史战绩和游戏规则,详细规则如下:
- 1. 飞机一直发射子弹,用手指滑动可以改变飞机的位置
- 2. 不同的敌机抗击打能力不同,当敌机被击中一定子弹数量时会爆炸,爆炸有动画效果
- 3. 每隔一段时间都会有双发子弹或炸弹等道具奖励
- 4. 获得双发子弹之后,子弹变为双发
- 5. 获得炸弹道具之后,可以通过双击将屏幕内的所有敌机炸毁
我们先来看下运行演示效果
Android Studio 实现飞机大战游戏
我的开发环境如下,大家的AS版本不需要和我相同,只要是近两年从官网下载的版本,都是比4.0.0 (2020)高的,是可以满足运行和开发要求的。
打开 Android studio 开发工具后,进行项目创建,左上角 File—>New Project、填写后点击 Finish 完成创建!
选中com.example.note包 名 右 键 New — >package 并按需求依次 activity(存放各类 Activity)、adapter(存放各类适配器) 等包名,后续代码将按对应包名去创建,并将 MainActivity.java 移动到 activity包 下
在 activity包上右键创建 New—>Activity—>Empty Activity 选项创建 Activity 后弹 出对话框,输入相关信息,即可创建 Activity.
启动页页面布局背景放置一张自己喜欢的logo即可
这里我们直接看java部分代码:
- package com.example.planewars.activity;
-
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.CountDownTimer;
- import android.os.Handler;
-
- import androidx.appcompat.app.AppCompatActivity;
-
- import com.example.planewars.R;
-
- public class StartActivity extends AppCompatActivity {
- private Handler handler = new Handler();
- private Runnable runnable = new Runnable() {
- @Override
- public void run() {
- tomainActive();
- }
- };
-
- // 进入主页面
- private void tomainActive() {
- startActivity(new Intent(this, LoginActivity.class));
- // 跳转完成后注销
- finish();
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_start);
-
- }
-
- }
在 activity包上右键创建 New—>Activity—>Empty Activity 选项创建 Activity 后弹 出对话框,输入相关信息,即可创建 Activity.
用户注册页面布局代码如下所示:
- <?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="#fff"
- tools:context=".activity.RegisterActivity">
-
- <LinearLayout
- android:id="@+id/linearLayout2"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="24dp"
- android:layout_marginEnd="24dp"
- android:orientation="vertical"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_bias="0.41"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/imageView">
-
- <EditText
- android:id="@+id/username_edittext"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:hint="请输入账号" />
-
- <EditText
- android:id="@+id/password_edittext"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:hint="请输入密码"
- android:inputType="textPassword" />
-
- <EditText
- android:id="@+id/repeat"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:ems="10"
- android:hint="再次输入您的密码"
- android:inputType="textPassword" />
-
- <TextView
- android:id="@+id/tv_login"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:gravity="center|right"
- android:text="已有账号?立即登录" />
-
- </LinearLayout>
-
- <ImageView
- android:id="@+id/imageView"
- android:layout_width="0dp"
- android:layout_height="200dp"
- android:src="@drawable/logo"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <Button
- android:id="@+id/register_button"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginTop="32dp"
- android:background="@drawable/btn_style"
- android:text="立 即 注 册"
- android:textColor="@color/white"
- android:textSize="20sp"
- app:layout_constraintEnd_toEndOf="@+id/linearLayout2"
- app:layout_constraintStart_toStartOf="@+id/linearLayout2"
- app:layout_constraintTop_toBottomOf="@+id/linearLayout2" />
- </androidx.constraintlayout.widget.ConstraintLayout>
编写 RegisterActivity.java 的代码为:
- package com.example.planewars.activity;
-
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- import android.widget.Toast;
-
- import androidx.appcompat.app.AppCompatActivity;
-
- import com.example.planewars.Data.DatabaseHelper;
- import com.example.planewars.R;
-
- public class RegisterActivity extends AppCompatActivity {
-
- private EditText mUserNameEditText;
- private EditText mPasswordEditText;
- private DatabaseHelper mDatabaseHelper;
- private EditText repeat;
- private TextView tvLogin;
- private Button registerButton;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_register);
- initView();
- button();
- login();
- }
- // 返回到登陆页面
- private void login() {
- tvLogin.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- finish();
- }
- });
- }
-
- private void button() {
- // 点击注册按钮进行验证
- registerButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // 获取三个输入框的内容
- String username = mUserNameEditText.getText().toString().trim();
- String password = mPasswordEditText.getText().toString().trim();
- String passwordrepeat = repeat.getText().toString().trim();
- // 判断是否输入内容
- if (username.isEmpty() || password.isEmpty()) {
- Toast.makeText(getApplicationContext(), "请输入账号或密码", Toast.LENGTH_SHORT).show();
- return;
- }
- // 判断两次密码是否一致
- if (passwordrepeat.equals(password) && password.equals(passwordrepeat)) {
- 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();
- }
- } else {
- Toast.makeText(getApplicationContext(), "两次密码不同,请检查!", Toast.LENGTH_SHORT).show();
- }
- }
- });
- }
- private void initView() {
- mUserNameEditText = findViewById(R.id.username_edittext);
- mPasswordEditText = findViewById(R.id.password_edittext);
- mDatabaseHelper = new DatabaseHelper(this);
- repeat = (EditText) findViewById(R.id.repeat);
- tvLogin = (TextView) findViewById(R.id.tv_login);
- registerButton = findViewById(R.id.register_button);
- }
- }
在 activity包上右键创建 New—>Activity—>Empty Activity 选项的对话框下输入 LoginActivity 创建,同时会在 res-layout 生成 activity_login.xml 文件.
activity_login.xml页面代码如下所示L:
- <?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="@color/white"
- tools:context=".activity.LoginActivity">
-
- <LinearLayout
- android:id="@+id/linearLayout"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="24dp"
- android:layout_marginTop="20dp"
- android:layout_marginEnd="24dp"
- android:orientation="vertical"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/imageView2">
-
- <EditText
- android:id="@+id/username_edittext"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="请输入账号" />
-
- <EditText
- android:id="@+id/password_edittext"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:hint="请输入密码"
- android:inputType="textPassword" />
-
- <TextView
- android:id="@+id/register_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:gravity="center|right"
- android:text="还没有账号?立即注册!" />
-
- </LinearLayout>
-
- <ImageView
- android:id="@+id/imageView2"
- android:layout_width="0dp"
- android:layout_height="200dp"
- android:layout_marginTop="24dp"
- android:src="@drawable/logo"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <Button
- android:id="@+id/login_button"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginTop="32dp"
- android:background="@drawable/btn_style"
- android:text="立 即 登 录"
- android:textColor="@color/white"
- android:textSize="20sp"
- app:layout_constraintEnd_toEndOf="@+id/linearLayout"
- app:layout_constraintStart_toStartOf="@+id/linearLayout"
- app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
- </androidx.constraintlayout.widget.ConstraintLayout>
对应的Java页面代码如下所示:
- package com.example.planewars.activity;
-
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- import android.widget.Toast;
-
- import androidx.appcompat.app.AppCompatActivity;
-
- import com.example.planewars.Data.DatabaseHelper;
- import com.example.planewars.R;
-
- public class LoginActivity extends AppCompatActivity {
-
- private EditText mUserNameEditText;
- private EditText mPasswordEditText;
- private Button mLoginButton;
- private TextView 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();
- }
- }
- });
- }
- }
编译代码启动 App,在登录页面(LoginActivity)的注册按钮中点击跳转注册 页面(RegisterActivity)进行注册,注册成功后自动返回登录页面进行登录 操作,登录成功之后正常跳转主页面(MainActivity)。
我们先来看activity_main.xml代码,详情布局代码如下所示:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#E8E8E8"
- android:gravity="center"
- android:orientation="vertical">
-
- <Button
- android:id="@+id/startGame"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:layout_marginBottom="20dp"
- android:background="@drawable/btn_style"
- android:text="@string/startGame"
- android:textColor="@color/white"
- android:textSize="20sp" />
-
- <Button
- android:id="@+id/historyScore"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:layout_marginBottom="20dp"
- android:background="@drawable/btn_style"
- android:text="@string/historyScore"
- android:textColor="@color/white"
- android:textSize="20sp" />
-
- <Button
- android:id="@+id/bgMusic"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:layout_marginBottom="20dp"
- android:background="@drawable/btn_style"
- android:text="@string/bg_music_close"
- android:textColor="@color/white"
- android:textSize="20sp" />
-
- <Button
- android:id="@+id/aboutGame"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:layout_marginBottom="20dp"
- android:background="@drawable/btn_style"
- android:text="@string/aboutGame"
- android:textColor="@color/white"
- android:textSize="20sp" />
-
- <Button
- android:id="@+id/exitGame"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="30dp"
- android:layout_marginRight="30dp"
- android:layout_marginBottom="20dp"
- android:background="@drawable/btn_style"
- android:text="@string/exitGame"
- android:textColor="@color/white"
- android:textSize="20sp" />
-
- </LinearLayout>
接下来我们看逻辑代码,这里我们实现的是页面跳转功能,详情代码如下所示:
- package com.example.planewars.activity;
-
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.view.View;
- import android.widget.Button;
-
- import com.example.planewars.R;
- import com.example.planewars.service.MusicService;
-
-
- public class MainActivity extends Activity implements View.OnClickListener {
- // 定义全局意图
- private Intent musicIntent;
- // 定义全局变量
- private Button startGame, bgMusic, aboutGame, exitGame, historyScore;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initView();
- }
-
- private void initView() {
- startGame = findViewById(R.id.startGame);
- historyScore = findViewById(R.id.historyScore);
- bgMusic = findViewById(R.id.bgMusic);
- aboutGame = findViewById(R.id.aboutGame);
- exitGame = findViewById(R.id.exitGame);
- startGame.setOnClickListener(this);
- historyScore.setOnClickListener(this);
- bgMusic.setOnClickListener(this);
- aboutGame.setOnClickListener(this);
- exitGame.setOnClickListener(this);
- musicIntent = new Intent(this, MusicService.class);
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.startGame:
- startGame();
- break;
- case R.id.historyScore:
- historyScore();
- break;
- case R.id.aboutGame:
- aboutGame();
- break;
- case R.id.exitGame:
- finish();
- break;
- }
- }
-
- private void historyScore() {
- Intent intent = new Intent(this, HistoryActivity.class);
- startActivity(intent);
- }
-
- public void startGame() {
- Intent intent = new Intent(this, GameActivity.class);
- startActivity(intent);
- }
-
-
- public void aboutGame() {
- Intent intent = new Intent(this, AboutActivity.class);
- startActivity(intent);
- }
-
-
-
- }
我们先来看activity_history.xml代码,这里我们用到了RecylerView列表来显示,详情代码如下所示:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:background="@drawable/history"
- android:orientation="vertical">
-
- <View
- android:layout_width="match_parent"
- android:layout_height="2dp"
- android:background="@color/white" />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:ellipsize="end"
- android:gravity="center"
- android:padding="5dp"
- android:singleLine="true"
- android:text="@string/rank"
- android:textColor="@color/white"
- android:textSize="18sp"
- android:textStyle="bold"
- android:typeface="serif" />
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="2"
- android:ellipsize="end"
- android:gravity="center"
- android:padding="5dp"
- android:singleLine="true"
- android:text="@string/score"
- android:textColor="@color/white"
- android:textSize="18sp"
- android:textStyle="bold"
- android:typeface="serif" />
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="3"
- android:ellipsize="end"
- android:gravity="center"
- android:padding="5dp"
- android:singleLine="true"
- android:text="@string/date"
- android:textColor="@color/white"
- android:textSize="18sp"
- android:textStyle="bold"
- android:typeface="serif" />
- </LinearLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="2dp"
- android:background="@color/white" />
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/rc_history"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- </LinearLayout>
然后我们进行逻辑代码的编写,实现成绩从高到低的显示功能
- package com.example.planewars.activity;
-
- import android.app.Activity;
- import android.os.Bundle;
-
- import androidx.recyclerview.widget.GridLayoutManager;
- import androidx.recyclerview.widget.RecyclerView;
-
- import com.example.planewars.R;
- import com.example.planewars.adapter.GradeAdapter;
- import com.example.planewars.database.DataBaseHelper;
- import com.example.planewars.database.Grade;
-
- import java.util.ArrayList;
- import java.util.List;
-
-
- /**
- * 历史成绩
- */
- public class HistoryActivity extends Activity {
- private List<Grade> gradeList = new ArrayList<>();
- private DataBaseHelper dataBaseHelper;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_history);
- dataBaseHelper = new DataBaseHelper(this);
- initData();
- initView();
- }
-
-
- //选择排序,降序排序
- for (int i = 0; i < gradeList.size() - 1; i++) {
- int maxIndex = i;
- for (int j = i + 1; j < gradeList.size(); j++) {
- int curNum = Integer.parseInt(gradeList.get(j).getScore());
- int maxNum = Integer.parseInt(gradeList.get(maxIndex).getScore());
- }
- if (i != maxIndex) {
- Grade temp = gradeList.get(i);
- gradeList.set(i, gradeList.get(maxIndex));
- gradeList.set(maxIndex, temp);
- }
- }
- }
-
- private void initView() {
- GradeAdapter gradeAdapter = new GradeAdapter(gradeList);
- // 列表加载适配器
- rcHistory.setAdapter(gradeAdapter);
- gradeAdapter.notifyDataSetChanged();
- }
- }
这里直接使用TextView文本编写:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="10dp"
- android:background="@drawable/bg_about">
-
- <TextView
- android:id="@+id/about_content"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:textSize="20sp"
- android:textColor="@color/white"
- android:typeface="monospace"
- android:layout_margin="25dp"
- android:text="1. 飞机一直发射子弹,用手指滑动可以改变飞机的位置。\n\n2. 不同的敌机抗击打能力不同,当敌机被击中一定子弹数量时会爆炸,爆炸有动画效果。\n\n3. 每隔一段时间都会有双发子弹或炸弹等道具奖励。\n\n4. 获得双发子弹之后,子弹变为双发。\n\n5. 获得炸弹道具之后,可以通过双击将屏幕内的所有敌机炸毁。"/>
- </LinearLayout>
在onCreate方法中,初始化了界面并获取了GameView的实例,然后载入了游戏所需的图片资源,并调用了GameView的start方法来启动游戏。
在GameView中,通过不断地绘制游戏画面来实现游戏的运行。此外,还定义了一个静态的Handler,在handleMessage方法中处理了一个消息,当收到标识为66的消息时,会将得分和当前时间保存到数据库中。
在onPause方法中,暂停了游戏的运行,而在onDestroy方法中,销毁了游戏界面并释放相关资源。整体来说,这段代码实现了游戏界面的初始化和销毁,以及处理得分信息并保存到数据库中。
页面布局代码如下所示:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".activity.MainActivity">
-
- <com.example.planewars.game.GameView
- android:id="@+id/gameView"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/bg"/>
-
- </RelativeLayout>
至此,完整的飞机大战游戏项目就创建完成了。
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。