Android游戏开发学习(2)--SurfaceView实例控制角色移动
程序员文章站
2022-04-02 16:05:44
...
先看效果
我用到的图片-
在看代码
package dk.game; import android.app.Activity; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //去掉标题 requestWindowFeature(Window.FEATURE_NO_TITLE); //全屏显示 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(new GameView(this)); } }
package dk.game; 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.util.Log; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; public class GameView extends SurfaceView implements Runnable,SurfaceHolder.Callback { //刷屏主线程 private Thread gameThread; //游戏屏幕宽和高 public static int screen_width,screen_height; private Paint paint; private Canvas canvas; private SurfaceHolder sfh; private boolean run_flag=false; //敌人图片 private Bitmap bmp_enemy; //移动速度 private int enemy_speed=5; //角色移动控制帧 private int frame=0; //按键上下左右移动的判断 private boolean is_up,is_down,is_left,is_right; //上下左右移动动画帧编号 private int[] enemy_up={3,4,5}; private int[] enemy_down={0,1,2}; private int[] enemy_left={6,7,8}; private int[] enemy_right={9,10,11}; //当前帧动画 private int[] enemy_start=enemy_down; //初始角色单帧图片右上角位置和单帧图片宽和高 //右上角位置作为图片的人物的控制点不太合适 //private int X=50,Y=50,W,H; //人物的控制点坐标和宽高 private int X,Y,W,H; public GameView(Context context) { super(context); sfh=getHolder(); sfh.addCallback(this); paint =new Paint(); paint.setAntiAlias(true); //获得焦点 setFocusable(true); setClickable(true); setFocusableInTouchMode(true); //保持屏幕常亮 setKeepScreenOn(true); bmp_enemy=BitmapFactory.decodeResource(getResources(), R.drawable.enemy); W=bmp_enemy.getWidth()/13; H=bmp_enemy.getHeight(); //这里我以单帧图片的中心点为控制点。具体控制点的位置,主要看你的图片了 X=X+W/2; Y=Y+Y/2; } public void draw(Canvas canvas,Paint paint){ /* 第一种绘制方法 */ /* canvas.drawColor(Color.GRAY); //屏幕显示区域 Rect rect_dst=new Rect(X-W/2, Y-H/2, X+W/2, Y+H/2); //图片截取区域 Rect rect_src=new Rect(enemy_start[frame]*W, 0, (enemy_start[frame]+1)*W, H); canvas.drawBitmap(bmp_enemy,rect_src,rect_dst,paint); */ /* 第二种绘制方法 */ canvas.save(); canvas.drawColor(Color.GRAY); //设置可视区域 canvas.clipRect(X-W/2, Y-H/2, X+W/2, Y+H/2); canvas.drawBitmap(bmp_enemy,X-enemy_start[frame]*W-W/2,Y-H/2,paint); canvas.restore(); } public void logic(){ //根据按键状态判断 if(is_up){ Y-=enemy_speed; }else if(is_down){ Y+=enemy_speed; }else if(is_left){ X-=enemy_speed; }else if(is_right){ X+=enemy_speed; } //边界暂时先不判断 if(X<0){ X=0; } if(Y<0){ Y=0; } if(X>screen_width){ X=screen_width; } if(Y>screen_height){ Y=screen_height; } //移动动画帧的处理 if((is_up || is_down||is_left ||is_right)|| frame!=0){ if(frame<2){ frame++; }else{ frame=0; } } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode==KeyEvent.KEYCODE_DPAD_UP){ is_up=true; enemy_start=enemy_up; }else if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN){ is_down=true; enemy_start=enemy_down; }else if(keyCode==KeyEvent.KEYCODE_DPAD_LEFT){ is_left=true; enemy_start=enemy_left; }else if(keyCode==KeyEvent.KEYCODE_DPAD_RIGHT){ is_right=true; enemy_start=enemy_right; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { is_up=false; is_down=false; is_left=false; is_right=false; return super.onKeyUp(keyCode, event); } @Override public void run() { while (run_flag) { try { long startTime=System.currentTimeMillis(); canvas=sfh.lockCanvas(); logic(); draw(canvas, paint); long endTime=System.currentTimeMillis(); long useTime=endTime-startTime; //固定屏幕刷新的时间为50ms if(useTime<50){ Thread.sleep(50-useTime); } } catch (Exception e) { Log.e("Error", "刷屏线程出错了"+e); }finally{ if(canvas!=null){ sfh.unlockCanvasAndPost(canvas); } } } } @Override public void surfaceCreated(SurfaceHolder holder) { screen_width=getWidth(); screen_height=getHeight(); gameThread=new Thread(this); run_flag=true; //启动线程 gameThread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { run_flag=false; try { gameThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {} }
最后源码下载 : http://dl.iteye.com/topics/download/638556d9-97b2-3bd9-a7b7-13588b3eb8b5