精华帖 (8) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-07-05
SurfaceView在游戏开发中有着举足轻重的地位,它对于画面的控制有着更大的自由度(不像View要用handler来更新,关于View的),但这方面的参考资料并不是太多,能找到的例子都有点喧宾夺主的感觉,不能把使用的流程清晰展示出来,下面是个简单的示例,力求把流程清楚展示,其他的可简则简。
程序效果:用线程画一个蓝色的长方形。 package com.ray.test; /* * SurfaceView的示例程序 * 演示其流程 */ import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; public class Test extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); } //内部类 class MyView extends SurfaceView implements SurfaceHolder.Callback{ SurfaceHolder holder; public MyView(Context context) { super(context); holder = this.getHolder();//获取holder holder.addCallback(this); //setFocusable(true); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { new Thread(new MyThread()).start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { } //内部类的内部类 class MyThread implements Runnable{ @Override public void run() { Canvas canvas = holder.lockCanvas(null);//获取画布 Paint mPaint = new Paint(); mPaint.setColor(Color.BLUE); canvas.drawRect(new RectF(40,60,80,80), mPaint); holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像 } } } }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-09-18
在用SurfaceView时遇到问题请指点.
每次把画当前正方形时,把上次的清除掉,现在显示很乱画图代码如下 public void selectSmallPicture(Point _origialPoint) { if(_origialPoint == null) { return ; } Canvas canvas = holder.lockCanvas();// 获取画布 int startX = _origialPoint.x * (PICTURE_EXTENT + CUBICLE) - 1; int startY = _origialPoint.y * (PICTURE_EXTENT + CUBICLE) - 1; //canvas.save(); Paint linePaint = new Paint(); linePaint.setColor(Color.RED); canvas.drawLine(startX, startY, startX , startY + PICTURE_EXTENT, linePaint); canvas.drawLine(startX, startY, startX + PICTURE_EXTENT, startY , linePaint); canvas.drawLine(startX+ PICTURE_EXTENT, startY, startX + PICTURE_EXTENT, startY + PICTURE_EXTENT, linePaint); canvas.drawLine(startX, startY + PICTURE_EXTENT, startX + PICTURE_EXTENT, startY + PICTURE_EXTENT, linePaint); if(tempPoint!=null) { startX = tempPoint.x * (PICTURE_EXTENT + CUBICLE) - 1; startY = tempPoint.y * (PICTURE_EXTENT + CUBICLE) - 1; linePaint.setColor(bgcolor); canvas.drawLine(startX, startY, startX , startY + PICTURE_EXTENT, linePaint); canvas.drawLine(startX, startY, startX + PICTURE_EXTENT, startY , linePaint); canvas.drawLine(startX+ PICTURE_EXTENT, startY, startX + PICTURE_EXTENT, startY + PICTURE_EXTENT, linePaint); canvas.drawLine(startX, startY + PICTURE_EXTENT, startX + PICTURE_EXTENT, startY + PICTURE_EXTENT, linePaint); } canvas.restore(); holder.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像 tempPoint = _origialPoint; } |
|
返回顶楼 | |
发表时间:2009-09-18
最后修改:2009-09-18
ansili 写道 在用SurfaceView时遇到问题请指点.
每次把画当前正方形时,把上次的清除掉,现在显示很乱画图代码如下 public void selectSmallPicture(Point _origialPoint) { if(_origialPoint == null) { return ; } Canvas canvas = holder.lockCanvas();// 获取画布 int startX = _origialPoint.x * (PICTURE_EXTENT + CUBICLE) - 1; int startY = _origialPoint.y * (PICTURE_EXTENT + CUBICLE) - 1; //canvas.save(); Paint linePaint = new Paint(); linePaint.setColor(Color.RED); canvas.drawLine(startX, startY, startX , startY + PICTURE_EXTENT, linePaint); canvas.drawLine(startX, startY, startX + PICTURE_EXTENT, startY , linePaint); canvas.drawLine(startX+ PICTURE_EXTENT, startY, startX + PICTURE_EXTENT, startY + PICTURE_EXTENT, linePaint); canvas.drawLine(startX, startY + PICTURE_EXTENT, startX + PICTURE_EXTENT, startY + PICTURE_EXTENT, linePaint); if(tempPoint!=null) { startX = tempPoint.x * (PICTURE_EXTENT + CUBICLE) - 1; startY = tempPoint.y * (PICTURE_EXTENT + CUBICLE) - 1; linePaint.setColor(bgcolor); canvas.drawLine(startX, startY, startX , startY + PICTURE_EXTENT, linePaint); canvas.drawLine(startX, startY, startX + PICTURE_EXTENT, startY , linePaint); canvas.drawLine(startX+ PICTURE_EXTENT, startY, startX + PICTURE_EXTENT, startY + PICTURE_EXTENT, linePaint); canvas.drawLine(startX, startY + PICTURE_EXTENT, startX + PICTURE_EXTENT, startY + PICTURE_EXTENT, linePaint); } canvas.restore(); holder.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像 tempPoint = _origialPoint; } Android surfaceview 的画图机制是这样设计的,只能画一次背景,再画你想画的才可以! |
|
返回顶楼 | |
发表时间:2009-09-18
那如果我想在上次画的基础上接着画呢?。
也就是说我第一次在surfaceview 画了一个方块,再次接到用户的动作时在上次所画结果上接着在surfaceview 再画一个方块.此时surfaceview 上已经存在两个方块了。 surfaceview 能否胜任? 需要怎么做? |
|
返回顶楼 | |
发表时间:2009-09-18
ansili 写道 那如果我想在上次画的基础上接着画呢?。
也就是说我第一次在surfaceview 画了一个方块,再次接到用户的动作时在上次所画结果上接着在surfaceview 再画一个方块.此时surfaceview 上已经存在两个方块了。 surfaceview 能否胜任? 需要怎么做? 如果要保留当前的接着画,SurfaceView是无法做到的! |
|
返回顶楼 | |
发表时间:2009-09-20
每次画2个方块
|
|
返回顶楼 | |
发表时间:2009-09-22
raymondlueng 写道
SurfaceView在游戏开发中有着举足轻重的地位,它对于画面的控制有着更大的自由度(不像View要用handler来更新,关于View的),但这方面的参考资料并不是太多,能找到的例子都有点喧宾夺主的感觉,不能把使用的流程清晰展示出来,下面是个简单的示例,力求把流程清楚展示,其他的可简则简。
程序效果:用线程画一个蓝色的长方形。 package com.ray.test; /* * SurfaceView的示例程序 * 演示其流程 */ import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; public class Test extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); } //内部类 class MyView extends SurfaceView implements SurfaceHolder.Callback{ SurfaceHolder holder; public MyView(Context context) { super(context); holder = this.getHolder();//获取holder holder.addCallback(this); //setFocusable(true); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { new Thread(new MyThread()).start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { } //内部类的内部类 class MyThread implements Runnable{ @Override public void run() { Canvas canvas = holder.lockCanvas(null);//获取画布 Paint mPaint = new Paint(); mPaint.setColor(Color.BLUE); canvas.drawRect(new RectF(40,60,80,80), mPaint); holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像 } } } }
根据楼主的demo我也写了个小小的demo,可就是物体移动的时候比较慢,不知道是为什么? package com.mcgk.paopao; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.os.Bundle; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import com.mcgk.paopao.Paopao.MyView.MyThread; import com.mcgk.util.BackgroundUtil; public class Paopao extends Activity { private MyThread mythread; private static boolean drawFlag = false; private static int x = 14; private static int y = 20; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); } class MyView extends SurfaceView implements SurfaceHolder.Callback { SurfaceHolder holder; public MyView(Context context) { super(context); holder = this.getHolder();// 获取holder holder.addCallback(this); setFocusable(true); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); Resources r = this.getContext().getResources(); BackgroundUtil.drawBackground(r, canvas); BackgroundUtil.drawTree(r, canvas, x, y); drawFlag = true; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub return mythread.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { // TODO Auto-generated method stub return mythread.onKeyUp(keyCode, event); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { mythread = new MyThread(holder, this); new Thread(mythread).start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { } class MyThread implements Runnable { private SurfaceHolder holder; private MyView _panel; public MyThread(SurfaceHolder holder, MyView panel) { this.holder = holder; this._panel = panel; } public boolean onKeyUp(int keyCode, KeyEvent event) { // TODO Auto-generated method stub return false; } public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub synchronized (holder) { if (keyCode == KeyEvent.KEYCODE_DPAD_UP){ y = y - 30; }else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN){ y = y + 30; }else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT){ x = x - 30; }else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){ x = x + 30; } } drawFlag = false; return false; } @Override public void run() { Canvas c; while (true) { c = null; if(drawFlag){ try { Thread.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } continue; } try { c = holder.lockCanvas(null); synchronized (holder) { _panel.onDraw(c); } } finally { if (c != null) { holder.unlockCanvasAndPost(c); } } } } } } } |
|
返回顶楼 | |
发表时间:2009-10-11
我明白了,更新画面时不用sleep,看LunarLander的例子里更新UI的线程也是一直狂跑的,占满了一个CPU
|
|
返回顶楼 | |
发表时间:2009-10-11
最后修改:2009-10-11
brumby007 写道 我明白了,更新画面时不用sleep,看LunarLander的例子里更新UI的线程也是一直狂跑的,占满了一个CPU
你错了,如果你不sleep而狂刷,你会发现不仅你的短信、电话等后台程序工作缓慢,而且你还能看到如下的警告信息 引用 10-11 13:20:01.534: WARN/SurfaceComposerClient(1938): lock_layer timed out (is the CPU pegged?) layer=1, lcblk=0x424d00a0, state=00000011 (was 00000012)
10-11 13:20:01.534: WARN/SurfaceFlinger(99): executeScheduledBroadcasts() skipped, contention on the client. We'll try again later... 10-11 13:20:01.534: WARN/SurfaceComposerClient(1938): lock_layer() timed out but didn't appear to need to be locked and we recovered (layer=1, lcblk=0x424d00a0, state=00000001) 所以,在lock之外sleep是非常必要滴 |
|
返回顶楼 | |
发表时间:2009-10-11
谢谢楼上大哥的回复,可是不知道为什么在lunarlander里面是这样实现的,也没有做sleep,我看logcat打出来的东西是一直在狂刷的:
public void run() { while (mRun) { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { if (mMode == STATE_RUNNING) updatePhysics(); Log.d("test", ">>>>>>>>>>>>dodraw"); doDraw(c); } } finally { // do this in a finally so that if an exception is thrown // during the above, we don't leave the Surface in an // inconsistent state if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } } 而且如果我用sleep的话,物体移动会有明显卡住的感觉。不知道是怎么回事? 小弟初学,还请赐教 |
|
返回顶楼 | |