SurfaceView’s use of instances of abuse

1, SurfaceView
public class SurfaceView extends View
SurfaceView is an inherited class of View, and a Surface dedicated for drawing is embedded in this view. You can control the format and size of this Surface. Surfaceview controls the drawing position of this Surface.
 
surfaceview的核心在于提供了两个线程:UI线程和渲染线程。
 
这里应注意:
 1> 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。
Various variables to be accessed by the rendering thread should be synchronized.
2> Since the surface may be destroyed, it is only valid between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed(), so make sure that the rendering thread accesses a legal and valid surface.
 
可以在主线程之外的线程中向屏幕绘图,这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。
SurfaceView is often used in game development, and the background, characters, animations, etc. in the game are drawn on the canvas as much as possible.
 
 2、SurfaceHolder
 public interface SurfaceHolder
 
显示一个surface的抽象接口,使你可以控制surface的大小和格式, 以及在surface上编辑像素,和监视surace的改变.
 
这个接口通常通过SurfaceView类实现。
 
surface的控制器,用来操纵surface,处理它的Canvas上画的效果和动画,控制表面,大小,像素等。
Several methods to pay attention to:
(1), abstract void addCallback(SurfaceHolder.Callback callback);
// Give the current holder of SurfaceView a callback object.
(2), abstract Canvas lockCanvas();
// Lock the canvas. Generally, after locking, you can use the returned canvas object Canvas to draw pictures on it.
(3), abstract Canvas lockCanvas(Rect dirty);
// Lock a certain area of ​​the canvas for drawing, etc.. Because after drawing the picture, the following unlockCanvasAndPost will be called to change the display content.
// Compared with some games with high memory requirements, it is not necessary to redraw pixels in other areas except dirty, which can increase the speed.
(4), abstract void unlockCanvasAndPost(Canvas canvas);
// End the lock drawing and submit the changes.
 

3、SurfaceHolder.Callback
 用户可以实现此接口接收surface变化的消息。 When used in a SurfaceView, it is only valid between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().设置Callback的方法是SurfaceHolder.addCallback.
 实现上一般继承SurfaceView并实现SurfaceHolder.Callback接口
 

游戏:
分析场景
游戏的角色:小人  和障碍物

跑起来的话,图片的轮播
障碍物,从右往左边移动

实现的第一步:
先让小人跑起来,让障碍物动起来(没有做碰撞检测)
图片轮播和界面的重画(surfview,线程)  

第二步:
小人能够跳起来,并进行碰撞检测

完善:1.选择游戏难度? ? ?
2. The time of the game
3. The choice of the mode for the game to restart after death? ? ?

选择游戏的难度,决定了同时控制几个小人。

SurfaceView是一个视图提供两个线程:UI线程和渲染线程
注意:
1> SurfaceView和SurfaceHolder.Callback的方法都应该在我们的UI线程调用,一般就是我们应用程序的主线程
  渲染线程所要访问的各种变量要做同步处理

2>由于Surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated和SurfaceHolder.Callback.surfaceDestroyed
  之间有效,所以要确保渲染线程访问的是合法的surface

SurfaceHolder显示一个Surface的抽象接口,是我们可以控制surface的大小和格式以及监听surface的改变< br>

几个需要注意到额方法:
addCallBack
lockCanvas
unlockCanvasAndPOst

SurfaceHolder.Callback
用户可以实现此接口接收surface变化的消息

效果图:

Character category:

import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Rect;public class Role {private Bitmap bitmap;//Current picture private Bitmap[] bms;//Complete an animated picture array float x,y;//Own coordinates float speedX,speedY;//speed float width, height;//own width and height private long lastTime; private int index;//record the subscript of the current picture in the picture array private boolean isJump;//mark whether the villain jumps up Public Role(Bitmap[] bms){ this.bms = bms; this.bitmap = bms[0]; this.width = bitmap.getWidth(); this.height = bitmap.getHeight();} public Bitmap getBitmap( ) {return bitmap;} public void setBitmap(Bitmap bitmap) {this.bitmap = bitmap;} public Bitmap[] getBms() {return bms;} public void setBms(Bitmap[] bms) {this.bms = bms;} public float getX() {return x;} public void setX(float x) {this.x = x;} public float getY() {return y;} public void setY(float y) {this.y = y;} public float getSpeedX() {return speedX;} public void setSpeedX(float speedX) {this.speedX = speedX;} public float getSpeedY() {return speedY;} public void setSpeedY(float speedY) {this.speedY = speedY;} public float getWidth() {return width;} public void setWidth(float width) {this.width = width;} publ ic float getHeight() {return height;} public void setHeight(float height) {this.height = height;} public boolean isJump() {return isJump;} public void setJump(boolean isJump) {this.isJump = isJump;} //Pass in the drawing board and draw yourself public void drawSelf(Canvas canvas){ if (System.currentTimeMillis()-lastTime >= 50){//How long does the interval take to switch pictures index++; if (index == bms.length) {index = 0;} bitmap = bms[index]; lastTime = System.currentTimeMillis();} //I can finally draw myself canvas.drawBitmap(bitmap, this.getX(), this.getY(), null); } /** * Get the task rectangle */ public Rect getRectFromRole(){ Rect rect = new Rect(); rect.left = (int) this.getX(); rect.right = (int) (this.getX( )+this.getWidth()); rect.top = (int) this.getY(); rect.bottom = (int) (this.getY()+this.getHeight()); return rect;} ) 

Drawing thread class:

import java.util.Random;import android.content.Context;import android. graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.view.SurfaceHolder;import com.tz .tony.R;import com.tz.tony.role.Role;public class MyThread extends Thread {private Context context; private SurfaceHolder holder; private int w,h; Paint paint; private int gameType; private boolean isStart;//Painting Whether the task starts private Bitmap[] bms;//The resource image of the corresponding villain private int[] paths;//The ID of the corresponding villain’s resource image //Game status private int gameStatu = 0; private int gameSpan; / /The role of the game public Role[] roles; private Rect[] rects; //Record the time of the game private long startTime,overTime; public static final int RUNNING =0; public static final int STANDOFF =1; public static final int GAMEOVER = 2; public MyThread(Context context, SurfaceHolder holder, int w,int h, int gameType) {this.context = context; this.holder = holder; this.w = w; this.h = h; this.gameType = gameType ; paint = new Paint(); isStart = tru e;//Game start// Initialize resource image paths = new int[]{ R.drawable.role1_00, R.drawable.role1_01, R.drawable.role1_02, R.drawable.role1_03, R.drawable.role1_04, R. drawable.role1_05, }; bms = new Bitmap[paths.length]; for (int i = 0; i =1000){ //The stalemate state stays for 1 second to enter the end state gameStatu = GAMEOVER ; }else{ for (int i = 0; i =lineY){ //It means that the villain has landed roles[i].setY(lineY-roles [i].getHeight()); roles[i].setSpeedY(0); roles[i].setJump(false);} //First let my obstacle move right and left rects[i].left = rects[i].left-(h/150); rects[i].right = rects[i].right-(h/150); //When my obstacle moves out if(rects[i]. right <= 0){ //The obstacle goes out, let it return to the right int random_w = (int) (roles[i].getWidth()*(Math.random()*5+1)/4);/ /(0.25--1.5) int random_h = (int) (roles[i].getHeight( )*(Math.random()*5+1)/4);//(0.25--1.5) int random_start = (int) (w* new Random().nextFloat()/2); rects[i] .left = 3*w/2+random_start; rects[i].right = rects[i].left + random_w; rects[i].top = rects[i].bottom-random_h;} //collision detection if ( rects[i].intersect(roles[i].getRectFromRole())){ //I have encountered //Enter a stalemate gameStatu = STANDOFF; overTime = System.currentTimeMillis();} //Draw a line canvas.drawLine(0, lineY, w, lineY, paint); //Draw the villain roles[i].drawSelf(canvas); //Draw obstacles canvas.drawRect(rects[i], paint);}} private void drawText(Canvas canvas, String text, float y, int textSize) {paint.setTextSize(textSize); float measureText = paint.measureText(text);//Calculate the width of the text canvas.drawText(text, (w-measureText)/2, y, paint );} public boolean isStart() {return isStart;} public void setStart(boolean isStart) {this.isStart = isStart;} public int getGameStatu() {return gameStatu;} public void setGameStatu(int gameStatu) {this.gameStatu = gameStatu;} }

Activity interface layout file:

main.xml

                       

< br>

Main activity:

import com.tz.tony.runnable.MyThread;import android.app.Activity;import android.os.Bundle;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android. view.SurfaceView;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnTouchListener;import android.widget.ImageView;public class MainActivity extends Activity implements OnClickListener, Callback,OnTouchListener{ private int gameType;//Mark the difficulty of the game private SurfaceView mSurfaceView ;//Drawing board private MyThread thread; private int w,h;//The width and height of the drawing board private int gameSpan;//Game area ImageView normal ,nightmare,hell,pur; public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); startMenuView();} /** * Start menu view*/ private void startMenuView() {setContentView(R.layout.main) ; normal = (ImageView) findViewById(R.id.normal); nightmare = (ImageView) findViewById(R.id.nightmare); hell = (ImageView) findViewById(R.id.hell); pur = (ImageView) findViewById( R.id.pur); normal.setOnClickListener(this); nightmare.setOnClickListener(this); hell.setOnClickListener(this); pur.setOnClickListener(this);} /** * Initialize the game interface*/ private void startGameView() {mSurfaceView = new SurfaceView(this);//Create artboard mSurfaceView.getHolder().addCallback(this); mSurfaceView.setOnTouchListener(this); setContentView(mSurfaceView);//Load our artboard into the activity interface} public boolean onTouch (View v, MotionEvent event) {switch (thread.getGameStatu()) {case MyThread.RUNNING: //The game is in progress, find the role of the corresponding game area and jump up confirmRole(event); break; case MyThread. GAMEOVER: //The game is over, re-select backOrStart(event); break; default: break;} return true;} /** * Whether to return or restart according to the Y coordinate pressed by the finger * @param event */ private void backOrStart(MotionEvent event) {float y = event.getY(); if (y>h/2 && y<3*h/4){ //return startMenuView(); }else if (y> 3*h/4 ){ //Restart restart();}} /** * Restart */ private void restart() {//Set the game back to normal running state thread.setGameStatu(MyThread.RUNNING); //Initialize the wizard thread .initSpirit();} /** *Confirm the clicked area * @param event */ private void confirmRole(MotionEvent event) {int action = event.getAction(); //Multi-touch switch (action & MotionEvent.ACTION_MASK ) {case MotionEvent.ACTION_DOWN: //The first finger float y = event.getY(); roleJump(y); break; //down case of multi-touch response MotionEvent.ACTION_POINTER_DOWN:// Other fingers gradually darken float y2 = event.getY(event.getPointerCount()-1); roleJump(y2); break; default: break;}} /** * Obtain the task of the corresponding game area according to the coordinates of the finger Y, and then jump up * @param y */ private void roleJump(float y) {for (int i = 0; i lineU && y

Related materials:

The above is organized from the tutorial

Leave a Comment

Your email address will not be published.