コンテンツにスキップ

Cocos2d Cheat Sheet

Overview

Cocos2d is a family of open-source game development frameworks, with Cocos Creator being the modern flagship product. Originally started as a Python framework, the ecosystem evolved through Cocos2d-x (C++) and Cocos2d-js (JavaScript) into Cocos Creator, a complete game engine with a visual editor, component-based architecture, and support for both 2D and 3D game development. Cocos Creator uses TypeScript/JavaScript as its primary scripting language and provides a workflow similar to Unity, with scene editing, animation timelines, and visual asset management.

Cocos Creator excels at mobile 2D game development and has strong adoption in the Asian gaming market, particularly for casual games, card games, and social games. It exports to iOS, Android, HTML5, Facebook Instant Games, WeChat Mini Games, and native desktop platforms. The engine includes a physics system (Box2D for 2D, Bullet/cannon.js for 3D), UI system, animation editor, particle effects, tilemaps, and a robust resource management pipeline with asset bundling for optimized loading.

Installation

# Download Cocos Creator from:
# https://www.cocos.com/en/creator/download

# macOS: Install Cocos Dashboard via DMG
# Windows: Install Cocos Dashboard via installer
# Linux: Use AppImage from official download

# Command-line project creation (Cocos Creator 3.x)
# After installing Cocos Dashboard, create project from UI
# Or clone a template:
git clone https://github.com/nicholasbailey/cocos-creator-template.git my-game
cd my-game
npm install

# Build from command line
npx cocos-creator build --platform web-desktop
npx cocos-creator build --platform android
npx cocos-creator build --platform ios

# For Cocos2d-x (legacy C++ framework)
# Clone and setup
git clone https://github.com/cocos2d/cocos2d-x.git
cd cocos2d-x
python setup.py
source ~/.bash_profile

# Create cocos2d-x project
cocos new MyGame -p com.example.mygame -l cpp -d ~/projects
cd ~/projects/MyGame
cocos run -p linux

Project Structure (Cocos Creator)

my-game/
├── assets/                    # Game assets
│   ├── scenes/               # Scene files (.scene)
│   ├── scripts/              # TypeScript/JavaScript
│   ├── prefabs/              # Reusable node templates
│   ├── textures/             # Images and sprite sheets
│   ├── animations/           # Animation clips
│   ├── audio/                # Sound files
│   └── fonts/                # Font files
├── settings/                  # Project settings
│   └── project.json
├── native/                    # Native platform configs
├── build/                     # Build output
├── temp/                      # Temporary files
├── package.json
└── tsconfig.json

Component Scripting (TypeScript)

import { _decorator, Component, Node, Vec3, input, Input, EventKeyboard, KeyCode } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('PlayerController')
export class PlayerController extends Component {
    @property
    speed: number = 200;

    @property
    jumpForce: number = 500;

    @property(Node)
    scoreLabel: Node = null;

    private _velocity: Vec3 = new Vec3();
    private _isGrounded: boolean = true;

    start() {
        input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
        input.on(Input.EventType.KEY_UP, this.onKeyUp, this);
    }

    update(deltaTime: number) {
        const pos = this.node.position;
        this.node.setPosition(
            pos.x + this._velocity.x * deltaTime,
            pos.y + this._velocity.y * deltaTime,
            pos.z
        );
    }

    onKeyDown(event: EventKeyboard) {
        switch (event.keyCode) {
            case KeyCode.ARROW_LEFT:
                this._velocity.x = -this.speed;
                break;
            case KeyCode.ARROW_RIGHT:
                this._velocity.x = this.speed;
                break;
            case KeyCode.SPACE:
                if (this._isGrounded) {
                    this._velocity.y = this.jumpForce;
                    this._isGrounded = false;
                }
                break;
        }
    }

    onKeyUp(event: EventKeyboard) {
        switch (event.keyCode) {
            case KeyCode.ARROW_LEFT:
            case KeyCode.ARROW_RIGHT:
                this._velocity.x = 0;
                break;
        }
    }

    onDestroy() {
        input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this);
        input.off(Input.EventType.KEY_UP, this.onKeyUp, this);
    }
}

Node and Component System

import { _decorator, Component, Node, Sprite, Label, SpriteFrame,
         instantiate, Prefab, director, find } from 'cc';

@ccclass('GameManager')
export class GameManager extends Component {
    @property(Prefab)
    enemyPrefab: Prefab = null;

    // Node operations
    createEnemy() {
        const enemy = instantiate(this.enemyPrefab);
        enemy.setPosition(400, 300, 0);
        enemy.setScale(2, 2, 1);
        enemy.setRotationFromEuler(0, 0, 45);
        this.node.addChild(enemy);
    }

    // Find nodes
    findNodes() {
        const player = find('Canvas/Player');
        const label = this.node.getChildByName('ScoreLabel');
        const allEnemies = this.node.getComponentsInChildren(EnemyController);
    }

    // Component operations
    setupSprite() {
        const sprite = this.node.getComponent(Sprite);
        const label = this.node.addComponent(Label);
        label.string = "Hello World";
        label.fontSize = 24;
    }

    // Scene management
    loadScene() {
        director.loadScene('GameScene');
    }

    // Scheduling
    start() {
        this.schedule(this.spawnEnemy, 2.0);       // Every 2 seconds
        this.scheduleOnce(this.startGame, 1.0);    // Once after 1 second
    }

    spawnEnemy() {
        this.createEnemy();
    }

    // Remove node
    destroyEnemy(enemy: Node) {
        enemy.removeFromParent();
        enemy.destroy();
    }
}

Common Components

ComponentDescription
Sprite2D image rendering
LabelText display
ButtonInteractive button
LayoutAuto-layout container
ScrollViewScrollable container
EditBoxText input field
ProgressBarProgress indicator
ToggleCheckbox/radio button
AnimationKeyframe animation
RigidBody2D2D physics body
BoxCollider2DBox collision shape
CircleCollider2DCircle collision shape
AudioSourceSound playback
ParticleSystem2D2D particle effects
TiledMapTiled map renderer
CameraScene camera

Touch and Input

import { _decorator, Component, EventTouch, Node, UITransform, Vec2, Vec3 } from 'cc';

@ccclass('TouchHandler')
export class TouchHandler extends Component {
    start() {
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
    }

    onTouchStart(event: EventTouch) {
        const location = event.getUILocation();
        console.log(`Touch start: ${location.x}, ${location.y}`);
    }

    onTouchMove(event: EventTouch) {
        const delta = event.getUIDelta();
        const pos = this.node.position;
        this.node.setPosition(pos.x + delta.x, pos.y + delta.y, pos.z);
    }

    onTouchEnd(event: EventTouch) {
        console.log('Touch ended');
    }
}

Animation

import { _decorator, Component, Animation, tween, Vec3, Node } from 'cc';

@ccclass('AnimController')
export class AnimController extends Component {
    // Component animation
    playAnimation() {
        const anim = this.getComponent(Animation);
        anim.play('walk');
        anim.on(Animation.EventType.FINISHED, this.onAnimFinished, this);
    }

    // Tween animation
    tweenExample() {
        tween(this.node)
            .to(1, { position: new Vec3(300, 200, 0) }, { easing: 'sineOut' })
            .to(0.5, { scale: new Vec3(2, 2, 1) })
            .call(() => { console.log('Tween complete'); })
            .start();

        // Repeat and yoyo
        tween(this.node)
            .to(0.5, { position: new Vec3(0, 50, 0) })
            .to(0.5, { position: new Vec3(0, 0, 0) })
            .union()
            .repeatForever()
            .start();
    }

    // Sequence
    sequenceAnimation() {
        tween(this.node)
            .parallel(
                tween().to(1, { position: new Vec3(500, 0, 0) }),
                tween().to(1, { angle: 360 })
            )
            .delay(0.5)
            .to(0.3, { scale: new Vec3(0, 0, 0) })
            .call(() => this.node.destroy())
            .start();
    }
}

Physics 2D

import { _decorator, Component, RigidBody2D, BoxCollider2D, Contact2DType,
         Collider2D, IPhysics2DContact, ERigidBody2DType, Vec2 } from 'cc';

@ccclass('PhysicsPlayer')
export class PhysicsPlayer extends Component {
    start() {
        const collider = this.getComponent(BoxCollider2D);
        if (collider) {
            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
            collider.on(Contact2DType.END_CONTACT, this.onEndContact, this);
        }
    }

    onBeginContact(self: Collider2D, other: Collider2D, contact: IPhysics2DContact | null) {
        console.log(`Collided with: ${other.node.name}`);
        if (other.node.name === 'Coin') {
            other.node.destroy();
        }
    }

    jump() {
        const rb = this.getComponent(RigidBody2D);
        rb.linearVelocity = new Vec2(rb.linearVelocity.x, 10);
    }

    move(direction: number) {
        const rb = this.getComponent(RigidBody2D);
        rb.linearVelocity = new Vec2(direction * 5, rb.linearVelocity.y);
    }
}

Configuration

// tsconfig.json
{
    "compilerOptions": {
        "target": "ES2015",
        "module": "ES2015",
        "strict": true,
        "types": ["cc/global"]
    }
}

Build and Deploy

# Build for web
npx cocos-creator build --platform web-desktop
npx cocos-creator build --platform web-mobile

# Build for native
npx cocos-creator build --platform android --android-studio
npx cocos-creator build --platform ios

# Build for mini games
npx cocos-creator build --platform wechatgame
npx cocos-creator build --platform bytedance-mini-game
npx cocos-creator build --platform facebook-instant-games

# Debug build
npx cocos-creator build --platform web-desktop --debug

Advanced Usage

// Resource loading
import { resources, SpriteFrame, Texture2D, JsonAsset } from 'cc';

resources.load('textures/hero/spriteFrame', SpriteFrame, (err, spriteFrame) => {
    if (!err) {
        this.getComponent(Sprite).spriteFrame = spriteFrame;
    }
});

// Load bundle
import { assetManager } from 'cc';
assetManager.loadBundle('level1', (err, bundle) => {
    bundle.load('map', TiledMapAsset, (err, asset) => {
        // Use asset
    });
});

// Event system
import { EventTarget } from 'cc';
const gameEvents = new EventTarget();
gameEvents.emit('score-changed', 100);
gameEvents.on('score-changed', (score: number) => {
    console.log(`Score: ${score}`);
});

// Object pooling
import { NodePool, instantiate } from 'cc';
const bulletPool = new NodePool();

function getBullet(): Node {
    let bullet = bulletPool.get();
    if (!bullet) {
        bullet = instantiate(bulletPrefab);
    }
    return bullet;
}

function recycleBullet(bullet: Node) {
    bulletPool.put(bullet);
}

Troubleshooting

IssueSolution
Script not attaching to nodeEnsure @ccclass decorator is present with correct name
Property not showing in editorUse @property decorator with correct type annotation
Touch events not firingCheck node has a UITransform component with proper size
Build fails for AndroidVerify Android SDK/NDK paths in Cocos Dashboard preferences
Assets not loadingCheck path is relative to assets/resources/; use correct loader
Physics not workingEnable physics in Project Settings; add RigidBody and Collider
Performance issues on mobileReduce draw calls; use texture atlases; limit particle count
TypeScript errorsRun tsc to check; ensure tsconfig.json is correct
Animation not playingVerify clip is assigned; check default clip and play-on-load settings
Scene transition blankPreload scene with director.preloadScene() before switching