android 项目实训——(二)

本文介绍了一个名为SnakeView的游戏视图组件的实现细节。SnakeView继承自TileView,用于展示经典的贪吃蛇游戏,包括游戏状态管理、方向控制、得分计算等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

5、SnakeView

001 package android.basic.lesson48;
002  
003 import java.util.ArrayList;
004 import java.util.Random;
005  
006 import android.content.Context;
007 import android.content.res.Resources;
008 import android.os.Bundle;
009 import android.os.Handler;
010 import android.os.Message;
011 import android.util.AttributeSet;
012 import android.util.Log;
013 import android.view.KeyEvent;
014 import android.view.View;
015 import android.widget.TextView;
016  
017 public class SnakeView extends TileView {
018  
019     private static final String tag = "yao";
020  
021     // 游戏状态,默认值是准备状态
022     private int mMode = READY;
023  
024     // 游戏的四个状态 暂停 准备 运行 和 失败
025     public static final int PAUSE = 0;
026     public static final int READY = 1;
027     public static final int RUNNING = 2;
028     public static final int LOSE = 3;
029  
030     // 游戏中蛇的前进方向,默认值北方
031     private int mDirection = NORTH;
032     // 下一步的移动方向,默认值北方
033     private int mNextDirection = NORTH;
034  
035     // 游戏方向设定 北 南 东 西
036     private static final int NORTH = 1;
037     private static final int SOUTH = 2;
038     private static final int EAST = 3;
039     private static final int WEST = 4;
040  
041     // 三种游戏元�
042     private static final int RED_STAR = 1;
043     private static final int YELLOW_STAR = 2;
044     private static final int GREEN_STAR = 3;
045  
046     // 游戏得分
047     private long mScore = 0;
048  
049     // 移动延迟
050     private long mMoveDelay = 600;
051  
052     // 最后一次移动时的毫秒时刻
053     private long mLastMoveTime;
054  
055     // 显示游戏状态的文本组件
056     private TextView mStatusTextView;
057  
058     // 蛇身数组(数组以坐标对象为元素)
059     private ArrayList mSnakeTrail = new ArrayList();
060  
061     // 苹果数组(数组以坐标对象为元素)
062     private ArrayList mAppleList = new ArrayList();
063  
064     //随机数
065     private static final Random RNG = new Random();
066  
067     //
068     private RefreshHandler mRedrawHandler = new RefreshHandler();
069  
070     //一个Handler
071     class RefreshHandler extends Handler {
072  
073         //处理消息队列
074         @Override
075         public void handleMessage(Message msg) {
076             //更新View对象
077             SnakeView.this.update();
078             //强制重绘
079             SnakeView.this.invalidate();
080             //
081             Log.i(tag, "handleMessage|Thread Name="+Thread.currentThread().getName());
082         }
083  
084         //延迟发送消息
085         public void sleep(long delayMillis) {
086             this.removeMessages(0);
087             Log.i(tag, "sleep|Thread Name="+Thread.currentThread().getName());
088             sendMessageDelayed(obtainMessage(0), delayMillis);
089         }
090     };
091  
092     // 构造函数
093     public SnakeView(Context context, AttributeSet attrs) {
094         super(context, attrs);
095         Log.i(tag, "SnakeView Constructor");
096         // 构造时初始化
097         initSnakeView();
098  
099     }
100  
101     // 初始化
102     private void initSnakeView() {
103  
104         Log.e(tag, "initSnakeView");
105  
106         // 可选焦点
107         setFocusable(true);
108  
109         Resources r = this.getContext().getResources();
110  
111         // 设置贴片图片数组
112         resetTiles(4);
113  
114         // 把三种图片存到Bitmap对象数组
115         loadTile(RED_STAR, r.getDrawable(R.drawable.redstar));
116         loadTile(YELLOW_STAR, r.getDrawable(R.drawable.yellowstar));
117         loadTile(GREEN_STAR, r.getDrawable(R.drawable.greenstar));
118  
119     }
120  
121     // 设置游戏状态
122     public void setMode(int newMode) {
123  
124         // 把当前游戏状态存入oldMode
125         int oldMode = mMode;
126         // 把游戏状态设置为新状态
127         mMode = newMode;
128  
129         Resources res = getContext().getResources();
130         CharSequence str = "";
131  
132         // 如果新状态是运行状态,且原有状态为不运行,那么就开始游戏
133         if (newMode == RUNNING & oldMode != RUNNING) {
134             // 设置mStatusTextView隐藏
135             mStatusTextView.setVisibility(View.INVISIBLE);
136             // 更新
137             update();
138             return;
139         }
140  
141         // 如果新状态是暂停状态,那么设置文本内容为暂停内容
142         if (newMode == PAUSE) {
143             str = res.getText(R.string.mode_pause);
144         }
145  
146         // 如果新状态是准备状态,那么设置文本内容为准备内容
147         if (newMode == READY) {
148             str = res.getText(R.string.mode_ready);
149         }
150  
151         // 如果新状态时失败状态,那么设置文本内容为失败内容
152         if (newMode == LOSE) {
153             // 把上轮的得分显示出来
154             str = res.getString(R.string.mode_lose_prefix) + mScore
155                     + res.getString(R.string.mode_lose_suffix);
156         }
157  
158         // 设置文本
159         mStatusTextView.setText(str);
160         // 显示该View
161         mStatusTextView.setVisibility(View.VISIBLE);
162     }
163  
164     // 设置状态显示View
165     public void setStatusTextView(TextView newView) {
166         mStatusTextView = newView;
167     }
168  
169     // 按键
170     public boolean onKeyDown(int keyCode, KeyEvent msg) {
171  
172         // 向上键
173         if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
174             // 准备状态或者失败状态时
175             if (mMode == READY | mMode == LOSE) {
176                 // 初始化游戏
177                 initNewGame();
178                 // 设置游戏状态为运行
179                 setMode(RUNNING);
180                 // 更新
181                 update();
182                 // 消费掉
183                 return (true);
184             }
185  
186             // 暂停状态时
187             if (mMode == PAUSE) {
188                 // 设置成运行状态
189                 setMode(RUNNING);
190                 update();
191                 // 消费掉
192                 return (true);
193             }
194  
195             // 如果是运行状态时,如果方向原有方向不是向南,那么方向转右
196             if (mDirection != SOUTH) {
197                 mNextDirection = NORTH;
198             }
199             return (true);
200         }
201  
202         // 向下键
203         if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
204             // 原方向不是向上时,方向转右
205             if (mDirection != NORTH) {
206                 mNextDirection = SOUTH;
207             }
208             // 消费掉
209             return (true);
210         }
211  
212         // 向左键
213         if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
214             // 原方向不是向右时,方向转右
215             if (mDirection != EAST) {
216                 mNextDirection = WEST;
217             }
218             // 消费掉
219             return (true);
220         }
221  
222         // 向右键
223         if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
224             // 原方向不是向左时,方向转右
225             if (mDirection != WEST) {
226                 mNextDirection = EAST;
227             }
228             // 消费掉
229             return (true);
230         }
231  
232         // 按其他键时按原有功能返回
233         return super.onKeyDown(keyCode, msg);
234     }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值