cocos2d-xã§å¼ã£ã±ãã²ã¼ãä½ã£ã¦ã¿ã
ãããããã±ãªå§«ã¹ã¤ã¼ãã¨ãAngry Birdsã¨ãã¢ã³ã¹ã¿ã¼ã¹ãã©ã¤ã¯ã¨ãããããã£ãé¡ãã®å¼ã£å¼µãã¢ã¯ã·ã§ã³ãcocos2d-xã§è©¦ããæã®ã¡ã¢ã
ä¾ã«ãã£ã¦ããã ã®ã¡ã¢ãªã®ã§ãã¬ã¤ã«æ¸ããã¨ãã¦ãªãã¨ããããããã¡ã½ããã®ä½ãæ¹ã¤ã±ã¦ãªãã¨ãã¯å¤ã
ããã¾ãã
ããã¸ã§ã¯ãã¯ååã®ã¨ã³ããªã¼ã§ä½ã£ãHelloWorldAppã使ãåãã
ãªã®ã§ããã§ã«èµ·åããã°HelloWorldã¨ãã¿ã³ã¨ç»åãåºã¦ãåæç¶æ
ã®ããã¸ã§ã¯ãããããã®ã¨ãã¦è©±ããé²ãã¾ãã
ç©çã¨ã³ã¸ã³
cocos2d-xã§ä½¿ããã¦ãç©çã¨ã³ã¸ã³ã¨ãã¦ã¯ãBox2Dã¨chipmunkã®2種é¡ã§ã2ç³»ã§ã¯çµæ§Box2Dã使ããã¦ããã®ããªï¼ã¨æãã¾ããã3ç³»ã§ã¯chipmunkãå¼·åã«ãµãã¼ããããããªæãã«ãªã£ãã¿ããã§ãã
ä¾ãã°ãä¸è¨ã®ã³ã¼ã
auto scene = Scene::create();
ããã¯åæç¶æ ã®ããã¸ã§ã¯ãã«æ¸ãã¦ããã³ã¼ãï¼HelloWorld.cppçãªãã¡ã¤ã«ã®createScene()ã¡ã½ããã«ããã¯ãã§ããï¼ã§ããããããä¸è¨ã®ããã«æ¸ãç´ãã¨ããã
auto scene = Scene::createWithPhysics();
å¤æ´ç¹ã¨ãã¦ã¯ãScene::create()
ãScene::createWithPhysics()
ã«ãã¾ããã
ããã ãã§ãããã®Sceneã¯ç©çã¨ã³ã¸ã³ã使ããããã«ãã¾ãããã¨ããè¨å®ãåºæ¥ã¦ãã¾ãã¾ãã
å
é¨çã«ã¯chipmunkã使ã£ã¦ããããã§ãã
å®è£
å®è£
ã¨ãã£ã¦ããã¾ãé£ãããã¨ã¯ãã¾ããã
å¼ã£å¼µã£ã¦é£ã°ãç©ä½ã¨å°é¢ãç¨æãã¦ãã³ã¼ããæ¸ãã ãã§ãã
ä»åã¯ãä¸è¨ã®ï¼ç¨®é¡ã®ç»åãç¨æãã¦ä½¿ãäºã«ãã¾ããã
sample_chara01.png
sample_floor.png
è¬ã®çãç©ã®æ¹ã®ã»ã³ã¹ã®ç¡ãã®æ¹ã¯ãã£ããç½®ãã¨ãã¦ãã ããï¼ï¼¾äººï¼¾ï¼
ç»åã¯é©å½ã«ç¨æãã¦ãResources
ã«å
¥ãã¦ããã¸ã§ã¯ãã«Addãã¦ãã ããã
ããã§ã¯ãHelloWorldApp.cpp
ï¼AppDeligateãããªãæ¹ã®.cppï¼ãããã£ã¦ããã¾ãã
ã¾ãã¯ãããã©ã«ãã§ç¨æããã¦ãinit()
ã¡ã½ãããå¥éºã«ãã¾ãã
// on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !Layer::init() ) { return false; } return true; }
ããã ãæ®ãã¦ããã以å¤ã¯å ¨é¨æ¶ãã¡ããã¾ãããã
ç¶ãã¦ãcreateScene()
ã¡ã½ãããããã£ã¦ããã¾ãã
ã¾ãã¯ãauto scene = Scene::create();
ãä¸è¨ã«æ¸ãæãã¾ãã
auto scene = Scene::createWithPhysics();
ç¶ãã¦ãreturn scene
ã®æåã«ä»¥ä¸ã®ã³ã¼ããæ¸ãã¾ãã
Size winSize = Director::getInstance()->getWinSize(); // éåãè¨å® PhysicsWorld* world = scene->getPhysicsWorld(); Vect gravity; gravity.setPoint(0, -150); world->setGravity(gravity); // å°é¢ Sprite* floor = Sprite::create("sample_floor.png"); floor->setPosition(Point(winSize.width / 2 , floor->getContentSize().height / 2)); PhysicsBody* floorPb = PhysicsBody::createBox(floor->getContentSize()); floorPb->setDynamic(false); floor->setPhysicsBody(floorPb); layer->addChild(floor); // ãã£ã©ã¯ã¿ã¼ Sprite* character = Sprite::create("sample_chara01.png"); character->setPosition(Point(winSize.width / 5 , winSize.height / 2)); PhysicsBody* charaPb = PhysicsBody::createCircle(40); charaPb->setMass(1.0f); // éããæå®ï¼ãããç¡ãã¨å¾ã§é£ã°ããªããªãï¼ character->setPhysicsBody(charaPb); character->setTag(1); layer->addChild(character);
ä¸ã¤ãã¤è¦ã¦è¡ãã¾ãããã
Director::getInstance()->getWinSize();
ããã§ã¯ç»é¢ã®ãµã¤ãºãåå¾ãã¦ãã¾ãã
cocos2d-xã®2ç³»ã§ã¯sharedDirector
ã使ã£ã¦ããã®ã§ããã3ç³»ã§ã¯getInstance
ã«ãªã£ãæ§ã§ãã
ä½åº¦ãç´ éããã¦ãã¾ã£ã¦ãã¾ãããCCDirector
ãªã©CC
ã®ãã¬ãã£ãã¯ã¹ãä»ããªããªã£ãã®ã大ããå¤æ´ç¹ã§ãã
ç¶ãã¦ãã·ã¼ã³ã«ç´ã¥ãç©çä¸çã«éåï¼ã£ã½ããã®ï¼ãä¸ãã¾ãã
gravity.setPoint(0, -150);
ãã®ã³ã¼ãã§ãããããã®Pointã®(x, y)ã«ç¸å½ããã®ãã®ã¯åº§æ¨ã§ã¯ãªãåã®æ¹åã§ãã
Point(100, 50)
ã¨ããå ´åãx座æ¨:100ãy座æ¨:50ã®å ´æãå¼åã®ä¸å¿ã«ãªãã¨ããè¨å®ã§ã¯ãªããxæ¹åã«100ãyæ¹åã«50ã®åãéåã£ã½ãå ããã¾ãããã¨ããè¨å®ã§ãã
次ã«å°é¢ãä½ãã¾ãã
ã ãããã¯èªãã§åã®ãã¨ããªã³ã¼ããªã®ã§ãããä¸è¨ã®ä¸æã ãã¯æ¼ããã¦ãããã»ããè¯ããã§ãã
floorPb->setDynamic(false);
ãããã¯éæ¢ããç¶æ
ã®ãç©ççãªæ§è³ªããã£ãç©ä½ã§ãããã¨ããè¨å®ã§ãã
ã¤ã¾ããéåã«ãã£ã¦ç§»åãããã¨ããªããä½ãã¨ã¶ã¤ãã£ã¦ãåçºãããã¨ããªããªããã¨ããè¨å®ã§ãã
ä»åãå°é¢ã«åæã«åããã¦ã¯å°ãã®ã§ãããã¾ããã
次ã«ãã£ã©ã¯ã¿ã¼ãä½ãã¾ãã
ãã¨ã§åç
§ããããã«ã¿ã°ãè¨å®ããããå¼ã£å¼µãã¢ã¯ã·ã§ã³ã®æã«éããç¡ãã¨åãã¦ãããªãã®ã§éãï¼massï¼ãè¨å®ããããã¦ãã¾ãã
ããã¾ã§æ¸ãçµããã¨ããã§ããã£ããã·ãã¥ã¬ã¼ã¿ã§å®è¡ãã¦ã¿ãã¨ã空ä¸ã«ãã£ã©ã¯ã¿ã¼ãç¾ãã¦ããããéåã«ãã£ã¦èªç±è½ä¸ããå°é¢ã«ã¶ã¤ãã£ã¦ãã¦ã³ããã¦éæ¢ãããã¨æãã¾ãã
ã¡ããã©ãããªç¶æ ã«ãªãã¾ããã
ããã¾ã§ã§å¤§æ ã¯ã§ããã®ã§ãç¶ãã¦ã¡ã¤ã³ã®å¼ã£å¼µãã¢ã¯ã·ã§ã³ã®å®è£
ããã¦ããã¾ãã
ä»åº¦ã¯æ°ããã¡ã½ãããç¨æããªãã¨ãããªãã®ã§ãHelloWorldApp.h
ãéãã¾ãã
æ¢ã«ããã¡ã½ãã群ã®æå¾ã«ä»¥ä¸ãä»ã足ãã¾ããã
// Touchã¤ãã³ãã®éå§å°ç¹ cocos2d::Point touchPoint; // Touchã¤ãã³ãç¨ bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event); void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event); // Nodeã®Rectãåå¾ãã cocos2d::Rect getRect(cocos2d::Node* node);
ããããHelloWorldApp.cpp
ã®æ¹ã«æ»ããå
ã»ã©ã®createScene()
ã®return scene
ã®æåã«ä»¥ä¸ã追è¨ãã¾ããï¼ãã£ã©ã¯ã¿ã¼ä½æãªã©ã®ç¶ãã®ã¨ããã§ããï¼
// Touchã¤ãã³ãç¨ auto eventDispatcher = Director::getInstance()->getEventDispatcher(); auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, layer); listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, layer); eventDispatcher->addEventListenerWithSceneGraphPriority(listener, layer);
ããã§ã¯ã¿ããã¤ãã³ãã«ãã£ã¦å¼ã°ããã¡ã½ãããå®ç¾©ãã¦ãã¾ãã
ãã以å¤ã«ãOnTouchMoved
ãonTouchCanceled
ãªã©ãããã®ã§ãããä»åã¯ãã¿ããããæãã¨ãé¢ããæãã ãã§ååãªã®ã§ä½¿ããªãäºã«ãã¾ããã
ç¶ãã¦ããããã®ã¡ã½ãããå®è£
ãã¦ããã¾ãã
Rect HelloWorld::getRect(Node* node) { Point point = node->getPosition(); int width = node->getContentSize().width; int height = node->getContentSize().height; return Rect(point.x - (width / 2), point.y - (height / 2), width, height); } bool HelloWorld::onTouchBegan(Touch* touch, Event* event) { Sprite* character = (Sprite*)this->getChildByTag(1); Rect characterRect = getRect(character); touchPoint = touch->getLocation(); return characterRect.containsPoint(touchPoint); } void HelloWorld::onTouchEnded(Touch* touch, Event* event) { Sprite* character = (Sprite*)this->getChildByTag(1); Point endPoint = touch->getLocation(); Vect force = Vect(touchPoint.x - endPoint.x, touchPoint.y - endPoint.y) * 4; character->getPhysicsBody()->applyImpulse(force); }
getRect()
ã¯ãå¼æ°ã®cocos2d::Node
ï¼ãç¶æ¿ãã¦ããï¼ãªãã¸ã§ã¯ãã®Rectãåå¾ãã¦è¿å´ãããã®ã§ãã
ãã¨ã§ãã¿ãããããæã«ãã£ã©ã¯ã¿ã¼ãã¿ãããããã©ããã®å¤å®ã®æã«ä½¿ãã¾ãã
onTouchBegan()
ã§ã¯ãã¿ãããããç¬éã«ãã£ã©ã¯ã¿ã¼ãã¿ããããããã©ãããå¤å®ãã¾ãã
ããã§ãã¤ã³ãã¨ãªãã®ãreturn
ã®é¨åãªã®ã§ãããããã§true
ãè¿ããªãã¨å¾ç¶ã®ã¡ã½ããonTouchEnded()
ãªã©ãå¼ã°ããªãã¨ããç¹ã§ãã
ã¤ã¾ããããã§ãã£ã©ã¯ã¿ã¼ãã¿ããããããå¦ããè¿ãã°ãonTouchEnded()
ãå¼ã°ããã®ã¯ãã£ã©ã¯ã¿ã¼ãã¿ãããããå ´åã®ã¿ããçµäºæã®ã¿ã«å¶éã§ãã¾ãã
便å©ã§ããï¼
æå¾ã«onTouchEnded
ã§ã¯ãã¿ãããããå°ç¹ã®åº§æ¨
ããã¿ããçµäºæã®å°ç¹ã®åº§æ¨
ãå¼ãããã¯ãã«ãåã¨ãã¦ãã£ã©ã¯ã¿ã¼ã«ä¸ãã¦ãã¾ãã
* 4
ãã¦ãã®ã¯ããã®ã¾ã¾ã ã¨ããã¾ãé£ã°ãªãã£ãã®ã§ã¡ãã£ã¨è£æ£ãããã¦ãããã ãã§æ©è½çãªæå³ã¯ç¹ã«ãªãã§ãã
å®æ
ããã§ä¸éãåºæ¥ãã®ã§å®éã«èµ·åãã¦ã¿ã¾ãã
å®æãããã®ãåããããä¸è¨ã®ãããªæãã«ãªãã¾ããã
ããã¼åããã¥ããã§ããããã£ã©ãã¯ãªãã¯ãã¦ããã®ã¾ã¾å¼ã£ã±ãé¢ãã¦ãã¾ãã
ã±ãªå§«ãAngry Birdsçã«ã¯ãããªæãã§ããããã
ããã«ã¹ãã«ã ã®æ¾ç©ç·ã¬ã¤ãã ã®ãä»ã足ãã¨ããã£ã½ããªãããªããã¨ããæãã§ãã
ã¦ãcocos2d-xãWebPlayer欲ããã§ãããã
ä¼ãã«ããã§ããã¼ï¼ï¼
æå¾ã«ãä»åããã£ãããã°ã©ã ãä¹ã£ãã¦ããã¾ãã
HelloWorldApp.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" class HelloWorld : public cocos2d::Layer { public: // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::Scene* createScene(); // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // a selector callback void menuCloseCallback(cocos2d::Ref* pSender); // implement the "static create()" method manually CREATE_FUNC(HelloWorld); /** * 以ä¸ã追å */ // Touchã¤ãã³ãã®éå§å°ç¹ cocos2d::Point touchPoint; // Touchã¤ãã³ãç¨ bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event); void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event); // Nodeã®Rectãåå¾ãã cocos2d::Rect getRect(cocos2d::Node* node); }; #endif // __HELLOWORLD_SCENE_H__
HelloWorldApp.cpp
#include "HelloWorldScene.h" USING_NS_CC; Scene* HelloWorld::createScene() { // 'scene' is an autorelease object auto scene = Scene::createWithPhysics(); // 'layer' is an autorelease object auto layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); /** * 以ä¸ã追å */ Size winSize = Director::getInstance()->getWinSize(); // éåãè¨å® PhysicsWorld* world = scene->getPhysicsWorld(); Vect gravity; gravity.setPoint(0, -150); world->setGravity(gravity); // å°é¢ Sprite* floor = Sprite::create("sample_floor.png"); floor->setPosition(Point(winSize.width / 2 , floor->getContentSize().height / 2)); PhysicsBody* floorPb = PhysicsBody::createBox(floor->getContentSize()); floorPb->setDynamic(false); floor->setPhysicsBody(floorPb); layer->addChild(floor); // ãã£ã©ã¯ã¿ã¼ Sprite* character = Sprite::create("sample_chara01.png"); character->setPosition(Point(winSize.width / 5 , winSize.height / 2)); PhysicsBody* charaPb = PhysicsBody::createCircle(40); charaPb->setMass(1.0f); // éããæå®ï¼ãããç¡ãã¨å¾ã§é£ã°ããªããªãï¼ character->setPhysicsBody(charaPb); character->setTag(1); layer->addChild(character); // Touchã¤ãã³ãç¨ auto eventDispatcher = Director::getInstance()->getEventDispatcher(); auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, layer); listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, layer); eventDispatcher->addEventListenerWithSceneGraphPriority(listener, layer); // return the scene return scene; } Rect HelloWorld::getRect(Node* node) { Point point = node->getPosition(); int width = node->getContentSize().width; int height = node->getContentSize().height; return Rect(point.x - (width / 2), point.y - (height / 2), width, height); } bool HelloWorld::onTouchBegan(Touch* touch, Event* event) { Sprite* character = (Sprite*)this->getChildByTag(1); Rect characterRect = getRect(character); touchPoint = touch->getLocation(); return characterRect.containsPoint(touchPoint); } void HelloWorld::onTouchEnded(Touch* touch, Event* event) { Sprite* character = (Sprite*)this->getChildByTag(1); Point endPoint = touch->getLocation(); Vect force = Vect(touchPoint.x - endPoint.x, touchPoint.y - endPoint.y) * 4; character->getPhysicsBody()->applyImpulse(force); } // on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !Layer::init() ) { return false; } return true; } void HelloWorld::menuCloseCallback(Ref* pSender) { Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif }