Android平台2D游戏简单实例
fmms
13年前
基于Android平台开发小游戏的首次尝试,通过自己设计的简易android框架,实现的简单2D壁球游戏。 <pre class="brush:java; toolbar: true; auto-links: false;">package com.tabletennis.main; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Resources; 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.graphics.Typeface; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View; public class MySurfaceView extends SurfaceView implements Callback,Runnable { private SurfaceHolder sfh; private Thread th; private Canvas canvas; private Paint paint; private int ScreenW,ScreenH; //ball informationetContentView private int moveSpeedX=10; private int moveSpeedY=10; private int tempSpeedX=moveSpeedX; private int tempSpeedY=moveSpeedY; private int head_left=21; private int head_top=41; private int radius=10;//半径 private int ball_score=100; //Bat information private int bat_left=10; private int bat_right=10; private int bat_width=55; private int bat_ply=5; private int bat_move_speed=16; private int ball_color=Color.WHITE; //Process information private int refresh_circle_time=50; //Game status private int score=0; private int score_count=0; private double time=0.0; private boolean show_score=false; private int game_status=GameStatus.GAME_READY; private int chances=0; //Window variabele int off_count=1; private Activity main_activity; public MySurfaceView(Context context) { super(context); // TODO Auto-generated constructor stub main_activity=(Activity) context; sfh = this.getHolder(); sfh.addCallback(this); paint=new Paint(); paint.setAntiAlias(true); paint.setColor(Color.WHITE); paint.setTextSize(16); this.setKeepScreenOn(true);// 保持屏幕常亮 setFocusable(true); th=new Thread(this); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if(game_status==GameStatus.GAME_NEW){ if(keyCode==KeyEvent.KEYCODE_DPAD_UP){ game_status=GameStatus.GAME_READY; drawReadyWindow(); } } if(game_status==GameStatus.GAME_OVER){ if(keyCode==KeyEvent.KEYCODE_DPAD_UP){ init_game_data(); game_status=GameStatus.GAME_READY; drawReadyWindow(); } } if(game_status==GameStatus.GAME_PAUSED){ //drawPausedWindow(); /* * 显示快捷键菜单,并提示游戏已经ready * */ if(keyCode==KeyEvent.KEYCODE_DPAD_RIGHT||keyCode==KeyEvent.KEYCODE_DPAD_LEFT||keyCode==KeyEvent.KEYCODE_DPAD_DOWN){ game_status=GameStatus.GAME_ON; }else if(keyCode==KeyEvent.KEYCODE_DPAD_UP){ init_game_data(); drawReadyWindow(); game_status=GameStatus.GAME_READY; } } if(game_status==GameStatus.GAME_READY){ //drawPausedWindow(); /* * 显示快捷键菜单,并提示游戏已经ready */ if(keyCode==KeyEvent.KEYCODE_DPAD_RIGHT||keyCode==KeyEvent.KEYCODE_DPAD_LEFT){ game_status=GameStatus.GAME_ON; }else if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN){ game_status=GameStatus.GAME_OFF; }; } if(game_status==GameStatus.GAME_ON){ if(keyCode==KeyEvent.KEYCODE_DPAD_RIGHT){ if(bat_left+bat_width<ScreenW-5){ bat_left+=bat_move_speed; bat_right=ScreenW-bat_left; } }else if(keyCode==KeyEvent.KEYCODE_DPAD_LEFT){ if(bat_left>5){ bat_left-=bat_move_speed; bat_right=ScreenW-bat_left; } }else if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN){ game_status=GameStatus.GAME_PAUSED; } } return super.onKeyDown(keyCode, event); } private void drawRectFrame(Canvas canvas,Paint paint,int margin_left,int margin_right,int margin_top,int margin_bottom){ canvas.drawLine(margin_left, margin_top, margin_left,ScreenH-margin_bottom, paint); canvas.drawLine(margin_left,margin_top,ScreenW-margin_right,margin_top,paint); canvas.drawLine(ScreenW-margin_right,ScreenH-margin_bottom,ScreenW-margin_right,margin_top,paint); canvas.drawLine(margin_left,ScreenH-margin_bottom,ScreenW-margin_right,ScreenH-margin_bottom,paint); } private void drawGameMonitor(Canvas canvas,Paint paint){ paint.setColor(Color.WHITE); drawRectFrame(canvas,paint,10,10,ScreenH-40,10); paint.setTextSize(18); canvas.drawText("Time:"+(int)time, 20,ScreenH-20 , paint); canvas.drawText("Score:"+score, 110,ScreenH-20 , paint); canvas.drawText("Chances: "+chances, 200,ScreenH-20 , paint); paint.setTextSize(16); } private void drawMainWindow(){ try{ canvas=sfh.lockCanvas(); Paint ball_paint=new Paint(); ball_paint.setAntiAlias(true); ball_paint.setColor(ball_color); canvas.drawColor(Color.DKGRAY); canvas.drawLine(0,0,ScreenW/5-20,ScreenH/5-20,ball_paint); canvas.drawLine(ScreenW,0,4*ScreenW/5+20,ScreenH/5-20,ball_paint); canvas.drawLine(ScreenW/5-20,ScreenH/5-20,4*ScreenW/5+20,ScreenH/5-20,ball_paint); canvas.drawLine(ScreenW/5-20,ScreenH/5-20,0,ScreenH,ball_paint); canvas.drawLine(ScreenW*4/5+20,ScreenH/5-20,ScreenW,ScreenH,ball_paint); canvas.drawCircle(head_left, head_top, radius, ball_paint); canvas.drawRect(bat_left,ScreenH-bat_ply-100,bat_left+bat_width,ScreenH-90, paint); paint.setColor(Color.RED); canvas.drawLine(0, ScreenH-bat_ply-100, ScreenW, ScreenH-bat_ply-100, paint); drawGameMonitor(canvas,paint); paint.setColor(Color.RED); //canvas.drawLine(0, ScreenH-92, ScreenW, ScreenH-92, paint); head_left+=moveSpeedX; head_top+=moveSpeedY; paint.setColor(Color.WHITE); if(show_score){ ball_paint.setTextSize(50); canvas.drawText("+"+ball_score, ScreenW/2-50, ScreenH/2, ball_paint); } //paint.setColor(Color.WHITE); if(head_left>=ScreenW-2*radius-20){ //Right edge moveSpeedX*=-1; show_score=false; head_left=ScreenW-2*radius-20; } if(head_left<=20){ //Left edge moveSpeedX*=-1; show_score=false; head_left=20; } if(head_top<=40){ //Top edge moveSpeedY*=-1; randomBallData(); show_score=false; head_top=40; } if(head_top>=ScreenH-2*radius-100){ float ball_current_pos=(float)(head_left+radius); if(ball_current_pos>=bat_left&&ball_current_pos<=bat_left+bat_width){ tempSpeedX=moveSpeedX; tempSpeedY=moveSpeedY; moveSpeedY*=-1; score+=ball_score; show_score=true; score_count=100; }else{ chances--; if(chances>0){ game_status=GameStatus.GAME_CHANCES; head_left=(int)(Math.random()*ScreenW-2*radius-20); head_top=41; if(head_left<=20){ head_left=21; } randomBallData(); }else game_status=GameStatus.GAME_OVER; } } }catch(Exception e){ e.printStackTrace(); }finally{ if(canvas!=null){ sfh.unlockCanvasAndPost(canvas); } } } private void drawPausedWindow() { // TODO Auto-generated method stub try{ canvas=sfh.lockCanvas(); paint.setColor(Color.WHITE); canvas.drawColor(Color.DKGRAY); drawRectFrame(canvas,paint,50,50,100,220); Paint title_paint=new Paint(); title_paint.setTextSize(20); title_paint.setAntiAlias(true); title_paint.setColor(Color.YELLOW); canvas.drawText("Game is paused!",78, 160, title_paint); canvas.drawText("Press any key to continue", 70, 200, paint); }catch(Exception e){ e.printStackTrace(); }finally{ if(canvas!=null){ sfh.unlockCanvasAndPost(canvas); } } } private void drawReadyWindow(){ // TODO Auto-generated method stub try{ canvas=sfh.lockCanvas(); paint.setColor(Color.WHITE); canvas.drawColor(Color.DKGRAY); Paint title_paint=new Paint(); //canvas.drawRect(50, 100, 200, 200, paint); drawRectFrame(canvas,paint,10,10,10,10); //drawRectFrame(canvas,paint,20,20,20,20); canvas.drawText("WELCOME TO PAY MY GAME", 50, 100, paint); canvas.drawText("------Copyright by Skyrain-------", 42, 300, paint); title_paint.setTextSize(35); title_paint.setAntiAlias(true); title_paint.setColor(Color.WHITE); title_paint.setTypeface(Typeface.SANS_SERIF); canvas.drawText("Tennis Game", 55, 250, title_paint); Resources res=getResources(); Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.icon); canvas.drawBitmap(bmp, 120,150, title_paint); paint.setTextSize(10); canvas.drawText("************************", 80, 350, paint); canvas.drawText("* [Left]or[Right]: Start/Move", 80, 365, paint); canvas.drawText("*", 220, 365, paint); canvas.drawText("* [Down]: Exit", 80, 380, paint); canvas.drawText("*", 220, 380, paint); canvas.drawText("************************", 80, 395, paint); //Thread.sleep(3000); //game_status=GameStatus.GAME_READY; paint.setTextSize(16); }catch(Exception e){ e.printStackTrace(); }finally{ if(canvas!=null){ sfh.unlockCanvasAndPost(canvas); } } } private void drawOffWindow() { // TODO Auto-generated method stub if(off_count==7){ main_activity.finish(); } try{ canvas=sfh.lockCanvas(); paint.setColor(Color.WHITE); canvas.drawColor(Color.DKGRAY); drawRectFrame(canvas,paint,50,50,100,250); Paint title_paint=new Paint(); title_paint.setTextSize(20); title_paint.setAntiAlias(true); title_paint.setColor(Color.RED); canvas.drawText("Game is Exiting", 93, 140, title_paint); title_paint.setColor(Color.GREEN); for(int i=0;i<off_count;i++){ canvas.drawCircle(80+i*28, 160, 5, title_paint); } off_count++; }catch(Exception e){ e.printStackTrace(); }finally{ if(canvas!=null){ sfh.unlockCanvasAndPost(canvas); } } } private void drawOverWindow() { // TODO Auto-generated method stub try{ canvas=sfh.lockCanvas(); paint.setColor(Color.WHITE); canvas.drawColor(Color.DKGRAY); drawRectFrame(canvas,paint,50,50,100,200); Paint title_paint=new Paint(); title_paint.setTextSize(20); title_paint.setAntiAlias(true); title_paint.setColor(Color.YELLOW); canvas.drawText("Your Total Score", 90, 140, title_paint); //canvas.drawText("[YOUR SCORE]: 0000", 100, 150, paint); //paint.setColor(Color.RED); //canvas.drawText("[score] ", 130, 170, paint); title_paint.setTextSize(43); title_paint.setColor(Color.RED); canvas.drawText(""+score, 120, 195, title_paint); paint.setColor(Color.WHITE); canvas.drawText("Press [UP] to continue", 80, 230, paint); }catch(Exception e){ e.printStackTrace(); }finally{ if(canvas!=null){ sfh.unlockCanvasAndPost(canvas); } } } private void drawChancesWindow() { // TODO Auto-generated method stub try{ canvas=sfh.lockCanvas(); paint.setColor(Color.WHITE); canvas.drawColor(Color.DKGRAY); drawRectFrame(canvas,paint,15,15,120,200); Paint title_paint=new Paint(); title_paint.setTextSize(20); title_paint.setAntiAlias(true); title_paint.setColor(Color.YELLOW); canvas.drawText("You have chances left!", 35, 210, title_paint); title_paint.setTextSize(50); title_paint.setColor(Color.RED); canvas.drawText(""+chances,130,220,title_paint); }catch(Exception e){ e.printStackTrace(); }finally{ if(canvas!=null){ sfh.unlockCanvasAndPost(canvas); } } } private void init_game_data() { // TODO Auto-generated method stub head_left=(int)(Math.random()*ScreenW-2*radius-20); head_top=41; if(head_left<=20){ head_left=21; } randomBallData(); bat_left=ScreenW/2; score=0; chances=3; } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { // TODO Auto-generated method stub return super.onKeyUp(keyCode, event); } public void draw() throws InterruptedException{ if(game_status==GameStatus.GAME_ON){ drawMainWindow(); }else if(game_status==GameStatus.GAME_OVER){ drawOverWindow(); }else if(game_status==GameStatus.GAME_PAUSED){ drawPausedWindow(); }else if(game_status==GameStatus.GAME_OFF){ drawOffWindow(); try { Thread.sleep(500); //main_activity.finish(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else if(game_status==GameStatus.GAME_CHANCES){ drawChancesWindow(); Thread.sleep(2000); game_status=GameStatus.GAME_ON; } } @Override public void run() { // TODO Auto-generated method stub while(true){ time+=0.1; try{ draw(); Thread.sleep(refresh_circle_time); //Thread.sleep(100000); }catch(InterruptedException e){ e.printStackTrace(); } } } private void randomBallData(){ int x=moveSpeedX/Math.abs(moveSpeedX); int y=moveSpeedY/Math.abs(moveSpeedY); ball_score=(int)(Math.random()*100); if(ball_score==0){ ball_score=100; } if(ball_score<30){ ball_color=Color.LTGRAY; moveSpeedX=12; moveSpeedY=12; }else if(ball_score>=30&&ball_score<50){ ball_color=Color.WHITE; moveSpeedX=14; moveSpeedY=14; }else if(ball_score>=50&&ball_score<70){ ball_color=Color.YELLOW; moveSpeedX=16; moveSpeedY=16; }else if(ball_score>=70&&ball_score<90){ ball_color=Color.BLUE; moveSpeedX=18; moveSpeedY=18; }else if(ball_score>=90&&ball_score<=100){ ball_color=Color.RED; moveSpeedX=20; moveSpeedY=20; } moveSpeedX*=x; moveSpeedY*=y; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub init_game_data(); ScreenW=this.getWidth(); ScreenH=this.getHeight(); head_left=21; head_top=41; bat_left=21; bat_right=ScreenW-bat_left; drawReadyWindow(); th.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } }</pre>