5-6 SurfaceViewによる高速描画

Download Report

Transcript 5-6 SurfaceViewによる高速描画

5-6 SurfaceView による高速描画
(1)SurfaceViewを使う
A. SurfaceView とは
①View でも描画できるが描画速度が遅いので、アクションゲーム等には不向き。
②描画速度を重視する場合、SurfaceViewを用いる。
③SurfaceViewは、より速く表示を更新できるよう設計されたViewのサブクラス。
B. SurfaceViewの使い方
① SurfaceViewを利用するクラスでは、SurfaceViewを継承する。
② SurfaceHolder.Callbackをimplementsする。
(サーフェースで表示更新に関する何らかの処理が発生すると、
コールバックとして用意したメソッドが呼び出される)
surfaceCreated
surfaceChange
: サーフェースが生成されたとき呼び出される。初期化処
理等を行う。
: サーフェースが変更されたとき。
surfaceDestroyed : サーフェースが破棄されたとき。通常はスレッドをnull
にする。
package jp.eclipse.surfaceView;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
public class SurfaceViewActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(new SurfaceViewView(this));
}
}
C. プログラム例(1)
プログラム例(2)
class SurfaceViewView extends SurfaceView
implements SurfaceHolder.Callback, Runnable{
private SurfaceHolder holder; private Thread thread;
private Bitmap image; private int sWidth=450, sHeight=750;
private Rect src; private int px=240, py=400, vx=10, vy=10;
public SurfaceViewView(Context context) {
super(context);
Resources res = getResources();
image = BitmapFactory.decodeResource(res, R.drawable.ball);
int w = image.getWidth(); int h = image.getHeight();
src=new Rect(0,0,w,h);
holder = getHolder(); holder.addCallback(this);
holder.setFixedSize(sWidth + 20, sHeight + 20);
}
D. 実行例
スレッドを用いたボールの動き。
ここではボール形状を
画像として用意している。
(Java 1.6で動かすこと)
(2)ScheduleExecutorServiceを使う
A. ScheduleExecutorServiceとは
指定された遅延時間後または定期的に処理を実行できるようスケジューリングする。
取り消されるまで定期的に実行されるタスクを作成・実行するメソッドとして、
①scheduleAtFixedRate メソッド
②scheduleWithFixedDelay メソッド
がある。
【例】1時間、10秒ごとにビープ音をならす。
mport static java.util.concurrent.TimeUnit.*;
class BeepCon{
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPoll(1);
public void beepForHour(){
final Runnable b = new Runnnable(){
public void run(){ System.out.println("beep");
};
final ScheduledFuture<?> beepH =
scheduler.scheduleAtFixedRate(b,10,10,SECONDS);
schduler.schedule(new Runnable(){
public void run() {beepH.cancel(true);}
}, 60*60. SECONDS);
}
}
package jp.Scedule;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
B. プログラム例(1)
プログラム例(2)
public class SchedulledExecutorActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(new SurfaceViewView(this));
}
}
class SurfaceViewView extends SurfaceView
implements SurfaceHolder.Callback{
private SurfaceHolder holder=null;
private Thread
thread;
float currentX, currentY, nextX, nextY;
private int currentColor;
public SurfaceViewView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initializeSurface();
}
public SurfaceViewView(Context context, AttributeSet attrs) {
super(context, attrs);
initializeSurface();
}
public SurfaceViewView(Context context) {
super(context);
initializeSurface();
}
private void initializeSurface() {
currentColor=Color.WHITE;
nextX=100; nextY=200;
holder = this.getHolder();
holder.addCallback(this);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1,
int arg2, int arg3) {}
public void surfaceCreated(SurfaceHolder arg0) {
drawSurface();doAnimation();
}
public void surfaceDestroyed(SurfaceHolder arg0) {}
public void drawSurface(){
Canvas c =holder.lockCanvas();
c.drawColor(Color.WHITE);
Paint p=new Paint();
p.setColor(Color.RED);
c.drawCircle(currentX, currentY, 50, p);
holder.unlockCanvasAndPost(c);
}
プログラム例(3)
プログラム例(4)
public void doAnimation(){
ScheduledExecutorService executor
=Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(new Runnable(){
public void run() {
currentX -= (currentX - nextX)/20;
currentY -= (currentY - nextY)/20;
currentX = Math.abs(currentX)<1.0f ? 1.0f : currentX;
currentY = Math.abs(currentY)<1.0f ? 1.0f : currentY;
drawSurface();
}
}, 0,100,TimeUnit.MILLISECONDS);
}
public boolean onTouchEvent(MotionEvent event){
nextX=event.getX();
nextY=event.getY();
return true;
}
}
C. 実行例
スクリーンにタッチすると
赤い円がタッチしたところに
近づいてくる。
(Java 1.6で動かすこと)