| // Copyright 2017 The Emscripten Authors. All rights reserved. |
| // Emscripten is available under two separate licenses, the MIT license and the |
| // University of Illinois/NCSA Open Source License. Both these licenses can be |
| // found in the LICENSE file. |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <unistd.h> |
| #include <string> |
| |
| #include "cocos2d.h" |
| |
| #include <emscripten.h> |
| |
| // ============= |
| // AppMacros.h |
| // ============= |
| |
| /* For demonstrating using one design resolution to match different resources, |
| or one resource to match different design resolutions. |
| |
| [Situation 1] Using one design resolution to match different resources. |
| Please look into Appdelegate::applicationDidFinishLaunching. |
| We check current device frame size to decide which resource need to be selected. |
| So if you want to test this situation which said in title '[Situation 1]', |
| you should change ios simulator to different device(e.g. iphone, iphone-retina3.5, iphone-retina4.0, ipad, ipad-retina), |
| or change the window size in "proj.XXX/main.cpp" by "CCEGLView::setFrameSize" if you are using win32 or linux plaform |
| and modify "proj.mac/AppController.mm" by changing the window rectangle. |
| |
| [Situation 2] Using one resource to match different design resolutions. |
| The coordinates in your codes is based on your current design resolution rather than resource size. |
| Therefore, your design resolution could be very large and your resource size could be small. |
| To test this, just define the marco 'TARGET_DESIGN_RESOLUTION_SIZE' to 'DESIGN_RESOLUTION_2048X1536' |
| and open iphone simulator or create a window of 480x320 size. |
| |
| [Note] Normally, developer just need to define one design resolution(e.g. 960x640) with one or more resources. |
| */ |
| |
| #define DESIGN_RESOLUTION_480X320 0 |
| #define DESIGN_RESOLUTION_1024X768 1 |
| #define DESIGN_RESOLUTION_2048X1536 2 |
| |
| /* If you want to switch design resolution, change next line */ |
| #define TARGET_DESIGN_RESOLUTION_SIZE DESIGN_RESOLUTION_480X320 |
| |
| typedef struct tagResource |
| { |
| cocos2d::Size size; |
| char directory[100]; |
| }Resource; |
| |
| static Resource smallResource = { cocos2d::Size(480, 320), "iphone" }; |
| static Resource mediumResource = { cocos2d::Size(1024, 768), "ipad" }; |
| static Resource largeResource = { cocos2d::Size(2048, 1536), "ipadhd" }; |
| |
| #if (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_480X320) |
| static cocos2d::Size designResolutionSize = cocos2d::Size(480, 320); |
| #elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_1024X768) |
| static cocos2d::Size designResolutionSize = cocos2d::Size(1024, 768); |
| #elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_2048X1536) |
| static cocos2d::Size designResolutionSize = cocos2d::Size(2048, 1536); |
| #else |
| #error unknown target design resolution! |
| #endif |
| |
| // The font size 24 is designed for small resolution, so we should change it to fit for current design resolution |
| #define TITLE_FONT_SIZE (cocos2d::EGLView::getInstance()->getDesignResolutionSize().width / smallResource.size.width * 24) |
| |
| // =============== |
| // AppDelegate.h |
| // =============== |
| |
| /** |
| @brief The cocos2d Application. |
| |
| The reason for implement as private inheritance is to hide some interface call by Director. |
| */ |
| class AppDelegate : private cocos2d::Application |
| { |
| public: |
| AppDelegate(); |
| virtual ~AppDelegate(); |
| |
| /** |
| @brief Implement Director and Scene init code here. |
| @return true Initialize success, app continue. |
| @return false Initialize failed, app terminate. |
| */ |
| virtual bool applicationDidFinishLaunching(); |
| |
| /** |
| @brief The function be called when the application enter background |
| @param the pointer of the application |
| */ |
| virtual void applicationDidEnterBackground(); |
| |
| /** |
| @brief The function be called when the application enter foreground |
| @param the pointer of the application |
| */ |
| virtual void applicationWillEnterForeground(); |
| }; |
| |
| // =================== |
| // HelloWorldScene.h |
| // =================== |
| |
| class HelloWorld : public cocos2d::Layer |
| { |
| public: |
| // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone |
| virtual bool init(); |
| |
| // there's no 'id' in cpp, so we recommend returning the class instance pointer |
| static cocos2d::Scene* scene(); |
| |
| // a selector callback |
| void menuCloseCallback(Object* sender); |
| |
| // implement the "static node()" method manually |
| CREATE_FUNC(HelloWorld); |
| }; |
| |
| USING_NS_CC; |
| |
| // ======================= |
| // HelloWorldScene.cpp |
| // ======================= |
| |
| Scene* HelloWorld::scene() |
| { |
| // 'scene' is an autorelease object |
| Scene *scene = Scene::create(); |
| |
| // 'layer' is an autorelease object |
| HelloWorld *layer = HelloWorld::create(); |
| |
| // add layer as a child to scene |
| scene->addChild(layer); |
| |
| // return the scene |
| return scene; |
| } |
| |
| // on "init" you need to initialize your instance |
| bool HelloWorld::init() |
| { |
| ////////////////////////////// |
| // 1. super init first |
| if ( !Layer::init() ) |
| { |
| return false; |
| } |
| |
| Size visibleSize = Director::getInstance()->getVisibleSize(); |
| Point origin = Director::getInstance()->getVisibleOrigin(); |
| |
| ///////////////////////////// |
| // 2. add a menu item with "X" image, which is clicked to quit the program |
| // you may modify it. |
| |
| // add a "close" icon to exit the progress. it's an autorelease object |
| MenuItemImage *closeItem = MenuItemImage::create( |
| "CloseNormal.png", |
| "CloseSelected.png", |
| CC_CALLBACK_1(HelloWorld::menuCloseCallback,this)); |
| |
| closeItem->setPosition(origin + Point(visibleSize) - Point(closeItem->getContentSize() / 2)); |
| |
| // create menu, it's an autorelease object |
| Menu* menu = Menu::create(closeItem, nullptr); |
| menu->setPosition(Point::ZERO); |
| this->addChild(menu, 1); |
| |
| ///////////////////////////// |
| // 3. add your codes below... |
| |
| // add a label shows "Hello World" |
| // create and initialize a label |
| |
| LabelTTF* label = LabelTTF::create("Hello World", "Arial", TITLE_FONT_SIZE); |
| |
| // position the label on the center of the screen |
| label->setPosition(Point(origin.x + visibleSize.width/2, |
| origin.y + visibleSize.height - label->getContentSize().height)); |
| |
| // add the label as a child to this layer |
| this->addChild(label, 1); |
| |
| // add "HelloWorld" splash screen" |
| Sprite* sprite = Sprite::create("HelloWorld.png"); |
| |
| // position the sprite on the center of the screen |
| sprite->setPosition(Point(visibleSize / 2) + origin); |
| |
| // add the sprite as a child to this layer |
| this->addChild(sprite, 0); |
| |
| return true; |
| } |
| |
| |
| void HelloWorld::menuCloseCallback(Object* sender) |
| { |
| Director::getInstance()->end(); |
| |
| #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) |
| exit(0); |
| #endif |
| } |
| |
| // ================= |
| // AppDelegate.cpp |
| // ================= |
| |
| using namespace std; |
| |
| AppDelegate::AppDelegate() { |
| |
| } |
| |
| AppDelegate::~AppDelegate() |
| { |
| } |
| |
| bool AppDelegate::applicationDidFinishLaunching() { |
| // initialize director |
| Director* director = Director::getInstance(); |
| EGLView* glView = EGLView::getInstance(); |
| |
| director->setOpenGLView(glView); |
| |
| Size size = director->getWinSize(); |
| |
| // Set the design resolution |
| glView->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER); |
| |
| Size frameSize = glView->getFrameSize(); |
| |
| vector<string> searchPath; |
| |
| // In this demo, we select resource according to the frame's height. |
| // If the resource size is different from design resolution size, you need to set contentScaleFactor. |
| // We use the ratio of resource's height to the height of design resolution, |
| // this can make sure that the resource's height could fit for the height of design resolution. |
| |
| // if the frame's height is larger than the height of medium resource size, select large resource. |
| if (frameSize.height > mediumResource.size.height) |
| { |
| searchPath.push_back(largeResource.directory); |
| |
| director->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height, largeResource.size.width/designResolutionSize.width)); |
| } |
| // if the frame's height is larger than the height of small resource size, select medium resource. |
| else if (frameSize.height > smallResource.size.height) |
| { |
| searchPath.push_back(mediumResource.directory); |
| |
| director->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height, mediumResource.size.width/designResolutionSize.width)); |
| } |
| // if the frame's height is smaller than the height of medium resource size, select small resource. |
| else |
| { |
| searchPath.push_back(smallResource.directory); |
| |
| director->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height, smallResource.size.width/designResolutionSize.width)); |
| } |
| |
| // set searching path |
| FileUtils::getInstance()->setSearchPaths(searchPath); |
| |
| // turn on display FPS |
| director->setDisplayStats(false); |
| |
| // set FPS. the default value is 1.0/60 if you don't call this |
| director->setAnimationInterval(1.0 / 60); |
| |
| // create a scene. it's an autorelease object |
| Scene *scene = HelloWorld::scene(); |
| |
| // run |
| director->runWithScene(scene); |
| |
| return true; |
| } |
| |
| // This function will be called when the app is inactive. When comes a phone call,it's be invoked too |
| void AppDelegate::applicationDidEnterBackground() { |
| Director::getInstance()->stopAnimation(); |
| |
| // if you use SimpleAudioEngine, it must be pause |
| // SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic(); |
| } |
| |
| // this function will be called when the app is active again |
| void AppDelegate::applicationWillEnterForeground() { |
| Director::getInstance()->startAnimation(); |
| |
| // if you use SimpleAudioEngine, it must resume here |
| // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic(); |
| } |
| |
| |
| // ========== |
| // main.cpp |
| // ========== |
| |
| int main(int argc, char **argv) |
| { |
| // create the application instance |
| AppDelegate app; |
| EM_ASM({ |
| Browser.setCanvasSize(640, 480); |
| }); |
| return Application::getInstance()->run(); |
| } |