Android碰撞的小球,密集恐惧症者谨慎
来源:互联网 发布:合肥科大讯飞待遇 知乎 编辑:程序博客网 时间:2024/04/29 03:41
今天又温习了一遍Java的进程。正好用Android写了一个小Demo,具体就是在手机屏幕上显示多个运动的小球,小球碰到手机屏幕边缘会自动弹回。大概就是下面图中显示的:
该本主要的结束的是自定义View封装,View视图绘制,通过xml文件自定义View属性并设置属性,多线程Thread,小球碰撞弹回简单算法。
下面是制作这个Demo的简单步骤:
step1:自定义一个View抽象类,它封装了View类的基本方法,以及多线程的创建和操作方法。具体代码如下:
<span style="font-size:12px;">package com.example.constumeview;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.view.View;public abstract class BaseCustomeView extends View {private MyThread myThread = null;private class MyThread extends Thread{@Overridepublic void run() {while(true){logicalDo();postInvalidate(); //通知更新界面,会重新调用onDraw()函数try{sleep(80);}catch(Exception e){e.printStackTrace();}}}}public abstract void logicDo(); //逻辑处理方法public abstract void drawSub(Canvas canvas); //绘画内容代码public abstract void initView();@Overrideprotected void onDraw(Canvas canvas) {if(myThread == null){ //第一次调用onDraw()方法的时候会创建一个线程,用来实现小球的碰撞弹回initView();<span style="white-space:pre"></span>//初始化View方法myThread = new MyThread();myThread.start(); //启动线程}else{ drawSub(canvas); //如果线程以创建,则调用绘制方法}}public BaseCustomeView(Context context) {super(context);}public BaseCustomeView(Context context, AttributeSet attrs) {super(context, attrs);}}</span>
下面我对View的两个构造方法View(Context context)和View(Context context,AttributeSet attrs)解释一下。第一个View(Context context)只有一个上下文context的参数,一般在代码(.javawenjian)中创建View进行调用,比如View view = new View(this)。第二个构造方法View(Context context,AttributeSet attrs)有两个参数,其中attrs是View的属性集合。一般在布局创建View对象时进行调用(.xml文件)。
<span style="font-size:12px;">package com.example.constumeview;import java.util.Random;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Point;import android.graphics.PointF;import android.util.AttributeSet;public class MyCustomeView extends BaseCustomeView {private Paint paint = new Paint(); private int ballNumber = 1; //定义小球个数,默认为1个,通过xml自定义属性进行设置,详细看后面 private PointF[] ballCenter = null; //存储各个小球的圆心坐标 private float ballRadius = 4.0f; //定义小球半径,通过xml自定义设置,看后面解释 private int viewWidth = 0; //手机屏幕宽度 private int viewHeight = 0; //手机屏幕高度 private float[] xspace; //存储各个小球横向运动速度,每个小球在横向和纵向运动的速度是不同 private float[] yspace;//存储各个小球纵向的运动速度public MyCustomeView(Context context) {//代码中解析super(context);}public MyCustomeView(Context context, AttributeSet attrs) {//布局中解析属性super(context, attrs);TypedArray typeArray = context.obtainStyledAttributes(attrs,R.styleable.NumberText);ballNumber = typeArray.getInt(R.styleable.NumberText_ballNumber, 1);//获得小球个数ballRadius = typeArray.getFloat(R.styleable.NumberText_ballRadius, 4.0f);//获得小球半径typeArray.recycle();//回收TypeArray资源productBallCenter(); //产生各个小球的圆心位置setBackgroundColor(Color.WHITE);//设置View背景色为白色}@Overridepublic void logicDo() {//小球碰撞弹回简单算法for(int i=0;i<ballNumber;i++){if((ballCenter[i].x-ballRadius)<0){ //如果小球到达屏幕左边缘,设置<span style="font-family: Arial, Helvetica, sans-serif;">ballCenter[i].x = ballRadius;</span>xspace[i] = 0-xspace[i];ballCenter[i].x = ballRadius;}else if((ballCenter[i].x+ballRadius)>viewWidth){//如果小球到达屏幕右边缘xspace[i] = 0-xspace[i];ballCenter[i].x = viewWidth-ballRadius;}else if((ballCenter[i].y-ballRadius)<0){//如果小球达到屏幕上边缘yspace[i] = 0-yspace[i];ballCenter[i].y = ballRadius;}else if((ballCenter[i].y+ballRadius)>viewHeight){//如果小球到达屏幕下边缘yspace[i] = 0-yspace[i];ballCenter[i].y = viewHeight-ballRadius;}else{<span style="white-space:pre"></span>//默认正常情况下ballCenter[i].x = ballCenter[i].x+xspace[i];ballCenter[i].y = ballCenter[i].y+yspace[i];}}}@Overridepublic void drawSub(Canvas canvas) {//以圆心坐标绘制每个小球在屏幕中的位置for(int i=0;i<ballNumber;i++){/*Random random = new Random();int r = random.nextInt(256);int g = random.nextInt(256);int b = random.nextInt(256);paint.setARGB(255,r, g, b);*/<span style="white-space:pre"></span>//随机产生小球的颜色,这里我注释了,用的是全黑canvas.drawCircle(ballCenter[i].x, ballCenter[i].y, ballRadius, paint);}}public void productBallCenter(){ //随机初始化小球的圆心和小球运动速度,只在initView中调用一次ballCenter = new PointF[ballNumber];xspace = new float[ballNumber];yspace = new float[ballNumber];Random random = new Random();float xpoint = 0;float ypoint = 0;for(int i=0;i<ballNumber;i++){xpoint = random.nextFloat()*viewWidth+ballRadius;ypoint = random.nextFloat()*viewHeight+ballRadius;ballCenter[i] = new PointF(xpoint,ypoint);xspace[i] = random.nextFloat()*ballRadius+1;yspace[i] = random.nextFloat()*ballRadius+1;}}@Overridepublic void initView() { //初始化View方法,准备工作viewWidth = getWidth(); viewHeight = getHeight();productBallCenter();}}</span>程序的运行过程我在注释中写得很详细了,现在我主要介绍一下怎么在xml中自定义View的属性。比如在上面程序中ballNumber和ballRadius属性是同xml文件设置的,以及我们自定义的MyCustomeView对象也是通过xml进行初始化的。下面是我的xml文件中代码,只有几行:
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" xmlns:yourname="http://schemas.android.com/apk/res/com.example.constumeview" xmlns:android="http://schemas.android.com/apk/res/android"> <com.example.constumeview.MyCustomeView android:layout_width="match_parent" android:layout_height="match_parent" yourname:ballNumber="500" yourname:ballRadius="10.0"/></LinearLayout>下面是具体步骤:
1.首先在自定义类中声明你要在xml文件设置的属性,比如我在MyCustomeView中声明了ballNumber和ballRadius属性。
2.在values文件夹中创建一个attrs.xml文件,在里面声明你要在xml文件中使用的属性,如下:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="NumberText"> <attr name="ballNumber" format="integer"/> <attr name="ballRadius" format="float"/> </declare-styleable></resources>name为属性名,format为属性的数据类型。
3.在主视图布局文件中(我这里是默认的activity_main.xml文件),设置属性的值,代码我已经贴在上面。
在主布局中添加xmlns:yourname="http://schemas.android.com/apk/res/com.example.constumeview";
其中xmlns:yourname中xmlns是固定的,yourname可以自定义,不过设置属性的时候要保持一致。后面的工具前面的http://schemas.android.com/apk/res/是不变的,后面的是你的工作空间包名。接下来就是设置属性了。例如:yourname:ballNumber="500" yourname:ballRadius="10.0".详细看上面的代码部分哦。
4.最后贴上我入口程序MainActivity.java中的代码,其实什么都没有,只是为了保持项目的完整性,读者好参考。
package com.example.constumeview;import android.app.Activity;import android.app.ActionBar;import android.app.Fragment;import android.os.Bundle;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.os.Build;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }}到此一个满屏幕都是碰撞小球的Demo就制作好了,密集恐惧症的人请将小球个数调少点哦。23333333
- Android碰撞的小球,密集恐惧症者谨慎
- android练习:碰撞的小球
- 碰撞的小球
- 碰撞的小球 HTML5
- 【HTML5】碰撞的小球
- BouncingBallView 碰撞的小球
- BouncingBallView 碰撞的小球
- 如何用数据可视化之美逼死密集恐惧症
- 用数据可视化之美逼死密集恐惧症
- Android 小球碰撞检测技术
- Java课程设计---碰撞的小球
- 8086汇编碰撞的小球
- 碰撞的小球开源小案例
- 可拖拽的弹性碰撞小球
- MFC游戏程序 - 碰撞的小球
- 基于WPF的一个小球碰撞代码
- 简易的Win32小球碰撞程序
- 有质量和碰撞的小球
- Objective C 链式调用
- VMware 虚拟机使用NAT模式上网
- Field data
- 记录C语言入门·三
- MapReduce实现join操作
- Android碰撞的小球,密集恐惧症者谨慎
- c语言之const理解
- swift归档解档
- Nginx 配置指令的执行顺序
- iOS8后地理定位问题解决和定为时错误的解决Error Domain=kCLErrorDomain
- NYOJ:01串 【DP入门】
- 项目感悟
- iOS中类和对象还有,nil/Nil/NULL的区别
- iOS 继承