(一)初识cocos2d

cocos2d版本:  3.15

vs版本: 2015

按照着网上说的一些教程,先到 http://www.cocos2d-x.org/download  下载源码包,但是我发现了一个坑,

我在2017-09-15下载的最新版是3.15.1,但是几次下载回来都说文件格式损坏,然后压缩出的文件不完整。

我很不解,于是下载了历史版本3.15  发现就没问题了,然后按照教程: http://www.cjjjs.com/paper/sckf/201652614817878.html

利用C++技术网中命令行的方式新建了一个项目,然后再用vs打开即可。

不过好像和我在《cocos2d高级开发教程》上看到的有些不一致(可能是因为《cocos2d高级开发教程》说的是过时的版本吧)


我看到的文件目录是这样的,然后参考《cocos2d高级开发教程》去看懂这个helloworld,运行结果如下:


右下角是我们加入的一个菜单,点击会关闭该窗口

我这里对一些代码写了一些注释,帮助读懂第一个helloworld的源代码:

HelloWorldScene.h:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Scene 
	//定义了一个 HelloWorld类,该类继承自 Scene,因此 HelloWorld 本身是一个场景
{	//从 CCLayer 类派生出 HelloWorld 类(这是一个层),并重载了 HelloWorld 类的 init()方法
public:
    static cocos2d::Scene* createScene(); //在 Cocos2d 中,在层下设置一个创建场景的静态函数是一个常见的技巧

	//为了保证初始化方法可以被子类重载,需要确保初始化方法声明为虚函数:
    virtual bool init(); //初始化 HelloWorld 类
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__


HelloWorldScene.c:

#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    return HelloWorld::create(); //????
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first, 调用父类的 init 方法来进行最初的初始化
    if ( !Scene::init() )
    {
        return false;
    }
    /* 为什么我们要在一个实例方法中初始化类, 而不在构造函数中初始化呢?
												在 C++中,一般习惯在构造函数中初始化类
	           ------Cocos2d-x 不使用传统的值类型,所有的对象都创建在堆上,然后通过指针引用	
	创建 Cocos2d-x 对象通常有两种方法:
	第一种是首先使用 new 操作符创造一个未初始化的对象,然后调用 init 系列方法来初始化;
	第二种是使用静态的工厂方法直接创建一个对象。
																										*/
    auto visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 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
	//在 HelloWorld 类的 init()方法中添加了一个菜单,当用户点击该菜单时,就会触发此类中的 menuCloseCallback()方法
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
	//放置在右下角
    closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));

    // create menu, it's an autorelease object
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1); //这个层添加菜单

    /////////////////////////////
    // 3. add your codes below... 创建"Hello World"标签并添加到层中

    // add a label shows "Hello World"
    // create and initialize a label
    //创建一个文本标签并添加到层中,显示内容"Hello World
    auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
    
    // position the label on the center of the screen
    label->setPosition(Vec2(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);//1是z轴顺序,也就是显示的先后顺序,其值越大,表示显示的位置就越靠前。

    //4. add "HelloWorld" splash screen",用"HelloWorld.png"创建一个精灵并添加到层中
    auto sprite = Sprite::create("HelloWorld.png"); //工厂方法
	/*
		使用构造函数创建的对象,它的所有权已经属于调用者了,使用工厂方法创建的对象的所有权却并不属于调用者,
								因此,使用构造函数创建的对象需要调用者负责释放,而使用工厂方法创建的对象则不需要。
																												*/
    // position the sprite on the center of the screen
    sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    // add the sprite as a child to this layer
    this->addChild(sprite, 0);
    
    return true;
}


void HelloWorld::menuCloseCallback(Ref* pSender)
{
    //Close the cocos2d-x game scene and quit the application
    Director::getInstance()->end();

    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
    
    /*To navigate back to native iOS screen(if present) without quitting the application  ,do not use Director::getInstance()->end() and exit(0) as given above,instead trigger a custom event created in RootViewController.mm as below*/
    
    //EventCustom customEndEvent("game_scene_close_event");
    //_eventDispatcher->dispatchEvent(&customEndEvent);
    
    
}
单例( singleton)则是一个很易于理解的概念。在 Cocos2d-x 引擎中,我们能看到大量单例的身影.它们大部分出现在一些系统资源管理类中。单例模式保证了全局有且只有一个实例对象,保证自动地初始化该对象,使得程序在任何时候任何地方都可以访问、获取该对象。 

例如, Cocos2d-x 的游戏流程控制器 CCDirector 是一个独一无二的控制器,用于切换游戏场景。换句话说,不可能同时存在两个 CCDirector 实例。 
在这种情况下, Cocos2d-x 采用了单例的技巧。用户可以通过类提供的静态方法获取独一无二的实例,而不需要自己来创建。 

例如,我在vs中的项目视图下的 base/ 看到的CCDirector.cpp中的代码:

static Director *s_SharedDirector = nullptr;
//...其他一些于此无关紧要的代码
Director* Director::getInstance()
{
    if (!s_SharedDirector)
    {
        s_SharedDirector = new (std::nothrow) Director;
        CCASSERT(s_SharedDirector, "FATAL: Not enough memory");
        s_SharedDirector->init();
    }


    return s_SharedDirector;
}

这里看到了熟悉的身影, 单例模式!!!!

内容概要:本文档是份针对2025-2026年Java后端大厂面试的高频考点全面梳理,涵盖Java基础、集合框架、并发编程、JVM、Spring全家桶、MySQL、Redis、消息队列、分布式与微服务等核心技术模块。内容不仅包括经典概念辨析(如String与StringBuilder区别、HashMap底层结构),还深入源码机制与设计原理(如Spring三级缓存解决循环依赖、AOP动态代理实现),并结合实际场景探讨问题排查与技术选型(如GC调优、缓存穿透解决方案)。特别强调从“背八股”向源码理解、线上排障和设计权衡的能力转变,体现当前面试趋势的深度化与实战化。; 适合人群:具备1-3年工作经验,准备冲击中高级Java岗位的研发人员,尤其适合希望系统提升面试竞争力、深入理解主流技术底层原理的开发者。; 使用场景及目标:①应对大厂Java后端技术面试,掌握高频考点与最新趋势;②深入理解核心技术的设计动机与实现细节,如ConcurrentHashMap的线程安全机制、分布式ID生成方案对比;③提升实际问题分析与解决能力,如Full GC排查、事务失效定位等。; 阅读建议:此资源以面试为导向,兼具广度与深度,建议结合自身项目经验进行对照学习,注重理解“为什么”而非仅仅记忆结论,对关键知识点应动手验证(如ThreadLocal内存泄漏实验),并在模拟面试中强化表达逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值