mirror of https://github.com/axmolengine/axmol.git
1101 lines
38 KiB
JavaScript
1101 lines
38 KiB
JavaScript
//
|
|
// http://www.cocos2d-iphone.org
|
|
// http://www.chipmunk-physics.org
|
|
//
|
|
// Watermelon with Me
|
|
// A JS game using cocos2d and Chipmunk
|
|
//
|
|
//
|
|
// Physics code based on Space Patrol:
|
|
// https://github.com/slembcke/SpacePatrol
|
|
//
|
|
// Most of the comments in the physics code were copied+pased from Space Patrol
|
|
//
|
|
//
|
|
// LICENSE:
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
//
|
|
|
|
require("js/helper.js");
|
|
|
|
// Z Orders (grouped by parent)
|
|
|
|
// parent is scroll batch node
|
|
Z_WATERMELON = 5;
|
|
Z_COIN = 8;
|
|
Z_FINISH = 9;
|
|
Z_CHASSIS = 10;
|
|
Z_WHEEL = 11;
|
|
|
|
// parent is scroll node (parallax node)
|
|
Z_MOUNTAINS = 0;
|
|
Z_SPRITES = 10;
|
|
Z_TERRAIN = 20;
|
|
Z_DEBUG_PHYSICS = 50;
|
|
|
|
// parent is game layer
|
|
Z_SCROLL = 10;
|
|
Z_SMOKE = 15;
|
|
Z_HUD = 20;
|
|
Z_LABEL = 30;
|
|
Z_DEBUG_MENU = 30;
|
|
|
|
// Game state
|
|
STATE_PAUSE = 0;
|
|
STATE_PLAYING = 1;
|
|
STATE_GAME_OVER = 2;
|
|
STATE_LEVEL_COMPLETE = 3;
|
|
|
|
audioEngine = cc.AudioEngine.getInstance();
|
|
director = cc.Director.getInstance();
|
|
winSize = director.getWinSize();
|
|
centerPos = cc.p( winSize.width/2, winSize.height/2 );
|
|
|
|
sizeRatio = winSize.width / 480;
|
|
|
|
//
|
|
// Levels
|
|
//
|
|
levels = [];
|
|
|
|
// Level 0
|
|
levels.push( {'coins' : [ {x:300,y:50},{x:350,y:50},{x:400,y:50},{x:450,y:50},{x:500,y:50},{x:550,y:50},{x:600,y:50},
|
|
{x:1300,y:50},{x:1350,y:50},{x:1400,y:50},{x:1450,y:50},{x:1500,y:50},{x:1550,y:50},{x:1600,y:50},
|
|
],
|
|
|
|
'car' : {x:80, y:60},
|
|
'finish' : {x:3000, y:20},
|
|
|
|
// points relatives to the previous point
|
|
'lines' : [ {x:0,y:0}, {x:850,y:0},
|
|
{x:20, y:5},{x:20,y:-5}, {x:20, y:10},{x:20,y:-10}, {x:20, y:5},{x:20,y:-5},
|
|
{x:500,y:0},
|
|
{x:20, y:5},{x:20,y:-5}, {x:20, y:10},{x:20,y:-10}, {x:20, y:5},{x:20,y:-5},
|
|
{x:500,y:0},
|
|
{x:20, y:5},{x:20,y:-5}, {x:20, y:10},{x:20,y:-10}, {x:20, y:5},{x:20,y:-5},
|
|
{x:500,y:0},
|
|
{x:20, y:5},{x:20,y:-5}, {x:20, y:10},{x:20,y:-10}, {x:20, y:5},{x:20,y:-5},
|
|
{x:300,y:0},
|
|
],
|
|
}
|
|
);
|
|
|
|
// Level 1
|
|
levels.push( {'coins' : [ {x:1120,y:150}, {x:1160,y:140}, {x:1200,y:130}, {x:1240,y:120}, {x:1280,y:110},
|
|
{x:2470,y:150}, {x:2510,y:140}, {x:2550,y:130}, {x:2590,y:120}, {x:2630,y:110},
|
|
{x:2220,y:60}, {x:2260,y:70}, {x:2300,y:80}, {x:2340,y:90}, {x:2380,y:100},
|
|
],
|
|
|
|
'car' : {x:80, y:60},
|
|
'finish' : {x:3400, y:20},
|
|
|
|
// points relatives to the previous point
|
|
'lines' : [ {x:0,y:0}, {x:350,y:10}, {x:20, y:5}, {x:500, y:-20}, {x:200, y:80}, {x:100, y:-40}, {x:200,y:-10}, {x:400, y:-50}, {x:300,y:0}, {x:400,y:100}, {x:200,y:-100}, {x:400,y:0}, {x:20,y:15}, {x:20,y:-15}, {x:400,y:0}, ],
|
|
}
|
|
);
|
|
|
|
// Level 2
|
|
levels.push( {'coins' : [ {x:1120,y:150}, {x:1160,y:140}, {x:1200,y:130}, {x:1240,y:120}, {x:1280,y:110},
|
|
],
|
|
|
|
'car' : {x:80, y:60},
|
|
'finish' : {x:4100, y:-100},
|
|
|
|
// points relatives to the previous point
|
|
'lines' : [ {x:0,y:0}, {x:350,y:0},
|
|
{x:300, y:100}, {x:100, y:50}, {x:50, y:12}, {x:25, y:0}, {x:50,y:-12}, {x:100, y:-25}, {x:400, y:-200}, {x:500, y:0},
|
|
{x:20, y:15},{x:20,y:-15}, {x:20, y:5},{x:20,y:-5},
|
|
{x:300,y:0},
|
|
{x:300, y:100}, {x:100, y:50}, {x:50, y:12}, {x:25, y:0}, {x:50,y:-12}, {x:100, y:-25}, {x:400, y:-200}, {x:500, y:0},
|
|
{x:20, y:15},{x:20,y:-15}, {x:20, y:5},{x:20,y:-5},
|
|
{x:300,y:0},
|
|
],
|
|
}
|
|
);
|
|
//
|
|
// Physics constants
|
|
//
|
|
|
|
INFINITY = 1e50;
|
|
|
|
COLLISION_TYPE_CAR = 1;
|
|
COLLISION_TYPE_COIN = 2;
|
|
COLLISION_TYPE_WATERMELON = 3;
|
|
COLLISION_TYPE_FLOOR = 4;
|
|
COLLISION_TYPE_FINISH = 5;
|
|
|
|
// Create some collision rules for fancy layer based filtering.
|
|
// There is more information about how this works in the Chipmunk docs.
|
|
COLLISION_RULE_TERRAIN_BUGGY = 1 << 0;
|
|
COLLISION_RULE_BUGGY_ONLY = 1 << 1;
|
|
|
|
// Bitwise or the rules together to get the layers for a certain shape type.
|
|
COLLISION_LAYERS_TERRAIN = COLLISION_RULE_TERRAIN_BUGGY;
|
|
COLLISION_LAYERS_BUGGY = (COLLISION_RULE_TERRAIN_BUGGY | COLLISION_RULE_BUGGY_ONLY);
|
|
|
|
// Some constants for controlling the car and world:
|
|
GRAVITY = 1200.0;
|
|
WHEEL_MASS = 0.25;
|
|
CHASSIS_MASS = 0.7;
|
|
FRONT_SPRING = 150.0;
|
|
FRONT_DAMPING = 3.0;
|
|
COG_ADJUSTMENT = cp.v(0.0, -10.0);
|
|
REAR_SPRING = 100.0;
|
|
REAR_DAMPING = 3.0;
|
|
ROLLING_FRICTION = 5e2;
|
|
ENGINE_MAX_TORQUE = 6.0e4;
|
|
ENGINE_MAX_W = 60;
|
|
BRAKING_TORQUE = 3.0e4;
|
|
DIFFERENTIAL_TORQUE = 0.5;
|
|
|
|
// Groups
|
|
GROUP_BUGGY = 1;
|
|
GROUP_COIN = 2;
|
|
|
|
WATERMELON_MASS = 0.05;
|
|
|
|
// Node Tags (used by CocosBuilder)
|
|
SCORE_LABEL_TAG = 10;
|
|
TIME_LABEL_TAG = 11;
|
|
TITLE_TAG = 50;
|
|
|
|
//
|
|
// Game Layer
|
|
//
|
|
var GameLayer = cc.LayerGradient.extend({
|
|
|
|
_space:null,
|
|
_motor:null,
|
|
_frontBrake:null,
|
|
_rearBrake:null,
|
|
_rearWheel:null,
|
|
_chassis:null,
|
|
_batch:null,
|
|
_shapesToRemove:[],
|
|
_score:0,
|
|
_scoreLabel:null,
|
|
_time:0,
|
|
_timeLabel:null,
|
|
_level:0,
|
|
_state:STATE_PAUSE,
|
|
_deferredState:null,
|
|
_debugNode:null,
|
|
_scrollNode:null,
|
|
_terrain:null,
|
|
_carSprite:null,
|
|
_carSmoke:null,
|
|
|
|
ctor:function (level) {
|
|
|
|
var parent = new cc.LayerGradient();
|
|
__associateObjWithNative(this, parent);
|
|
this.init(cc.c4b(0, 0, 0, 255), cc.c4b(255, 255, 255, 255));
|
|
|
|
this.scheduleUpdate();
|
|
|
|
this.enableEvents( true );
|
|
|
|
cc.MenuItemFont.setFontSize(16 * sizeRatio );
|
|
|
|
var item1_pause = cc.MenuItemFont.create("Pause" );
|
|
var item1_resume = cc.MenuItemFont.create("Resume" );
|
|
var item1 = cc.MenuItemToggle.create( item1_pause, item1_resume );
|
|
item1.setCallback( this, this.onPause);
|
|
var item2 = cc.MenuItemFont.create("Debug On/Off", this, this.onToggleDebug);
|
|
var menu = cc.Menu.create( item1, item2 );
|
|
menu.alignItemsVertically();
|
|
this.addChild( menu, Z_DEBUG_MENU );
|
|
menu.setPosition( cc._p( winSize.width-(50*sizeRatio), winSize.height-(80*sizeRatio) ) );
|
|
|
|
var animCache = cc.AnimationCache.getInstance();
|
|
animCache.addAnimations("coins_animation.plist");
|
|
|
|
// scrollng Node.. all game objects are children of this node (or one of its subchildre)
|
|
var scroll = cc.ParallaxNode.create();
|
|
this.addChild( scroll, Z_SCROLL );
|
|
this._scrollNode = scroll;
|
|
|
|
// coin only needed to obtain the texture for the Batch Node
|
|
var coin = cc.Sprite.createWithSpriteFrameName("coin01.png");
|
|
this._batch = cc.SpriteBatchNode.createWithTexture( coin.getTexture(), 100 );
|
|
scroll.addChild( this._batch, Z_SPRITES, cc._p(1,1), cc.POINT_ZERO );
|
|
|
|
// "endless" background image
|
|
var background = cc.Sprite.create("Parallax.pvr.gz", cc.rect(0,0,4096,512) );
|
|
scroll.addChild(background, Z_MOUNTAINS , cc._p(0.2, 0.2), cc._p(0,-150));
|
|
background.setAnchorPoint( cc.POINT_ZERO );
|
|
background.getTexture().setTexParameters(gl.LINEAR, gl.LINEAR, gl.REPEAT, gl.CLAMP_TO_EDGE);
|
|
|
|
// Terrain
|
|
this._terrain = cc.DrawNode.create();
|
|
scroll.addChild( this._terrain, Z_TERRAIN, cc._p(1,1), cc.POINT_ZERO );
|
|
// this._terrain.setVisible( false );
|
|
|
|
// Smoke
|
|
this._carSmoke = cc.ParticleSystem.create( "car_smoke.plist" );
|
|
this._carSmoke.setPosition( cc.POINT_ZERO );
|
|
this.addChild( this._carSmoke, Z_SMOKE );
|
|
this._carSmoke.setPositionType( cc.PARTICLE_TYPE_RELATIVE );
|
|
|
|
this._shapesToRemove = [];
|
|
|
|
this.initHUD();
|
|
|
|
this._score = 0;
|
|
this._time = 0;
|
|
this._state = STATE_PAUSE;
|
|
this._level = level;
|
|
|
|
},
|
|
|
|
// HUD stuff
|
|
initHUD:function() {
|
|
var hud = cc.Reader.load("HUD.ccbi", this);
|
|
this.addChild( hud, Z_HUD );
|
|
this._scoreLabel = hud.getChildByTag( SCORE_LABEL_TAG );
|
|
this._timeLabel = hud.getChildByTag( TIME_LABEL_TAG );
|
|
|
|
// bug in cocosbuilder
|
|
this._scoreLabel.setAnchorPoint( cc._p(1, 0.5) );
|
|
this._timeLabel.setAnchorPoint( cc._p(0, 0.5) );
|
|
},
|
|
|
|
addScore:function(value) {
|
|
this._score += value;
|
|
this._scoreLabel.setString( this._score );
|
|
this._scoreLabel.stopAllActions();
|
|
|
|
var scaleUpTo = cc.ScaleTo.create(0.05, 1.2);
|
|
var scaleDownTo = cc.ScaleTo.create(0.05, 1.0);
|
|
var seq = cc.Sequence.create( scaleUpTo, scaleDownTo );
|
|
this._scoreLabel.runAction( seq );
|
|
|
|
},
|
|
|
|
//
|
|
// Events
|
|
//
|
|
onRestart:function(sender) {
|
|
var scene = cc.Scene.create();
|
|
var layer = new GameLayer(this._level);
|
|
scene.addChild( layer );
|
|
director.replaceScene( cc.TransitionFade.create(1, scene) );
|
|
},
|
|
|
|
onPause:function(sender) {
|
|
if( this._state == STATE_PAUSE )
|
|
this._state = STATE_PLAYING;
|
|
else
|
|
this._state = STATE_PAUSE;
|
|
},
|
|
|
|
onNextLevel:function(sender) {
|
|
var scene = cc.Scene.create();
|
|
var layer = new GameLayer(this._level+1);
|
|
scene.addChild( layer );
|
|
director.replaceScene( cc.TransitionFade.create(1, scene) );
|
|
},
|
|
|
|
onMainMenu:function(sender) {
|
|
var scene = cc.Scene.create();
|
|
var layer = new MenuLayer();
|
|
scene.addChild( layer );
|
|
director.replaceScene( cc.TransitionProgressRadialCCW.create(1, scene) );
|
|
},
|
|
|
|
onToggleDebug:function(sender) {
|
|
var state = this._debugNode.getVisible();
|
|
this._debugNode.setVisible( !state );
|
|
},
|
|
|
|
onMouseDown:function(event) {
|
|
this.setThrottle(1);
|
|
return true;
|
|
},
|
|
onMouseUp:function(event) {
|
|
this.setThrottle(0);
|
|
return true;
|
|
},
|
|
onTouchesBegan:function( touches, event) {
|
|
this.setThrottle(1);
|
|
return true;
|
|
},
|
|
onTouchesEnded:function( touches, event) {
|
|
this.setThrottle(0);
|
|
return true;
|
|
},
|
|
|
|
onEnterTransitionDidFinish:function() {
|
|
|
|
this.initPhysics();
|
|
this.setupLevel(this._level);
|
|
|
|
this._state = STATE_PLAYING;
|
|
|
|
// Level Label
|
|
var label = cc.LabelBMFont.create("LEVEL " + this._level, "Abadi40.fnt" );
|
|
label.setPosition( centerPos );
|
|
this.addChild( label, Z_LABEL );
|
|
var d = cc.DelayTime.create(1);
|
|
var scale = cc.ScaleBy.create(1.1, 5);
|
|
var fade = cc.FadeOut.create(1.1);
|
|
var s = cc.Spawn.create( scale, fade );
|
|
var selfremove = cc.CallFunc.create(this, this.onRemoveMe );
|
|
var seq = cc.Sequence.create(d, s, selfremove );
|
|
label.runAction( seq );
|
|
|
|
},
|
|
|
|
onRemoveMe:function( sender ) {
|
|
sender.removeFromParentAndCleanup( true );
|
|
},
|
|
|
|
onExit:function() {
|
|
|
|
this.enableCollisionEvents( false );
|
|
// XXX: Leak... all Shapes and Bodies should be freed
|
|
cp.spaceFree( this._space );
|
|
},
|
|
|
|
// Coin and Car
|
|
onCollisionBeginCoin : function ( arbiter, space ) {
|
|
|
|
var bodies = cp.arbiterGetBodies( arbiter );
|
|
var shapes = cp.arbiterGetShapes( arbiter );
|
|
var collTypeA = cp.shapeGetCollisionType( shapes[0] );
|
|
var collTypeB = cp.shapeGetCollisionType( shapes[1] );
|
|
|
|
var shapeCoin = (collTypeA == COLLISION_TYPE_COIN) ? shapes[0] : shapes[1];
|
|
|
|
// XXX: hack to prevent double deletion... argh...
|
|
// Since shapeCoin in 64bits is a typedArray and in 32-bits is an integer
|
|
// a ad-hoc solution needs to be implemented
|
|
if( this._shapesToRemove.length == 0 ) {
|
|
// since Coin is a sensor, it can't be removed at PostStep.
|
|
// PostStep is not called for Sensors
|
|
this._shapesToRemove.push( shapeCoin );
|
|
audioEngine.playEffect("pickup_coin.wav");
|
|
|
|
// cc.log("Adding shape: " + shapeCoin[0] + " : " + shapeCoin[1] );
|
|
cc.log("Adding shape: " + shapeCoin );
|
|
this.addScore(1);
|
|
}
|
|
return true;
|
|
},
|
|
|
|
// Floor and Watermelon
|
|
onCollisionBeginWatermelon : function ( arbiter, space ) {
|
|
this.setThrottle(0);
|
|
this.setGameStateDeferred( STATE_GAME_OVER );
|
|
return true;
|
|
},
|
|
|
|
// Car and Finish line
|
|
onCollisionBeginFinish : function ( arbiter, space ) {
|
|
this.setThrottle(0);
|
|
this.setGameStateDeferred( STATE_LEVEL_COMPLETE );
|
|
return true;
|
|
},
|
|
|
|
update:function(dt) {
|
|
|
|
// update state if necessary
|
|
if( this._deferredState )
|
|
this.setGameState( this._deferredState );
|
|
|
|
if( this._state == STATE_PLAYING ) {
|
|
// update time
|
|
this._time += dt;
|
|
this._timeLabel.setString( '' + this._time.toFixed(1) );
|
|
}
|
|
|
|
// Don't update physics on game over
|
|
if( this._state != STATE_PAUSE )
|
|
cp.spaceStep( this._space, dt);
|
|
|
|
// sync smoke with car
|
|
if( this._carSprite ) {
|
|
var p = this._carSprite.convertToWorldSpace( cc.POINT_ZERO );
|
|
this._carSmoke.setPosition( p );
|
|
}
|
|
|
|
var l = this._shapesToRemove.length;
|
|
|
|
for( var i=0; i < l; i++ ) {
|
|
var shape = this._shapesToRemove[i];
|
|
|
|
// cc.log("removing shape: " + shape[0] + " : " + shape[1] );
|
|
cc.log("removing shape: " + shape );
|
|
|
|
cp.spaceRemoveStaticShape( this._space, shape );
|
|
cp.shapeFree( shape );
|
|
|
|
var body = cp.shapeGetBody( shape );
|
|
|
|
var sprite = cp.bodyGetUserData( body );
|
|
sprite.removeFromParentAndCleanup(true);
|
|
|
|
cp.bodyFree( body );
|
|
|
|
}
|
|
|
|
if( l > 0 )
|
|
this._shapesToRemove = [];
|
|
},
|
|
|
|
//
|
|
// Level Setup
|
|
//
|
|
setupLevel : function(lvl) {
|
|
|
|
var x = 0;
|
|
var y = 0;
|
|
var width = winSize.width;
|
|
var height = winSize.height;
|
|
|
|
var level = levels[ lvl ];
|
|
|
|
// Coins
|
|
var coins = level['coins'];
|
|
for( var i=0;i < coins.length; i++) {
|
|
var coin = coins[i];
|
|
this.createCoin( cc._p( coin.x, coin.y) );
|
|
}
|
|
|
|
// car
|
|
var car = level['car'];
|
|
this.createCar( cp.v( car.x, car.y) );
|
|
|
|
// finish
|
|
var finish = level['finish'];
|
|
this.createFinish( cp._v(finish.x, finish.y) );
|
|
|
|
//lines
|
|
var poly = [];
|
|
var p = {x:0, y:0};
|
|
var lines = level['lines'];
|
|
|
|
for( var i=0; i < lines.length; i++) {
|
|
var line = lines[i];
|
|
if( i > 0 ) {
|
|
this.createSegment( cp._v(p.x, p.y), cp._v( p.x+line.x, p.y+line.y ) );
|
|
this._terrain.drawSegment( cc._p(p.x, p.y), cc._p(p.x+line.x, p.y+line.y), 5, cc.c4f(0.43,0.39,0.34,1) );
|
|
}
|
|
|
|
p = {x:p.x+line.x, y:p.y+line.y};
|
|
|
|
poly.push( cc.p(p.x, p.y) );
|
|
|
|
// needed for world boundary
|
|
x = Math.min(x, p.x);
|
|
y = Math.min(y, p.y);
|
|
width = Math.max( width, p.x);
|
|
height = Math.max( height, p.y);
|
|
}
|
|
|
|
poly.unshift( cc.p(x,y) );
|
|
|
|
// XXX: Bug in CCDrawNode: No tesselation, so "fill" is disabled
|
|
// XXX: CCDrawNode#drawPoly is super expensive... using drawSegment instead
|
|
// poly, fill color, border width, border color
|
|
// this._terrain.drawPoly( poly, cc.c4f(0,0,0,0 ), 1, cc.c4f(0.82,0.41,0.04,1) );
|
|
|
|
cc.log("World Boundary: " + x + " " + y + " " + width + " " + height );
|
|
|
|
var rect = cc.rect(x,y,width,height);
|
|
var a = cc.Follow.create( this._carSprite, rect );
|
|
this._scrollNode.runAction( a );
|
|
|
|
this.createWorldBoundary( rect );
|
|
},
|
|
|
|
createWorldBoundary:function( rect ) {
|
|
|
|
var staticBody = cp.spaceGetStaticBody( this._space );
|
|
|
|
var x = rect.x;
|
|
var y = rect.y;
|
|
var w = rect.width;
|
|
var h = rect.height;
|
|
|
|
// Walls
|
|
var walls =[cp.segmentShapeNew( staticBody, cp._v(x,y), cp._v(w,y), 0 ), // bottom
|
|
cp.segmentShapeNew( staticBody, cp._v(x,h), cp._v(w,h), 0), // top
|
|
cp.segmentShapeNew( staticBody, cp._v(x,y), cp._v(x,h), 0), // left
|
|
cp.segmentShapeNew( staticBody, cp._v(w,y), cp._v(w,h), 0) // right
|
|
];
|
|
for( var i=0; i < walls.length; i++ ) {
|
|
var wall = walls[i];
|
|
cp.shapeSetElasticity(wall, 0);
|
|
cp.shapeSetFriction(wall, 0);
|
|
cp.shapeSetCollisionType(wall, COLLISION_TYPE_FLOOR);
|
|
cp.spaceAddStaticShape( this._space, wall );
|
|
}
|
|
},
|
|
|
|
//
|
|
// Physics
|
|
//
|
|
initPhysics : function() {
|
|
this._space = cp.spaceNew();
|
|
|
|
// Gravity
|
|
cp.spaceSetGravity( this._space, cp._v(0, -GRAVITY) );
|
|
|
|
this.enableCollisionEvents( true );
|
|
|
|
// debug only
|
|
this._debugNode = cc.ChipmunkDebugNode.create( this._space );
|
|
this._debugNode.setVisible( false );
|
|
// Parallax ratio and offset
|
|
this._scrollNode.addChild( this._debugNode, Z_DEBUG_PHYSICS, cc._p(1,1), cc.POINT_ZERO );
|
|
},
|
|
|
|
setThrottle : function( throttle ) {
|
|
if(throttle > 0){
|
|
// The motor is modeled like an electric motor where the torque decreases inversely as the rate approaches the maximum.
|
|
// It's simple to code up and feels nice.
|
|
|
|
// _motor.maxForce = cpfclamp01(1.0 - (_chassis.body.angVel - _rearWheel.body.angVel)/ENGINE_MAX_W)*ENGINE_MAX_TORQUE;
|
|
var maxForce = cp.fclamp01(1.0 - ( (cp.bodyGetAngVel(this._chassis) - cp.bodyGetAngVel(this._rearWheel)) / ENGINE_MAX_W)) * ENGINE_MAX_TORQUE;
|
|
cp.constraintSetMaxForce( this._motor, maxForce );
|
|
|
|
// Set the brakes to apply the baseline rolling friction torque.
|
|
cp.constraintSetMaxForce( this._frontBrake, ROLLING_FRICTION );
|
|
cp.constraintSetMaxForce( this._rearBrake, ROLLING_FRICTION );
|
|
} else if(throttle < 0){
|
|
// Disable the motor.
|
|
cp.constraintSetMaxForce( this._motor, 0 );
|
|
// It would be a pretty good idea to give the front and rear brakes different torques.
|
|
// The buggy as is now has a tendency to tip forward when braking hard.
|
|
cp.constraintSetMaxForce( this._frontBrake, BRAKING_TORQUE);
|
|
cp.constraintSetMaxForce( this._rearBrake, BRAKING_TORQUE);
|
|
} else {
|
|
// Disable the motor.
|
|
cp.constraintSetMaxForce( this._motor, 0 );
|
|
// Set the brakes to apply the baseline rolling friction torque.
|
|
cp.constraintSetMaxForce( this._frontBrake, ROLLING_FRICTION );
|
|
cp.constraintSetMaxForce( this._rearBrake, ROLLING_FRICTION );
|
|
}
|
|
},
|
|
|
|
createCar : function(pos) {
|
|
var front = this.createWheel( cp.vadd(pos, cp._v(47,-25) ) );
|
|
this._chassis = this.createChassis( cp.vadd( pos, COG_ADJUSTMENT ) );
|
|
this._rearWheel = this.createWheel( cp.vadd( pos, cp._v(-35, -25) ) );
|
|
this.createCarJoints( this._chassis, front, this._rearWheel );
|
|
this.createCarFruits( pos );
|
|
|
|
this.setThrottle( 0 );
|
|
},
|
|
|
|
createCarJoints: function( chassis, front, rear ) {
|
|
|
|
// The front wheel strut telescopes, so we'll attach the center of the wheel to a groov joint on the chassis.
|
|
// I created the graphics specifically to have a 45 degree angle. So it's easy to just fudge the numbers.
|
|
var grv_a = cp.bodyWorld2Local( chassis, cp.bodyGetPos(front) );
|
|
var grv_b = cp.vadd( grv_a, cp.vmult( cp._v(-1, 1), 7 ) );
|
|
var frontJoint = cp.grooveJointNew( chassis, front, grv_a, grv_b, cp.vzero );
|
|
|
|
// Create the front zero-length spring.
|
|
var front_anchor = cp.bodyWorld2Local( chassis, cp.bodyGetPos(front) );
|
|
var frontSpring = cp.dampedSpringNew( chassis, front, front_anchor, cp.vzero, 0, FRONT_SPRING, FRONT_DAMPING );
|
|
|
|
// The rear strut is a swinging arm that holds the wheel a at a certain distance from a pivot on the chassis.
|
|
// A perfect fit for a pin joint conected between the chassis and the wheel's center.
|
|
var rearJoint = cp.pinJointNew( chassis, rear, cp.vsub( cp._v(-14,-8), COG_ADJUSTMENT), cp.vzero );
|
|
|
|
// return cpvtoangle(cpvsub([_chassis.body local2world:_rearJoint.anchr1], _rearWheel.body.pos));
|
|
var rearStrutRestAngle = cp.vtoangle( cp.vsub(
|
|
cp.bodyLocal2World( chassis, cp.pinJointGetAnchr1(rearJoint) ),
|
|
cp.bodyGetPos(rear) ) );
|
|
|
|
// Create the rear zero-length spring.
|
|
var rear_anchor = cp.bodyWorld2Local( chassis, cp.bodyGetPos( rear ) );
|
|
var rearSpring = cp.dampedSpringNew( chassis, rear, rear_anchor, cp.vzero, 0, REAR_SPRING, REAR_DAMPING );
|
|
|
|
// Attach a slide joint to the wheel to limit it's range of motion.
|
|
var rearStrutLimit = cp.slideJointNew( chassis, rear, rear_anchor, cp.vzero, 0, 20 );
|
|
|
|
// The main motor that drives the buggy.
|
|
var motor = cp.simpleMotorNew( chassis, rear, ENGINE_MAX_W );
|
|
cp.constraintSetMaxForce( motor, 0.0 );
|
|
|
|
// I don't know if "differential" is the correct word, but it transfers a fraction of the rear torque to the front wheels.
|
|
// In case the rear wheels are slipping. This makes the buggy less frustrating when climbing steep hills.
|
|
var differential = cp.simpleMotorNew( rear, front, 0 );
|
|
cp.constraintSetMaxForce( differential, ENGINE_MAX_TORQUE*DIFFERENTIAL_TORQUE );
|
|
|
|
// Wheel brakes.
|
|
// While you could reuse the main motor for the brakes, it's easier not to.
|
|
// It won't cause a performance issue to have too many extra motors unless you have hundreds of buggies in the game.
|
|
// Even then, the motor constraints would be the least of your performance worries.
|
|
var frontBrake = cp.simpleMotorNew( chassis, front, 0 );
|
|
cp.constraintSetMaxForce( frontBrake, ROLLING_FRICTION );
|
|
var rearBrake = cp.simpleMotorNew( chassis, rear, 0 );
|
|
cp.constraintSetMaxForce( rearBrake, ROLLING_FRICTION );
|
|
|
|
cp.spaceAddConstraint(this._space, frontJoint );
|
|
cp.spaceAddConstraint(this._space, rearJoint );
|
|
cp.spaceAddConstraint(this._space, rearSpring );
|
|
cp.spaceAddConstraint(this._space, motor );
|
|
cp.spaceAddConstraint(this._space, differential );
|
|
cp.spaceAddConstraint(this._space, frontBrake );
|
|
cp.spaceAddConstraint(this._space, rearBrake );
|
|
|
|
this._motor = motor;
|
|
this._frontBrake = frontBrake;
|
|
this._rearBrake = rearBrake;
|
|
},
|
|
|
|
createWheel : function( pos ) {
|
|
var sprite = cc.ChipmunkSprite.createWithSpriteFrameName("Wheel.png");
|
|
var radius = 0.95 * sprite.getContentSize().width / 2;
|
|
|
|
var body = cp.bodyNew(WHEEL_MASS, cp.momentForCircle(WHEEL_MASS, 0, radius, cp.vzero ) );
|
|
cp.bodySetPos( body, pos );
|
|
sprite.setBody( body );
|
|
|
|
var shape = cp.circleShapeNew( body, radius, cp.vzero );
|
|
cp.shapeSetFriction( shape, 1 );
|
|
cp.shapeSetGroup( shape, GROUP_BUGGY );
|
|
cp.shapeSetLayers( shape, COLLISION_LAYERS_BUGGY );
|
|
cp.shapeSetCollisionType( shape, COLLISION_TYPE_CAR );
|
|
|
|
cp.spaceAddBody( this._space, body );
|
|
cp.spaceAddShape( this._space, shape );
|
|
this._batch.addChild( sprite, Z_WHEEL);
|
|
|
|
return body;
|
|
},
|
|
|
|
createChassis : function(pos) {
|
|
var sprite = cc.ChipmunkSprite.createWithSpriteFrameName("Chassis.png");
|
|
var anchor = cp.vadd( sprite.getAnchorPointInPoints(), COG_ADJUSTMENT );
|
|
var cs = sprite.getContentSize();
|
|
sprite.setAnchorPoint( cc.p(anchor.x / cs.width, anchor.y/cs.height) );
|
|
|
|
// XXX: Space Patrol uses a nice poly for the chassis.
|
|
// XXX: Add something similar here, instead of a boxed chassis
|
|
|
|
var body = cp.bodyNew( CHASSIS_MASS, cp.momentForBox(CHASSIS_MASS, cs.width, cs.height ) );
|
|
cp.bodySetPos( body, pos );
|
|
sprite.setBody( body );
|
|
|
|
cp.spaceAddBody( this._space, body );
|
|
this._batch.addChild( sprite, Z_CHASSIS );
|
|
this._carSprite = sprite;
|
|
|
|
// bottom of chassis
|
|
var shape = cp.boxShapeNew( body, cs.width, 15 );
|
|
cp.shapeSetFriction(shape, 0.3);
|
|
cp.shapeSetGroup( shape, GROUP_BUGGY );
|
|
cp.shapeSetLayers( shape, COLLISION_LAYERS_BUGGY );
|
|
cp.shapeSetCollisionType( shape, COLLISION_TYPE_CAR );
|
|
|
|
cp.spaceAddShape( this._space, shape );
|
|
|
|
// box for fruits (left)
|
|
var shape = cp.boxShapeNew2( body, cp.bBNew(-50,0, -46,30) );
|
|
cp.shapeSetFriction(shape, 0.3);
|
|
cp.shapeSetGroup( shape, GROUP_BUGGY );
|
|
cp.shapeSetLayers( shape, COLLISION_LAYERS_BUGGY );
|
|
cp.shapeSetCollisionType( shape, COLLISION_TYPE_CAR );
|
|
cp.spaceAddShape( this._space, shape );
|
|
|
|
// box for fruits (right)
|
|
var shape = cp.boxShapeNew2( body, cp.bBNew(8,0, 12,30) );
|
|
cp.shapeSetFriction(shape, 0.3);
|
|
cp.shapeSetGroup( shape, GROUP_BUGGY );
|
|
cp.shapeSetLayers( shape, COLLISION_LAYERS_BUGGY );
|
|
cp.shapeSetCollisionType( shape, COLLISION_TYPE_CAR );
|
|
cp.spaceAddShape( this._space, shape );
|
|
|
|
return body;
|
|
},
|
|
|
|
createCarFruits : function(pos) {
|
|
// create some fruits
|
|
for(var i=0; i < 4;i++) {
|
|
var sprite = cc.ChipmunkSprite.createWithSpriteFrameName("watermelon.png");
|
|
var radius = 0.95 * sprite.getContentSize().width / 2;
|
|
|
|
var body = cp.bodyNew(WATERMELON_MASS, cp.momentForCircle(WATERMELON_MASS, 0, radius, cp.vzero) );
|
|
cp.bodySetPos( body, pos );
|
|
sprite.setBody( body );
|
|
|
|
var shape = cp.circleShapeNew( body, radius, cp.vzero );
|
|
cp.shapeSetFriction( shape, 1 );
|
|
cp.shapeSetCollisionType( shape, COLLISION_TYPE_WATERMELON);
|
|
|
|
cp.spaceAddShape( this._space, shape );
|
|
cp.spaceAddBody( this._space, body );
|
|
this._batch.addChild( sprite, Z_WATERMELON );
|
|
}
|
|
},
|
|
|
|
createCoin: function( pos ) {
|
|
// coins are static bodies and sensors
|
|
var sprite = cc.ChipmunkSprite.createWithSpriteFrameName("coin01.png");
|
|
var radius = 0.95 * sprite.getContentSize().width / 2;
|
|
|
|
var body = cp.bodyNew(1, 1);
|
|
cp.bodyInitStatic(body);
|
|
cp.bodySetPos( body, pos );
|
|
sprite.setBody( body );
|
|
|
|
var shape = cp.circleShapeNew( body, radius, cp.vzero );
|
|
cp.shapeSetFriction( shape, 1 );
|
|
cp.shapeSetGroup( shape, GROUP_COIN );
|
|
cp.shapeSetCollisionType( shape, COLLISION_TYPE_COIN );
|
|
cp.shapeSetSensor( shape, true );
|
|
|
|
cp.spaceAddStaticShape( this._space, shape );
|
|
this._batch.addChild( sprite, Z_COIN);
|
|
|
|
var animation = cc.AnimationCache.getInstance().getAnimation("coin");
|
|
var animate = cc.Animate.create(animation);
|
|
var repeat = cc.RepeatForever.create( animate );
|
|
sprite.runAction( repeat );
|
|
|
|
// Needed for deletion
|
|
cp.bodySetUserData( body, sprite );
|
|
|
|
return body;
|
|
},
|
|
|
|
createFinish:function( pos ) {
|
|
var sprite = cc.ChipmunkSprite.createWithSpriteFrameName("farmers-market.png");
|
|
var cs = sprite.getContentSize();
|
|
var body = cp.bodyNew( 1, 1);
|
|
cp.bodyInitStatic( body );
|
|
sprite.setBody( body );
|
|
cp.bodySetPos( body, pos );
|
|
|
|
var shape = cp.boxShapeNew( body, cs.width, cs.height );
|
|
cp.shapeSetCollisionType( shape, COLLISION_TYPE_FINISH );
|
|
cp.shapeSetSensor( shape, true );
|
|
|
|
cp.spaceAddStaticShape( this._space, shape );
|
|
this._batch.addChild( sprite, Z_FINISH);
|
|
},
|
|
|
|
createSegment: function( src, dst) {
|
|
var staticBody = cp.spaceGetStaticBody( this._space );
|
|
var segment = cp.segmentShapeNew( staticBody, src, dst, 5 );
|
|
cp.shapeSetElasticity(segment, 1);
|
|
cp.shapeSetFriction(segment, 1);
|
|
cp.shapeSetCollisionType(segment, COLLISION_TYPE_FLOOR);
|
|
cp.spaceAddStaticShape( this._space, segment );
|
|
},
|
|
|
|
//
|
|
// Game State
|
|
//
|
|
|
|
// call the 'deferred' option if you want to modify Chipmunk's state from a Chipmunk's callback
|
|
setGameStateDeferred: function( state ) {
|
|
this._deferredState = state;
|
|
},
|
|
|
|
setGameState: function( state ) {
|
|
if( state != this._state ) {
|
|
|
|
if( state == STATE_GAME_OVER )
|
|
this.displayGameOver();
|
|
|
|
else if (state == STATE_LEVEL_COMPLETE )
|
|
this.displayLevelComplete();
|
|
|
|
this._state = state;
|
|
}
|
|
this._deferredState = null;
|
|
},
|
|
|
|
displayLevelComplete:function() {
|
|
|
|
|
|
if( this._level+1 < levels.length ) {
|
|
cc.MenuItemFont.setFontSize(16 * sizeRatio );
|
|
var item1 = cc.MenuItemFont.create("Next Level", this, this.onNextLevel);
|
|
var menu = cc.Menu.create( item1 );
|
|
menu.alignItemsVertically();
|
|
this.addChild( menu, Z_DEBUG_MENU );
|
|
menu.setPosition( cc._p( winSize.width/2, winSize.height/3 ) );
|
|
|
|
var legend = "LEVEL COMPLETE";
|
|
} else {
|
|
cc.MenuItemFont.setFontSize(16 * sizeRatio );
|
|
var item1 = cc.MenuItemFont.create("Main Menu", this, this.onMainMenu);
|
|
var menu = cc.Menu.create( item1 );
|
|
menu.alignItemsVertically();
|
|
this.addChild( menu, Z_DEBUG_MENU );
|
|
menu.setPosition( cc._p( winSize.width/2, winSize.height/3 ) );
|
|
|
|
var legend = "GAME COMPLETE";
|
|
}
|
|
|
|
var label = cc.LabelBMFont.create(legend, "Abadi40.fnt" );
|
|
label.setPosition( centerPos );
|
|
label.setScale(0.2);
|
|
var sa = cc.ScaleTo.create(0.5, 1.05 );
|
|
var sb1 = cc.ScaleTo.create(0.5, 1 );
|
|
var sb2 = cc.ScaleTo.create(0.5, 1.05);
|
|
var seq = cc.Sequence.create( sb1, sb2 );
|
|
var rep = cc.Repeat.create( seq, 1000 );
|
|
var all = cc.Sequence.create( sa, rep );
|
|
label.runAction( all );
|
|
this.addChild( label, Z_LABEL );
|
|
|
|
this.enableEvents( false );
|
|
this.enableCollisionEvents( false );
|
|
|
|
audioEngine.playEffect("LevelComplete.wav");
|
|
},
|
|
|
|
displayGameOver:function() {
|
|
var label = cc.LabelBMFont.create("GAME OVER", "Abadi40.fnt" );
|
|
label.setPosition( centerPos );
|
|
this.addChild( label, Z_LABEL );
|
|
label.setScale(0.2);
|
|
var sa = cc.ScaleTo.create(0.5, 1.05 );
|
|
var sb1 = cc.ScaleTo.create(0.5, 1 );
|
|
var sb2 = cc.ScaleTo.create(0.5, 1.05);
|
|
var seq = cc.Sequence.create( sb1, sb2 );
|
|
var rep = cc.Repeat.create( seq, 1000 );
|
|
var all = cc.Sequence.create( sa, rep );
|
|
label.runAction( all );
|
|
|
|
this.enableEvents( false );
|
|
this.enableCollisionEvents( false );
|
|
|
|
audioEngine.playEffect("GameOver.wav");
|
|
|
|
cc.MenuItemFont.setFontSize(16 * sizeRatio );
|
|
var item1 = cc.MenuItemFont.create("Play Again", this, this.onRestart);
|
|
var item2 = cc.MenuItemFont.create("Main Menu", this, this.onMainMenu);
|
|
var menu = cc.Menu.create( item1, item2 );
|
|
menu.alignItemsVertically();
|
|
this.addChild( menu, Z_DEBUG_MENU );
|
|
menu.setPosition( cc._p( winSize.width/2, winSize.height/3 ) );
|
|
},
|
|
|
|
|
|
//
|
|
// Helpers
|
|
//
|
|
enableEvents:function(enabled) {
|
|
var platform = __getPlatform();
|
|
if( platform.substring(0,7) == 'desktop' ) {
|
|
this.setMouseEnabled( enabled );
|
|
} else if( platform.substring(0,6) == 'mobile' ) {
|
|
this.setTouchEnabled( enabled );
|
|
}
|
|
},
|
|
|
|
enableCollisionEvents:function(enabled) {
|
|
if( enabled ) {
|
|
// collision handler
|
|
cp.spaceAddCollisionHandler( this._space, COLLISION_TYPE_CAR, COLLISION_TYPE_COIN, this, this.onCollisionBeginCoin, null, null, null );
|
|
cp.spaceAddCollisionHandler( this._space, COLLISION_TYPE_CAR, COLLISION_TYPE_FINISH, this, this.onCollisionBeginFinish, null, null, null );
|
|
cp.spaceAddCollisionHandler( this._space, COLLISION_TYPE_FLOOR, COLLISION_TYPE_WATERMELON, this, this.onCollisionBeginWatermelon, null, null, null );
|
|
} else {
|
|
cp.spaceRemoveCollisionHandler( this._space, COLLISION_TYPE_FLOOR, COLLISION_TYPE_WATERMELON );
|
|
cp.spaceRemoveCollisionHandler( this._space, COLLISION_TYPE_COIN, COLLISION_TYPE_CAR );
|
|
cp.spaceRemoveCollisionHandler( this._space, COLLISION_TYPE_FINISH, COLLISION_TYPE_CAR );
|
|
}
|
|
},
|
|
|
|
|
|
});
|
|
|
|
//
|
|
// Boot Layer
|
|
//
|
|
var BootLayer = cc.Layer.extend({
|
|
|
|
ctor:function () {
|
|
|
|
var parent = new cc.Layer();
|
|
__associateObjWithNative(this, parent);
|
|
this.init();
|
|
|
|
// music
|
|
audioEngine.playBackgroundMusic("game-music.mp3");
|
|
audioEngine.preloadEffect("pickup_coin.wav");
|
|
|
|
var cache = cc.SpriteFrameCache.getInstance();
|
|
cache.addSpriteFrames( "coins.plist" );
|
|
},
|
|
|
|
onEnter:function() {
|
|
var scene = cc.Scene.create();
|
|
var layer = new MenuLayer();
|
|
scene.addChild( layer );
|
|
director.replaceScene( scene );
|
|
},
|
|
});
|
|
|
|
//
|
|
// Main Menu
|
|
//
|
|
var MenuLayer = cc.Layer.extend({
|
|
|
|
ctor:function () {
|
|
|
|
var parent = new cc.Layer();
|
|
__associateObjWithNative(this, parent);
|
|
this.init();
|
|
|
|
// background
|
|
var node = cc.Reader.load("MainMenu.ccbi", this, winSize);
|
|
this.addChild( node );
|
|
var label = node.getChildByTag( TITLE_TAG );
|
|
var o = label.getChildByTag( 8 );
|
|
|
|
var a_delay = cc.DelayTime.create(6);
|
|
var a_tint = cc.TintTo.create( 0.5, 0, 255, 0 );
|
|
var a_rotate = cc.RotateBy.create( 4, 360 );
|
|
var a_rep = cc.Repeat.create( a_rotate, 1000 );
|
|
var a_seq = cc.Sequence.create( a_delay, a_tint, a_delay.copy(), a_rep );
|
|
o.runAction( a_seq );
|
|
|
|
},
|
|
|
|
onPlay:function( sender) {
|
|
var scene = cc.Scene.create();
|
|
var layer = new GameLayer(0);
|
|
scene.addChild( layer );
|
|
director.replaceScene( cc.TransitionFade.create(1, scene) );
|
|
},
|
|
|
|
onOptions:function( sender) {
|
|
var scene = cc.Scene.create();
|
|
var layer = new OptionsLayer();
|
|
scene.addChild( layer );
|
|
director.replaceScene( cc.TransitionFlipY.create(1, scene) );
|
|
},
|
|
|
|
onAbout:function( sender ) {
|
|
var scene = cc.Scene.create();
|
|
var layer = new AboutLayer();
|
|
scene.addChild( layer );
|
|
director.replaceScene( cc.TransitionZoomFlipY.create(1, scene) );
|
|
},
|
|
});
|
|
|
|
//
|
|
// About
|
|
//
|
|
var AboutLayer = cc.Layer.extend({
|
|
|
|
ctor:function () {
|
|
var parent = new cc.LayerGradient();
|
|
__associateObjWithNative(this, parent);
|
|
this.init();
|
|
|
|
var about = cc.Reader.load("About.ccbi", this);
|
|
this.addChild( about )
|
|
|
|
var back = cc.MenuItemFont.create("Back", this, this.onBack );
|
|
back.setColor( cc.BLACK );
|
|
var menu = cc.Menu.create( back );
|
|
this.addChild( menu );
|
|
menu.alignItemsVertically();
|
|
menu.setPosition( cc._p( winSize.width - 50, 50) );
|
|
|
|
},
|
|
|
|
onBack:function( sender) {
|
|
var scene = cc.Scene.create();
|
|
var layer = new MenuLayer();
|
|
scene.addChild( layer );
|
|
director.replaceScene( cc.TransitionFlipX.create(1, scene) );
|
|
},
|
|
});
|
|
|
|
//
|
|
// Options
|
|
//
|
|
var OptionsLayer = cc.LayerGradient.extend({
|
|
|
|
ctor:function () {
|
|
var parent = new cc.LayerGradient();
|
|
__associateObjWithNative(this, parent);
|
|
this.init(cc.c4b(0, 0, 0, 255), cc.c4b(255, 255, 255, 255));
|
|
|
|
var label1 = cc.LabelBMFont.create("MUSIC ON", "konqa32.fnt" );
|
|
var item1 = cc.MenuItemLabel.create(label1);
|
|
var label2 = cc.LabelBMFont.create("MUSIC OFF", "konqa32.fnt" );
|
|
var item2 = cc.MenuItemLabel.create(label2);
|
|
var toggle = cc.MenuItemToggle.create( item1, item2 );
|
|
toggle.setCallback( this, this.onMusicToggle);
|
|
|
|
var back = cc.MenuItemFont.create("Back", this, this.onBack );
|
|
var menu = cc.Menu.create( toggle, back );
|
|
this.addChild( menu );
|
|
menu.alignItemsVertically();
|
|
menu.setPosition( centerPos );
|
|
},
|
|
|
|
onBack:function( sender) {
|
|
var scene = cc.Scene.create();
|
|
var layer = new MenuLayer();
|
|
scene.addChild( layer );
|
|
director.replaceScene( cc.TransitionFlipX.create(1, scene) );
|
|
},
|
|
|
|
onMusicToggle:function( sender ) {
|
|
// music
|
|
if ( audioEngine.isBackgroundMusicPlaying() ) {
|
|
audioEngine.stopBackgroundMusic();
|
|
} else {
|
|
audioEngine.playBackgroundMusic("game-music.mp3");
|
|
}
|
|
},
|
|
});
|
|
|
|
//------------------------------------------------------------------
|
|
//
|
|
// Main entry point
|
|
//
|
|
//------------------------------------------------------------------
|
|
function run()
|
|
{
|
|
// update globals
|
|
winSize = director.getWinSize();
|
|
centerPos = cc.p( winSize.width/2, winSize.height/2 );
|
|
|
|
var scene = cc.Scene.create();
|
|
|
|
// main menu
|
|
var menu = new BootLayer();
|
|
scene.addChild( menu);
|
|
|
|
var runningScene = director.getRunningScene();
|
|
if( runningScene == null )
|
|
director.runWithScene( scene );
|
|
else
|
|
director.replaceScene( cc.TransitionFade.create(0.5, scene ) );
|
|
}
|
|
|
|
run();
|
|
|