一、创建主界面

1)把cocos2d.jar拷贝的libs目录,

2)把图片拷贝的asserts目录

Cocos2d 植物大战僵尸游戏解析_界面

public class MainActivity extends BaseActivity {

private CCScene mScene;
//导演
private CCDirector mDirector;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//创建画布
CCGLSurfaceView surfaceView = new CCGLSurfaceView(this);
setContentView(surfaceView);

mDirector = CCDirector.sharedDirector();
//开启线程
mDirector.attachInView(surfaceView);
//显示帧率
mDirector.setDisplayFPS(true);
//设置屏幕大小
mDirector.setScreenSize(800, 600);
//水平
mDirector.setDeviceOrientation(CCDirector.kCCDeviceOrientationLandscapeLeft);
//添加场景
mScene = CCScene.node();
//添加欢迎界面
mScene.addChild(new WelcomeLayer());
//运行场景
mDirector.runWithScene(mScene);

}

@Override
protected void onResume() {
mDirector.onResume();
super.onResume();
}

@Override
protected void onPause() {
mDirector.onPause();
super.onPause();
}

@Override
protected void onDestroy() {
mDirector.end();
super.onDestroy();
}
}

二、创建欢迎图层

1)加载logo

2)加载welcome界面

Cocos2d 植物大战僵尸游戏解析_界面_02

public void loadWelcome() {
mWelcomeSprite = CCSprite.sprite("image/welcome.jpg");
mWelcomeSprite.setAnchorPoint(0.0f, 0.0f);
this.addChild(mWelcomeSprite);
loading();
}

3)添加loading,因为loading是由帧动画实现的,在加载完loading精灵后,必须实现其帧动画

private void loading() {
mLoadingSprite = CCSprite.sprite("image/loading/loading_01.png");
mLoadingSprite.setPosition(mWinSize.width / 2, 50);
this.addChild(mLoadingSprite);

//创建桢动画
createFrameAnimate();
}

4)加载开始按钮,加载是按钮是隐藏的

private void loadStart() {
mStartSprite = CCSprite.sprite("image/loading/loading_start.png");
mStartSprite.setPosition(mWinSize.width / 2, 50);
mStartSprite.setVisible(false);
this.addChild(mStartSprite);
}

5)创建一个异步类,实现在loading加载完后显示start按钮

Cocos2d 植物大战僵尸游戏解析_界面_03

private class Task extends AsyncTask<Void, Void, Void> {
private CCSprite startSprite;

public Task(CCSprite startSprite) {
this.startSprite = startSprite;
}

@Override
protected Void doInBackground(Void... params) {
// init();
SystemClock.sleep(8000);
return null;
}

@Override
protected void onPostExecute(Void result) {
startSprite.setVisible(true);
setIsTouchEnabled(true);
super.onPostExecute(result);
}

}

使用:
在构造方法里
new Task(mStartSprite).execute();

详细代码如下:

public class WelcomeLayer extends CCLayer {

private CCSprite mLogoSprite;
private CCSprite mWelcomeSprite;
private CGSize mWinSize;
private CCSprite mLoadingSprite;
private CCSprite mStartSprite;

public WelcomeLayer() {
mWinSize = CCDirector.sharedDirector().getWinSize();
init();
new Task().execute();

}

private void init() {
loadLogo();
}

/**
* 加载logo界面
*/
public void loadLogo() {
mLogoSprite = CCSprite.sprite("image/popcap_logo.png");
// logo在中间位置
mLogoSprite.setPosition(mWinSize.width / 2, mWinSize.height / 2);
// 添加到图层
this.addChild(mLogoSprite);

CCHide ccHide = CCHide.action();// 隐藏
CCDelayTime delayTime = CCDelayTime.action(2);// 延时1秒

// 慢慢地隐藏,然后调用loadWelcome方法
CCSequence sequence = CCSequence.actions(delayTime, ccHide, delayTime, CCCallFunc.action(this, "loadWelcome"));
mLogoSprite.runAction(sequence);
}

/**
* 加载欢迎界面
*/
public void loadWelcome() {
mWelcomeSprite = CCSprite.sprite("image/welcome.jpg");
mWelcomeSprite.setAnchorPoint(0.0f, 0.0f);
this.addChild(mWelcomeSprite);

loading();
}

/**
* 加载进度条
*/
private void loading() {
mLoadingSprite = CCSprite.sprite("image/loading/loading_01.png");
mLoadingSprite.setPosition(mWinSize.width / 2, 50);
this.addChild(mLoadingSprite);

// 创建桢动画
createFrameAnimate();

}

private void loadStart() {
mStartSprite = CCSprite.sprite("image/loading/loading_start.png");
mStartSprite.setPosition(mWinSize.width / 2, 50);
mStartSprite.setVisible(false);
this.addChild(mStartSprite);
}

private void createFrameAnimate() {
ArrayList<CCSpriteFrame> frames = new ArrayList<CCSpriteFrame>();
String str = "image/loading/loading_%02d.png";
for (int i = 1; i <= 9; i++) {
CCSpriteFrame frame = CCSprite.sprite(String.format(str, i)).displayedFrame();
frames.add(frame);
}
CCAnimation animation = CCAnimation.animation("", 0.2f, frames);
// 表示不需要永不停止播放
CCAnimate animate = CCAnimate.action(animation, false);
mLoadingSprite.runAction(animate);

// 加载开始按钮
loadStart();
}

@Override
public boolean ccTouchesBegan(MotionEvent event) {
// 判断是否点击了开始按钮
CGRect boundingBox = mStartSprite.getBoundingBox();
CGPoint cgPoint = this.convertTouchToNodeSpace(event);
if (CGRect.containsPoint(boundingBox, cgPoint)) {
//切换界面
GameUtil.switfLayer(new MenuLayer());
}
return super.ccTouchesBegan(event);
}

private class Task extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
SystemClock.sleep(6000);
return null;
}

@Override
protected void onPostExecute(Void result) {
if (mStartSprite != null) {
mStartSprite.setVisible(true);
setIsTouchEnabled(true);
}
super.onPostExecute(result);
}

}
}

菜单图层:

public class MenuLayer extends CCLayer {
private CGSize mWinSize;

public MenuLayer() {
init();
}

private void init() {
mWinSize = CCDirector.sharedDirector().getWinSize();
CCSprite sprite = CCSprite.sprite("image/menu/main_menu_bg.jpg");
sprite.setAnchorPoint(0.0f, 0.0f);
this.addChild(sprite);

addMenu();
}

private void addMenu() {
CCSprite normalSprite = CCSprite.sprite("image/menu/start_adventure_default.png");
CCSprite selectSprite = CCSprite.sprite("image/menu/start_adventure_press.png");
CCMenuItem items = CCMenuItemSprite.item(normalSprite, selectSprite, this, "onClick");
CCMenu menu = CCMenu.menu(items);
menu.setPosition(mWinSize.width/2 - 25, mWinSize.height/2 - 110);
menu.setScale(0.5f);
this.addChild(menu);
}

/**
* @param object 用于反射,代表点击的条目
*/
public void onClick(Object object) {
//切换到对战图层
GameUtil.switfLayer(new FightLayer());
}
}

对战图层:

Cocos2d 植物大战僵尸游戏解析_游戏_04


1)加载地图

private void loadMap() {
CCTMXTiledMap map = CCTMXTiledMap.tiledMap("image/fight/map_day.tmx");
map.setAnchorPoint(0.5f, 0.5f);
CGSize contentSize = map.getContentSize();
map.setPosition(contentSize.width /2 , contentSize.height / 2);
this.addChild(map);
}

2)移动地图

private void moveMap() {
CGPoint pos = ccp(-(mMapSize.width - mWinSize.width), 0);
CCMoveBy moveBy = CCMoveBy.action(2, pos);
//停留4秒再移动
CCSequence sequence = CCSequence.actions(CCDelayTime.action(4), moveBy);
mMap.runAction(sequence);
}

3)显示僵尸

private void showZombiles() {
for (int i = 0; i < mZombiesPoints.size(); i++) {
CGPoint cgPoint = mZombiesPoints.get(i);
ZombiesSprite zombiesSprite = new ZombiesSprite();
zombiesSprite.setPosition(cgPoint);
mMap.addChild(zombiesSprite);
}
}

4)加载道具

CCSequence sequence = CCSequence.actions(CCDelayTime.action(4), moveBy, CCDelayTime.action(4), CCCallFunc.action(this, "loadContainer"));

public void loadContainer(){
//加载以选择的容器
CCSprite choseSprite = CCSprite.sprite("image/fight/chose/fight_chose.png");
choseSprite.setAnchorPoint(0f,1.0f);//左上角
choseSprite.setPosition(0, mWinSize.height);
this.addChild(choseSprite);

//加载可选择的容器
CCSprite chooseSprite = CCSprite.sprite("image/fight/chose/fight_choose.png");
chooseSprite.setAnchorPoint(0, 0);
this.addChild(chooseSprite);//底部
}

5)加载植物,重点是计算植物的位置

Cocos2d 植物大战僵尸游戏解析_加载_05

private void loadPlant() {
for (int i = 1; i <= 9; i++) {
Plant plant = new Plant(i);
CCSprite plantSprite = plant.getPlantSprite();
float x = 16 + ((i - 1))%4 * 54;
float y = 175 -((i - 1))%4 * 59;
plantSprite.setPosition(x, y);
mChooseSprite.addChild(plantSprite);//添加植物
}
}

植物实体类

public class Plant {
private static Map<Integer, HashMap<String, String>> mDatas;
private static CCSprite mPlantSprite;

//查询数据库 获取植物
static{
//模拟数据库
mDatas = new HashMap<Integer, HashMap<String,String>>();
String path = "image/fight/chose/choose_default%02d.png";
for (int i = 1; i <= 9; i++) {
HashMap<String,String> data = new HashMap<String, String>();
data.put("path", String.format(path, i));//路径
data.put("sun", 50+"");//阳光数
mDatas.put(i, data);
}
}

public Plant(int id){
HashMap<String, String> data = mDatas.get(id);
String path = data.get("path");
mPlantSprite = CCSprite.sprite(path);
}

/**
* 获得植物精灵
* @return
*/
public CCSprite getPlantSprite(){
return mPlantSprite;
}
}

效果图

Cocos2d 植物大战僵尸游戏解析_cocos2d_06

工具类:

场景动画

Cocos2d 植物大战僵尸游戏解析_植物大战僵尸_07

public class GameUtil {

public static void switfLayer(CCLayer layer){
//
CCScene sence = CCScene.node();
sence.addChild(layer);
//跳跃式的切换
//CCJumpZoomTransition transition = CCJumpZoomTransition.transition(2, sence);
//CCFadeTRTransition transition = CCFadeTRTransition.transition(2f, sence);
//CCSplitColsTransition transition = CCSplitColsTransition.transition(2, sence);
CCFlipAngularTransition transition = CCFlipAngularTransition.transition(3, sence, 1);
//切换场景
CCDirector.sharedDirector().replaceScene(transition);
}

}