项目信息表
项目名称 | 角色扮演游戏简介 |
项目需求 | 展示热门游戏,用户可以选择其中一个游戏,查看相应游戏介绍,包括文字,图片,游戏演示视频;给 出游戏评分功能,游戏列表按照评分进行排序,游戏按照点击次数进行排序 |
项目设计 | 游戏介绍,视频播放,点击次数排序,评分排序 |
项目基本功能 | 点击游戏查看游戏介绍,播放视频,相关排序 |
项目附加功能 | 无 |
项目特色 | 可以根据评分和点击次数排序 |
项目测试 | 良好 |
项目展望 | 良好 |
代码量(行数) | 655 |
类个数 | 5 |
项目开发中面临的主要困难 | 按点击次数与评分排序 |
采用的解决策略 | 百度、论坛、博客 |
目录
1引言 1
1.1项目背景及意义 1
1.2项目内容 1
2开发环境及技术介绍 1
2.1 技术一 2
2.2 技术二 2
2.3 技术三 3
3系统分析 3
3.1系统可行性分析 3
3.2系统需求分析 4
4系统设计 4
5系统实现 5
5.1系统实现 5
5.2 系统配置文件 23
5.3系统测试 24
参考文献 25
1引言
1.1项目背景及意义
目前Android平台手机渗透到我们生活,20 世纪末,电子技术获得了飞速的发展,在其推动下,基于Android平台手机的现代电子产品在我们生活的各个角落都能见到,有力地推动了社会信息化程度的提高,同时也使现代电子产品性能进一步提高, 产品更新换代的节奏也越来越快。基于Android平台手机的发展趋势,本设计以Android平台手机为核心制作了一个文件浏览器。
游戏简介是游戏公司给用户推荐游戏的软件,给用户提供娱乐的。所有游戏简介软件都提供了基本的功能:如游戏文字介绍、游戏视频播放、给游戏评分、还有游戏排序。许多Android游戏软件还提供了额外功能,如网络连接、评论、下载、搜索等。
1.2项目内容
展示热门游戏,用户可以选择其中一个游戏,查看相应游戏介绍,包括文字,图片,游戏演示视频;给出游戏评分功能,游戏列表按照评分进行排序,游戏按照点击次数进行排序。
2开发环境及技术介绍
2.1 Android
Android一词本意是指“机器人”,与2007年被Google公司宣布基于Linux平台的开源手机操作系统,是首个为移动终端打造的真正开放和完整的移动操作系统。从某种方面而言,开源,意味着生产细节的公开化以及大众的可参与性,这在根本意义上决定了与IOS,Windows等系统不同。因为其可参与性和内部细节的透明化从某种意义上来说使得Android的生态圈呈一片欣欣向荣的情景。
绝大多数Android开发是指的基于Android平台的SDK开发,而谈到SDK开发,则不得不对其Android系统分层进行了解。
如上图所示,Android系统分层大抵可分为这四层:
①Linux内核层:包含Linux内核和驱动模块(比如USB,Camera,蓝牙等);
②Libraries层:这一层提供动态库(也叫共享库),Android运行时库,Dalvik虚拟机等。编程语言主要为C或者C++,所以可以简单的看出native层;
③Framework层:这一层大部分用Java语言编写,它是基于Android平台上Java世界的基础;
④Application层:应用层,主要存放各种各样的应用程序。
而我们平常绝大多数的Android开发就是在Application层上的Java开发。
2.2 Eclipse
Eclipse: Eclipse 是一款相当优秀的开放源代码的、基于Java的可扩展的集成开发环境。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse附带了一个标准的插件集,包括Java开发工具。Eclipse 是一个开放源代码的软件开发项目,专注于为高度集成的工具开发提供一个全功能的、具有商业品质的工业平台。
2.3 Java
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言是静态面向对象编程语言的代表,极好地实现了面向对象理论。Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点。
3系统分析
3.1系统可行性分析
(1)技术可行性
游戏推荐类的应用有很多,目前有很多在android market中使用,在国内的应用市场中能看见。由于在国内外Android领域中,还处于发展的初级阶段,还很少有开发者能对整体设计有一定的思想以及理念,成熟度非常低,有待于完善的地方也很多。在开发中可能会遇到的问题,对于一个屏幕有限制的项目如何展现出尽可能让用户了解更多的内容,对于安全性的问题。所以,对于技术上的实现可能有一定的问题,但是为会努力的克服困难,完成技术方面的问题。
(2)操作可行性
该文件管理器需要如下的运行环境:CPU:500MHZ及以上;内存:256 M及以上。安装有Android 2.1以上的操作系统。因此,从操作可行性来看,只要系统用户的硬件软件设备满足以上条件,即可用该文件管理器。
3.2系统需求分析
3.2.1 系统的主要功能需求
角色扮演游戏推荐最终是要安装到手机上以供用户操作,所以应该从用户出发和 Android 系统手机的使用者进行不断的沟通,深入了解以便很好的获取需求。将用户的模糊需求转化成为具体的软件模型,这样才能简化用户的操作,使大众用户很乐意用你的软件,本课题所设计的基于 Android 的角色扮演游戏。
1、游戏的浏览:
打开PersonGame之后,主界面就会显示当前热门的角色扮演游戏,我们可以点击游戏进入所点击的游戏介绍页,有文字说明,游戏相关视频,以及评星界面。
2、视频的操作
对于本项目,视频操作很简单只有播放,暂停,以及重播。
3、评分操作
点击评星数即可打分。
4、排序操作
分为两种排序:通过右上角的meun选择排序方式(评分和点击次数)
3.2.2 系统功能性需求
Android游戏推荐系统面向用户功能明确,并且由于是基于Android系统手机嵌入式软件,所以满足本项目的主要功能的同时,还需要满足一些非功能性需求。非功能性需求在以往的软件开发中经常被研发人员忽视,导致非功能性需求得不到保障,进而致使保障不了功能性需求的定义和实现。为了更好的实现角色扮演游戏系统的带给用户的体验,基于提高软件质量和遵守Android软件设计的主流标准和规范的考虑,文件管理系统非功能性需求有以下几个方面:
1、界面设计需求:此处的界面设计需求不同于详细的界面的设计, 主要体现的是用户在手机上使用本软件的体验感觉。作为手机应用,应该注重软件界面设计的美观,简单,大方。由于文件类型的较多,不同文件类型模块间的切换要求平滑实现。界面主题颜色采用醒目亮色。调用 Android操作系统的控件时充分考虑系统对控件的支持是否良好和使用范围是否超出软件需求。
2、 易用性需求:在满足用户功能的需求的同时,软件最终提供给用户的功能的调用要符合用户使用手机软件的习惯操作和对软件的前期期望值。系统需求分析中心围绕的用户的使用习惯展开,细分用户习惯和需求,和软件应用功能相结合,最终达到用户可以更快的操作软件。
3、适应性需求:适应性需求主要包括角色扮演游戏软件对手机软件环境和硬件环境的适应。系统适应的软件环境主要是适应手机Android 操作系统,软件适合于 Android 2 . 1 以上的所有版本的系统。
4系统设计
4.1系统结构设计
Android系统架构由五部分组成:Linux Kernel,Android Runtime,Libraries,Application Framework,Applications。
5系统实现
5.1系统实现
功能说明:
展示热门游戏,用户可以选择其中一个游戏,查看相应游戏介绍,包括文字,图片,游戏演示视频;给 出游戏评分功能,游戏列表按照评分进行排序,游戏按照点击次数进行排序。
排序实现类说明:
首先排序需要调用Collections.sort(mDatas, new SortByDateline());
mDatas:是排序的数据源
new SortByDateline():是排序重写类需要实现Comparator方法
重写compare(Object o1, Object o2)方法。
返回 -1(小于0):o1排在o2前面
返回1(大于0):o2排在o1前面
返回0:默认排序
实现代码:
//显示角色扮演游戏详细界面
package com.example.persongame;
import java.io.File;
import com.example.bean.GameInfo;
import com.example.hotgame.R;
import android.app.ActionBar;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.RatingBar.OnRatingBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
public class GameDetailActivity extends Activity implements OnClickListener {
private GameInfo mGameInfo;
private VideoView videoView;
private Button btnPlay, btnPause, btnReplay;
private ImageView ivIntro, ivIntro1;
private TextView tvIntro;
private RatingBar ratingbar;
private int position;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.detail);
position = getIntent().getIntExtra("POSITION", 0);
mGameInfo = MyApplication.mListQP.get(position);
ActionBar bar = getActionBar();
bar.setDisplayShowHomeEnabled(true);
bar.setDisplayHomeAsUpEnabled(true);
bar.setTitle(mGameInfo.name);
ratingbar = (RatingBar) findViewById(R.id.ratingbar);
ratingbar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar arg0, float arg1, boolean arg2) {
// TODO Auto-generated method stub
mGameInfo.pinFen = arg1;
MyApplication.mListQP.get(position).pinFen = arg1;
Toast.makeText(GameDetailActivity.this, arg1 + "分",
Toast.LENGTH_LONG).show();
}
});
tvIntro = (TextView) findViewById(R.id.tvIntro);
ivIntro = (ImageView) findViewById(R.id.ivIntro);
ivIntro1 = (ImageView) findViewById(R.id.ivIntro1);
videoView = (VideoView) findViewById(R.id.vdvwFilm);
btnPlay = (Button) findViewById(R.id.btnPlay);
btnPause = (Button) findViewById(R.id.btnPause);
btnReplay = (Button) findViewById(R.id.btnReplay);
btnPlay.setOnClickListener(this);
btnPause.setOnClickListener(this);
btnReplay.setOnClickListener(this);
initVideoPath(bar);
}
private void initVideoPath(ActionBar mActionBar) {
Uri uri = null;
String text = null;
Drawable one = null, two = null;
switch (mGameInfo.type) {
case 1:
one = getResources().getDrawable(R.drawable.gtx3);
two = getResources().getDrawable(R.drawable.gtx1);
text = getResources().getString(R.string.gtx);
uri = Uri.parse("android.resource://com.example.hotgame" + "/"
+ R.raw.gtx);
break;
//梦幻西游
case 2:
one = getResources().getDrawable(R.drawable.mhxy3);
two = getResources().getDrawable(R.drawable.mhxy1);
text = getResources().getString(R.string.mhxy);
uri = Uri.parse("android.resource://com.example.hotgame" + "/"
+ R.raw.mhxy);
break;
// zhuoyaoji
case 3:
one = getResources().getDrawable(R.drawable.zyj3);
two = getResources().getDrawable(R.drawable.zyj1);
text = getResources().getString(R.string.zyj);
uri = Uri.parse("android.resource://com.example.hotgame" + "/"
+ R.raw.zyj);
break;
// 轩辕传奇2
case 4:
one = getResources().getDrawable(R.drawable.xycq3);
two = getResources().getDrawable(R.drawable.xycq1);
text = getResources().getString(R.string.xycq);
uri = Uri.parse("android.resource://com.example.hotgame" + "/"
+ R.raw.xycq);
break;
}
mActionBar.setIcon(one);
ivIntro.setImageDrawable(one);
ivIntro1.setImageDrawable(two);
tvIntro.setText(text);
videoView.setVideoURI(uri);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnPlay:
if (!videoView.isPlaying()) {
videoView.start();
}
break;
case R.id.btnPause:
if (videoView.isPlaying()) {
videoView.pause();
}
break;
case R.id.btnReplay:
if (videoView.isPlaying()) {
videoView.resume();
}
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (videoView != null) {
videoView.suspend();
}
}
}
// 显示游戏信息listview的适配器
package com.example.adapter;
import java.util.List;
import com.example.bean.GameInfo;
import com.example.hotgame.R;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class GameInfoAdapter extends BaseAdapter {
private List<GameInfo> mList;
private Context mContext;
public GameInfoAdapter(Context mContext, List<GameInfo> list) {
this.mList = list;
this.mContext = mContext;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mList.size();
}
@Override
public GameInfo getItem(int arg0) {
// TODO Auto-generated method stub
return mList.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int arg0, View convertView, ViewGroup arg2) {
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.listview_item, null);
holder = new ViewHolder();
holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
holder.tvCiShu = (TextView) convertView.findViewById(R.id.tvCiShu);
holder.tvPinFen = (TextView) convertView
.findViewById(R.id.tvPinFen);
holder.imageView = (ImageView) convertView
.findViewById(R.id.mImageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
GameInfo mGameInfo = mList.get(arg0);
Drawable temp = null;
switch (mGameInfo.type) {
case 1:
temp = mContext.getResources().getDrawable(R.drawable.gtx3);
break;
case 2:
temp = mContext.getResources().getDrawable(R.drawable.mhxy3);
break;
case 3:
temp = mContext.getResources().getDrawable(R.drawable.zyj3);
break;
case 4:
temp = mContext.getResources().getDrawable(R.drawable.xycq3);
break;
}
holder.imageView.setImageDrawable(temp);
holder.tvName.setText(mGameInfo.name);
return convertView;
}
public class ViewHolder {
TextView tvName;
TextView tvCiShu;
TextView tvPinFen;
ImageView imageView;
}
}
//数据点击次数及评分
package com.example.bean;
import java.io.Serializable;
public class GameInfo implements Serializable{
private static final long serialVersionUID = -967229318303568857L;
public String name;
public String introduction;
public int clickNum;
public float pinFen;
public int type;
}
//myapplication
package com.example.persongame;
import java.util.ArrayList;
import java.util.List;
import com.example.bean.GameInfo;
import com.example.hotgame.R;
import android.app.Application;
public class MyApplication extends Application {
public static List<GameInfo> mListQP = new ArrayList<GameInfo>();
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
GameInfo gtx = new GameInfo();
gtx.name = "钢铁侠3";
gtx.type = 1;
gtx.introduction = getResources().getString(R.string.gtx);
mListQP.add(gtx);
GameInfo mhxy = new GameInfo();
mhxy.name = "梦幻西游";
mhxy.type = 2;
mhxy.introduction = getResources().getString(R.string.gtx);
mListQP.add(mhxy);
GameInfo zyj = new GameInfo();
zyj.name = "爆笑捉妖记";
zyj.type = 3;
zyj.introduction = getResources().getString(R.string.zyj);
mListQP.add(zyj);
GameInfo xycj = new GameInfo();
xycj.name = "轩辕传奇2";
xycj.type = 4;
xycj.introduction = getResources().getString(R.string.xycq);
mListQP.add(xycj);
}
}
//主界面
package com.example.persongame;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.example.adapter.GameInfoAdapter;
import com.example.bean.GameInfo;
import com.example.hotgame.R;
public class GameListActivity extends Activity {
private ListView mListView;
private List<GameInfo> mList = new ArrayList<GameInfo>();
private GameInfoAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gamelist);
ActionBar mActionBar = getActionBar();
String title = "角色扮演";
mActionBar.setTitle(title);
mList.addAll(MyApplication.mListQP);
mListView = (ListView) findViewById(R.id.mListView);
adapter = new GameInfoAdapter(this, mList);
mListView.setAdapter(adapter);
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
GameInfo gameInfo = mList.get(arg2);
gameInfo.clickNum = gameInfo.clickNum + 1;
Intent intent = new Intent(GameListActivity.this,
GameDetailActivity.class);//intent.putExtra("TYPE", gameInfo.type);
intent.putExtra("POSITION", arg2);
startActivity(intent);
}
});
}
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
adapter.notifyDataSetChanged();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.sort, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_settings:
if (mList.size() > 0) {
Collections.sort(mList, new Comparator<GameInfo>() {
@Override
public int compare(GameInfo arg0, GameInfo arg1) {
// TODO Auto-generated method stub
int temp = arg1.clickNum - arg0.clickNum;
return temp;
}
});
adapter.notifyDataSetChanged();
}
break;
case R.id.action_one:
if (mList.size() > 0) {
Collections.sort(mList, new Comparator<GameInfo>() {
@Override
public int compare(GameInfo arg0, GameInfo arg1) {
// TODO Auto-generated method stub
if (arg0.pinFen < arg1.pinFen) {
return 1;
} else if (arg0.pinFen > arg1.pinFen) {
return -1;
} else {
return 0;
}
}
});
adapter.notifyDataSetChanged();
}
break;
case R.id.aboutme:
showAbout();
break;
}
return super.onOptionsItemSelected(item);
}
//关于我
private void showAbout() {
new AlertDialog.Builder(this)
.setTitle(R.string.app_name)//标题
.setMessage(R.string.about_meesage)//消息内容
.setPositiveButton(android.R.string.ok, null)
.create()
.show();
}
}
//右上角菜单
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.hotgame.MainActivity" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="点击排序"
android:showAsAction="never"/>
<item
android:id="@+id/action_one"
android:orderInCategory="100"
android:title="评分排序"
android:showAsAction="never"/>
<item
android:id="@+id/aboutme"
android:orderInCategory="100"
android:title="关于我"
android:showAsAction="never"/>
</menu>
实现效果截图:
主界面
详细游戏介绍
5.2系统配置文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hotgame"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="21" />
<application
android:name="com.example.persongame.MyApplication"
android:allowBackup="true"
android:icon="@drawable/gtx1"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.persongame.GameListActivity"
android:launchMode="singleTask"
android:theme="@style/AppTheme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.persongame.GameDetailActivity"
android:parentActivityName="com.example.persongame.GameListActivity"
android:theme="@style/AppTheme" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.hotgame.GameListActivity" />
</activity>
<activity
android:name="com.example.persongame.AboutMeActivity"
android:parentActivityName="com.example.persongame.GameListActivity"
android:theme="@style/AppTheme" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.hotgame.GameListActivity" />
</activity>
</application>
</manifest>
5.3系统测试
系统测试是检验系统是否确实能提供系统方案说明书中指定功能的有效方法,为了发现缺陷并度量产品质量,按照系统的功能和性能需求进行的测试,找出存在的问题并加以修改,使系统稳定运行。
参考文献
[1] 卢海东 Android应用开发从入门到精通 android6.0系统程序开发教程书籍 安卓编程教程 2016.
[2] 张荣 Android开发与应用 人民邮电大学出版社 2014.2
[3] 明日科技 《Java从入门到精通(第4版)》 清华大学出版社出版 2016.