Android植物大战僵尸教程学习总结(三)

植物都处理好了,那接下来先是阳光。

阳光,是由向日葵产生的。所以,我们回到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. 枚举类型定义的一般形式为:
enum 枚举名{ 枚举值表 };
枚举值表中应罗列出所有可用值。这些值也称为枚举元素。
例如:
该枚举名为weekday,枚举值共有7个,即一周中的七天。凡被说明为weekday类型变量的取值只能是七天中的某一天。
2. 枚举变量的说明
如同结构体(struct)和共用体(union)一样,枚举变量也可用不同的方式说明,即先定义后说明,同时定义说明或直接说明。
设有变量a,b,c被说明为上述的weekday,可采用下述任一种方式:
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;
		}
	}


别忘了僵尸层的存放,以及ondraw方法,还有deadlist去除

这样,僵尸也画好了


最后,开始写碰撞了

还是在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(百度网盘)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值