Happy Bird2


開発環境

・Cocos2d-JS v.3.0
・Cocos Code IDE


Happy Birdからの改善点

・リセットボタンの設置


res(サンプル画像データ/音データ)

・ダウンロード(ZiPファイル)


app.js

// グローバル変数
var bird;
var scoreLabel;
var bg1;
var bg2;
var block1;
var block2;
var bgm;
var vSpeed = 0;
var score = 0;

// ゲームのレーヤー
var Game = cc.Layer.extend({
	// (1)初期化の命令ブロック
	init:function(){
		this._super();
		var size = cc.winSize;

		// キャラクターを登場させる
		bird = cc.Sprite(res.bird_png);
		bird.setPosition(800/2, 450/2);
		this.addChild(bird, 10);

		// アニメーションしながら登場させる
		// 0.01秒で4倍の大きさにする(1)
		var scaleTo = cc.scaleTo(0.01, 4.0, 4.0);

		// 0.3秒で360度回転させる(2)
		var rotateBy = cc.rotateBy(0.3, 360);

		// 0.3秒で元の大きさにする(3)
		var scaleTo2 = cc.scaleTo(0.3, 1.0, 1.0);

		// (2)と(3)を同時に実行する(4)
		var spawn = cc.spawn(rotateBy,scaleTo2);

		// (1)→(4)の順番で実行する
		var sequence = cc.sequence(scaleTo,spawn);
		bird.runAction(sequence);

		// 背景画面を作る
		bg1 = cc.Sprite(res.bg_star_png);
		bg1.setAnchorPoint(0, 0);
		bg1.setPosition(0, 0);
		this.addChild(bg1, 1);

		bg2 = cc.Sprite(res.bg_star_png);
		bg2.setAnchorPoint(0, 0);
		bg2.setPosition(800, 0);
		this.addChild(bg2, 1);

		// ブロックを作る(上に設置)
		block1 = cc.Sprite(res.block_png);
		block1.setAnchorPoint(0, 0);
		block1.setPosition(600, 0);
		this.addChild(block1, 2);

		// ブロックを作る(下に設置)
		block2 = cc.Sprite(res.block_png);
		block2.setAnchorPoint(0, 1);
		block2.setPosition(700, 450);
		block2.setScale(1.0, 0.8)
		this.addChild(block2, 2);

		// BGMを再生する
		bgm = cc.audioEngine;
		bgm.playMusic(res.bgm_mp3, true);

		// 点数ラベルを作る
		scoreLabel = cc.LabelTTF("SCORE", "Arial", 20);
		scoreLabel.setAnchorPoint(0, 0);
		scoreLabel.setPosition(50, 400);
		this.addChild(scoreLabel, 8);

		// このレーヤーでタッチイベントを実行できるようにする
		cc.eventManager.addListener({
			event:cc.EventListener.TOUCH_ONE_BY_ONE,
			swallowTouches:true,
			onTouchBegan:this.onTouchBegan,
			onTouchMoved:this.onTouchMoved,
			onTouchEnded:this.onTouchEnded,
		}, this);

		// updateの命令ブロックを呼び出す
		this.scheduleUpdate();
		return true;
	},

	// (2)updateの命令ブロック(毎フレームごとに呼び出される)
	update:function(){
		// 背景画面を横に動かす
		bg1.setPosition(bg1.getPosition().x - 1, bg1.getPosition().y);
		bg2.setPosition(bg2.getPosition().x - 1, bg2.getPosition().y);

		// 背景画面をループさせる
		if (bg1.getPosition().x < -800) {
			bg1.setPosition(800, 0);
		}
		if (bg2.getPosition().x < -800) {
			bg2.setPosition(800, 0);
		}

		// ブロックを横に動かす
		block1.setPosition(block1.getPosition().x - 2, block1.getPosition().y);
		block2.setPosition(block2.getPosition().x - 2, block2.getPosition().y);

		// ブロックをループさせる
		if (block1.getPosition().x < -50) {
			block1.setPosition(900, 0);
		}
		if (block2.getPosition().x < -50) {
			block2.setPosition(1100, 450);
		}

		// キャラクターを動かす
		var pos = bird.getPosition();
		vSpeed -= 0.1;

		// 落下スピードを加速させる
		bird.setPosition(pos.x, pos.y + vSpeed);

		// 点数を動かす
		score++;
		scoreLabel.setString("SCORE:" + score + "m");

		// 衝突したらゲームオーバー
		// キャラクターの枠を取得する
		var birdRect = bird.getBoundingBox();

		// ブロックの枠を取得する
		var block1Rect = block1.getBoundingBox();
		var block2Rect = block2.getBoundingBox();

		// もし枠同士がぶつかったら、
		if (cc.rectIntersectsRect(birdRect, block1Rect)) {
			// ゲームオーバーの命令ブロックを呼び出す
			this.gameOver();
		}
		if (cc.rectIntersectsRect(birdRect, block2Rect)) {
			// ゲームオーバーの命令ブロックを呼び出す
			this.gameOver();
		}

		// もし地面とぶつかったら、
		if (pos.y <= 40) {
			// ゲームオーバーの命令ブロックを呼び出す
			this.gameOver();
		}
	},

	// (3)タッチイベントの命令ブロック
	onTouchBegan:function(touch,event){
		// タッチすると羽の音が鳴る
		var sound = cc.audioEngine;
		sound.playEffect(res.swing_mp3);

		// タッチするとキャラクターが上昇する
		vSpeed = 5;

		// キャラクターにアニメーションを付ける
		var rotate = cc.rotateTo(0.01, -10);
		var rotate2 = cc.rotateTo(1.0, 20);
		var sequence = cc.sequence(rotate, rotate2);
		bird.runAction(sequence);

		return true;
	},

	// (4)ゲームオーバーの命令ブロック
	gameOver:function(){
		// update命令ブロックを停止する
		this.unscheduleUpdate();

		// 衝突音を出す
		var sound = cc.audioEngine;
		sound.playEffect(res.hit_sound_mp3);

		// BGMを停止する
		bgm.stopMusic();

		// タッチイベントを除去してジャンプしないようにする
		cc.eventManager.removeAllListeners();

		// ゲームオーバーを表示する
		var gameover = cc.Sprite(res.gameover_png);
		gameover.setPosition(800/2, 450/2);
		this.addChild(gameover, 20);

		// リセットボタンを作成する
		// 「もう一度」が押されると、リセットの命令ブロックが呼び出される
		var resetButton = cc.MenuItemFont("もう一度", this.onReset);

		// リセットボタンのサイズを決める
		resetButton.setFontSize(30);

		// menuの中にリセットボタンを代入する
		var menu = cc.Menu(resetButton);

		// menuの表示位置を決める
		menu.setPosition(800/2, 100);

		// menuを画面に追加する
		this.addChild(menu, 20);
	},

	// (5)リセットの命令ブロック
	onReset:function(){
		// グローバル変数を初期化する(nullは空っぽの意味)
		bird = null;
		scoreLabel = null;
		bg1 = null;
		bg2 = null;
		block1 = null;
		block2 = null;
		bgm = null;
		vSpeed = 0;
		score = 0;

		// 再度、GameSceneを呼び出してゲームスタート!
		cc.director.replaceScene(new GameScene);
	}
});

// ゲームのシーン
var GameScene = cc.Scene.extend({
	onEnter:function(){
		this._super();
		var layer = new Game();
		layer.init();
		this.addChild(layer);
	}
});

resource.js

var res = {
    bg_star_png : "res/bg_star.png",
    bgm_mp3 : "res/bgm.mp3",
    bird_png : "res/bird.png",
    block_png : "res/block.png",
    gameover_png : "res/gameoverIMG.png",
    hit_sound_mp3 : "res/hit_sound.mp3",
    swing_mp3 : "res/swing.mp3"
};

var g_resources = [];
for (var i in res) {
    g_resources.push(res[i]);
}

main.js

cc.game.onStart = function(){
    cc.view.adjustViewPort(true);
    cc.view.setDesignResolutionSize(800, 450, cc.ResolutionPolicy.SHOW_ALL);
    cc.view.resizeWithBrowserSize(true);
    //load resources
    cc.LoaderScene.preload(g_resources, function () {
        cc.director.runScene(new GameScene());
    }, this);
};
cc.game.run();