目录
一、项目演示
网络资源模板--基于Android studio 飞狗游戏
二、项目测试环境
三、项目详情
首页
这段代码是一个名为 `MainActivity` 的活动,实现了一个简单的游戏首页界面功能。以下是它的主要功能和结构:
1. **界面初始化与控件绑定**:
- 在 `onCreate` 方法中,设置了全屏显示,加载了 `activity_main.xml` 布局。
- 使用自定义字体设置了标题文本视图 (`main_text`) 的字体样式。
- 初始化了输入框 (`main_edit`) 和两个按钮 (`main_btn` 和 `main_btn_2`)。
2. **按钮点击事件处理**:
- 使用 `initevent` 方法将两个按钮 (`btn_1` 和 `btn_2`) 的点击事件绑定到 `click` 监听器上。
- `click` 监听器根据点击的按钮不同,执行以下操作:
- **开始游戏按钮 (`main_btn`)**:获取用户输入的游戏名,如果输入有效则将游戏名保存到全局应用 (`app`) 中,并跳转到 `FlyDog` 活动。
- **查看榜单按钮 (`main_btn_2`)**:直接跳转到 `BangDan` 活动,无需用户输入游戏名。
3. **音效处理**:
- 使用 `SoundUtils` 类来处理按钮点击时的音效播放,包括开始游戏按钮和查看榜单按钮。
4. **全局应用数据存储**:
- 使用 `UserData` 类来存储全局的游戏数据,包括用户的游戏名 (`name`),确保在不同活动之间共享数据。
5. **生命周期管理**:
- 在 `onDestroy` 方法中停止了音效的播放,确保活动销毁时资源被正确释放。
这段代码通过监听按钮点击事件,实现了从游戏首页跳转到游戏开始界面或查看榜单界面的功能,并在用户输入有效游戏名时保存数据。
package com.example.myapplication;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
EditText edit;
Button btn_1,btn_2;
String name; //玩家游戏名
SoundUtils soundUtils;
UserData app;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("tag","---onCreate()");
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.main_text);
Typeface typeface = Typeface.createFromAsset(getAssets(),"font/腾祥孔淼卡通字体.ttf");
textView.setTypeface(typeface);
app = (UserData) getApplication();
//初始化控件
initview();
//初始化事件
initevent();
}
public void initview(){
edit = findViewById(R.id.main_edit);
btn_1 = findViewById(R.id.main_btn);
btn_2 = findViewById(R.id.main_btn_2);
}
public void initevent(){
btn_1.setOnClickListener(click);
btn_2.setOnClickListener(click);
}
View.OnClickListener click = new View.OnClickListener() {
@Override
public void onClick(View v) {
soundUtils = new SoundUtils(com.example.myapplication.MainActivity.this, SoundUtils.RING_SOUND);
switch (v.getId()){
case R.id.main_btn:
Log.d("tag","---用户点击开始游戏按钮");
//开始播放音效
soundUtils.putSound(0, R.raw.btn_yin);
soundUtils.playSound(0, SoundUtils.SINGLE_PLAY);
name = edit.getText().toString();
if(name!=null&&!name.equals("")){
app.setName(name);
Intent it = new Intent(com.example.myapplication.MainActivity.this, FlyDog.class);
startActivity(it);
}else{
Toast.makeText(com.example.myapplication.MainActivity.this, "请输入一个游戏名", Toast.LENGTH_SHORT).show();
}
break;
case R.id.main_btn_2:
Log.d("tag","---用户首页点击查看榜单按钮");
//开始播放音效
soundUtils.putSound(0, R.raw.btn_yin);
soundUtils.playSound(0, SoundUtils.SINGLE_PLAY);
Intent it = new Intent(com.example.myapplication.MainActivity.this,BangDan.class);
startActivity(it);
break;
}
}
};
@Override
protected void onDestroy() {
Log.d("tag","---onDestroy()");
super.onDestroy();
soundUtils.stop();
}
}
排行榜
这段代码实现了一个名为 `BangDan` 的活动,用于显示用户的排行榜数据。以下是它的主要功能和结构:
1. **界面初始化与数据加载**:
- 在 `onCreate` 方法中,设置了全屏显示并加载了 `bangdan.xml` 布局。
- 初始化了排行榜数据通过调用 `initBangdan()` 方法。
- 创建了 `BangDanAdapter` 对象并将其与 `ListView` 控件关联,用于显示用户榜单数据。
2. **数据库操作**:
- 使用 `DbHelper` 类获取可读数据库 (`getReadableDatabase()`),并执行查询操作获取排行榜数据。
- 将查询结果封装成 `UserBangDan` 对象并添加到 `UserList` 中,用于后续在列表中显示。
3. **返回按钮处理**:
- 实现了 `ReturnBack(View view)` 方法,用于处理返回按钮的点击事件。
- 在方法中播放了返回按钮点击时的音效,并调用 `finish()` 方法关闭当前活动,返回上一次的界面。
4. **音效处理**:
- 使用 `SoundUtils` 类来处理按钮点击时的音效播放,确保用户操作有音效反馈。
5. **生命周期管理**:
- 在 `onDestroy` 方法中停止了音效的播放,确保活动销毁时资源被正确释放。
总体来说,这段代码实现了一个简单的排行榜页面,通过数据库查询和适配器的使用,展示了用户的排名、得分和时间信息,并提供了返回按钮来退出当前页面。
package com.example.myapplication;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class BangDan extends Activity {
SoundUtils soundUtils;
private List<UserBangDan> UserList = new ArrayList<UserBangDan>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去掉窗口标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
//使程序全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.bangdan);
initBangdan(); // 初始化榜单数据
BangDanAdapter adapter = new BangDanAdapter(BangDan.this, R.layout.item_bangdan_view, UserList);
ListView listView = (ListView) findViewById(R.id.bangdan_listview);
listView.setAdapter(adapter);
}
private void initBangdan() {
Log.d("tag","---显示用户榜单");
String selection = null;
DbHelper dbHelper = new DbHelper(getApplicationContext());
SQLiteDatabase db = dbHelper.getReadableDatabase();
StringBuilder stringBuilder = new StringBuilder();
Cursor cursor = db.query("BangDan",null,selection,null,
null, null,"fen desc");
int ranking=1;//排名
while(cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String fen = cursor.getString(cursor.getColumnIndex("fen"));
String time = cursor.getString(cursor.getColumnIndex("date"));
UserBangDan user = new UserBangDan(name, 1,fen,time);
UserList.add(user);
ranking++;
}
}
public void ReturnBack(View view) {
Log.d("tag","---返回上一次的界面");
//开始播放音效
soundUtils = new SoundUtils(BangDan.this, SoundUtils.RING_SOUND);
soundUtils.putSound(0, R.raw.btn_yin);
soundUtils.playSound(0, SoundUtils.SINGLE_PLAY);
this.finish();
}
@Override
protected void onDestroy() {
Log.d("BangDan.java","---onDestroy()");
super.onDestroy();
if(soundUtils!=null){
soundUtils.stop();
}
}
}
游戏页面
这段代码实现了一个游戏开始的方法 `play()`,主要功能是游戏的初始化设置、用户操作的响应、游戏逻辑的处理以及定时器的使用。以下是它的详细解释:
1. **游戏初始化**:
- 在 `play()` 方法开始处,设置了一系列游戏参数的初始值,包括柱子的位置、速度,狗子的位置和速度,以及其他相关参数。
2. **触摸事件处理**:
- 使用 `gameview.setOnTouchListener` 方法重写了触摸事件处理逻辑。根据用户的手指动作(按下、滑动、抬起),改变狗子的图像并处理相应的音效播放。当用户手指按下时,狗子上升;抬起时,狗子下降;滑动时保持狗子状态不变。
3. **定时器任务**:
- 使用 `Timer` 和 `TimerTask` 实现了游戏的主循环逻辑。在 `run()` 方法中,根据游戏逻辑判断狗子与柱子的碰撞、游戏进度和音效播放等。
- 如果狗子碰到屏幕底部,游戏结束;如果狗子越过柱子并且没有处于无敌状态,进行相应的处理;如果狗子撞到柱子,播放撞击音效并减少生命值;如果柱子移动到屏幕边缘,重置位置并增加游戏难度等。
4. **生命周期管理**:
- 通过日志输出在不同的游戏事件和状态下记录信息,帮助调试和跟踪游戏的运行情况。
5. **游戏参数动态调整**:
- 根据游戏进度,如达到特定分数 (`WudiNum`) 后进入无敌状态,加分规则的动态调整等,实现游戏难度逐渐增加的效果。
总体来说,这段代码实现了一个简单的竖版飞行类游戏的核心逻辑,包括用户操作响应、游戏状态判断、音效播放和动态游戏参数的调整,以及通过定时器实现游戏主循环。
public void play(){
Log.d("tag","---游戏开始");
isOver = false;
//设置两根柱子的初始位子
zhuX = zmWidth - zhu_kuan;
zhuY = 0;
zhuX_2 = zmWidth - zhu_kuan;
zhuY_2 = zmHeight;
zhu_gao = zmHeight/2 - 200;
zhu_gao_2 = zmHeight - zhu_gao -200;
pass_num =0;
zhu_speed = 5;
dog_speed = 3.5f;
dog_up = 85;
//设置狗子的初始位子
imageId = R.drawable.dog;//默认无角度图
dogX = 50;
dogY = zmHeight/2;
//重写手势识别
gameview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: // 用户手指按下事件
Log.d("tag","---用户手指按下");
imageId = R.drawable.dog_up;//狗抬头
//开始播放音效
soundUtils.putSound(1, R.raw.pu);
soundUtils.playSound(1, SoundUtils.SINGLE_PLAY);
//用户手指按下时上升狗子高度
if(dogY >20){
Log.d("tag","---用户点击屏幕狗子高度上升");
dogY = dogY - dog_up;
}else{
dogY = dogY -1;
}
break;
case MotionEvent.ACTION_MOVE: // 用户手指滑动事件
Log.d("tag","---用户手指滑动");
imageId = R.drawable.dog_up;//狗抬头
break;
case MotionEvent.ACTION_UP: //用户手指抬起事件
Log.d("tag","---用户手指抬起");
imageId = R.drawable.dog_down;//狗低头
break;
}
//通知gameView组件从新绘制
gameview.invalidate();
return true;
}
});
//创建一个定时器实例
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
//判断是否达到无敌的分数
if(pass_num >=WudiNum&& pass_num <=WudiNum+100){
Log.d("tag","---达到无敌分数");
isWudi=true;
}
else
isWudi=false;
//如果狗子碰到屏幕边缘
if(dogY >= zmHeight){
Log.d("tag","---狗子碰到屏幕边缘");
imageId = R.drawable.split;//狗裂开
soundUtils.putSound(1, R.raw.fail);
soundUtils.playSound(1, SoundUtils.SINGLE_PLAY);
isOver = true;
}
//如果狗子碰到柱子
if(dogX >= zhuX){
Log.d("tag","---狗子越过柱子");
imageId = R.drawable.funny;//过关后狗滑稽
if(isWudi==true){
Log.d("tag","---无敌状态获得额外加分");
pass_num +=5;
}
if(dogY < zhuY+zhu_gao|| dogY > zhuY_2 - zhu_gao_2){
Log.d("tag","---狗子撞到柱子");
soundUtils.putSound(2, R.raw.hit);
soundUtils.playSound(2, SoundUtils.SINGLE_PLAY);
imageId = R.drawable.split;//狗裂开
lifeNum-=2*lifetimes;
lifetimes+=1;
pass_num -=2;
}
if(lifeNum<=200){//因为血条起始x坐标为200,因此当生命值减少至200时游戏结束
Log.d("tag","---生命值归零,游戏结束");
isOver=true;
}
}
if(dogY <zmHeight){
dogY = dogY + dog_speed;//加速
}
//如果柱子碰到边缘
if(zhuX <= 0){
Log.d("tag","---柱子到达屏幕,进行加分和上下柱位置重置操作");
zhuX = zmWidth - zhu_kuan;
zhuY = 0;
zhuX_2 = zmWidth - zhu_kuan;
zhuY_2 = zmHeight;
float i = (float) (Math.random());
pass_num +=10;
//开始播放音效
soundUtils.putSound(3, R.raw.pass);
soundUtils.playSound(3, SoundUtils.SINGLE_PLAY);
zhu_speed = zhu_speed +0.7f;
dog_speed = dog_speed +0.08f;
dog_up = dog_up + 2f;
Log.e("i:",i+"");
if(i>0.3&&i<0.95){
zhu_gao = zmHeight*i - 200;
zhu_gao_2 = zmHeight - zhu_gao -200;
}
}
zhuX = zhuX - zhu_speed;
zhuX_2 = zhuX_2- zhu_speed;
//重置柱子移动速度
if(pass_num>=200&&pass_num<=220){
zhu_speed=12;
}
//发送空消息,通知游戏组件重新绘制
handler.sendEmptyMessage(0x123);
}
},0,15);
}
四、完整的项目源码
👇👇👇👇👇快捷获取方式👇👇👇👇👇