读书人

小弟我的Android进阶之旅-gt;Android疯狂

发布时间: 2013-11-04 16:56:03 作者: rapoo

我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)

正如在《我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)》一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piece对象时,程序会直接调用ImageUtil的getPlayImages()方法去获取图片,该方法会随机从res/drawable目录中取得N张图片。

下面是res/drawable目录视图:

小弟我的Android进阶之旅->Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)

为了让getPlayImages()方法能随机从res/drawable目录中取得N张图片,具体实现分为以下几步:

    通过反射来获取R.drawable的所有Field(Android的每张图片资源都会自动转换为R.drawable的静态Field),并将这些Field值添加到一个List集合中。从第一步得到的List集合中随机“抽取”N/2个图片ID。将第二步得到的N/2个图片ID全部复制一份,这样就得到了N个图片ID,而且每个图片ID都可以找到与之配对的。将第三步得到的N个图片ID再次“随机打乱”,并根据图片ID加载相应的Bitmap对象,最后把图片ID及对应的Bitmap封装成PieceImage对象后返回。
下面是ImageUtil类的代码:cn\oyp\link\utils\ImageUtil.java
package cn.oyp.link;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.os.Vibrator;import android.view.MotionEvent;import android.view.View;import android.widget.Button;import android.widget.TextView;import cn.oyp.link.board.GameService;import cn.oyp.link.board.impl.GameServiceImpl;import cn.oyp.link.utils.GameConf;import cn.oyp.link.utils.LinkInfo;import cn.oyp.link.view.GameView;import cn.oyp.link.view.Piece;/** * 游戏Activity <br/> * <br/> * 关于本代码介绍可以参考一下博客: <a href="http://blog.csdn.net/ouyang_peng">欧阳鹏的CSDN博客</a> <br/> */public class LinkActivity extends Activity {/** * 游戏配置对象 */private GameConf config;/** * 游戏业务逻辑接口 */private GameService gameService;/** * 游戏界面 */private GameView gameView;/** * 开始按钮 */private Button startButton;/** * 记录剩余时间的TextView */private TextView timeTextView;/** * 失败后弹出的对话框 */private AlertDialog.Builder lostDialog;/** * 游戏胜利后的对话框 */private AlertDialog.Builder successDialog;/** * 定时器 */private Timer timer = new Timer();/** * 记录游戏的剩余时间 */private int gameTime;/** * 记录是否处于游戏状态 */private boolean isPlaying;/** * 振动处理类 */private Vibrator vibrator;/** * 记录已经选中的方块 */private Piece selectedPiece = null;/** * Handler类,异步处理 */private Handler handler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case 0x123:timeTextView.setText("剩余时间: " + gameTime);gameTime--; // 游戏剩余时间减少// 时间小于0, 游戏失败if (gameTime < 0) {// 停止计时stopTimer();// 更改游戏的状态isPlaying = false;// 失败后弹出对话框lostDialog.show();return;}break;}}};@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);// 初始化界面init();}/** * 初始化游戏的方法 */private void init() {config = new GameConf(8, 9, 2, 10, GameConf.DEFAULT_TIME, this);// 得到游戏区域对象gameView = (GameView) findViewById(R.id.gameView);// 获取显示剩余时间的文本框timeTextView = (TextView) findViewById(R.id.timeText);// 获取开始按钮startButton = (Button) this.findViewById(R.id.startButton);// 获取振动器vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);// 初始化游戏业务逻辑接口gameService = new GameServiceImpl(this.config);// 设置游戏逻辑的实现类gameView.setGameService(gameService);// 为开始按钮的单击事件绑定事件监听器startButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View source) {startGame(GameConf.DEFAULT_TIME);}});// 为游戏区域的触碰事件绑定监听器this.gameView.setOnTouchListener(new View.OnTouchListener() {public boolean onTouch(View view, MotionEvent e) {if (e.getAction() == MotionEvent.ACTION_DOWN) {gameViewTouchDown(e);}if (e.getAction() == MotionEvent.ACTION_UP) {gameViewTouchUp(e);}return true;}});// 初始化游戏失败的对话框lostDialog = createDialog("Lost", "游戏失败! 重新开始", R.drawable.lost).setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {startGame(GameConf.DEFAULT_TIME);}});// 初始化游戏胜利的对话框successDialog = createDialog("Success", "游戏胜利! 重新开始",R.drawable.success).setPositiveButton("确定",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {startGame(GameConf.DEFAULT_TIME);}});}@Overrideprotected void onPause() {// 暂停游戏stopTimer();super.onPause();}@Overrideprotected void onResume() {// 如果处于游戏状态中if (isPlaying) {// 以剩余时间重新开始游戏startGame(gameTime);}super.onResume();}/** * 触碰游戏区域的处理方法 *  * @param event */private void gameViewTouchDown(MotionEvent event) {// 获取GameServiceImpl中的Piece[][]数组Piece[][] pieces = gameService.getPieces();// 获取用户点击的x座标float touchX = event.getX();// 获取用户点击的y座标float touchY = event.getY();// 根据用户触碰的座标得到对应的Piece对象Piece currentPiece = gameService.findPiece(touchX, touchY);// 如果没有选中任何Piece对象(即鼠标点击的地方没有图片), 不再往下执行if (currentPiece == null)return;// 将gameView中的选中方块设为当前方块this.gameView.setSelectedPiece(currentPiece);// 表示之前没有选中任何一个Pieceif (this.selectedPiece == null) {// 将当前方块设为已选中的方块, 重新将GamePanel绘制, 并不再往下执行this.selectedPiece = currentPiece;this.gameView.postInvalidate();return;}// 表示之前已经选择了一个if (this.selectedPiece != null) {// 在这里就要对currentPiece和prePiece进行判断并进行连接LinkInfo linkInfo = this.gameService.link(this.selectedPiece,currentPiece);// 两个Piece不可连, linkInfo为nullif (linkInfo == null) {// 如果连接不成功, 将当前方块设为选中方块this.selectedPiece = currentPiece;this.gameView.postInvalidate();} else {// 处理成功连接handleSuccessLink(linkInfo, this.selectedPiece, currentPiece,pieces);}}}/** * 触碰游戏区域的处理方法 *  * @param e */private void gameViewTouchUp(MotionEvent e) {this.gameView.postInvalidate();}/** * 以gameTime作为剩余时间开始或恢复游戏 *  * @param gameTime *            剩余时间 */private void startGame(int gameTime) {// 如果之前的timer还未取消,取消timerif (this.timer != null) {stopTimer();}// 重新设置游戏时间this.gameTime = gameTime;// 如果游戏剩余时间与总游戏时间相等,即为重新开始新游戏if (gameTime == GameConf.DEFAULT_TIME) {// 开始新的游戏游戏gameView.startGame();}isPlaying = true;this.timer = new Timer();// 启动计时器 , 每隔1秒发送一次消息this.timer.schedule(new TimerTask() {public void run() {handler.sendEmptyMessage(0x123);}}, 0, 1000);// 将选中方块设为null。this.selectedPiece = null;}/** * 成功连接后处理 *  * @param linkInfo *            连接信息 * @param prePiece *            前一个选中方块 * @param currentPiece *            当前选择方块 * @param pieces *            系统中还剩的全部方块 */private void handleSuccessLink(LinkInfo linkInfo, Piece prePiece,Piece currentPiece, Piece[][] pieces) {// 它们可以相连, 让GamePanel处理LinkInfothis.gameView.setLinkInfo(linkInfo);// 将gameView中的选中方块设为nullthis.gameView.setSelectedPiece(null);this.gameView.postInvalidate();// 将两个Piece对象从数组中删除pieces[prePiece.getIndexX()][prePiece.getIndexY()] = null;pieces[currentPiece.getIndexX()][currentPiece.getIndexY()] = null;// 将选中的方块设置null。this.selectedPiece = null;// 手机振动(100毫秒)this.vibrator.vibrate(100);// 判断是否还有剩下的方块, 如果没有, 游戏胜利if (!this.gameService.hasPieces()) {// 游戏胜利this.successDialog.show();// 停止定时器stopTimer();// 更改游戏状态isPlaying = false;}}/** * 创建对话框的工具方法 *  * @param title *            标题 * @param message *            内容 * @param imageResource *            图片 * @return */private AlertDialog.Builder createDialog(String title, String message,int imageResource) {return new AlertDialog.Builder(this).setTitle(title).setMessage(message).setIcon(imageResource);}/** * 停止计时 */private void stopTimer() {// 停止定时器this.timer.cancel();this.timer = null;}}

该Activity用了两个类,这两个类在下一篇博客中再进行相关描述。
    GameConf:负责管理游戏的初始化设置信息。GameService:负责游戏的逻辑实现。

关于具体的实现步骤,请参考下面的链接:

读书人网 >Android

热点推荐