开发者社区> JKXQJ> 正文

Android弹球游戏

简介: import java.util.Random; import java.util.Timer; import java.util.TimerTask; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics
+关注继续查看

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
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.view.Display;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.Window;
import android.view.WindowManager;

public class PinBall extends Activity
{
	// 桌面的宽度
	private int tableWidth;
	// 桌面的高度
	private int tableHeight;
	// 球拍的垂直位置
	private int racketY;
	// 下面定义球拍的高度和宽度
	private final int RACKET_HEIGHT = 20;
	private final int RACKET_WIDTH = 70;
	// 小球的大小
	private final int BALL_SIZE = 12;
	// 小球纵向的运行速度
	private int ySpeed = 10;
	Random rand = new Random();
	// 返回一个-0.5~0.5的比率,用于控制小球的运行方向。
	private double xyRate = rand.nextDouble() - 0.5;
	// 小球横向的运行速度
	private int xSpeed = (int) (ySpeed * xyRate * 2);
	// 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;
	@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组件
		final GameView gameView = new GameView(this);
		setContentView(gameView);
		// 获取窗口管理器
		WindowManager windowManager = getWindowManager();
		Display display = windowManager.getDefaultDisplay();
		DisplayMetrics metrics = new DisplayMetrics();
		display.getMetrics(metrics);
		// 获得屏幕宽和高
		tableWidth = metrics.widthPixels;
		tableHeight = metrics.heightPixels;
		racketY = tableHeight - 80;
		final Handler handler = new Handler()
		{
			public void handleMessage(Message msg)
			{
				if (msg.what == 0x123)
				{
					gameView.invalidate();
				}
			}
		};
		gameView.setOnKeyListener(new OnKeyListener() // 
		{
			@Override
			public boolean onKey(View source, int keyCode, KeyEvent event)
			{
				// 获取由哪个键触发的事件
				switch (event.getKeyCode())
				{
					// 控制挡板左移  A左移
					case KeyEvent.KEYCODE_A:
						if (racketX > 0) racketX -= 10;
						break;
					// 控制挡板右移,D右移
					case KeyEvent.KEYCODE_D:
						if (racketX < tableWidth - RACKET_WIDTH) racketX += 10;
						break;
				}
				// 通知gameView组件重绘
				gameView.invalidate();
				return true;
			}
		});
		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);
	}

	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(30);
				canvas.drawText("游戏已结束", 50, 200, paint);
			}
			// 如果游戏还未结束
			else
			{
				// 设置颜色,并绘制小球
				paint.setColor(Color.rgb(240, 240, 80));
				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);
			}
		}
	}
}


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【Android 逆向】逆向修改游戏应用 ( APK 解析工具 | 解包 -> 分析 -> 重打包 -> 签名 流程 )
【Android 逆向】逆向修改游戏应用 ( APK 解析工具 | 解包 -> 分析 -> 重打包 -> 签名 流程 )
437 0
【Android 应用开发】Android游戏音效实现
【Android 应用开发】Android游戏音效实现
84 0
如何用 GPU硬件层加速优化Android系统的游戏流畅度
作为一款VR实时操作游戏App,我们需要根据重力感应系统,实时监控手机的角度,并渲染出相应位置的VR图像,因此在不同 Android 设备之间,由于使用的芯片组和不同架构的GPU,游戏性能会因此受到影响。举例来说:游戏在 Galaxy S20+ 上可能以 60fps 的速度渲染,但它在HUAWEI P50 Pro上的表现可能与前者大相径庭。
242 0
基于Unity3d 引擎的Android游戏优化(续)
VSync Count 垂直同步 中新建一个场景空的时候,帧速率(FPS总是很低),大概在60~70之间。一直不太明白是怎么回事,现在基本上明白了。我在这里解释一下原因,如有错误,欢迎指正。在Unity3D中当运行场景打开Profiler的时候,我们会看到VSync 这一项占了很大的比重。
1252 0
基于Unity3d 引擎的Android游戏优化
更新不透明贴图的压缩格式为ETC 4bit,因为android市场的手机中的GPU有多种,每家的GPU支持不同的压缩格式,但他们都兼容ETC格式, 对于透明贴图,我们只能选择RGBA 16bit 或者RGBA 32bit。
1825 0
Android项目实战(四十一):游戏和视频类型应用 状态栏沉浸式效果
原文:Android项目实战(四十一):游戏和视频类型应用 状态栏沉浸式效果   需求:    手机app ,当打游戏或者全屏看视频的时候会发现这时候手机顶部的状态栏是不显示的,当我们从手机顶端向下进行滑动或手机底端向上滑动的时候,状态栏会显示出来,如果短暂的几秒时间没有操作的话,状态栏会再次隐藏。
927 0
Android项目实战(四十一):游戏和视频类型应用 状态栏沉浸式效果
  需求:    手机app ,当打游戏或者全屏看视频的时候会发现这时候手机顶部的状态栏是不显示的,当我们从手机顶端向下进行滑动或手机底端向上滑动的时候,状态栏会显示出来,如果短暂的几秒时间没有操作的话,状态栏会再次隐藏。
1186 0
Android兼H5游戏SDK开发详解(原创)
本文已独家授权 鸿洋( hongyangAndroid ) 公众号发布!     前不久入职于一家游戏研发公司,公司部门给我的开发需求是研发H5游戏SDK和对接H5渠道SDK(对于只有App研发的我来说,其中经历和酸甜苦辣那可真是一把鼻涕一把泪。
1364 0
+关注
JKXQJ
好好学习,天天向上
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
蚂蚁聚宝Android秒级编译——Freeline
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
相关镜像