Android 弹球游戏
16lz
2021-01-23
本文内容摘自《疯狂Android讲义 第3版》李刚 著
package shortcut.song.com.myapplication;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.DisplayMetrics;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 PinBallActivity extends AppCompatActivity { private int tableWidth; //桌面宽度; private int tableHeight; //桌面高度 private int racketY; //球拍的垂直位置; //球拍的高宽 private final int RACKET_WIDTH = 90; private final int RACKET_HEIGHT = 30; //球的大小 private final int BALL_SIZE = 16; //小球运动的速度 private int ySpeed = 15; Random random = new Random(); //返回一个-0.5 ~ 0.5的比率,用于控制小球的运动方向; private double xyRate = random.nextDouble() - 0.5; //小球横向运动速度 private int xSpeed = (int)(ySpeed * xyRate * 2); //小球的座标 private int ballX = random.nextInt(200) + 20; private int ballY = random.nextInt(10) + 20; //球拍的水平位置 private int racketX = random.nextInt(200); private boolean isLose = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //去掉窗口标题 requestWindowFeature(Window.FEATURE_NO_TITLE); //设置全屏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); final GameView gameView = new GameView(this); setContentView(gameView); WindowManager windowManager = getWindowManager(); Display display = windowManager.getDefaultDisplay(); DisplayMetrics displayMetrics = new DisplayMetrics(); display.getMetrics(displayMetrics); //获得屏幕宽高 tableHeight = displayMetrics.heightPixels; tableWidth = displayMetrics.widthPixels; racketY = tableHeight - 80; final Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what == 0x1234){ gameView.invalidate(); } } }; gameView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { switch(event.getKeyCode()) { case KeyEvent.KEYCODE_A: if (racketX > 0) racketX -= 10; break; case KeyEvent.KEYCODE_D: if (racketX < tableWidth - RACKET_WIDTH) racketX += 10; break; } gameView.invalidate(); return false; } }); 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(); isLose = true; } else if (ballY <= 0 || (ballY >= racketY - BALL_SIZE && ballX > racketX && ballX <= racketX + RACKET_WIDTH)) { ySpeed = -ySpeed; } //小球座标增加 ballX += xSpeed; ballY += ySpeed; //发送消息,通知重绘组件 handler.sendEmptyMessage(0x1234); } }, 0, 100); } class GameView extends View{ Paint paint = new Paint(); public GameView(Context context){ super(context); setFocusable(true); } @Override protected void onDraw(Canvas canvas) { paint.setStyle(Paint.Style.FILL); paint.setAntiAlias(true); if(isLose){ paint.setColor(Color.RED); paint.setTextSize(40); canvas.drawText("Game Over!",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); } super.onDraw(canvas); } }}
运行效果: