原代码来自于网络,因为cocos2d-x 3.0的资料,的确不多,与曾经版本号的接口非常难对上,
所以网上非常多样例都无法调试,对于新学习cocos2d-x 的同学,难度添加了,所以出一个超具体的样例给大家。
源代码地址:http://download.csdn.net/detail/adady/7293629
#include "HelloWorldScene.h" #include "SimpleAudioEngine.h" USING_NS_CC; Scene* HelloWorld::createScene() { // 1.创建场景 auto scene = Scene::create(); // 2.创建图层,把当本类创建出来,至layer auto layer = HelloWorld::create(); // 3.把layer放到 场景其中 scene->addChild(layer); // 4.返回此场景 return scene; } void HelloWorld::onEnter() //init() 之后就到这个函数 { LayerColor::onEnter(); //执行 LayerColor 的 onEnter(); auto listener = EventListenerTouchOneByOne::create(); //创建监听事件 listener->setSwallowTouches(true); //时间是否向下传递,true 就不会向下传递 listener->onTouchBegan = [=](cocos2d::Touch* touch,cocos2d::Event* event) //****这还没懂,是什么意思,弄清楚了,告诉大家,或则大家能够与我分享 { return true; }; listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this); //弹起后,调用onTouchEnded函数 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); //导演加入 listener 事件 } void HelloWorld::update(float t) { Vector<Sprite*> targetsToDelete; //列表targetsToDelete Vector<Sprite*> projectilesToDelete; //列表projectilesToDelete for (int i = 0; i < _projectiles.size(); i++) //从0至全部进入列表的子弹(所以还没有消失的子弹,包含屏幕外面的还没有结束的) { auto projectile = _projectiles.at(i); //当前第i 个子弹 保存至 projectile //获取当前子弹的坐标及大小 得到一个矩形 这里减一个projectile->getContentSize().width / 2,是由于他的锚点在中心,所以要减掉 auto projectileRect = Rect( projectile->getPositionX() - projectile->getContentSize().width / 2, projectile->getPositionY() - projectile->getContentSize().height / 2, projectile->getContentSize().width, projectile->getContentSize().height ); for (int j = 0; j < _targets.size(); j++) { auto target = _targets.at(j); //当前第j 个目标 保存至 target //获取当前目标的坐标及大小 得到一个矩形 auto targetRect = Rect( target->getPositionX() - target->getContentSize().width / 2, target->getPositionY() - target->getContentSize().height / 2, target->getContentSize().width, target->getContentSize().height); if (projectileRect.intersectsRect(targetRect)) //一一比对,有没有子弹与目标碰撞了 { targetsToDelete.pushBack(target); //碰撞后,把要删除的目标,加入队列 } } //C++11 的 range-based for循环 for (Sprite* target : targetsToDelete) //遍历 targetsToDelete 里全部元素 一一保存至 target { _targets.eraseObject(target); //移除 _target表里的 target,并非 targetsToDelete this->removeChild(target); //当前 layer 移掉 target _projectilesDestroyed++; //每打中一个 加一分 if (_projectilesDestroyed >3) { //大于3分 转换至 成功场景 auto gameOverScene = GameOverScene::create(); gameOverScene->getLayer()->getLabel()->setString("You Win!"); Director::getInstance()->replaceScene(gameOverScene); } } if (targetsToDelete.size() >0) //当第i个子弹 有碰撞,就意味着 size 大于0 { projectilesToDelete.pushBack(projectile); //把当前子弹加入入 子弹删除列表 } targetsToDelete.clear(); // 清空 目标删除 列表 } for (const auto& p : projectilesToDelete) //遍历 targetsToDelete 里全部元素 一一保存至 p { _projectiles.eraseObject(p); //移除 _projectiles表里的 target,并非 projectilesToDelete this->removeChild(p); //当前 layer 移掉 projectiles //p->removeFromParentAndCleanup(true); } projectilesToDelete.clear(); // 清空 目标删除 列表 } // on "init" you need to initialize your instance bool HelloWorld::init() { if ( !LayerColor::initWithColor(Color4B(255,255,255,255)) ) //5. 把本图层的背景设置成白色 { return false; //假设图层没有被创建就false } Size visibleSize = Director::getInstance()->getVisibleSize(); //getInstance()应该是得到导演的句柄,取得屏幕的尺寸 auto player = Sprite::create("Player.png", Rect(0, 0, 27, 40)); //创建一个玩家的精灵,他的大小改动为width:27 hight:40 player->setPosition(Point(player->getContentSize().width/2, visibleSize.height / 2)); //设置精灵出现的位子,程序选择放在(27/2,屏幕中间)的位子,就是在左中,全然的能够显示图片 this->addChild(player, 0); //加入玩家精灵,进入图层 //更新函数 this->schedule(schedule_selector(HelloWorld::gameLogic), 1.0f); //schedule是按时调用一个函数的方法,定义这个以后就会隔一段时间调用一次该方法,每一秒调用一次gameLogic函数 //schedule_selector 应该是注冊HelloWorld::gameLogic 这个函数 this->scheduleUpdate(); //这表示大概每0.01秒 调用一次 Update()函数 CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("background-music-aac.caf"); //载入声音文件 return true; } void HelloWorld::gameLogic(float dt) //每1秒调用一次 { addTarget();//每1秒调用一次 } void HelloWorld::addTarget() { Size visibleSize = Director::getInstance()->getVisibleSize(); //得到屏幕尺寸 auto target = Sprite::create("Target.png", Rect(0, 0, 27, 40)); //创建一个 目标精灵 // Determine where to spawn the target along the Y axis int minY = target->getContentSize().height / 2; // 得到Target 能够显示的最小位置 (相当于图片的height 的中点) int maxY = visibleSize.height - target->getContentSize().height / 2; // 得到Target 能够显示的最大位置 int rangeY = maxY - minY; // 得到可显示区域的大小 int actualY = (CCRANDOM_0_1() * rangeY) + minY; //(随机产生一个数(0,1) * rangeY) + minY 得到(0-1)的小数 target->setPosition(Point(visibleSize.width + target->getContentSize().width / 2, actualY)); //设置Target 出现的位子 this->addChild(target,0); //加入到本图层内 target->setTag(1); //设置这个Targer 的标签为1 _targets.pushBack(target); //把Target 存于 _targets的列表 //以下4句,随即产生一个速度 int minDuration = 2.0; int maxDuration = 4.0; int rangeDuration = maxDuration - minDuration; int actualDuration = (CCRANDOM_0_1() * rangeDuration) + minDuration; auto actionMove = MoveTo::create(actualDuration, Point(-target->getContentSize().width, actualY)); //创建一个速度移动, actualDuration速度, Point(-target->getContentSize().width, actualY)是起始点 auto actionMoveDone = CallFuncN::create(CC_CALLBACK_1(HelloWorld::spriteMoveFinished, this)); //这里是创建一个回调函数,就是调用spriteMoveFinished函数 并把自己传出去this。 target->runAction(Sequence::create(actionMove, actionMoveDone, NULL)); //执行一个动画 actionMove 移动方法 actionMoveDone回调的函数 //从上面看来,这个函数,每1秒创建一个Target 精灵,从屏幕的最右边,随机高度,至左移动 } void HelloWorld::onTouchEnded(Touch* touch, Event* event) //按下事件 { Size visibleSize = Director::getInstance()->getVisibleSize(); //获得屏幕尺寸 auto touchPoint = touch->getLocation(); //获得点击坐标 auto projectile = Sprite::create("Projectile.png", Rect(0, 0, 20, 20)); //创建一个子弹 projectile->setPosition(Point(20, visibleSize.height / 2)); //设置子弹位子 // Determine offset of location to projectile int offX = touchPoint.x - projectile->getPosition().x; //点击位置与子弹X位置的差值 int offY = touchPoint.y - projectile->getPosition().y; //点击位置与子弹Y位置的差值 if (offX <= 0) return; //假设 子弹 超出范围 return this->addChild(projectile); //把 子弹 加入进图层 projectile->setTag(2); // 把子弹的标签设置为2 _projectiles.pushBack(projectile); // 把子弹加入进子弹列表 // Determine where we wish to shoot the projectile to int realX = visibleSize.width + (projectile->getContentSize().width / 2); //求出屏幕最大 + 子弹的一半, (求出子弹消失的最大x) float ratio = (float)offY / (float)offX; //斜率 int realY = (realX * ratio) + projectile->getPosition().y; //求出真实的y值,同样的斜率 auto realDest = Point(realX, realY); //子弹要去位置 // 理解上面的话,以下5句就非常好理解了 int offRealX = realX - projectile->getPosition().x; //真实X值 int offRealY = realY - projectile->getPosition().y; //真实Y值 float length = sqrtf((offRealX*offRealX) + (offRealY*offRealY)); //求出 直线距离 float velocity = 960 / 1; // 960pixels/1sec //960 像素/ 1秒 float realMoveDuration = length / velocity; //速度 // 创建一个动作,移动动作,realMoveDuration速度,至realDest,并进入回调函数 projectile->runAction(Sequence::create(MoveTo::create(realMoveDuration, realDest),CallFuncN::create(CC_CALLBACK_1(HelloWorld::spriteMoveFinished, this)), NULL)); CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("pew-pew-lei.caf"); //载入声音文件 } void HelloWorld::spriteMoveFinished(Ref* pSender) { Sprite *sprite = (Sprite *)pSender; //获得的Target 转成 sprite 类型 if (sprite->getTag() == 1) { //假设 标签 等于 1 _targets.eraseObject(sprite); //从_target列表里删掉Target 仅仅是从列表里删掉 auto gameOverScene = GameOverScene::create(); //创建一个GameOver的场景 gameOverScene->getLayer()->getLabel()->setString("You Lose :["); //显示youLose Director::getInstance()->replaceScene(gameOverScene); //替换成刚生成的GameOver场景 } else if(sprite->getTag() == 2) { //假设 标签 等于 2 _projectiles.eraseObject(sprite); //从_projectiles列表里删掉 Projectiles 仅仅是从列表里删掉 } this->removeChild(sprite); //删掉sprite 这个图层 } void HelloWorld::menuCloseCallback(Ref* pSender) { Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif }