植物都处理好了,那接下来先是阳光。
阳光,是由向日葵产生的。所以,我们回到Flower类。这边的话,跟之前的思考方式是一样的,不过加了一个时间的限定,毕竟,阳光产生要冷却的。
private long lastBirthTime;
lastBirthTime = System.currentTimeMillis();
drawSelf方法里添加
if ((System.currentTimeMillis() - lastBirthTime) > 8000) {
lastBirthTime = System.currentTimeMillis();
giveBirth2Sun();
}
然后是
private void giveBirth2Sun() {
GameView.getInstance().giveBirth2Sun(locationX, locationY);
}
回到GameView,这边很简单,新建一个gameLayout3
已经驾轻就熟了
</pre><pre name="code" class="java"><pre name="code" class="java">public void giveBirth2Sun(int locationX, int locationY) {
synchronized (surfaceHolder) {
gamelayout3.add(new Sun(locationX, locationY));
}
}
此时,我们新建Sun类(别忘了全局静态变量的配置和图片资源的配置)
Sun类,想一想,继承BaseModel,接口TouchAble
这里呢,我们用到了枚举Enum
关于Enum
1
2
3
4
5
6
|
enum weekday{sun,mon,tue,wed,thu,fri,sat};
enum weekdaya,b,c;
//或者为:
enum weekday{sun,mon,tue,wed,thu,fri,sat}a,b,c;
//或者为:
enum {sun,mon,tue,wed,thu,fri,sat}a,b,c;
|
public enum SunState {
SHOW, MOVE
}
先来看构造方法,跟之前卡片的有些类似,只是这个时候需将sunstate对象设置为SHOW
public Sun(int locationX, int locationY) {
this.locationX = locationX;
this.locationY = locationY;
touchArea = new Rect(locationX, locationY, locationX
+ Config.sun.getWidth(), locationY + Config.sun.getHeight());
lastBirthTime = System.currentTimeMillis();
state = SunState.SHOW;
isAlive = true;
}
我们先从SHOW状态入手
drawSelf方法
public void drawself(Canvas canvas, Paint paint) {
if (isAlive) {
if (state == SunState.SHOW) {
if ((System.currentTimeMillis()-lastBirthTime)>5000) {
isAlive=false;
}
}
canvas.drawBitmap(Config.sun, locationX, locationY, paint);
}
这边呢,给了一个额外的判定,就是阳光存在5s就会消失(不然你不点,阳光会重复产生的)
onTouch方法
public boolean onTouch(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if (touchArea.contains(x, y)) {
state = SunState.MOVE;
xWayDistance = locationX - Config.sunDisapperX;
yWayDistance = locationY - 0;
xSpeed = xWayDistance / 10f;
ySpeed = yWayDistance / 10f;
}
return false;
}
这边就涉及到状态的转换了,点击事件触发了,阳光就切换成了MOVE状态。并自动的计算出了距离(消失处),然后算出速度(这里的sunDisappearX是不是很眼熟呢?这是之前设置好的阳光消失的位置)
自然地,在drawSelf方法里添上对应的方法
else {
locationX-=xSpeed;
locationY-=ySpeed;
if (locationY<=0) {
isAlive=false;
}
}
与if形成对应关系
接下来就写僵尸了。为了让僵尸的产生与阳光的产生显得更相似一些,我们先来创建一个ZombieManager,继承BaseModel。里面的方法与Flower的差不多,但是不涉及显示自身的一些参数(你是看不到生僵尸的XX的)
public class ZombieManager extends BaseModel {
private boolean isAlive;
private long lastBirthTime;
public ZombieManager() {
isAlive = true;
lastBirthTime=System.currentTimeMillis();
}
@Override
public void drawself(Canvas canvas, Paint paint) {
if ((System.currentTimeMillis()-lastBirthTime)>8000) {
lastBirthTime=System.currentTimeMillis();
giveBirth2Zombie();
}
}
private void giveBirth2Zombie() {
GameView.getInstance().apply4AddZombie();
}
}
回到GameView,写apply4AddZombie方法。记得先新建ZombieManager的实例,并在ondraw方法里写入 对象.drawSelf,不然可是不会产生僵尸的(这个地方我总是忘记,总是出不来僵尸)
接下来开始写apply4AddZombie方法
public void apply4AddZombie() {
synchronized (surfaceHolder) {
int raceWay = 0;
raceWay = (int) (Math.random() * 5);
switch (raceWay) {
case 0:
gameLayout4Zombie0.add(new Zombie(Config.DeviceWidth,
Config.raceWayPointY[0] - Config.heightDistanceLong,
raceWay));
break;
case 1:
gameLayout4Zombie1.add(new Zombie(Config.DeviceWidth,
Config.raceWayPointY[1] - Config.heightDistanceLong,
raceWay));
break;
这边,利用Math.random方法来产生随机数,记得强转类型(这边我用的是5而不是4,因为3~3.99都会因为强转变成3,蛋疼的4实在是几乎出不来)
接下来,我们写Zombie类,这个跟之前的植物是一样的。不多说,就是加了个速度。画的时候不断更新就好
public void drawself(Canvas canvas, Paint paint) {
if (isAlive) {
canvas.drawBitmap(Config.zombieMoveFrames[frames], locationX,
locationY, paint);
frames = (++frames) % 29;
locationX -= xSpeed;
}
}
这样,僵尸也画好了
最后,开始写碰撞了
还是在Zombie类
checkCollision();
drawSelf里,只要isAlive==true;
每次判断是否发生碰撞
private void checkCollision() {
GameView.getInstance().checkCollision(this, raceWay);
}
这个时候,我们忘了一件事。对,在Flower,Pea,以及Zombie中重写getModelWidth方法
public int getModelWidth() {
return Config.zombieMoveFrames[0].getWidth();
}
另外两个同理
好了,同样的,回到GameView。
public void checkCollision(Zombie zombie, int raceWay) {
synchronized (surfaceHolder) {
switch (raceWay) {
case 0:
for (BaseModel model : gameLayout4plant0) {
if (Math.abs((model.getLocationX() + model.getModelWidth() / 2)
- (zombie.getLocationX() + zombie.getModelWidth() / 2)) < (model
.getModelWidth() + zombie.getModelWidth()) / 3) {
if (model instanceof Plant) {
model.setAlive(false);
} else {
zombie.setAlive(false);
}
}
}
break;
剩下的几层是一样的。这边呢,是根据raceWay来判断的,首先你需要确定僵尸产生的跑到位置。然后遍历这一层上的植物(给植物分5个layout就是这个原因) 接下来就是矩形检测了,这边的意思就是两个矩形的X轴中点位置相减比两个矩形的宽之和的三分之一小就算发生碰撞。(还是比较好理解的) 判断,是植物的话,就让植物死亡。否则,僵尸死亡(豌豆威力有点大

至此,就结束了。总之,这个教程给的还不够完善,因为还有许多可以改进的地方。不过已经3点半了,没想到打个总结打了这么久。睡醒了,明天继续在上面添加一些有意思的内容。附件呢,还是传一下吧。
还有,就是学到了几个使用eclipse的小技巧:
(1)用LogCat调试时,在发生问题非预期情况而又不失error时,可以通过在某些地方加Log.i(String Tag,String Message)并在Filter里设置好你所想输出的Tag来检查情况(不设Filter的话就怕乱七八糟的内容太多,反正我是绝大多数看不懂)
(2)ctrl+o可以快速调出查找(可以快速切换至该类的方法或参数的一行),真方便
(3)选中某个类或者变量之类的,按ctrl+alt+H,可以调出被调用的关系(这个我也不知道到底是什么,就这么叫吧),在关系复杂的时候,用这个真的很自然地就能理好顺序了
以上,纯属一个小白的个人理解,有不对的地方,还请大拿不吝赐教。
好吧,附件上传不了,太大了
http://pan.baidu.com/s/18Phs6(百度网盘)