// Copyright 2017 The Emscripten Authors. All rights reserved.1// Emscripten is available under two separate licenses, the MIT license and the2// University of Illinois/NCSA Open Source License. Both these licenses can be3// found in the LICENSE file.45#include <stdlib.h>6#include <stdio.h>7#include <unistd.h>8#include <string>910#include "cocos2d.h"1112#include <emscripten.h>1314// =============15// AppMacros.h16// =============1718/* For demonstrating using one design resolution to match different resources,19or one resource to match different design resolutions.2021[Situation 1] Using one design resolution to match different resources.22Please look into Appdelegate::applicationDidFinishLaunching.23We check current device frame size to decide which resource need to be selected.24So if you want to test this situation which said in title '[Situation 1]',25you should change ios simulator to different device(e.g. iphone, iphone-retina3.5, iphone-retina4.0, ipad, ipad-retina),26or change the window size in "proj.XXX/main.cpp" by "CCEGLView::setFrameSize" if you are using win32 or linux plaform27and modify "proj.mac/AppController.mm" by changing the window rectangle.2829[Situation 2] Using one resource to match different design resolutions.30The coordinates in your codes is based on your current design resolution rather than resource size.31Therefore, your design resolution could be very large and your resource size could be small.32To test this, just define the marco 'TARGET_DESIGN_RESOLUTION_SIZE' to 'DESIGN_RESOLUTION_2048X1536'33and open iphone simulator or create a window of 480x320 size.3435[Note] Normally, developer just need to define one design resolution(e.g. 960x640) with one or more resources.36*/3738#define DESIGN_RESOLUTION_480X320 039#define DESIGN_RESOLUTION_1024X768 140#define DESIGN_RESOLUTION_2048X1536 24142/* If you want to switch design resolution, change next line */43#define TARGET_DESIGN_RESOLUTION_SIZE DESIGN_RESOLUTION_480X3204445typedef struct tagResource46{47cocos2d::Size size;48char directory[100];49}Resource;5051static Resource smallResource = { cocos2d::Size(480, 320), "iphone" };52static Resource mediumResource = { cocos2d::Size(1024, 768), "ipad" };53static Resource largeResource = { cocos2d::Size(2048, 1536), "ipadhd" };5455#if (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_480X320)56static cocos2d::Size designResolutionSize = cocos2d::Size(480, 320);57#elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_1024X768)58static cocos2d::Size designResolutionSize = cocos2d::Size(1024, 768);59#elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_2048X1536)60static cocos2d::Size designResolutionSize = cocos2d::Size(2048, 1536);61#else62#error unknown target design resolution!63#endif6465// The font size 24 is designed for small resolution, so we should change it to fit for current design resolution66#define TITLE_FONT_SIZE (cocos2d::EGLView::getInstance()->getDesignResolutionSize().width / smallResource.size.width * 24)6768// ===============69// AppDelegate.h70// ===============7172/**73@brief The cocos2d Application.7475The reason for implement as private inheritance is to hide some interface call by Director.76*/77class AppDelegate : private cocos2d::Application78{79public:80AppDelegate();81virtual ~AppDelegate();8283/**84@brief Implement Director and Scene init code here.85@return true Initialize success, app continue.86@return false Initialize failed, app terminate.87*/88virtual bool applicationDidFinishLaunching();8990/**91@brief The function be called when the application enter background92@param the pointer of the application93*/94virtual void applicationDidEnterBackground();9596/**97@brief The function be called when the application enter foreground98@param the pointer of the application99*/100virtual void applicationWillEnterForeground();101};102103// ===================104// HelloWorldScene.h105// ===================106107class HelloWorld : public cocos2d::Layer108{109public:110// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone111virtual bool init();112113// there's no 'id' in cpp, so we recommend returning the class instance pointer114static cocos2d::Scene* scene();115116// a selector callback117void menuCloseCallback(Object* sender);118119// implement the "static node()" method manually120CREATE_FUNC(HelloWorld);121};122123USING_NS_CC;124125// =======================126// HelloWorldScene.cpp127// =======================128129Scene* HelloWorld::scene()130{131// 'scene' is an autorelease object132Scene *scene = Scene::create();133134// 'layer' is an autorelease object135HelloWorld *layer = HelloWorld::create();136137// add layer as a child to scene138scene->addChild(layer);139140// return the scene141return scene;142}143144// on "init" you need to initialize your instance145bool HelloWorld::init()146{147//////////////////////////////148// 1. super init first149if ( !Layer::init() )150{151return false;152}153154Size visibleSize = Director::getInstance()->getVisibleSize();155Point origin = Director::getInstance()->getVisibleOrigin();156157/////////////////////////////158// 2. add a menu item with "X" image, which is clicked to quit the program159// you may modify it.160161// add a "close" icon to exit the progress. it's an autorelease object162MenuItemImage *closeItem = MenuItemImage::create(163"CloseNormal.png",164"CloseSelected.png",165CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));166167closeItem->setPosition(origin + Point(visibleSize) - Point(closeItem->getContentSize() / 2));168169// create menu, it's an autorelease object170Menu* menu = Menu::create(closeItem, nullptr);171menu->setPosition(Point::ZERO);172this->addChild(menu, 1);173174/////////////////////////////175// 3. add your codes below...176177// add a label shows "Hello World"178// create and initialize a label179180LabelTTF* label = LabelTTF::create("Hello World", "Arial", TITLE_FONT_SIZE);181182// position the label on the center of the screen183label->setPosition(Point(origin.x + visibleSize.width/2,184origin.y + visibleSize.height - label->getContentSize().height));185186// add the label as a child to this layer187this->addChild(label, 1);188189// add "HelloWorld" splash screen"190Sprite* sprite = Sprite::create("HelloWorld.png");191192// position the sprite on the center of the screen193sprite->setPosition(Point(visibleSize / 2) + origin);194195// add the sprite as a child to this layer196this->addChild(sprite, 0);197198return true;199}200201202void HelloWorld::menuCloseCallback(Object* sender)203{204Director::getInstance()->end();205206#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)207exit(0);208#endif209}210211// =================212// AppDelegate.cpp213// =================214215using namespace std;216217AppDelegate::AppDelegate() {218219}220221AppDelegate::~AppDelegate()222{223}224225bool AppDelegate::applicationDidFinishLaunching() {226// initialize director227Director* director = Director::getInstance();228EGLView* glView = EGLView::getInstance();229230director->setOpenGLView(glView);231232Size size = director->getWinSize();233234// Set the design resolution235glView->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER);236237Size frameSize = glView->getFrameSize();238239vector<string> searchPath;240241// In this demo, we select resource according to the frame's height.242// If the resource size is different from design resolution size, you need to set contentScaleFactor.243// We use the ratio of resource's height to the height of design resolution,244// this can make sure that the resource's height could fit for the height of design resolution.245246// if the frame's height is larger than the height of medium resource size, select large resource.247if (frameSize.height > mediumResource.size.height)248{249searchPath.push_back(largeResource.directory);250251director->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height, largeResource.size.width/designResolutionSize.width));252}253// if the frame's height is larger than the height of small resource size, select medium resource.254else if (frameSize.height > smallResource.size.height)255{256searchPath.push_back(mediumResource.directory);257258director->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height, mediumResource.size.width/designResolutionSize.width));259}260// if the frame's height is smaller than the height of medium resource size, select small resource.261else262{263searchPath.push_back(smallResource.directory);264265director->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height, smallResource.size.width/designResolutionSize.width));266}267268// set searching path269FileUtils::getInstance()->setSearchPaths(searchPath);270271// turn on display FPS272director->setDisplayStats(false);273274// set FPS. the default value is 1.0/60 if you don't call this275director->setAnimationInterval(1.0 / 60);276277// create a scene. it's an autorelease object278Scene *scene = HelloWorld::scene();279280// run281director->runWithScene(scene);282283return true;284}285286// This function will be called when the app is inactive. When comes a phone call,it's be invoked too287void AppDelegate::applicationDidEnterBackground() {288Director::getInstance()->stopAnimation();289290// if you use SimpleAudioEngine, it must be pause291// SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();292}293294// this function will be called when the app is active again295void AppDelegate::applicationWillEnterForeground() {296Director::getInstance()->startAnimation();297298// if you use SimpleAudioEngine, it must resume here299// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();300}301302303// ==========304// main.cpp305// ==========306307int main(int argc, char **argv)308{309// create the application instance310AppDelegate app;311EM_ASM({312Browser.setCanvasSize(640, 480);313});314return Application::getInstance()->run();315}316317318