Android游戏开发的入门实例
- 格式:doc
- 大小:159.05 KB
- 文档页数:10
Undroid移动应用开发》课程大纲5. 4. Activity 的传值5. 4. 1. Activity跳转时传递数据5. 4. 2.获得Activity返回的数据5. 4. 3.案例3:个人信息发送与接收APP开发5. 5. Activity的生命周期5. 5.1关于任务和返回栈5.5.2 Activity生命周期的回调方法5. 5.3案例4:体验Activity的生命周期5. 6.案例5:用户注册及登录APP开发5. 7.课程小结5. 8.课后练习5. 9.课堂笔记5. 10.实训记录六、Android 高级组件List View 和RecyclerView 6.1.学习目标6.2.ListView 控件6.2.1.List View 控件介绍6.2.2.ListView控件的使用6.2.3.ListView 常用Adapter6.2.4.案例1:使用List View完成通讯录开发6.3.Base Adapter 适配器6.3.1.BaseAdapter 适配器介绍6.3.2.BaseAdaptcr适配器的使用6.3.3.案例2:使用BaseAdapter升级通讯录6.4.ListView 的常用Listener6.4.1.ListView 的Listener 简介6.4.2.ListView 的Listener 使用6.4.3.案例3:完成通讯录的选中及下拉刷新功能6.5.RecyclerView 控件6.5.1.RecyclerView 控件介绍6.5.2.RecyclerView 控件的使用6.5.3.案例4:使用RecyclerView开发我爱电影6.6.RecyclerView 的Listener6.6.1 .RecyclerView 的单击监听6.6.2.SwipcRcfrcshLayout 刷新控件的使用6.6.3.案例5:完成我爱电影的选中及刷新功能6.7.课程小结6.8.课后练习6.9.课堂笔记6.1().实训记录七、Android 高级控件ViewPager 和Fragment 7.1学习目标7.2 ViewPager控件使用7.2.1ViewPager 介绍7.2.2PagerAdapter 介绍和用法7.2.3案例1: APP启动页的开发7.3 Fragment 使用7.3.1Fragment 介绍7.3.2Fragment的生命周期7.3.3Fragment适配器介绍7.3.4案例2: APP底部导航功能开发7.4案例3:商城导航APP开发7.5课程小结7.5课后练习1.7.课堂笔记1.8.实训记录八、Android的网络编程Volley 和Gson框架8.1学习目标8.2HTTP协议简介8.3Volley框架的使用8.3.1Volley框架的简介8.3.2Android 中使用Volley8.3.3案例1:狗狗图片APP8.4JSON数据解析8.4.1JSON格式数据介绍8.4.2JSON格式数据解析8.4.3案例2:我爱电影APP (网络版)8.5Gson框架的使用8.5.1Gson框架简介8.5.2Gson使用流程8.5.3案例3:使用Gson框架改造我爱电影(网络版)8.6课程小结8.7课后练习8.8.课堂笔记8.9.实训记录九、综合项目:影视分享APP开发9.1学习目标9.2项目需求9. 3 Meterial Design风格界面设计9. 3. 1 Meterial Design 风格9. 3. 2侧滑导航9. 3. 3菜单项切换9.3.4悬浮按钮和底部消息9.4搭建项目图片与数据访问框架9.4.1图片及数据访问框架配置9. 4. 2 JavaBean 设计9.4.3数据访问框架测试9. 5电影列表功能开发9. 5. 1需求描述9. 5. 2 UI布局设计9. 5. 3业务功能实现9. 5.4运行效果。
pythonkiwi安卓开发实例PythonKiwi是一个基于Python和KiwiGUI库的开发工具,用于创建跨平台的移动应用程序。
在本文中,我们将介绍一些关于PythonKiwi和安卓开发的实例,并提供一些参考内容来帮助您快速开始使用这个工具。
1. 安装PythonKiwi和必要的库:要使用PythonKiwi进行安卓开发,首先需要安装Python和KiwiGUI库。
以下是一些参考内容,可以帮助您完成这些安装步骤:- Python安装教程:可以在Python官方网站上找到详细的安装指南和下载链接。
安装Python后,您还可以使用pip命令安装其他必要的Python库。
- KiwiGUI库安装教程:KiwiGUI是一个Python库,用于创建跨平台的移动应用程序。
您可以在KiwiGUI的官方文档中找到详细的安装说明和使用指南。
2. 创建一个简单的安卓应用程序:下面是一个使用PythonKiwi创建简单安卓应用程序的示例代码:```pythonfrom kiwi.models import AndroidApp# 创建一个AndroidApp对象app = AndroidApp()# 添加一个布局,用于显示文本和按钮layout = app.add_layout()# 添加一个标签,显示欢迎信息label = layout.add_label(text='Hello, Android!')# 添加一个按钮,用于更改标签的文本button = layout.add_button(text='Click me')# 定义一个事件处理函数,用于更改标签的文本def change_text():label.set_text('Button clicked!')# 将按钮的单击事件与事件处理函数关联起来button.on_click(change_text)# 运行应用程序app.run()```此示例创建了一个简单的安卓应用程序,包含一个标签和一个按钮。
Android的猜拳游戏猜拳游戏是一种非常经典和简单的游戏,它可以在各种平台上实现。
我们将使用Android平台来演示如何创建一个简单的猜拳游戏应用程序。
准备工作在开始编写应用程序之前,我们需要确保我们的开发环境已正确配置。
以下是所需的准备工作:1.安装并配置Android Studio:Android Studio是一个用于Android应用程序开发的集成开发环境(IDE)。
确保您已按照安装说明正确安装并配置了Android Studio。
2.创建一个新的Android项目:打开Android Studio并选择“创建新项目”选项。
按照向导的提示进行操作,包括选择目标Android版本和选择应用程序的名称。
3.配置应用程序的用户界面:在新创建的Android项目中,我们将使用XML布局文件来定义应用程序的用户界面。
打开res/layout目录下的activity_mn.xml文件,并使用所需的视图组件来设计用户界面。
游戏规则在猜拳游戏中,有三种手势可供选择:石头,剪刀和布。
石头打败剪刀,剪刀打败布,布打败石头。
玩家将选择一种手势,与计算机进行比较,并根据比赛结果确定胜负。
实现游戏逻辑要在Android应用程序中实现猜拳游戏,我们需要编写Java代码来处理游戏逻辑。
以下是一些关键步骤:1.定义手势类型:我们将创建一个枚举类来表示手势类型。
在这个枚举类中,我们将定义石头,剪刀和布作为枚举常量。
enum Gesture {ROCK,SCISSORS,PAPER}2.获取玩家选择:我们将使用一个对话框来提供给玩家选择手势的选项。
玩家可以通过按钮来选择手势。
当玩家做出选择后,我们将从对话框中获取所选的手势类型。
AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.set(。
快速记忆小游戏使用Java开发Android应用在技术迅速发展的当下,移动应用已成为人们生活的一部分。
如今,Android平台上的小游戏越来越受欢迎,而快速记忆小游戏则是其中一种备受青睐的选择。
本文将介绍如何使用Java语言开发一款基于Android平台的快速记忆小游戏。
I. 游戏概述快速记忆小游戏旨在提高玩家的记忆力和反应速度。
游戏开始时,屏幕上会显示一组物体或数字,并在短时间内隐藏。
玩家需要在规定的时间内记住这些物体或数字,并尝试在记忆结束后重新选择正确的组合。
II. 开发环境准备在开始开发之前,我们需要准备以下环境:1. 安装并配置Java Development Kit(JDK)以及安装最新的Android Studio。
2. 在Android Studio中创建一个新的Android项目,并选择Java作为主要编程语言。
III. 游戏设计在我们开始编写代码之前,让我们先设计游戏的外观和功能:1. 游戏主界面设计:- 设置一个屏幕中央的表格布局,用于显示物体或数字。
- 添加一个计时器,用以记录玩家的反应时间和游戏进度。
- 显示玩家的得分和当前关卡。
2. 游戏逻辑设计:- 在每个关卡开始时,随机生成一组物体或数字并显示在屏幕上。
- 记录玩家选择的答案,并在记忆时间结束后进行比对。
- 根据玩家的选择和正确答案的比对结果,更新得分和关卡等级。
- 提供不同难度级别的游戏,如增加物体或数字的数量或减少记忆时间。
IV. 代码实现接下来,我们将使用Java语言来实现这一快速记忆小游戏。
1. 创建游戏布局:- 在XML文件中定义游戏主界面的布局。
- 使用GridLayout布局来显示物体或数字,计时器,得分和关卡。
2. 定义游戏逻辑:- 创建一个类来管理游戏逻辑和数据。
- 实现功能如生成随机数或物体、计时器控制、比对答案等。
3. 实现游戏交互逻辑:- 在主Activity中,处理玩家选择答案的事件。
- 调用游戏逻辑类的方法来进行比对、更新得分和关卡等操作。
跳一跳游戏(Android应用使用Java开发)跳一跳游戏是一款简单而又富有挑战性的休闲游戏,经常出现在我们的手机屏幕上。
本文将介绍跳一跳游戏的开发过程,使用Java语言在Android平台上实现。
1. 游戏概述跳一跳是一款基于物理引擎的游戏,玩家通过点击屏幕来控制角色跳跃,目的是在不碰到障碍物的情况下尽可能远地跳跃。
游戏界面简洁明了,操作简单直观,非常受欢迎。
2. 技术要求为了实现跳一跳游戏,我们需要使用Java语言进行Android应用开发。
除此之外,还需要掌握Android开发框架和物理引擎的使用,以及基本的游戏逻辑设计。
3. 开发环境搭建首先,我们需要安装Android Studio,这是一款专门用于Android应用开发的集成开发环境(IDE)。
然后,我们需要下载并配置Java Development Kit(JDK),确保Android Studio可以正常编译和运行我们的代码。
4. 项目创建在Android Studio中,我们可以通过创建一个新项目来开始跳一跳游戏的开发。
在创建项目的过程中,我们可以选择一些基本的配置,例如应用名称、包名、最低支持的Android版本等。
5. 游戏界面设计跳一跳游戏的界面主要由两个部分组成:游戏区域和角色。
游戏区域通常是一个类似于方块的地图,上面有随机生成的障碍物。
角色则是一个小球,玩家通过点击屏幕来控制角色的跳跃。
6. 游戏逻辑设计在跳一跳游戏中,玩家通过点击屏幕控制角色的跳跃力度。
跳跃的力度决定了角色跳跃的高度和距离。
玩家需要在不碰到障碍物的情况下跳跃到另一个平台上,每次跳跃成功都会获得一定的分数。
7. 物理引擎应用为了实现跳一跳游戏中的物理效果,我们可以使用一些开源的物理引擎库,例如Box2D。
物理引擎可以模拟真实世界中的物理效果,使得角色的跳跃和碰撞更加逼真。
8. 分数统计与排名为了增加游戏的竞争性和挑战性,我们可以在跳一跳游戏中添加分数统计和排名功能。
学会使用AndroidStudio进行游戏开发第一章:介绍Android Studio和游戏开发Android Studio是一款针对Android系统开发的集成开发环境(IDE),它提供了丰富的工具和功能,方便开发者进行Android应用的设计、编码和调试等工作。
游戏开发是Android应用开发中的一个重要方向,在Android Studio中,可以利用其强大的功能来创建精彩的游戏作品。
第二章:安装和配置Android Studio在使用Android Studio开发游戏之前,首先需要正确安装和配置这个开发工具。
下载安装包后,按照安装向导的指引进行操作,选择合适的安装目录和组件。
安装完成后,还需要为工具集成合适的SDK和虚拟设备,以方便开发者进行测试和调试。
第三章:创建新的游戏项目在Android Studio中创建新的游戏项目是开发的第一步。
通过选择"File"->"New"->"New Project",可以进入项目创建向导。
在向导中,需要提供项目的名称、包名、最低支持的Android版本等基本信息。
可以选择创建空白模板或者直接使用已有的模板来快速开始游戏开发。
第四章:设计游戏界面游戏界面的设计是游戏开发过程中的重点之一。
在Android Studio中,可以通过可视化布局编辑器来快速创建和调整界面布局。
开发者可以拖拽和调整控件的位置、大小和样式,也可以通过XML文件来设置界面的属性和行为。
同时,还可以添加图像、音频和视频等资源来丰富游戏界面的内容。
第五章:编写游戏逻辑游戏逻辑的编写是游戏开发的核心工作。
在Android Studio中,可以通过Java编程语言来实现游戏的各种逻辑功能。
开发者可以利用Android SDK提供的API来处理用户输入、更新游戏状态、处理碰撞检测等功能。
同时,也可以利用第三方游戏引擎和库来快速构建游戏逻辑,如Unity、Cocos2d-x等。
使用Unity进行ARM64 Android游戏开发Unity是一款功能强大的游戏开发引擎,可以用于开发各种平台上的游戏,包括ARM64架构的Android设备。
本文将介绍如何使用Unity来进行ARM64 Android游戏开发,并提供一些相关的技巧和经验。
一、准备工作在开始ARM64 Android游戏开发之前,我们需要进行一些准备工作。
首先,确保你已经安装了最新版本的Unity开发环境,并且选择了ARM64架构的Android支持。
其次,确保你已经了解了Unity的基本操作和游戏开发的相关知识。
如果你是初学者,建议先学习一些入门教程和文档。
二、创建新项目在Unity中创建一个新的ARM64 Android游戏项目非常简单。
打开Unity编辑器,点击"New"按钮,然后选择"3D"或"2D"游戏模板,接着选择"Android"平台,并确保选择了ARM64架构。
然后,选择一个项目保存路径,点击"Create"按钮就可以创建一个新的项目了。
三、设置项目属性在开始开发游戏之前,我们需要进行一些项目属性的设置。
点击Unity编辑器上方的"File"菜单,选择"Build Settings"选项。
在Build Settings窗口中,选择"Android"平台,并点击"Player Settings"按钮。
在Player Settings面板中,你可以设置游戏的应用程序ID、版本号、图标等属性。
确保你设置的应用程序ID是唯一的,并且版本号符合你的需求。
此外,你还可以设置游戏的横竖屏方向、屏幕分辨率等属性,根据你的游戏需求进行相应的设置。
四、导入资源在开始开发游戏之前,你可能需要导入一些资源,比如模型、纹理、音频等。
点击Unity编辑器上方的"Assets"菜单,选择"Import Package"选项,然后选择你要导入的资源包。
android 2D 游戏的开发的方法n n n n n n n 最近学习了android 2D 应用的开发,拿来和大家分享一下,学习2D 开发前我们先了解一下SurfaceView的使用以及贴图技术的使用,最后呢,是一个简单的2的游戏的实现。
n n1.SurfaceView的一些用法 n n n n n n n n n n n n提供了一个专门的绘图渲染的图形嵌入在一个视图层次;SurfaceView负责将图形正确的显示在屏幕上,访问底层图形是通过SurfaceHolder提供接口,可通过调用getHolder(),图形创建SurfaceView的窗口是可见的;实现方法是surfaceCreated(SurfaceHolder)和surfaceDestroyed (SurfaceHolder)销毁图形 n n n n n n n n n n n n 简单的例子如下 [java] n package com.nyist.wj; n nn import android.app.Activity; n import android.content.Context; n importandroid.graphics.Canvas; n import android.graphics.Color; n import android.graphics.Paint; n import android.graphics.Rect; n import android.graphics.RectF; n importandroid.graphics.Paint.Style; n import android.os.Bundle; n import android.view.SurfaceHolder; n import android.view.SurfaceView; n nn public class SurfaceViewActivity extends Activity { n n n MySurfaceView mySurfaceView; n nn n n /** Called when the activity is first created. */ n n n@Override n n n public void onCreate(Bundle savedInstanceState) { n n n n n super.onCreate (savedInstanceState); n nn n n n n mySurfaceView = new MySurfaceView(this); n n n n n setContentView(mySurfaceView); n nn n n } n n n public class MySurfaceView extends SurfaceView implements n n n SurfaceHolder.Callback { n SurfaceViewActivity surfaceViewActivity; // Activity 的引用 n Paint paint; // 画笔的引用 n nn public MySurfaceView(Context context) // 构造器 n { n n n super(context); n n n this.surfaceViewActivity = (SurfaceViewActivity) context; // 拿到Activity 引用 n n n this.getHolder().addCallback(this); // 设置生命周期回调接口的实现者 n n n paint = new Paint(); // 创建画笔n n n paint.setAntiAlias(true); // 打开抗锯齿n } n nn @Override n protected void onDraw(Canvas canvas) // onDraw方法 n { n n n paint.setColor(Color.WHITE); // 设置画笔颜色为白色 n n n canvas.drawRect(0, 0, getWidth(), getHeight(), paint); // 绘制白色矩形背景 n n n paint.reset(); // 清除画笔设置 n n n paint.setARGB(50, 0, 255, 0); // 设置画笔颜色和透明度 n n n paint.setStrokeWidth(5); // 设置画笔宽度 n n n RectF rf = new RectF(50, 100, 160, 180); // 创建一个矩形 n n n canvas.drawRect(rf, paint); // 绘制矩形 n n n paint.setARGB(50, 0, 0, 255); // 设置画笔颜色和透明度 n n n paint.setStyle(Style.STROKE); // 设置风格为边框 n n n paint.setStrokeWidth (5); // 设置画笔宽度 n n n Rect r = new Rect(200, 100, 300, 180); // 创建一个矩形 n n ncanvas.drawRect(r, paint); // 画一个矩形边框 n n n paint.setColor(Color.RED); // 设置画笔颜色 n n n paint.setAntiAlias(true); // 打开抗锯齿n n n canvas.drawCircle(100, 250, 30, paint);// 画一个圆n n n paint.setColor(Color.YELLOW); // 设置画笔颜色 n n n rf = new RectF(200, 250, 300, 300); // 创建一个矩形 n n n canvas.drawOval(rf, paint); // 画一个椭圆,充满矩形 n n n paint.reset (); // 清除画笔设置 n n n paint.setColor(Color.RED); // 设置画笔颜色 n nn n n paint.setTextSize (40); // 设置文字大小 n n n paint.setStyle(Style.FILL_AND_STROKE); n n n canvas.drawText ("loading...", 50, 350, paint); // 画一个字符串 n } n nn @Override n public void surfaceCreated (SurfaceHolder holder) // 创建时被调用 n { n n n Canvas canvas = holder.lockCanvas(); // 获取画布 n n n try { n n n n n synchronized (holder) { n n n n n n n onDraw(canvas); n n n n n } // 绘制 n n n } catch (Exception e) { n n n n n e.printStackTrace(); n n n } finally { n n n n n if (canvas != null) { n n n n n n n holder.unlockCanvasAndPost(canvas); n n n n n } n n n } n } n nn @Override n public void surfaceDestroyed(SurfaceHolder holder) { n } // 继承方法,空实现n nn@Override n // 继承方法,空实现n public void surfaceChanged(SurfaceHolder holder, int format,int width, n n n n n int height) { n } n } n nn } n 实现的效果是: n 2.贴图技术的使用 n n 贴图技术主要包括图片的移动、旋转、透明度、等变化下面是关于贴图技术的使用方法 首先是自定义的一个布局 [html] n <com.nyist.wj.MysurfaceView n n n n nandroid:id="@+id/mysurfaceview" n n n nnandroid:layout_width="fill_parent" n n n n nandroid:layout_height="fill_parent" /> n 然后就是实现自定义布局引用的类[java] n package com.nyist.wj; n nn import android.content.Context; n import android.graphics.Bitmap; n import android.graphics.BitmapFactory; n importandroid.graphics.Canvas; n import android.graphics.Matrix; n import android.graphics.Paint; n import android.util.AttributeSet; n import android.view.View; n nn public class MysurfaceView extends View { n nn nBitmap bitmap; n nPaint paint; n npublic MysurfaceView(Contextcontext,AttributeSet attributeSet) { n n super(context,attributeSet); n n // TODO Auto-generated constructor stub n n this.initBitmap(); n n nn n} n npublic nvoid initBitmap() { n n // TODOAuto-generated method stub n n paint=new Paint(); n n bitmap=BitmapFactory.decodeResource (getResources(), R.drawable.ball); n n nn n} n n@Override n nprotected void onDraw(Canvas canvas) { n n // TODO Auto-generated method stub n n super.onDraw(canvas); n n //打开抗锯齿n npaint.setAntiAlias(true); n n canvas.drawBitmap(bitmap, 50,50,paint); n n canvas.save(); n n nn n Matrix matrix=new Matrix(); n n //移动n n matrix.setTranslate(100, 100); n n Matrix matrix2=new Matrix(); n // n旋转n n matrix2.setRotate(50); n n Matrix matrix3=new Matrix(); n nmatrix3.setConcat(matrix, matrix2); n n //缩放 n n matrix.setScale(0.5f, 0.5f); n nmatrix2.setConcat(matrix3, matrix); n n canvas.drawBitmap(bitmap, matrix2, paint); n ncanvas.restore(); n n canvas.save(); n n paint.setAlpha(200); n n matrix.setTranslate(150, 150); n n //放大 n n matrix2.setScale(1.3f, 1.3f); n n //设置总矩阵n n matrix3.setConcat(matrix, matrix2); n n canvas.drawBitmap(bitmap, matrix3, paint); n n paint.reset(); n n nn n} n nn n nnn } n n 实现的效果如下 n 解释一下:这是横屏显示的结果,左上方是原图片大小 接着是缩放的和放大的图片 n 3.广告条的实现方法广告虽不好,但是这确实为android开发者提供了一点微薄的力量,下面就看看广告条的开发效果图: n 实现的过程有自定义的View [html] n <com.nyist.wj.myView n n n n nandroid:layout_width="fill_parent" n n n n n android:layout_height="50dip" n n n n n /> n 实现view的方法 [java] n package com.nyist.wj; n nn import android.content.Context; n importandroid.content.Intent; n import android.content.res.Resources; n import android.graphics.Bitmap; n import android.graphics.BitmapFactory; n import android.graphics.Canvas; n importandroid.graphics.Matrix; n import android.graphics.Paint; n import android.os.Bundle; n import android.util.AttributeSet; n import android.view.MotionEvent; n import android.view.View; n nn public class myView extends View { n n n Bitmap[] bitmap; n n n int currentindex = 1; n n n int time = 3000; n n n boolean isAnima = false; n n n Paint paint; n n n int[] imageID; n n n // 初始化图片数阻 n n n boolean initFlag = false; n n n float prex, prey; n n n int xoffset; n nn n n public myView(Context context, AttributeSet attributeSet) { n n n n n super(context, attributeSet); n n n n n // TODO Auto-generated constructor stub n n n n n this.imageID = new int [] { R.drawable.test1, R.drawable.test2, n n n n n n n n n R.drawable.test3, R.drawable.test4 }; n n n n n // 生成图片数组n n n n n bitmap = new Bitmap[imageID.length]; n n n n n paint = new Paint(); n n n n n // 抗锯齿n n n n n paint.setFlags(Paint.ANTI_ALIAS_FLAG); n n n n nthis.setOnTouchListener(null); n n n n n new Thread() { n n n n n n n public void run() { n nn n n n n n n n n while (true) { n n n n n n n n n n n if (!isAnima) { n n n n n n n n n n n n n currentindex = (currentindex + 1) % imageID.length; n nn n n n n n n n n n n } n n n n n n n n n n n // 刷帧重绘n n n n n n n n n n n myView.this.postInvalidate(); n n n n n n n n n n n try { n n n n n n n n n n n n n Thread.sleep(time); n n n n n n n n n n n } catch (Exception e) { n n n n n n n n n n n n n // TODO: handthele exception n n n n n n n n n n n } n nn n n n n n n n n } n nn n n n n n n }; n n n n n }.start(); n nn n n } n nn n n public void initBitmap() { n n n n n Resources resources = this.getResources(); n n n n n for (int i = 0; i < imageID.length; i++) { n n n n n n n // ------------------------------n n n n n n n // 实现图片 的缩放 n n n n n n n bitmap[i] = scaleChange(BitmapFactory.decodeResource(resources, n n n n n n n n n n n imageID[i] n nn n n n n n n )); n n n n n } n nn n n } n nn n n public static Bitmap scaleChange(Bitmap bitmap) { n n n n n int w = bitmap.getWidth(); n n n n n int h = bitmap.getHeight(); n n n n n double xratio = (double) Constant.SCREEN_WIDTH / w; n n n n n double yratio = 50.0 / h; n n n n n // 生成矩阵n n n n n Matrix matrix = new Matrix(); n n n n n matrix.postScale((float) xratio, (float) yratio); n n n n n Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true); n nn n n n n return result; n nn n n } n nn n n @Override n n n public void onDraw(Canvas canvas) { n n n n n // TODO Auto-generated method stub n n n n n // 第一次运行onDraw方法的时候,调用初始化图片数组的方法 n n n n n if (!initFlag) { n n n n n n n initBitmap(); n n n n n n n initFlag = true; n n n n n } n n n n n if (canvas == null) { n n n n n n n return; n n n n n } n n n n n if (!isAnima) { n n n n n n n // -------------------------------------n n n n n n n // 当没有播放动画时候绘制当前图片 n n n n n n n drawAD(canvas, xoffset, currentindex); n n n n n } n n n n n if (isAnima) { n n n n n n n // 当向右滑动时候 n n n n n n n if (xoffset > 0) { n n n n n n n n nint size = imageID.length; n n n n n n n n n // 得到上一张图片的索引 n n n n n n n n n int preIndex = (currentindex -1 + size) % size; n n n n n n n n n // 根据x轴偏移量,算出上一张图片绘制时的x坐标n n n n n n n n n int nextIndex = xoffset -Constant.SCREEN_WIDTH; n n n n n n n nn // 绘制当前索引图片 n n n n n n n n n drawAD(canvas, xoffset, (preIndex + 1) % size); n n n n n n n n n drawAD(canvas, nextIndex, preIndex); n nn n n n n n n } // 当往左抹时n n n n n n n else if (xoffset < 0) { n n n n n n n n n int size = imageID.length; n n n n n n n n n // 得到下一张图片的索引 n n n n n n n n n int preIndex = (currentindex + 1 + size) % size; n n n n n n n n n int nextIndex = xoffset + Constant.SCREEN_WIDTH; n n n n n n n n n // 绘制当前图片的索引 n n n n n n n n n drawAD(canvas, xoffset, (preIndex -1 + size) % size); n n n n n n n n n drawAD(canvas, nextIndex, preIndex); n nn n n n n n n } n n n n n } n nn n n } n nn n n public void drawAD (Canvas canvas, int offset, int Index) { n n n n n canvas.drawBitmap(bitmap[Index], offset, 0, paint); n nn n n } n nn n n @Override n n n public boolean onTouchEvent(MotionEvent event) { n n n n n // TODO Auto-generated method stub n nn n n n n float x = event.getX(); n n n n n float y = event.getY(); n n n n n switch (event.getAction()) { n n n n n case MotionEvent.ACTION_DOWN: n n n n n n n prex = x; n n n n n n n prey = y; n n n n n n n System.out.println("------------------------------------"); n n n n n n n System.out.println("+++++++++++++++++++++++++++++++++++" n n n n n n n n n n n + currentindex); n nn n n n n n n return true; n n n n n caseMotionEvent.ACTION_MOVE: n n n n n n n if (!isAnima && Math.abs(x -prex) > 10) { n n n n n n n n n isAnima = true; n n n n n n n } n n n n n n n if (isAnima) { n n n n n n n n n xoffset = (int) (xoffset + x -prex); n n n n n n n n n prex = x; n n n n n n n n n prey = y; n nn n n n n n n } n n n n n n n this.postInvalidate(); n n n n n n n return true; n n n n n caseMotionEvent.ACTION_UP: n nn n n n n n n if (isAnima) { n n n n n n n n n if (x <Constant.SCREEN_WIDTH / 4 && xoffset < 0) { n n n n n n n n n n n int size = imageID.length; n n n n n n n n n n n currentindex = (currentindex + 1) % size; n nn n n n n n n n n } else if (x > Constant.SCREEN_WIDTH * 3 / 4 && xoffset > 0) { n n n n n n n n n n n int size = imageID.length; n n n n n n n n n n n currentindex = (currentindex -1 + size) % size; n nn n n n n n n n n } n nn n n n n n n } n n n n n n n isAnima = false; n n n n n n n xoffset = 0; n n n n n n nthis.postInvalidate(); n n n n n n n return true; n nn n n n n } n nn n n n n return false; n n n } n nn } n n 接着是在activity中的插入 [java] n package com.nyist.wj; n nn nn importandroid.app.Activity; n import android.content.pm.ActivityInfo; n import android.os.Bundle; n import android.util.DisplayMetrics; n import android.view.Window; n importandroid.view.WindowManager; n nn public class GuangGaoActivity extends Activity { n n n /** Called when the activity is first created. */ n n n @Override n n n public void onCreate(Bundle savedInstanceState) { n n n n n super.onCreate(savedInstanceState); n n n n n requestWindowFeature(Window.FEATURE_NO_TITLE); n n n n n getWindow().setFlags (youtParams.FLAG_FULLSCREEN,youtParams.FLAG_FULLSCREEN); n // n n n nsetRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); n n n n n nn n n n n nn n n n n setContentView(yout.main); n n n n n DisplayMetrics displayMetrics=new DisplayMetrics (); n n n n n getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); n n n n n Constant.SCREEN_HEIGHT=displayMetrics.heightPixels; //获取具体的屏幕分辨率数值n n n n n Constant.SCREEN_WIDTH=displayMetrics.widthPixels; n n n } n } n n 4.下面是介绍2D下简单的游戏开发效果图如下 n 主要用到的SurfaceView 和贴图技术以及声音的处理用到的处理方法共有5个类1.BallGameActivity n n n n n n n n n n n n设置屏幕的相关属性2.GameSurfaceView n n n n n n n n n 实现显示界面的设置3.ThreadForDraw n n n n n n n n n n n 刷帧线程重新绘制游戏界面4.ThreadForGo n n n n n n n n n n n n n n控制小球移动5.ThreadForTimecControl n n n n 计算小球运行的时间下面分别介绍每个类是如何实现的 1.BallGameActivity [java] n package com.nyist.wj; n nn importjava.util.HashMap; n nn import org.apache.http.auth.AUTH; n nn import android.app.Activity; n import android.content.Context; n import android.media.AudioManager; n importandroid.media.SoundPool; n import android.os.Bundle; n import android.view.Window; n import android.view.WindowManager; n nn public class BallGameActivity extends Activity { n n n GameSurfaceView gameSurfaceView; n n n // 声音缓冲池 n n n SoundPool soundPool; n n n // 存放声音ID的 map n n n HashMap<Integer, Integer> soundpoolMap; n nn n n /** Called when the activity is first created. */ n n n @Override n n n public void onCreate(Bundle savedInstanceState) { n n n n n super.onCreate(savedInstanceState); n nn n n n n // 初始化声音 n n n n n initSounds(); n n n n n // 设置全屏n n n n n requestWindowFeature(Window.FEATURE_NO_TITLE); n n n n n getWindow().setFlags(youtParams.FLAG_FULLSCREEN, n n n n n n n n nyoutParams.FLAG_FULLSCREEN); n nn n n n n gameSurfaceView = new GameSurfaceView (this); n n n n n setContentView(gameSurfaceView); n n n n n // 循环播放音乐n n n n n playSound (1, -1); n nn n n } n nn n n public void playSound(int sound, int loop) { n n n n n // TODO Auto-generated method stub n n n n n // 播放声音的方法 n n n n n AudioManager audioManager = (AudioManager) this n n n n n n n n n .getSystemService(Context.AUDIO_SERVICE); n n n n n float streamVolumeMax = audioManager n n n n n n n n n .getStreamMaxVolume(audioManager.STREAM_MUSIC); n n n n n float streamVolumeCurrent = audioManager n n n n n n n n n .getStreamVolume (AudioManager.STREAM_MUSIC); n n n n n float volume = streamVolumeCurrent / streamVolumeMax; n n n n n // 参数声音资源的ID 左声道 右声道 优先级 循环次数 回访速度 n n n n n soundPool.play (soundpoolMap.get(sound), volume, volume, 1, loop, 0.5f); n n n } n nn n n public void initSounds () { n n n n n // TODO Auto-generated method stub n n n n n // 参数 播放的个数 音频类型 播放的质量 n n n n n soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100); n n n n n // 创建声音资源的MAP n n n n n soundpoolMap = new HashMap<Integer, Integer>(); n n n n n // 将加载声音的资源 放在map中 n n n n n soundpoolMap.put(1, soundPool.load(this, R.raw.bg, 1)); n nn n n } n } n n n 2.GameSurfaceView [html]n package com.nyist.wj; n nn import android.graphics.Bitmap; n import android.graphics.BitmapFactory; n import android.graphics.Canvas; n importandroid.view.MotionEvent; n import android.view.SurfaceHolder; n import android.view.SurfaceView; n nn public class GameSurfaceView extends SurfaceView implements n n n n n SurfaceHolder.Callback { n nn n n BallGameActivity ballGameActivity; n n n ThreadForTimecControl threadForTimecControl; n n n ThreadForGo threadForGo; n n n ThreadForDraw threadForDraw; n nn n n int backSize = 16; // 背景块大小 n n n int screenWidth = 320; // 屏幕宽度 n n n int screenHeight = 480; // 屏幕高度 n n n int bannerWidth = 40; // 挡板宽度 n n n int bannerHeight = 6; // 挡板高度 n n n int bottomSpance = 16; // 下端留白 n n n int bannerSpan = 5; // 板每次移动的距离n n n int ballSpan = 8; // 球每次移动的距离n n n int ballSize = 16; // 小球大小 n n n int hintWidth = 100; // 游戏说明宽度 n n n int hintHeight = 20; // 游戏说明高度 n n n int status = 0; // 游戏状态控制 0-等待开始 1-进行中 2-游戏结束 3-游戏胜利 n n n int score = 0; // 得分 n n n int ballx; // 小球x坐标n n n int bally; // 小球y坐标n n n int direction = 0; // 小球方向 n n n int bannerX; // 挡板X坐标n n n int bannerY; // 挡板Y坐标n n n int scoreWidth = 32; n n n Bitmap iback; // 背景图n n n Bitmap[] iscore = new Bitmap[10];// 得分图n n n Bitmap iball; // 小球用图n n n Bitmapibanner; // 挡板用图n n n Bitmap ibegin; // 开始用图n n n Bitmap igameover; // 游戏结束用图n n n Bitmap iwin; // 游戏结束用图n n n Bitmap iexit; // 退出用图n n n Bitmap ireplay; // 重玩用图n nn n n public GameSurfaceView(BallGameActivity ballGameActivity) { n n n n n super (ballGameActivity); n n n n n // 注册回调接口 n n n n n getHolder().addCallback(this); n n n n n this.ballGameActivity = ballGameActivity; n nn n n n n initBitmap(); n n n n n // /////////----------------------------------------------n n n n n threadForDraw = new ThreadForDraw(this); n n n n n // TODO Auto-generated constructor stub n n n } n nn n n public void initBitmap() { n n n n n iback = BitmapFactory.decodeResource(getResources(), R.drawable.back); n n n n n iscore[0] = BitmapFactory.decodeResource(getResources(), R.drawable.d0); n n n n n iscore[1] = BitmapFactory.decodeResource(getResources(), R.drawable.d1); n n n n n iscore[2] = BitmapFactory.decodeResource(getResources(), R.drawable.d2); n n n n n iscore[3] = BitmapFactory.decodeResource(getResources(), R.drawable.d3); n n n n n iscore[4] = BitmapFactory.decodeResource(getResources(), R.drawable.d4); n n n n n iscore[5] = BitmapFactory.decodeResource(getResources(), R.drawable.d5); n n n n n iscore[6] = BitmapFactory.decodeResource(getResources(), R.drawable.d6); n n n n n iscore[7] = BitmapFactory.decodeResource(getResources(), R.drawable.d7); n n n n n iscore[8] = BitmapFactory.decodeResource(getResources(), R.drawable.d8); n n n n n iscore[9] = BitmapFactory.decodeResource(getResources(), R.drawable.d9); n n n n n iball =BitmapFactory.decodeResource(getResources(), R.drawable.ball); n n n n n ibanner = BitmapFactory.decodeResource(getResources(), n n n n n n n n n R.drawable.banner); n n n n n ibegin = BitmapFactory.decodeResource(getResources(), R.drawable.begin); n n n n n igameover = BitmapFactory.decodeResource(getResources(), n n n n n n n n n R.drawable.gameover); n n n n n iwin = BitmapFactory.decodeResource(getResources(), R.drawable.win); n n n n n iexit = BitmapFactory.decodeResource(getResources(), R.drawable.exit); n n n n n ireplay = BitmapFactory.decodeResource(getResources(), n n n n n n n n n R.drawable.replay); n n n n n // 初始化小球位置及板X坐标n n n n n initBallAndBanner(); n n n } n nn n n public void initBallAndBanner() { n n n n n // 初始化小球位置 n n n n n bally = screenHeight -bottomSpance -bannerHeight -ballSize; n n n n n ballx = screenWidth / 2 -ballSize / 2; n n n n n // 初始化板X 坐标n n n n n bannerX = screenWidth / 2 -bannerWidth / 2; n n n n n bannerY = screenHeight -bottomSpance -bannerHeight; n n n } n nn n n public void replay() { n nn n n n n if (status == 2 || status == 3) { n n n n n n n // 初始化小球的位置 n n n n n n n initBallAndBanner(); n n n n n n n score = 0; n n n n n n n status = 0; n n n n n n n direction = 3; n nn n n n n } n n n } n nn n n @Override n n n protected void onDraw(Canvas canvas) { n n n n n // TODO Auto-generated method stub n nn n n n n super.onDraw(canvas); n n n n n // 清除背景 n n n n n int colum = screenWidth / backSize n n n n n n n n n + ((scoreWidth % backSize == 0) ?0:1); n n n n n int rows = screenHeight / backSize n n n n n n n n n + ((screenHeight % backSize == 0) ? 0 : 1); n n n n n for (int i = 0; i < rows; i++) { n n n n n n n for (int j = 0; j < colum; j++) { n nn n n n n n n n n canvas.drawBitmap(iback, 16*j, 16*i, null); n nn n n n n n n } n n n n n } n n n n n // 绘制得分 n n n n n String scorestr = score + ""; n n n n n int loop = 3 -scorestr.length(); n n n n n for (int i = 0; i < loop; i++) { n nn n n n n n n scorestr = "0" + scorestr; n n n n n } n n n n n int startX = screenWidth -scoreWidth * 3 -10; n n n n n for (int i = 0; i < 3; i++) { n n n n n n n int tempScore = scorestr.charAt(i) -'0'; n n n n n n n canvas.drawBitmap(iscore [tempScore], startX + i * scoreWidth, 5, n n n n n n n n n n n null); n nn n n n n } n n n n n // 绘制小球 n n n n n canvas.drawBitmap(iball, ballx, bally, null); n n n n n // 绘制板 n n n n n canvas.drawBitmap(ibanner, bannerX, bannerY, null); n n n n n // 绘制开始提示 n n n n n if (status == 0) { n n n n n n n canvas.drawBitmap(ibegin, screenWidth / 2 -hintWidth / 2, n n n n n n n n n n n screenHeight / 2 -hintHeight / 2, null); n nn n n n n } n n n n n // 绘制失败提示 n n n n n if (status == 2) { n n n n n n n canvas.drawBitmap(igameover, screenWidth / 2 -hintWidth / 2, n n n n n n n n n n n screenHeight / 2 -hintHeight / 2, null); n nn n n n n } n n n n n // 绘制胜利提示 n n n n n if (status == 3) { n n n n n n n canvas.drawBitmap(iwin, screenWidth / 2 -hintWidth / 2, n n n n n n n n n n n screenHeight / 2 -hintHeight / 2, null); n nn n n n n } n n n n n // 绘制退出提示 n n n n n canvas.drawBitmap(iexit, screenWidth -32, screenHeight -16, null); n n n n n // /绘制重玩提示 n n n n n if (status == 2 || status == 3) { n n n n n n n canvas.drawBitmap(ireplay, 0, screenHeight -16, null); n nn n n n n } n nn n n } n nn n n @Override n n n public boolean onTouchEvent(MotionEvent event) { n nn n n n n int x = (int) event.getX(); n n n n n int y = (int) event.getY(); n n n n n if (x < screenWidth && x > screenWidth -32 && y < screenHeight n n n n n n n n n && y > screenHeight -16) { n n n n n nn // ----------------------------------------------------------n n n n n n n // 按下退出选项退出系统n n n n n n n ballGameActivity.soundPool.stop(1); n n n n n n n System.exit(0); n n n n n } n n n n n // 等待状态n n n n n if (status == 0) { n n n n n n n status = 1; n n n n n n n // ----------------------------------------------n n n n n n n threadForTimecControl = new ThreadForTimecControl(this); n n n n n n n threadForGo = new ThreadForGo(this); n n n n n n n threadForTimecControl.start(); n n n n n n n threadForGo.start(); n n n n n } else if (status == 1) { n n n n n n n bannerX = x; n n n n n } else if (status == 2 || status == 3) { n n n n n n n if (x < 32 && x > 0 && y < screenHeight && y > screenHeight -16) { n n n n n n n n n //按下重玩 n n n n n n n n n replay(); n nn n n n n n n } n nn n n n n } n nn n n n n // TODO Auto-generated method stub n n n n n return super.onTouchEvent(event); n nn n n } n nn n n @Override n n n public void surfaceChanged(SurfaceHolder holder, int format, int width, n n n n n n n int height) { n nn n n n n // TODO Auto-generated method stub n nn n n } n nn n n @Override n n n public void surfaceCreated(SurfaceHolder holder) { n n n n n // TODO Auto-generated method stub n n n n n // ----------------------------------n n n n n // 创建时候启动相关进程 n n n n nthis.threadForDraw.flag = true; n n n n n threadForDraw.start(); n nn n n } n nn n n @Override n n n public void surfaceDestroyed(SurfaceHolder holder) { n nn n n n n // 释放相应的进程 n n n n n boolean retry = true; n n n n n this.threadForDraw.flag = false; n n n n n // 不断的循环知道刷帧结束 n n n n n while (retry) { n n n n n n n try { n n n n n n n n n threadForDraw.join(); n n n n n n n n n retry = false; n nn n n n n n n } catch (InterruptedException e) { n n n n n n n nn // TODO: handle exception n n n n n n n } n nn n n n n } n nn n n } n nn } n n n3.ThreadForDraw [java] n package com.nyist.wj; n nn import android.graphics.Canvas; n import android.view.SurfaceHolder; n nn public class ThreadForDraw extends Thread { n boolean flag=true; n int sleep=100; n GameSurfaceView gameSurfaceView; n SurfaceHolder surfaceHolder; n nn public ThreadForDraw (GameSurfaceView gameSurfaceView){ n n n nn n n nn n nthis.gameSurfaceView=gameSurfaceView; n n n this.surfaceHolder=gameSurfaceView.getHolder(); n n n nn } n nn @Override n public void run() { n n n // TODO Auto-generated method stub n n n nn n n Canvas canvas; n n n while (this.flag) { n n n n n nn n n n n canvas=null; n n n n n try { n n n n n n n canvas=this.surfaceHolder.lockCanvas(null); n n n n n n n synchronized(this.surfaceHolder) { n n n n n n n n n gameSurfaceView.onDraw(canvas); n n n n n n n } n n n n n } catch (Exception e) { n n n n n nn n n n n }finally{ n n n n n n n if (canvas!=null) { n n n n n n n n n this.surfaceHolder.unlockCanvasAndPost(canvas); n n n n n n n n n nn n n n n n n } n n n n n } n n n n n try { n n n n n n n Thread.sleep(sleep); n n n n n } catch (Exception e) { n n n n n n n // TODO: handle exception n n n n n } n n n } n n n super.run(); n } n nn nn nn nn } n n n 4.ThreadForGo [java] n package com.nyist.wj; n nn //游戏过程中移动小球的线程 n public class ThreadForGo extends Thread { n n n // 设置线程执行的标志 n n n boolean flag = true; n n n // 游戏界面的引用 n n n GameSurfaceView gameSurfaceView; n nn n n public ThreadForGo(GameSurfaceView gameSurfaceView) { n n n n n this.gameSurfaceView = gameSurfaceView; n n n } n nn n n @Override n n n public void run() { n n n n n // TODO Auto-generated method stub n n n n n while (flag) { n n n n n n n switch (gameSurfaceView.direction) { n nn n n n n n n case 0: n n n n n n n n n // 右上控制当前方向移动球 n n n n n n n n n gameSurfaceView.ballx = gameSurfaceView.ballx n n n n n n n n n n n n n + gameSurfaceView.ballSpan; n n n n n n n n n gameSurfaceView.bally = gameSurfaceView.bally n n n n n n n n n n n n n -gameSurfaceView.ballSpan; n n n n n n n n n // 判断是否碰壁 n n n n n n n n n if (gameSurfaceView.ballx >= gameSurfaceView.screenWidth n n n n n n n n n n n n n -gameSurfaceView.ballSize) { n n n n n n n n n n n // 碰到上壁 n n n n n n n n n n n gameSurfaceView.direction = 3; n n n n n n n n n } else if (gameSurfaceView.bally <= 0) { n n n n n n n n n n n gameSurfaceView.direction = 1; n nn n n n n n n n n } n nn n n n n n n n n break; n nn n n n n n n case 1: n n n n n n n n n // 右下 n n n n n n n n n gameSurfaceView.ballx = gameSurfaceView.ballx n n n n n n n n n n n n n + gameSurfaceView.ballSpan; n n n n n n n n n gameSurfaceView.bally = gameSurfaceView.bally n n n n n n n n n n n n n +gameSurfaceView.ballSpan; n n n n n n n n n // 碰到下壁 n n n n n n n n n if (gameSurfaceView.bally >= gameSurfaceView.screenHeight n n n n n n n n n n n n n -gameSurfaceView.bannerHeight n n n n n n n n n n n n n -gameSurfaceView.bottomSpance n n n n n n n n n n n n n -gameSurfaceView.ballSize) { n n n n n n n n n n n // /-----------------------------------------n n n n n n n n n n n checkCollision(1); n n n n n n n n n n n // 碰到右臂 n n n n n n n n n } else if (gameSurfaceView.ballx >= gameSurfaceView.screenWidth n n n n n n n n n n n n n -gameSurfaceView.ballSize) { n n n n n n n n n n n gameSurfaceView.direction = 2; n n n n n n n n n } n nn n n n n n n n n break; n n n n n n n case 2: n n n n n n n n n // 左下 n n n n n n n n n gameSurfaceView.ballx = gameSurfaceView.ballx n n n n n n n n n n n n n -gameSurfaceView.ballSpan; n n n n n n n n n gameSurfaceView.bally = gameSurfaceView.bally n n n n n n n n n n n n n + gameSurfaceView.ballSpan; n n n n n n n n n // 碰到下壁 n n n n n n n n n if (gameSurfaceView.bally >= gameSurfaceView.screenHeight n n n n n n n n n n n n n -gameSurfaceView.bannerHeight n n n n n n n n n n n n n -gameSurfaceView.bottomSpance n n n n n n n n n n n n n -gameSurfaceView.ballSize) { n n n n n n n n n n n // ////////////////////-----------------------------------n n n n n n n n n n n checkCollision(2); n nn n n n n n n n n } n n n n n n n n n // 碰到左壁 n n n n n n n n n else if (gameSurfaceView.ballx <= 0) { n nn n n n n n n n n n n gameSurfaceView.direction = 1; n nn n n n n n n n n } n nn n n n n n n n n break; n nn n n n n n n case 3: n n n n n n n n n gameSurfaceView.ballx = gameSurfaceView.ballx n n n n n n n n n n n n n -gameSurfaceView.ballSpan; n n n n n n n n n gameSurfaceView.bally = gameSurfaceView.bally n n n n n n n n n n n n n -gameSurfaceView.ballSpan; n n n n n n n nn // /碰到左壁 n n n n n n n n n if (gameSurfaceView.ballx <= 0) { n n n n n n n n n n n gameSurfaceView.direction = 0; n n n n n n n n n } n n n n n n n n n // 碰到上壁 n n n n n n n n n else if (gameSurfaceView.bally <= 0) { n n n n n n n n n n n gameSurfaceView.direction = 2; n n n n n n n n n } n nn n n n n n n n n break; n nn n n n n n n default: n n n n n n n n n break; n nn n n n n n n } n n n n n n n try { n n n n n n n n n Thread.sleep(100); n n n n n n n } catch (Exception e) { n n n n n n n n n // TODO: handle exception n n n n n n n } n n n n n } n n n } n nn n n public void checkCollision(int dirction) { n n n n n if (gameSurfaceView.ballx >= gameSurfaceView.bannerX n n n n n n n n n -gameSurfaceView.ballSize n n n n n n n n n && gameSurfaceView.ballx <= gameSurfaceView.bannerX n n n n n n n n n n n n n +gameSurfaceView.bannerWidth) { n n n n n n n switch (dirction) { n n n n n n n case 1: n n n n n n n n n gameSurfaceView.direction = 0; n n n n n n n n n break; n n n n n n n case 2: n n n n n n n n n gameSurfaceView.direction = 3; n n n n n n n n n break; n n n n n n n default: n n n n n n n n n break; n n n n n n n } n n n n n } else { n n n n n n n // 没有碰到板 n n n n n n n gameSurfaceView.threadForTimecControl.flag = false; n n n n n n ngameSurfaceView.threadForGo.flag = false; n n n n n n n gameSurfaceView.status = 2; n n n n n } n nn n n } n } n n n n n5.ThreadForTimecControl n [java] n package com.nyist.wj; n nn public class ThreadForTimecControl extends Thread { n n n //计算生存时间的线程 n n n //判断是否胜利的值n n n int highest = 200; n // n游戏界面的引入 n n n GameSurfaceView gameSurfaceView; n n n //线程标志位 n n n boolean flag = true; n nn n n public ThreadForTimecControl(GameSurfaceView gameSurfaceView) { n nn n n n n this.gameSurfaceView = gameSurfaceView; n n n } n nn n n @Override n n n public void run() { n n n n n // TODO Auto-generated method stub n n n n n while(flag){ n n n n n n n nn n n n n n n gameSurfaceView.score++; n n n n n n n if (gameSurfaceView.score==highest) { n n n n n n n n n //游戏胜利 n n n n n n n n n gameSurfaceView.status=3; n n n n n n n n n //----------------------------------------n n n n n n n n n gameSurfaceView.threadForTimecControl.flag=false; n n n n n n n n n gameSurfaceView.threadForGo.flag=false; n n n n n n n n n nn n n n n n n } n n n n n n n try { n n n n n n n n n Thread.sleep(1000); n n n n n n n n n nn n n n n n n } catch (Exception e) { n n n n n n n n n // TODO: handle exception n n n n n n n } n n n n n } n n n nn n n } n nn } n n。
Android游戏开发的入门实例在Android中,SurfaceView是一个重要的绘图容器,它可以可以直接从内存或者DMA 等硬件接口取得图像数据。
通常情况程序的View和用户响应都是在同一个线程中处理的,这也是为什么处理长时间事件(例如访问网络)需要放到另外的线程中去(防止阻塞当前UI 线程的操作和绘制)。
但是在其他线程中却不能修改UI元素,例如用后台线程更新自定义View(调用View的在自定义 View中的onDraw函数)是不允许的。
在Android系统上开发游戏是Android开发学习者所向往的,有成就感也有乐趣,还能取得经济上的报酬。
那怎样开发Android游戏呢?下面介绍一个简单的入门实例。
一、创建新工程首先,我们在Eclipse中新建一个名为Movement的工程,并且选择合适的Android SDK,在这里,我们选用的API是比较低的1.5版本,这样可以让其适应性更强。
接下来,我们新建两个类,一个是UpdateThread类,一个是 SurfaceView类,它们在项目中分别是负责处理线程和画面的两个类,在接下来会有详细介绍,如下图,分别建立这两个类,注意选择正确它们继承的父类:在建立完成后,系统的项目结构看上去应该象如下的样子:二、编写Movment.java启动程序任何一个Android应用都必须有一个主启动程序来启动,我们这里把这个启动程序命名为Movment,代码很简单如下:1public class Movement extends Activity {2@Override3public void onCreate(Bundle savedInstanceState) {45super.onCreate(savedInstanceState);6 setContentView(new MovementView(this));7 }注意的是,我们这个启动程序不象其他程序一样,在启动的时候,在setContentView 中传入界面布局文件,而是直接将MovementView的实例传递进来,也就是说,直接启动了MovementView这个类,在这个类中,我们将绘画我们的小球。
三、什么是SurfaceView在Android中,SurfaceView是一个重要的绘图容器,它可以可以直接从内存或者DMA 等硬件接口取得图像数据。
通常情况程序的View和用户响应都是在同一个线程中处理的,这也是为什么处理长时间事件(例如访问网络)需要放到另外的线程中去(防止阻塞当前UI 线程的操作和绘制)。
但是在其他线程中却不能修改UI元素,例如用后台线程更新自定义View(调用View的在自定义 View中的onDraw函数)是不允许的。
如果需要在另外的线程绘制界面、需要迅速的更新界面或则渲染UI界面需要较长的时间,这种情况就要使用SurfaceView了。
SurfaceView中包含一个Surface对象,而Surface 是可以在后台线程中绘制的。
在本文中,我们将使用它,直接通过代码创建一个小球,并且随着UpdateThread线程的更新,不断改变小球的位置,下面我们开始学习MovementView的编写,先看下如何运用SurfaceView。
首先导入SurfaceView及绘图的相关库文件,如下所示:8package example.movement;9import android.content.Context;10import android.graphics.Canvas;11import android.graphics.Color;12import android.graphics.Paint;13import android.graphics.Rect;14import android.view.SurfaceHolder;15import android.view.SurfaceView;接着,我们要继承SurfaceView并且实现SurfaceHolder.Callback接口,这是一个SurfaceHolder的内部接口,可以实现该接口获得界面改变的信息,代码如下,并且我们声明了一些成员变量:16public class MovementView extends SurfaceView implements SurfaceHolder.Callback {17private int xPos;18private int yPos;19private int xVel;20private int yVel;21private int width;22private int height;23private int circleRadius;24private Paint circlePaint;25 UpdateThread updateThread;26}而在MovementView的构造函数中,我们设置了小球的大小和在X,Y方向上的初始坐标,如下:27public MovementView(Context context) {28super(context);29 getHolder().addCallback(this);30 circleRadius = 10;31 circlePaint = new Paint();32 circlePaint.setColor(Color.BLUE);33 xVel = 2;34 yVel = 2;35}接着我们来看下ondraw方法的编写,在这里,我们将绘画小球,并且每次都把画布Canvas的背景色设置为白色,以重新覆盖之前一帧,代码如下:36protected void onDraw(Canvas canvas) {3738 canvas.drawColor(Color.WHITE);3940 canvas.drawCircle(xPos, yPos, circleRadius, circlePaint);41 }下页将为您带来UpdateThread线程程序和启动并运行程序我们再来看下updatePhysics这个方法如何编写。
这个方法的作用有两个:一是处理小球的运动,二是更新小球的实时位置,因为小球在屏幕中不断地运动,因此当小球到达比如屏幕绘画区域的顶端后,要被弹回,88娱乐城因此代码如下:1public void updatePhysics() {2//更新当前的x,y坐标3 xPos += xVel;4 yPos += yVel;5if (yPos - circleRadius < 0 || yPos + circleRadius > height) { 6if (yPos - circleRadius < 0) {7//如果小球到达画布区域的上顶端,则弹回8 yPos = circleRadius;9 }else{10//如果小球到达了画布的下端边界,则弹回11 yPos = height - circleRadius;12 }13// 将Y坐标设置为相反方向14 yVel *= -1;15 }16if (xPos - circleRadius < 0 || xPos + circleRadius > width) { 17if (xPos - circleRadius < 0) {18// 如果小球到达左边缘19 xPos = circleRadius;20 } else {21// 如果小球到达右边缘22 xPos = width - circleRadius;23 }24// 重新设置x轴坐标25 xVel *= -1;26 }27 }最后我们看下surfaceCreated这个方法的代码,在这个方法中,主要是取得了可用的SurfaceView的区域的高度和宽度,然后设置了小球的起始坐标(将其设置在屏幕的正中央位置),并且启动了UpdateThread线程,代码如下:28public void surfaceCreated(SurfaceHolder holder) {29 Rect surfaceFrame = holder.getSurfaceFrame();30 width = surfaceFrame.width();31 height = surfaceFrame.height();32 xPos = width / 2;33 yPos = circleRadius;34 updateThread = new UpdateThread(this);35 updateThread.setRunning(true);36 updateThread.start();37 }此外,我们要补上surfaceChanged这个方法,这个方法意思是界面尺寸改变时才调用,在我们这个应用中并没用到,所以我们保留为空的方法实现:38public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)39 {4041 }而surfaceDestroyed方法中,主要实现的是界面被销毁时才调用,这里我们停止了当前的线程所处理的任务,88娱乐城/这里使用了线程的join方法:42public void surfaceDestroyed(SurfaceHolder holder) {43boolean retry = true;44 updateThread.setRunning(false);45while (retry) {46try {47 updateThread.join();48 retry = false;49 } catch (InterruptedException e) {50 }51 }52 }归纳下,完整的MovementView代码如下:53package example.movement;54import android.content.Context;55import android.graphics.Canvas;56import android.graphics.Color;57import android.graphics.Paint;58import android.graphics.Rect;59import android.view.SurfaceHolder;60import android.view.SurfaceView;61public class MovementView extends SurfaceView implements SurfaceHolder.Callback {62private int xPos;63private int yPos;64private int xVel;65private int yVel;66private int width;67private int height;68private int circleRadius;69private Paint circlePaint;70 UpdateThread updateThread;71public MovementView(Context context) {72super(context);73 getHolder().addCallback(this);74 circleRadius = 10;75 circlePaint = new Paint();76 circlePaint.setColor(Color.BLUE);77 xVel = 2;78 yVel = 2;79 }80@Override81protected void onDraw(Canvas canvas) {82 canvas.drawColor(Color.WHITE);83 canvas.drawCircle(xPos, yPos, circleRadius, circlePaint);84 }85public void updatePhysics() {86 xPos += xVel;87 yPos += yVel;88if (yPos - circleRadius < 0 || yPos + circleRadius > height) { 89if (yPos - circleRadius < 0) {90 yPos = circleRadius;91 }else{92 yPos = height - circleRadius;93 }94 yVel *= -1;95 }96if (xPos - circleRadius < 0 || xPos + circleRadius > width) { 97if (xPos - circleRadius < 0) {98 xPos = circleRadius;99 } else {100 xPos = width - circleRadius;101 }102 xVel *= -1;103 }104 }105public void surfaceCreated(SurfaceHolder holder) {106 Rect surfaceFrame = holder.getSurfaceFrame();107 width = surfaceFrame.width();108 height = surfaceFrame.height();109 xPos = width / 2;110 yPos = circleRadius;111 updateThread = new UpdateThread(this);112 updateThread.setRunning(true);113 updateThread.start();114 }115public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {116 }117public void surfaceDestroyed(SurfaceHolder holder) {118boolean retry = true;119 updateThread.setRunning(false);120while (retry) {121try {122 updateThread.join();123 retry = false;124 } catch (InterruptedException e) {125 }126 }127 }128}四、UpdateThread线程程序下面,我们开始着手编写UpdateThread线程程序。