两个铁球同时落地
by
at 2010-12-11 15:22:49
original http://www.javaeye.com/topic/839598
这是一篇"在比萨斜塔上模拟两个铁球同时落地",如下:
代码如下:
package com.chaoqun;import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.Bitmap.Config; import android.graphics.Paint.FontMetrics; import android.graphics.PorterDuff.Mode; import android.os.Bundle; import android.os.Handler; import android.view.Display; import android.view.Gravity; import android.view.View; import android.view.WindowManager; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView;
public class TwoBalls extends Activity { /* Called when the activity is first created. / protected WindowManager.LayoutParams windowParams; protected WindowManager windowManager; protected static Display display; protected ImageView icon01; protected ImageView icon02; private Handler messageHandler; private Button _go;
@Override protected void onDestroy() { //清除手工添加的View if(_icon01 != null && _windowManager != null) { _windowManager.removeViewImmediate(_icon01); _icon01 = null; } if(_icon02 != null && _windowManager != null) { _windowManager.removeViewImmediate(_icon02); _icon02 = null; } super.onDestroy(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); _go =(Button)findViewById(R.id.options_btn); _display = ((WindowManager)this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); //获取屏幕介质信息 _messageHandler = new Handler(); _go.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { startAnim(genBitMapforAnim("02", 40), _display.getWidth()-100 , 2, (30-40)/2); startAnim(genBitMapforAnim("01", 30), _display.getWidth()-150, 1, 0); //这里先后有时间差,忽略了,另外UI Thread在消息处理也有时间差,忽略了。 //要精确模拟,只有自定义View,单独绘制了。 } }); } protected Bitmap genBitMapforAnim(String itemCode, int size) { String text = itemCode.length() >= 5 ? itemCode.substring(0, 5) : itemCode; Bitmap result = Bitmap.createBitmap(size*2,size*2, Config.ARGB_8888); Canvas canvas = new Canvas(result); canvas.drawARGB(0, 0xff, 0, 0); Paint paint = new Paint(); paint.setAntiAlias(true); //抗锯齿 paint.setFilterBitmap(true); //透明设置 paint.setColor(Color.RED); paint.setAlpha(200); canvas.drawCircle(size/2, size/2, size/2, paint);//绘制半径为size/2的圆 paint.setAlpha(255); paint.setTextSize(9); paint.setColor(Color.WHITE); float textWidth = paint.measureText(text); //取得字体宽度 FontMetrics fm = paint.getFontMetrics(); float textHeight = (float)(fm.descent + fm.ascent) / 2; //取得字体高度 canvas.drawText(text, (size-textWidth) /2.0f,(size-textHeight)/2.0f, paint); //编号 final Rect rect = new Rect(0, 0,size, size); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(result, rect, rect, paint); //生成透明位图 return result; } protected void startAnim(final Bitmap bitmap, final int startXLocation, int id, final int offset) { final int startY = 160; final ImageView imageView = new ImageView(this); imageView.setImageBitmap(bitmap); if(_windowParams == null) _windowParams = new WindowManager.LayoutParams(); _windowParams.gravity = Gravity.TOP | Gravity.LEFT; //标示要关注上下,左右位置 _windowParams.x = startXLocation; //起点坐标x _windowParams.y = startY + offset; //起点坐标y, 设置offset是为了保证起始位置在同一高度 _windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT; _windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT; _windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; _windowParams.format = PixelFormat.TRANSLUCENT; _windowParams.windowAnimations = 0; if(_windowManager == null) _windowManager = (WindowManager)TwoBalls.this.getSystemService("window"); //获取全局实例WindowManager ImageView icon = id == 1 ? _icon01 : _icon02; if(icon != null) { _windowManager.removeViewImmediate(icon); //移除先前的View icon = null; } else { icon = imageView; } _windowManager.addView(icon, _windowParams); //添加View到当前界面 final Runnable runnable = new Runnable() { double t = 0.0d; final double g = 2.0d; public void run() { t++; _windowParams.x = startXLocation; //由于WindowManager是单实例,所以这里要记录每个的x坐标 _windowParams.y = startY + offset + (int)(0.5 * g * t * t); //匀加速运动位置计算 _windowManager.updateViewLayout(imageView, _windowParams); //更新坐标 } }; new Thread() { long lastUpdate = System.currentTimeMillis(); public void run() { //设置大家都经过同一高度(这里依旧考虑到球的半径不同) while (_windowParams.y + offset < _display.getHeight() - 60 && !Thread.interrupted() && !TwoBalls.this.isFinishing()) { if(System.currentTimeMillis() - lastUpdate >= 100) { //每隔100ms动一下,移动一侦 lastUpdate = System.currentTimeMillis(); _messageHandler.post(runnable); } } if(!bitmap.isRecycled()) bitmap.recycle(); } }.start(); }
}
已打包,有兴趣的看看.
-
本文附件下载:
<li><a href="http://dl.javaeye.com/topics/download/7d859098-4cbe-388b-b324-e2e9080d7254">TwoBalls.zip</a> (180.2 KB)</li>
<br><br>
作者: <a href="http://ihavegotyou.javaeye.com">Ihavegotyou</a>
<br>
声明: 本文系JavaEye网站发布的原创文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任!
<br><br>
<span style="color:red">
<a href="http://www.javaeye.com/topic/839598" style="color:red">已有 <strong>0</strong> 人发表回复,猛击->><strong>这里</strong><<-参与讨论</a>
</span>
<br><br><br>
JavaEye推荐