#include "HelloWorldScene.h"
#include "cloud.h"
#include "Missile.h"
#include "Box.h"
using namespace cocos2d;
//天空的颜色
static const ccColor4B SKY_COLOR = {30, 66, 78, 255};
static HelloWorld* layer;
//导弹精灵
static Missile* MissileSprite;
//天空背景图层
static cocos2d::CCLayerColor* skyLayer;
enum {
//设定一个父节点的tag
kTagParentNode = 1,
};
enum {
Z_PHYSICS_DEBUG = 100,
};
HelloWorld::HelloWorld(){
}
HelloWorld::~HelloWorld()
{
// manually Free rogue shapes
for( int i=0;i<4;i++) {
cpShapeFree( m_pWalls[i] );
}
cpSpaceFree( m_pSpace );
}
//调试模式下可以看到为刚体定义的形状,否则形状会不可见
void HelloWorld::toggleDebugCallback(CCObject* pSender)
{
#if CC_ENABLE_CHIPMUNK_INTEGRATION
m_pDebugLayer->setVisible(! m_pDebugLayer->isVisible());
#endif
}
CCScene* HelloWorld::scene()
{
CCScene * scene = NULL;
do
{
// 'scene' is an autorelease object
scene = CCScene::create();
CC_BREAK_IF(! scene);
// 'layer' is an autorelease object
layer = HelloWorld::create();
CC_BREAK_IF(! layer);
// add layer as a child to scene
scene->addChild(layer,0,1);
} while (0);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
bool bRet = false;
do
{
//////////////////////////////////////////////////////////////////////////
// super init first
//////////////////////////////////////////////////////////////////////////
CC_BREAK_IF(! CCLayer::init());
//////////////////////////////////////////////////////////////////////////
// add your codes below...
//////////////////////////////////////////////////////////////////////////
// 1. Add a menu item with "X" image, which is clicked to quit the program.
// Create a "close" menu item with close icon, it's an auto release object.
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
CC_BREAK_IF(! pCloseItem);
// Place the menu item bottom-right conner.
pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));
// Create a menu with the "close" menu item, it's an auto release object.
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
CC_BREAK_IF(! pMenu);
// Add the menu to HelloWorld layer as a child layer.
this->addChild(pMenu, 1);
this->setTouchEnabled(true);
// Get window size and place the label upper.
CCSize size = CCDirector::sharedDirector()->getWinSize();
//建立天空颜色图层
CCLayerColor *skyLayer = CCLayerColor::create(SKY_COLOR);
addChild(skyLayer);
// 创建地面精灵.
CCSprite* pSprite = CCSprite::create("Terrain.png");
pSprite->setScale(0.5f);
CC_BREAK_IF(! pSprite);
// Place the sprite on the center of the screen
pSprite->setPosition(ccp(size.width/2, size.height/2));
// Add the sprite to HelloWorld layer as a child layer.
this->addChild(pSprite, 0);
//加入箱子的表情纹理
CCTextureCache::sharedTextureCache()->addImage("BoxUpset.png");
CCTextureCache::sharedTextureCache()->addImage("BoxHappy.png");
initPhysics();
//创建并设置自定义的精灵-愤怒的乌云
cloudSprite=cloud::create("Cloud.png");
cloudSprite->setScale(0.5f);
addChild(cloudSprite);
cloudSprite->setPosition(ccp(240,280));
// menu for debug layer 设定物理引擎运行的模式用的菜单按钮
CCMenuItemFont::setFontSize(24);
CCMenuItemFont *item = CCMenuItemFont::create("Toggle debug", this, menu_selector(HelloWorld::toggleDebugCallback));
CCMenu *menu = CCMenu::create(item, NULL);
this->addChild(menu);
menu->setPosition(ccp(VisibleRect::right().x-100, VisibleRect::top().y-60));
Box* box=Box::create("BoxHappy.png",ccp(110,100),m_pSpace);
box->setScale(0.6f);
addChild(box);
//调用计时器,此类计时器只认update方法,也就是层里定义的那个
scheduleUpdate();
bRet = true;
} while (0);
return bRet;
}
void HelloWorld::ccTouchesBegan(CCSet* touches, CCEvent* event)
{
//Add a new body/atlas sprite at the touched location
//根据触屏位置添加刚体精灵
CCSetIterator it;
CCTouch* touch;
for( it = touches->begin(); it != touches->end(); it++)
{
touch = (CCTouch*)(*it);
if(!touch)
break;
//根据触屏点创建一个导弹
MissileSprite=Missile::create("Missile.png",cloudSprite->getPosition(),cpv(this->getParent()->convertTouchToNodeSpace(touch).x,this->convertTouchToNodeSpace(touch).y),m_pSpace);
MissileSprite->setScale(0.5f);
addChild(MissileSprite);
//更新乌云眼神的角度
cloudSprite->lookAt=touch->getLocation();
}
}
//触摸移动时的回调函数,用于引导导弹
void HelloWorld::ccTouchesMoved(CCSet* touches, CCEvent* event){
CCSetIterator it;
CCTouch* touch;
for( it = touches->begin(); it != touches->end(); it++)
{
touch = (CCTouch*)(*it);
if(!touch)
break;
}
if(MissileSprite){
//开启导弹追踪属性并设置重力矢量点到当前触屏移动到的位置
MissileSprite->isTracking=true;
MissileSprite->target=cpv(this->getParent()->convertTouchToNodeSpace(touch).x,this->convertTouchToNodeSpace(touch).y);
}
//更新乌云眼神的角度
cloudSprite->lookAt=touch->getLocation();
}
//触摸结束时的回调
void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event){
//去除导弹的跟踪属性
if(MissileSprite){
MissileSprite->isTracking=false;
}
}
//物理系统初始化
void HelloWorld::initPhysics()
{
#if CC_ENABLE_CHIPMUNK_INTEGRATION
// init chipmunk
//cpInitChipmunk();
//创建一个物理空间
m_pSpace = cpSpaceNew();
//设定空间的重力点
m_pSpace->gravity = cpv(0, -100);
//
// rogue shapes
// We have to free them manually
//这里创建了四个形状用于创建一个矩形的墙体,其对应的刚体是静态刚体,也就是保持静止不动的刚体
//cpSegmentShapeNew用来建立一个段状形状,其它定义请看源码
// bottom
m_pWalls[0] = cpSegmentShapeNew( m_pSpace->staticBody,
cpv(VisibleRect::leftBottom().x,VisibleRect::leftBottom().y),
cpv(VisibleRect::rightBottom().x, VisibleRect::rightBottom().y), 9.0f);
// top
m_pWalls[1] = cpSegmentShapeNew( m_pSpace->staticBody,
cpv(VisibleRect::leftTop().x, VisibleRect::leftTop().y),
cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f);
// left
m_pWalls[2] = cpSegmentShapeNew( m_pSpace->staticBody,
cpv(VisibleRect::leftBottom().x,VisibleRect::leftBottom().y),
cpv(VisibleRect::leftTop().x,VisibleRect::leftTop().y), 0.0f);
// right
m_pWalls[3] = cpSegmentShapeNew( m_pSpace->staticBody,
cpv(VisibleRect::rightBottom().x, VisibleRect::rightBottom().y),
cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f);
//为形状设定弹性及摩擦系数并加入到物理空间
for( int i=0;i<4;i++) {
m_pWalls[i]->e = 1.0f;
m_pWalls[i]->u = 1.0f;
//设定碰撞类型标识
m_pWalls[i]->collision_type=i;
//添加墙体到物理空间
cpSpaceAddStaticShape(m_pSpace, m_pWalls[i] );
//设定碰撞的回调函数,5是导弹的碰撞类型标识
cpSpaceAddCollisionHandler(m_pSpace,5,i,beginCollision,NULL,NULL,NULL,NULL);
}
// Physics debug layer
m_pDebugLayer = CCPhysicsDebugNode::create(m_pSpace);
this->addChild(m_pDebugLayer, Z_PHYSICS_DEBUG);
#endif
}
void HelloWorld::update(float delta)
{
// Should use a fixed size step based on the animation interval.
int steps = 2;
flo