【Android游戏开发详细过程1】Android平台飞机大战游戏APP设计与实现


前言

本系统是基于以上主流开发工具之一的 Android Studio 软件进行客户端的开发, 利用 Eclipse2017 软件实现服务器端开发,所用语言皆为 Java 语言。通过上述软件开发一款童年经典的小游戏: 飞机大战小游戏。


一、界面设计与功能实现

通过 activity 将各个界面连接起来,当跳转时展现他们各自不同的生命周期,以此来实现不同界面功能和效果的呈现.
在这里插入图片描述

1.1 主界面

主界面设计
打开飞机大战游戏 app 后能够看到两个按钮分别为登录按钮和注册按钮在屏幕的中下方显示,后面有背景图片。当再次进入主界面时只显示开始游戏按钮和注销按钮,并在右上角显示用户的姓名,如果用户的姓名过长会将用户的姓名实现为跑马灯效果进行播放。点击登录按钮后会跳转到登录界面(LoginActivity),点击注册后会跳转到注册界面(RegisterActivity)。 点击开始游戏后会跳转到主菜单界面(MenuActivity),点击注销后也会跳转到登录界面(LoginActivity)。
主界面功能实现
通过 setVisibility()函数对按钮控件进行隐藏和显示操作。通过点击事件onClick()和按钮监听 setOnClickListener()来实现界面的跳转,登录界面和注册界面进行跳转时不销毁当前界面,只有当点击开始游戏按钮后才会销毁当前界面, MainActivity.finish()实现销毁功能;跑马灯效果的实现,将 textview 控件中的 foucesable 和 focusableInTouchMode 都是为 true,将 marqueeRepeatLimit 设置为“marquee_forever” 等如图 3.2 操作。
在这里插入图片描述主界面效果
运行后第一次登录界面呈现的效果如图 3.3 所示,第二次登录界面的效果如图 3.4 所示
在这里插入图片描述在这里插入图片描述

1.2 登录界面

登录界面设计
输入用户的姓名和密码,点击登录后进行密码和用户是否存在的验证,若出错会弹出提示。如果都通过则跳转到主界面,并将用户名呈现出来。
登录界面功能实现
将用户名和 SharedPreferences 存储类中的数据进行比对查看用户名是否存在, 若存在,对密码 MD5 加密之后和该用户的存储密码进行比较看是否相同。登录成功后通过 intent将状态告诉主界面下次登录不是第一次登录,可以直接显示开始游戏和注销按钮,隐藏登录和注册按钮。登录成功后页面进行销毁 Login.Finnish ( )。
登录界面效果
运行后登录界面如图 3.4 所示
在这里插入图片描述

1.2 注册界面

注册界面设计
输入用户名, 用户名不能和已有的用户名重复,在输入密码和确认密码,并选择本地的一张图片作为用户头像
注册界面功能实现
通过和 SharedPreferences 存储类中的用户名进行对比查看用户是否存在,对密码进行 MD5 加密和两次比对。
从手机本地读取图片的过程如下:
第一步:将电脑上的七张头像图片上传的 android 虚拟机中,首先开启虚拟机,点击 android studio 右边的 Device File Explorer,找到 sdcard 文件夹下的Pictures 文件夹,将图片复制进去。再在 android 虚拟机的文件夹中找到 sdcard文件夹将图片复制到 Android 虚拟机的本地 sdk_gphone_x86 下的Pictures 文件夹中。
第二步:在 AndroidManifest.xml 配置文件中设置可以访问本地相册的权限如下:

<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

第三步: 将本地图片的地址返回给注册界面inent.getdata(),并在控件中显示出来通过 setImageURI()。
将图片通过 compress() 压缩、 Base64.encodeToString转化为字符串,当用户名称、头像和密码都正确后将数据插入到数据库中,并将数据存入到 SharedPreferences 存储类中,以便后面使用。
如果从登录界面进行注册时, 注册成功后。 界面会自动跳转回登陆界面,并将用户名自动填充。通过 intent.putExtra()将用户名在不同的 activity 之间进行传值。
注册成功后界面进行销毁 Register.Finnish()。
注册界面效果
运行后注册界面如图 3.5 所示
在这里插入图片描述

1.4 菜单界面

菜单界面的设计
左上角显示用户头像,头像下面显示好友的排名和分数, 在下面显示我的飞机按钮,按下后会跳到我的飞机界面(MyPlaneActivity),中间有两个按钮分别为的单机模式和联机模式,点击后分别跳转到游戏界面( GameActivity)和联机界面(UnionActivity),上方显示用户的金币数量,右上角为设置图标和商店图标,点击后分别跳转到设置界面(Set_UpActivity)和飞机商店界面(ShopActivity),该界面拥有背景,并且进入时自动播放背景音乐。
菜单界面的实现
通过 SharedPreferences 存储类中存储的用户名,将用户的头像和金币数量从 Room 数据库中读取出来显示在界面上,通过 recycleview 和适配器的配合将用户头像、姓名、分数按分数从高到底排列出来。
将得到的图片字符数据通过 Base64.decode()进行字符转化,再通过 BitmapFactory.decodeStream()把它变成 bitmap 类型, 再通过 setImageBitmap()将头像在控件上显示出来。
在进入菜单界面的时候通过 startService(intent)开启音乐服务,进行音乐播放。
该界面进行跳转时不进行界面销毁,只有当进行注销后或者退出程序后才将该界面进行销毁。
菜单界面效果
运行后菜单界面如图 3.6 所示
在这里插入图片描述

1.5 设置界面

设置界面设计
左上角有退出键,下面为注销按钮, 点击后能够销毁菜单界面( MenuActivity)进入主界面( MainActivity), 右面能够显示音乐播放的进度,能够切换背景音乐,能够暂停和播放背景音乐,以及设置背景音乐声音的大小。
设置界面实现
通过广播接收器接收服务,即继承 BroadcastReceiver 类重写它的 onReceive()方法,来接收服务发来的背景音乐进度、状态和背景音乐声音大小。
通过接口 SeekBar.OnSeekBarChangeListener 对音量大小和音乐进度的监听来实时更新服务的当前音乐的状态。当单击播放、 暂停和切换歌曲按钮后会发送一个广播 sendBroadcast(intent)给服务,让它实时更新音乐的状态。
当点击注销按钮时,通过intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_T
ASK | Intent.FLAG_ACTIVITY_NEW_TASK)销毁在这之前没有销毁的界面即 Set_UpActivity 和 MenuActivity 并进入到主界面。
当点击回退按钮时, 通过 Set_upActivity.finish()销毁当前界面。
设置界面效果
运行后设置界面如图 3.7 所示
在这里插入图片描述

1.6 商店界面

商店界面设计
左上角为退出键,下方分为最新产品和全部产品,通过点击不同的产品按钮,对应右边的窗口进行不同的切换, 按下的按钮颜色会更改,另一个会还原。在右边窗口上显示飞机的图片和按钮,按钮上显示飞机姓名,点击购买后提示购买成功,并将按钮颜色变为灰色,若飞机该用户已经拥有则默认显示为灰色。右上方显示金币的图标和数量,点击购买产品后金币会发生相应的变化。 购买成功后将数据插入到该用户的数据库中, 才能够在换机界面进行显示。
商店界面实现
通过点击按钮在右边的窗口上来回切换不同的 Fragment,并通过 setBackgroundColor()来切换按钮的颜色。 通过四步将界面进行切换,核心代码如下:

FragmentManager fragmentManager=getSupportFragmentManager();
FragmentTransaction transaction=fragmentManager.beginTransaction();
transaction.replace(R.id.frame1,fragment);
transaction.commit();

通过 recycleview 和适配器 planeAdapter 的配合,将飞机图标和按钮显示在右方。通过 GridLayoutManager 将图片和按钮的组合设置为网格型(一行显示 6个)。通过适配器封装好的单个 list 点击事件来判断产品是否购买,并显示购买的飞机信息。
通过 Room 数据库对金币进行动态查询并显示在界面上。当进行购买时通过 Room 封装好的 Updata 语句对数据库的金币进行更新。 并通过 Room 封装好的 Insert 的语句将新购买的飞机数据插入到用户飞机表中。
商店界面效果
运行后商店界面如图 3.8 所示
在这里插入图片描述

1.7 换机界面

换机界面设计
左上角显示退出按钮,下方为不同的飞机类型,分别为全部、战斗机、救援机、轰炸机。右方显示飞机图片和登场按钮,点击登场后按钮变为灰色,其他按钮颜色一致。
换机界面实现
通过 recycleview 和 MyPlaneAdapter 的联合使用将图片和按钮的组合显示在右面界面上。 通过 GridLayoutManager 将图片和按钮的组合设置为网格型(一行显示 6 个)。通过适配器封装好的单个 list 点击事件来判断飞机是否登场,并显示该飞机的登场信息。
通过在 drawable 文件下设置自定义按钮风格布局 buttonstyle.xml 和 button1style.xml 实现点击之后不同风格的切换,将按钮变成圆角类型。
运行后换机界面如图 3.9 所示
在这里插入图片描述

1.8 游戏界面

游戏界面设计
横屏显示,我方飞机在下方,地方飞机在上方随机位置刷新。 左上角有飞机击败的数量和图标,右上角有暂停游戏按钮, 点击后出现一个小的对话框,上面有继续游戏和重新开始的按钮。 右下角有清除所有敌机的功能图标。
游戏的背景进行来回滚动并且有背景音乐,当击杀对方敌机时会有击杀音效,并且动态更新击杀敌人的数量。当和对方敌机碰撞时死亡,死亡后显示所获得的分数,以及显示重新开始和退出游戏的按钮。
敌机数据表如表 3.1 所示。
在这里插入图片描述游戏界面实现
单机模式
创建 gameview 继承 view, 在 GameActivity 上用 setContentview(gameview)将 gameview 所绘制的内容显示在界面上。
Gameview 是创建静态的画面,通过调用线程 GameRunThread 线程来动态刷新界面, Gameview 重写 view 的方法 onTouchEvent(),当触发 MotionEvent.ACTION_DOWN 点击事件时判断是点击了暂停键还是敌机清屏键,当触发 MotionEvent。 ACTION_MOVE 移动事件时,让飞机移动到手指的触点处去。
GameOverDialog 和 GamePauseDialog 继承了 Dialog 对话框。 当点击暂停键时,创建 GamePauseDialog 对话框,当两飞机相撞时,设置Message 对象的 what 值, handler 通过 message.what 的值通知主线程进行相应操作,及创建 GameOverDialo 对话框,并将分数值返回给对话框。
设置移动的背景图片:先获取屏幕的长度和宽度, 再准备两张一样的背景图片, 当一个背景图片移动到了设备的高度的时候把它的 y 值设置为负的设备
的高度。 获取屏幕的长宽通过如下代码:

WindowManager windowManager=this.getWindowManager();
Display defaultDisplay=windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics=new DisplayMetrics();
defaultDisplay.getMetrics(displayMetrics);
宽度(高度)= displayMetrics.widthPixels(heightPixels);

通过音乐池 soundPool来让背景音乐,击败音乐进行播放, 通过 soundPlay()设置音乐的播放方式如 loop=-1 为循环播放。并通过音乐的 ID 进行暂停 soundPool.pause(音乐 ID)和继续播放 soundPool.resume(音乐 ID)。
在游戏线程 GameRunThread的 run方法中添加 while(true)死循环在里面添加实现游戏的关键方法,代码如下:

moveBg();//移动背景
createEmenyPlanes();//创建敌机
emenyPlaneMove();//敌方飞机移动
createBullets();//创建子弹 1、 2、 3
createBullets1();
createBullets2();
bulletMove();//子弹移动
myPlaneAndEnemyPlaneCollide();//本机与敌机的碰撞判断
myPlaneBulletAndEnemyPlaneCollide();//本机子弹与敌机发生碰撞判断
gameView.postInvalidate();//界面刷新

通过两个 for 循环遍历子弹集合 myPlaneBulletList 和敌机集合 enemyPlaneList,获取他们的 x 坐标和 y 坐标之后,通过碰撞算法来判断飞机和子弹是否碰撞,若碰撞则将子弹状态设置为死亡, 将相应的敌机设置 HP减少,并且播放击打特效,并根据血量切换不同状态图片,并将获得的分数显示在界面上。关键代码如下:

myPlaneBullet.setIslive(false);
enemyPlane.setHp(enemyPlane.getHp()-1);
enemyPlane.setIslive(false);
MusicUtil.soundPool.play();
gameView.setGamescore(gameView.getGamescore()+enemyPlane.getScore());

当移动子弹时判断子弹是否存活,如果未存活将其移除子弹集合 myPlaneBulletList.remove(i);当敌机移动时根据 hp 判断是否存活,如果不存活则移除敌机集合Enmtylist.remove(i);
飞机初始时图片在屏幕外面, 先通过 MyPlaneMoveThread 线程让飞机自动移动到相应位置,到位后结束线程并通知飞机可以创建子弹。关键代码如下:

gameView.getMyPlane().planeMove();
//当本机移动到距离底部 300dp 的时候,线程结束
if(MenuActivity.screenHeight-300>=gameView.getMyPlane().getPlane_y()){
gameView.setIscreateBullet(true); //可以创建子弹
break;
}

联机模式
在 UnionActivity 中先将双方飞机的静态图片画好,再通过自定义控件 view.GameView1 来操作飞机图片位置的改变,通过继承 DrawThread 线程实现 surfaceview 的动态更新。
通过 NetworkThread线程,将客户端和服务器端进行绑定套接字 Socket,参数分别为服务器 IP 地址和服务器对应的监听端口,并打开输入输出流。在 windos 下按住 win+r 键输入 cmd,在输入命令 ipconfig,查看当前主机的 IP 地址。如
图 3.10 所示, IP 地址为 172.30.212.42。
在这里插入图片描述
通过摇杆技术 Joystick 控制飞机的移动。
游戏界面效果
运行后单机界面如图 3.11 所示,联机界面如图 3.12 所示
在这里插入图片描述在这里插入图片描述

1.9 欢迎界面

欢迎界面设计
在点开 App 时,在欢迎界面(WelcomeActivity)播放一段加载视频之后跳转到主界面(MainActivity)。
欢迎界面实现
将视频存储到 raw 文件夹中, 通过 videoview 控件设置连接,再通过媒体控制器(mediaController)进行视频播放。为界面添加延时操作,在满足条件后及进行页面跳转,通过 timer.schedule()和 new TimerTask()来实现跳转。
欢迎界面效果
运行后欢迎界面如图 3.13 所示。
在这里插入图片描述

1.10 游戏图标

游戏图标实现
在 AndroidManifest.xml 配置文件中的 application 中的 icon 和 roundIcon 的地址。
游戏图标效果
在这里插入图片描述

二、数据库设计与实现

【Android游戏开发详细过程2】Android平台飞机大战游戏APP设计与实现

三、服务器设计与实现

四、其他功能实现

  • 5
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

手可摘辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值