一個簡單的彈球遊戲
阿新 • • 發佈:2019-01-09
主要程式脫胎於瘋狂android講義第三版第七章page349
就是用畫板劃出圓球和球拍,並不斷改變座標然後通知重繪,程式碼如下
package org.crazyit.image; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; import java.util.Random; import java.util.Timer; import java.util.TimerTask; public class MainActivity extends Activity { // 桌面的寬度 private int tableWidth; // 桌面的高度 private int tableHeight; // 球拍的垂直位置 private int racketY; // 下面定義球拍的高度和寬度 private final int RACKET_HEIGHT = 40; private final int RACKET_WIDTH = 180; // 小球的大小 private final int BALL_SIZE = 16; // 小球縱向的執行速度 private int ySpeed = 60; Random rand = new Random(); // 返回一個-0.5~0.5的比率,用於控制小球的執行方向 private double xyRate = rand.nextDouble()-0.5; // 小球橫向的執行速度 private int xSpeed = (int)( ySpeed*xyRate*4 ); // ballX和ballY代表小球的座標 private int ballX = rand.nextInt(200)+20; private int ballY = rand.nextInt(10)+20; // racketX代表球拍的水平位置 private int racketX = rand.nextInt(200); // 遊戲是否結束的旗標 private boolean isLose = false; private GameView mGameView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 去掉視窗標題 requestWindowFeature(Window.FEATURE_NO_TITLE); // 全屏顯示 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 建立GameView元件 mGameView = new GameView(this); setContentView(mGameView); // 獲取視窗管理器 WindowManager windowManager = getWindowManager(); Display display = windowManager.getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); display.getMetrics(metrics); // 獲得螢幕寬和高 tableWidth = metrics.widthPixels; tableHeight = metrics.heightPixels; racketY = tableHeight-300; final Handler handler = new Handler() { public void handleMessage(Message msg) { if(msg.what == 0x123) { mGameView.invalidate(); } } }; final Timer timer = new Timer(); timer.schedule(new TimerTask() // ① { @Override public void run() { // 如果小球碰到左邊邊框 if(ballX<=0 || ballX>=tableWidth-BALL_SIZE) { xSpeed = -xSpeed; } // 如果小球高度超出了球拍位置,且橫向不在球拍範圍之內,遊戲結束 if(ballY>=racketY-BALL_SIZE && ( ballX<racketX || ballX>racketX+RACKET_WIDTH )) { timer.cancel(); // 設定遊戲是否結束的旗標為true isLose = true; } // 如果小球位於球拍之內,且到達球拍位置,小球反彈 else if(ballY<=0 || ( ballY>=racketY-BALL_SIZE && ballX>racketX && ballX<=racketX+RACKET_WIDTH )) { ySpeed = -ySpeed; } // 小球座標增加 ballY += ySpeed; ballX += xSpeed; // 傳送訊息,通知系統重繪元件 handler.sendEmptyMessage(0x123); } }, 0, 100); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) { // 獲取由哪個鍵觸發的事件 switch(event.getKeyCode()) { // 控制擋板左移 case KeyEvent.KEYCODE_VOLUME_UP: if(racketX>0) { racketX -= 10; } Log.e("-=-=", "方法被執行"); break; // 控制擋板右移 case KeyEvent.KEYCODE_VOLUME_DOWN: if(racketX<tableWidth-RACKET_WIDTH) { racketX += 10; } break; } // 通知gameView元件重繪 mGameView.invalidate(); return true; }else { return super.onKeyDown(keyCode, event); } } @Override public boolean onTouchEvent(MotionEvent event) { racketX = (int)event.getX()-60; mGameView.invalidate(); return true; } class GameView extends View { Paint paint = new Paint(); public GameView(Context context) { super(context); setFocusable(true); } // 重寫View的onDraw方法,實現繪畫 public void onDraw(Canvas canvas) { paint.setStyle(Paint.Style.FILL); // 設定去鋸齒 paint.setAntiAlias(true); // 如果遊戲已經結束 if(isLose) { paint.setColor(Color.RED); paint.setTextSize(40); canvas.drawText("遊戲已結束", tableWidth/2-100, 200, paint); } // 如果遊戲還未結束 else { // 設定顏色,並繪製小球 paint.setColor(Color.rgb(255, 0, 0)); canvas.drawCircle(ballX, ballY, BALL_SIZE, paint); // 設定顏色,並繪製球拍 paint.setColor(Color.rgb(80, 80, 200)); canvas.drawRect(racketX, racketY, racketX+RACKET_WIDTH, racketY+RACKET_HEIGHT, paint); } } } }