滨江学院
《Android》课程设计报告
题 目 飞翔的圆(类似Flappy Bird)
专 业_ _ 学生姓名_____ _ ____ __ 学 号_ _
二O一五年 六月 二十五日
目录
一 安卓应用程序开发背景 .................................................................. 3
1.1 1.2
开发背景 .................................................................................. 3 开发环境 .................................................................................. 4
二 安卓应用程序开发理论与方法 ...................................................... 4 三 小游戏应用程序的设计与实现 ...................................................... 6
3.1 3.2 3.3
拟解决的问题及目标 ............................................................ 6 总体设计 ............................................................................... 5 详细设计与编码实现 ............................................................ 6
四 总结 ............................................................................................... 17
一 安卓应用程序开发背景
1.1开发背景
1.智能手机的市场
(1)功能多样化的智能手机挑战全球PC出货量
移动互联网时代的来临,直接促进了搭载智能操作系统、具有强大扩展性的智能手机、平板电脑等移动终端产业的蓬勃发展。来自美国最大的风险投资机构KPCB的数据显示,全球智能手机出货量正在以远高于台式电脑、笔记本电脑出货量的速度快速增长,该机构预计2011年全球智能手机出货量将达到4.13亿,超过台式电脑与笔记本电脑出货量的总和。 (2)智能手机的用户使用数量正在高速增长。据市场调研机构Gartner信息,2011年全球智能手机的总出货量将会达到4.68亿部,相比2010年实现了57.7%的增长,而谷歌Android操作系统将会在今年之内成为全球最大的智能手机操作系统。另外,全球市场调研机构IDC预计未来5年中国手机市场上,智能手机替代传统功能手机的趋势将日益明显,未来5年中国智能手机市场复合增长率将达到34.1%,人们对IT设备智能化的向往是这一增长率能够实现的主要因素,并且与其他国家相比,中国智能手机市场的发展空间更加广阔。 (3)操作系统格局预测:Android有望成为智能手机市场主导力量
搭载Android操作系统的智能手机目前已经成为市场上最炙手可热的智能产品。来自美国市场研究机构Gartner的数据显示,Android操作系统所占的市场份额从2008年的0.5%急剧增长到2011年的15.94%。开放的源代码和零成本已经让Android在全世界范围内受到青睐并迅速获得了主要手机厂商和数百万软件开发者的支持,Gartner预计,未来Android系统的市场份额有望超过其他操作系统,从而成为全球第一大智能手机操作系统。 2.安卓手机介绍
安卓手机指的是用Android操作系统的手机。安卓(Android)是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。
同样都是手机上面用的智能系统,安卓的系统是新生系统,界面更为华丽,开源性更强,当然因为是新生系统,所以在第三方软件方面暂时还不太多。因此,安卓应用程序的需求还是很迫切的。 3.软件人才需求
据业内统计,目前国内的Android研发人才缺口至少30万。由于目前Android技术较新,无论是相关书籍、培训还是大学教育,都处于初级阶段,因此Android人才短期将供不应求。从长期来看,随着各种移动应用和手机游戏等内容需求日益增加,也将激励大中小型手机应用开发商加大对Android应用的开发力度,因此Android人才的就业前景也非常广泛。
综上所述,在这样的背景下,安卓有很强的生命力。同时,作为一个新生的系统,其应用程序目前并不多,安卓应用程序的需求还是很迫切的,安卓研发人才的缺口还很大。这些都促进了我们学习开发安卓应用程序。
1.2开发环境
安卓应用程序开发环境如下:
①JDK 5 or JDK 6 (JRE alone is not sufficient) ②Eclipse 3.3 (Europa), 3.4 (Ganymede) ③Android SDK ④ADT 0.8.0
⑤Eclipse安装ADT 插件
二 安卓应用程序开发理论与方法
1、Activity的相关知识
简单理解Activity 代表一个用户所能看到的屏幕,Activity 主要是处理一个应用的整体性工作。Activity是最基本的Android 应用程序组件,应用程序中,一个活动通常就是一个单独的屏幕。每一个活动都被实现为一个独立的类,并且从活动基类中继承而来,活动类将会显示由视图控件组成的用户接口,并对事件做出响应。大多数的应用是由多个屏幕显示组成,因而要用到多个Activity。 (1)Activity的相关方法及相关函数: A、void onCreate(Bundle)
首次启动时调用,接受参数:Null or savedInstanceState(保存的以前某些状态信息)
B、void onStart()
说明了将要显示给用户的活动 C、void onRestart()
将处于停止状态的活动重新显示给用户 D、void onResume()
用户可以开始与活动进行交互时调用。如动画播放和音乐播放。 E、void onPause()
活动将要进入后台运行时调用。(此时前台启动了另一个活动) F、void onStop()
不需要某个活动了,就调用 G、void onDestroy() 销毁活动
(2)多个Activity之间的跳转:
通过Intent类实现屏幕之间的跳转(包括没有参数关系和需要传递参数两种情况)。 (3)两个Activity之间进行数据交换: startActivity() 只有Intent一个参数。
public void startSubActivity(Intent intent, int requestCode) (requestCode:用来标识某一个调用,一般定义一个常量。)
传过去:函数原型为: public Intent setData(ContentURI data) 然后,参数带到新的Activity后,同样用Activity.getIntent()函数可得到当前过来的Intent对象,然后用getData()就取到参数了。
传回来:函数原型为: public final void setResult(int resultCode, String data) 2、Intent的相关知识
Intent 是描述应用想要做什么。Android 使用了Intent 这个特殊类,实现在屏幕与屏幕之间移动。Intent 数据结构两个最重要的部分是动作和动作对应的数据。Intent类绑定一次操作,它负责携带这次操作所需要的数据以及操作的类型等。 3、Layout
用于用户界面设计。包含AbsoluteLayout, FrameLayout,GridView, LinearLayout, ListLayout, RadioGroup, TableLayout等等。
在本程序中用到的有: (1) 线性布局LinearLayout
垂直:android:orientation=\"vertical“ 水平:android:orientation=\"horizontal\"
(2) 相对布局RelativeLayout
让子元素指定它们相对于其他元素的位置(通过ID 来指定)或相对于父布局对象。在RelativeLayout布局里的控件包含丰富的排列属性: Layout above:控件在指定控件的上方
Layout below:控件在指定控件的下方 Layout to left of……
三 小游戏应用程序的设计与实现
3.1 拟解决的问题及目标
本游戏上手简单,主旨在让人在紧张的生活中,获得游戏的乐趣,程序要实现的目标有如下几个: (1) 界面流畅 (2) 有当前得分 (3) 有最高得分
(4) 后点击界面重新开始游戏
3.2 总体设计
1、游戏的操作流程
点击屏幕即可开始,当出现游戏界面是,通过点击屏幕控制圆点的高度,使得圆点触碰不到上下两边的长方形。
3.3 详细设计与编码实现
1、游戏界面
开始界面,点击屏幕圆点自动向前移动
当前得分0,点击屏幕控制圆点高度
2、核心代码如下:
GameBirdActivity类
触碰到长方形,游戏结束,点击屏幕重新开始
public class GameBirdActivity extends Activity { public static GameBirdActivity instance; private LinearLayout gameView;
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); instance = this;
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.content_view);
//game
gameView = (LinearLayout)this.findViewById(R.id.game_view); gameView.addView(new GameBirdSurfaceView(this)); }
public void showMessage(int level){ saveSettingData(level);
Intent intent = new Intent(this, LoadingActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent);
}
public static final String GameBirdSettingsFile = \"GameBird_Settings\"; public static final String Settings_LevelLast = \"LevelLast\"; public static final String Settings_LevelTop = \"LevelTop\";
private void saveSettingData(int level) {
SharedPreferences gb_settings = getSharedPreferences( GameBirdSettingsFile, 0);
gb_settings.edit().putInt(Settings_LevelLast, level).commit(); int top = gb_settings.getInt(Settings_LevelTop, 0); if(level>top){
gb_settings.edit().putInt(Settings_LevelTop, level).commit(); }
} }
GameBirdSurfaceView类 public class GameBirdSurfaceView extends SurfaceView implements Callback, Runnable {
private SurfaceHolder sfh; private Paint paint;
private Thread th; private boolean flag;
private Canvas canvas;
private static int screenW, screenH;
private static final int GAME_MENU = 0; private static final int GAMEING = 1; private static final int GAME_OVER = -1;
private static int gameState = GAME_MENU;
private int[] floor = new int[2]; private int floor_width = 15;
private int speed = 3;
private int[] level = new int[2]; private int level_value = 0;
private int[] bird = new int[2]; private int bird_width = 10; private int bird_v = 0; private int bird_a = 2;
private int bird_vUp = -16;
private ArrayList private ArrayList public GameBirdSurfaceView(Context context) { super(context); sfh = this.getHolder(); sfh.addCallback(this); paint = new Paint(); paint.setColor(Color.WHITE); paint.setAntiAlias(true); paint.setTextSize(50); paint.setStyle(Style.STROKE); setFocusable(true); setFocusableInTouchMode(true); this.setKeepScreenOn(true); } public void surfaceCreated(SurfaceHolder holder) { screenW = this.getWidth(); screenH = this.getHeight(); initGame(); flag = true; th = new Thread(this); th.start(); } private void initGame() { if (gameState == GAME_MENU) { floor[0] = 0; floor[1] = screenH - screenH/5; level[0] = screenW/2; level[1] = screenH/5; level_value = 0; bird[0] = screenW/3; bird[1] = screenH/2; walls.clear(); floor_width = dp2px(15); speed = dp2px(3); bird_width = dp2px(10); bird_a = dp2px(2); bird_vUp = -dp2px(16); wall_w = dp2px(45); wall_h = dp2px(100); wall_step = wall_w*4; } } private int dp2px(float dp){ int px Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, getResources().getDisplayMetrics())); return px; } public void myDraw() { try { canvas = sfh.lockCanvas(); if (canvas != null) { //clear canvas.drawColor(Color.BLACK); //background int floor_start = floor[0]; while(floor_start floor_start += floor_width*2; } //wall for (int i = 0; i < walls.size(); i++) { int[] wall = walls.get(i); = dp, floor[1], float[] pts = { wall[0],0,wall[0],wall[1], wall[0],wall[1]+wall_h,wall[0],floor[1], wall[0]+wall_w,0,wall[0]+wall_w,wall[1], wall[0]+wall_w,wall[1]+wall_h,wall[0]+wall_w,floor[1], wall[0],wall[1], wall[0]+wall_w, wall[1], wall[0],wall[1]+wall_h, wall[0]+wall_w, wall[1]+wall_h }; canvas.drawLines(pts, paint); paint); floor[1], paint); } //bird canvas.drawCircle(bird[0], bird[1], bird_width, paint); //level canvas.drawText(String.valueOf(level_value), level[0], level[1], paint); } } catch (Exception e) { } finally { if (canvas != null) sfh.unlockCanvasAndPost(canvas); } } public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ switch (gameState) { case GAME_MENU: gameState = GAMEING; //bird_v = bird_vUp; //break; case GAMEING: bird_v = bird_vUp; break; case GAME_OVER: //bird down if(bird[1] >= floor[1] - bird_width){ gameState = GAME_MENU; initGame(); } break; } } return true; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { GameBirdActivity.instance.finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } private int move_step = 0; private void logic() { switch (gameState) { case GAME_MENU: break; case GAMEING: //bird bird_v+=bird_a; bird[1] += bird_v; if(bird[1] > floor[1] - bird_width){ bird[1] = floor[1] - bird_width; gameState = GAME_OVER; } //top //if(bird[1]<=bird_width){ //bird[1]=bird_width; //} //floor if(floor[0] < -floor_width){ floor[0] += floor_width*2; } floor[0] -= speed; //wall remove_walls.clear(); for (int i = 0; i < walls.size(); i++) { int[] wall = walls.get(i); wall[0] -= speed; if(wall[0]<-wall_w){ remove_walls.add(wall); }else if(wall[0]-bird_width<=bird[0]&& wall[0]+wall_w+bird_width>=bird[0] &&(bird[1]<=wall[1]+bird_width||bird[1]>=wall[1]+wall_h-bird_width)){ gameState = GAME_OVER; } int pass = wall[0]+wall_w+bird_width-bird[0]; if(pass<0 && -pass<=speed){ level_value++; } } //out of screen if(remove_walls.size()>0){ walls.removeAll(remove_walls); } //new wall move_step += speed; if(move_step>wall_step){ int[] wall = new int[]{screenW, (int)(Math.random()*(floor[1]-2*wall_h)+0.5*wall_h)}; walls.add(wall); move_step = 0; } break; case GAME_OVER: //bird if(bird[1] < floor[1] - bird_width){ bird_v+=bird_a; bird[1] += bird_v; if(bird[1] >= floor[1] - bird_width){ bird[1] = floor[1] - bird_width; } }else{ GameBirdActivity.instance.showMessage(level_value); gameState = GAME_MENU; initGame(); } break; } } public void run() { while (flag) { long start = System.currentTimeMillis(); myDraw(); logic(); long end = System.currentTimeMillis(); try { if (end - start < 50) { Thread.sleep(50 - (end - start)); } } catch (InterruptedException e) { e.printStackTrace(); } } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceDestroyed(SurfaceHolder holder) { flag = false; } } LoadingActivity类 public class LoadingActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.loading); final TextView gameStart = (TextView)findViewById(R.id.game_start); AdView adView = (AdView)findViewById(R.id.adView); adView.setAdListener(new AdListener() { public void onReceiveAd(Ad arg0) { gameStart.setVisibility(View.VISIBLE); } public void onPresentScreen(Ad arg0) { // TODO Auto-generated method stub } public void onLeaveApplication(Ad arg0) { // TODO Auto-generated method stub } public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) { // TODO Auto-generated method stub } public void onDismissScreen(Ad arg0) { // TODO Auto-generated method stub } }); View gameMessage = findViewById(R.id.GameMessage); int[] data = getSettingData(); TextView levelMessage = (TextView)findViewById(R.id.level_Message); levelMessage.setText(\"SCORE: \"+data[0]+\"\\nBEST: \"+data[1]); gameMessage.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { Intent intent = new Intent(LoadingActivity.this, GameBirdActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } }); } private int[] getSettingData() { SharedPreferences gb_settings = getSharedPreferences(GameBirdActivity.GameBirdSettingsFile, 0); int last = gb_settings.getInt(GameBirdActivity.Settings_LevelLast, 0); int top = gb_settings.getInt(GameBirdActivity.Settings_LevelTop, 0); return new int[]{last, top}; } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { try{ GameBirdActivity.instance.finish(); }catch(Exception e){} finish(); System.exit(0); return true; } return super.onKeyDown(keyCode, event); } } 四 总结 在本次开发过程中,我对开发环境进一步的熟悉,基本上可以熟练运用这个环境,也基本掌握了安卓的开发方法及基本流程。在本次开发过程中,主要用到的知识有Activity的使用,在程序中用到了多个窗口,因而需创建多个Activity。 开发期间,我学会了有目的的去学习一些将要用到的东西,仔细地考虑工作流程的规律和步骤,充分利用手中的开发工具,利用其所具备的功能,尽量使自己的开发在代码上实现少而精确、让用户能够尽量简单地进行操作。但是在检测过程中,还是出现了很多的不足之处,这些都是要在今后的工作中需要努力改进和完善的。 因篇幅问题不能全部显示,请点此查看更多更全内容