package com.ball;
import android.graphics.Bitmap;
import android.graphics.Canvas;
public class Movable {
int startX = 0; // 初始X坐标
int startY = 0; // 初始Y坐标
int x; // 实时X坐标
int y; // 实时Y坐标
float startVX = 0f; // 初始水平方向的速度
float startVY = 0f; // 初始竖直方向的速度
float v_x = 0f; // 实时水平方向的速度
float v_y = 0f; // 实时竖直方向的速度
int r; // 可移动物体半径
double timeX; // X方向上的运动时间
double timeY; // Y方向上的运动时间
Bitmap bitmap=null; // 可移动物体图片
BallThread bt=null; // 负责小球移动
boolean bFall=false; // 小球是否已经从木板上下落
float impactFactor=0.25f; // 小球撞地后速度的损失系数
public Movable(int x,int y,int r,Bitmap bitmap) {
this.startX=x;
this.x=x;
this.startY=y;
this.y=y;
this.r=r;
this.bitmap=bitmap;
timeX=System.nanoTime(); // 获取系统时间初始化timeX
this.v_x=BallView.V_MIN+(int)((BallView.V_MAX-BallView.V_MIN)*Math.random());
bt=new BallThread(this); // 创建并启动BallThread
bt.start();
}
public void drawSelf(Canvas canvas) {
canvas.drawBitmap(bitmap,x,y,null);
}
}
package com.ball;
public class BallThread extends Thread {
Movable father; // Movable对象引用
boolean flag = false; // 线程执行标识位
int sleepSpan = 40; // 休眠时间
float g = 200; // 球下落的加速度
double current; // 记录当前时间
public BallThread(Movable father) {
this.father = father;
this.flag = true;
}
@Override
public void run() {
while (flag) {
current = System.nanoTime(); // 获取当前时间,单位为纳秒,处理水平方向上的运动
double timeSpanX = (double) ((current - father.timeX) / 1000 / 1000 / 1000); // 获取水平方向走过的时间
father.x = (int) (father.startX + father.v_x * timeSpanX);
if (father.bFall) { // 处理竖直方向上的运动,判断球是否已经移出挡板
double timeSpanY = (double) ((current - father.timeY) / 1000 / 1000 / 1000);
father.y = (int) (father.startY + father.startVY * timeSpanY + timeSpanY
* timeSpanY * g / 2);
father.v_y = (float) (father.startVY + g * timeSpanY);
//此处先省略检测和处理特殊事件的代码,随后补全
} else if (father.x + father.r / 2 >= BallView.WOOD_EDGE) {// 通过X坐标判断球是否移出了挡板
father.timeY = System.nanoTime();
father.bFall = true; // 确定下落
}
try {
Thread.sleep(sleepSpan);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// 判断小球是否到达最高点
if (father.startVY < 0 && Math.abs(father.v_y) <= BallView.UP_ZERO) {
father.timeY = System.nanoTime();
father.v_y = 0;
father.startVY = 0;
father.startY = father.y;
}
// 判断小球是否撞地
if (father.y + father.r * 2 >= BallView.GROUND_LING && father.v_y > 0) {
father.v_x = father.v_x * (1 - father.impactFactor); // 衰减水平方向的速度
father.v_y = 0 - father.v_y * (1 - father.impactFactor); // 衰减竖直方向的速度并改变方向
if (Math.abs(father.v_y) < BallView.DOWN_ZERO) { // 判断撞地衰减后的速度,太小就停止运动
this.flag = false;
} else {
// 撞地后的速度还可以弹起继续下一阶段的运动
father.startX = father.x;
father.timeX = System.nanoTime();
father.startY = father.y;
father.timeY = System.nanoTime();
father.startVY = father.v_y;
}
}
package com.ball;
import java.util.ArrayList;
import java.util.Random;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import com.bp.R;
public class BallView extends SurfaceView implements Callback {
public static final int V_MAX=35;
public static final int V_MIN=15;
public static final int WOOD_EDGE=60;
public static final int GROUND_LING=450; //代表地面的Y坐标,小球下落到此会弹起
public static final int UP_ZERO=30; //小球在上升过程中,速度小于该值就算0
public static final int DOWN_ZERO=60; //小球在撞击地面后,速度小于该值就算0
Bitmap[] bitmapArray =new Bitmap[6];
Bitmap bmpBack; //背景图片
Bitmap bmpWood; // 挡板图片
String fps="FPS:N/A"; //用于显示帧速率的字符串
int ballNumber =8; //小球数目
ArrayList<Movable> alMovable=new ArrayList<Movable>(); //小球对象数组
DrawThread dt; //后台屏幕绘制线程
public BallView(Context activity) {
super(activity);
getHolder().addCallback(this);
initBitmaps(getResources()); //初始化图片
initMovables(); //初始化小球
dt=new DrawThread(this,getHolder()); //初始化重绘线程
}
public void initBitmaps(Resources r) {
bitmapArray[0]=BitmapFactory.decodeResource(r, R.drawable.ball_red_small);
bitmapArray[1]=BitmapFactory.decodeResource(r, R.drawable.ball_purple_small);
bitmapArray[2]=BitmapFactory.decodeResource(r, R.drawable.ball_green_small);
bitmapArray[3]=BitmapFactory.decodeResource(r, R.drawable.ball_red);
bitmapArray[4]=BitmapFactory.decodeResource(r, R.drawable.ball_purple);
bitmapArray[5]=BitmapFactory.decodeResource(r, R.drawable.ball_green);
bmpBack=BitmapFactory.decodeResource(r, R.drawable.back);
bmpWood=BitmapFactory.decodeResource(r, R.drawable.wood);
}
public void initMovables() {
Random r=new Random();
for(int i=0;i<ballNumber;i++) {
int index=r.nextInt(32);
Bitmap tempBitmap=null;
if(i<ballNumber/2) { //如果是初始化前一半球,就从大球中随机找一个
tempBitmap=bitmapArray[3+index%3];
} else { //如果是初始化前一半球,就从小球中随机找一个
tempBitmap=bitmapArray[index%3];
}
//创建Movable对象
Movable m=new Movable(0, 70-tempBitmap.getHeight(), tempBitmap.getWidth()/2, tempBitmap);
alMovable.add(m); //加入列表中
}
}
public void doDraw(Canvas canvas) { //绘制程序中需要的图片等信息
canvas.drawBitmap(bmpBack, 0, 0,null);
canvas.drawBitmap(bmpWood, 0, 60,null);
for (Movable m : alMovable) { //遍历绘制每个Movable对象
m.drawSelf(canvas);
}
Paint p=new Paint();
p.setColor(Color.BLUE);
p.setTextSize(18);
p.setAntiAlias(true); //设置抗锯齿
canvas.drawText(fps, 30, 30, p); //画出帧速率字符串
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
if(!dt.isAlive()) {
dt.start();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
dt.flag=false;
dt=null;
}
}
package com.ball;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class DrawThread extends Thread {
BallView bv;
SurfaceHolder surfaceHolder;
boolean flag=false;
int sleepSpan=30;
long start =System.nanoTime(); //记录起始时间,该变量用于计算帧速率
int count=0 ; //记录帧数
public DrawThread(BallView bv,SurfaceHolder surfaceHolder) {
this.bv=bv;
this.surfaceHolder=surfaceHolder;
this.flag=true;
}
public void run() {
Canvas canvas=null;
while(flag) {
try {
canvas=surfaceHolder.lockCanvas(null); //获取BallView的画布
synchronized (surfaceHolder) {
bv.doDraw(canvas);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(canvas!=null) {
surfaceHolder.unlockCanvasAndPost(canvas); // surfaceHolder解锁,并将画布传回
}
}
this.count++;
if(count==20) { //计满20帧时计算一次帧速率
count=0;
long tempStamp=System.nanoTime();
long span=tempStamp-start;
start=tempStamp;
double fps=Math.round(100000000000.0/span*20)/100.0;
bv.fps="FPS:"+fps;
}
try {
Thread.sleep(sleepSpan);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.ball;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
BallView bv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //设置不显示标题
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //设置全屏
bv=new BallView(this);
setContentView(bv);
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有