#include "GameLayer.h"
#include "CollisionListener.h"
#define SHOT_POWER 6.0
using namespace cocos2d;
GameLayer::GameLayer() {
_screenSize = CCDirector::sharedDirector()->getWinSize();
CCSprite * bg = CCSprite::create("bg.png");
bg->setPosition(ccp(_screenSize.width * 0.5f, _screenSize.height * 0.5f));
this->addChild(bg);
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("sprite_sheet.plist");
_gameBatchNode = CCSpriteBatchNode::create("sprite_sheet.png", 50);
this->addChild(_gameBatchNode, kMiddleground);
// init physics
this->initPhysics();
setTouchEnabled( true );
scheduleUpdate();
_usingCue = false;
_running = true;
_canShoot = true;
_gameState = kGameIntro;
_time = 0;
_ballsInPlay = 15;
_lineContainer = LineContainer::create();
this->addChild(_lineContainer);
_intro = CCSprite::createWithSpriteFrameName("logo.png");
_intro->setPosition(ccp(_screenSize.width * 0.5f, _screenSize.height * 0.55f));
_gameBatchNode->addChild(_intro, kForeground);
_gameOver = CCSprite::createWithSpriteFrameName("gameover.png");
_gameOver->setPosition(ccp(_screenSize.width * 0.5f, _screenSize.height * 0.55f));
_gameOver->setVisible(false);
_gameBatchNode->addChild(_gameOver, kForeground);
_timer = CCLabelBMFont::create("0", "font.fnt", _screenSize.width * 0.5f);
_timer->setPosition(ccp(_screenSize.width * 0.5f, _screenSize.height * 0.94f));
_timer->setVisible(false);
this->addChild(_timer, kForeground);
this->schedule(schedule_selector(GameLayer::ticktock), 1.5f);
}
GameLayer::~GameLayer() {
delete _world;
_world = NULL;
delete m_debugDraw;
delete _collisionListener;
CC_SAFE_RELEASE(_balls);
CC_SAFE_RELEASE(_pockets);
}
CCScene* GameLayer::scene()
{
CCScene * scene = NULL;
do
{
// 'scene' is an autorelease object
scene = CCScene::create();
CC_BREAK_IF(! scene);
// 'layer' is an autorelease object
GameLayer *layer = GameLayer::create();
CC_BREAK_IF(! layer);
// add layer as a child to scene
scene->addChild(layer);
} while (0);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool GameLayer::init()
{
bool bRet = false;
do
{
//////////////////////////////////////////////////////////////////////////
// super init first
//////////////////////////////////////////////////////////////////////////
CC_BREAK_IF(! CCLayer::init());
//////////////////////////////////////////////////////////////////////////
// add your codes below...
//////////////////////////////////////////////////////////////////////////
setTouchEnabled( true );
bRet = true;
} while (0);
return bRet;
}
void GameLayer::initPhysics(){
b2Vec2 gravity;
gravity.Set(0.0f,0.0f);
_world = new b2World(gravity);
_world->SetAllowSleeping(true);
_world->SetContinuousPhysics(true);
_collisionListener = new CollisionListener();
_world->SetContactListener(_collisionListener);
m_debugDraw = new GLESDebugDraw(PTM_RATIO);
_world->SetDebugDraw(m_debugDraw);
uint32 flags = 0;
flags += b2Draw::e_shapeBit;
m_debugDraw->SetFlags(flags);
b2FixtureDef fixtureDef;
b2BodyDef bodyDef;
_pockets = CCArray::createWithCapacity(6);
_pockets->retain();
b2Body *pocket;
b2Sprite *pocketData;
b2CircleShape circle;
float startX = _screenSize.width * 0.07;
float startY = _screenSize.height * 0.92f;
for(int i = 0; i < 6; ++i){
bodyDef.type = b2_staticBody;
if(i < 3){
bodyDef.position.Set(
startX / PTM_RATIO,
(startY - i * (_screenSize.height * 0.84f * 0.5f)) / PTM_RATIO);
}else{
bodyDef.position.Set(
(startX + _screenSize.width * 0.85f) / PTM_RATIO,
(startY - (i - 3) * (_screenSize.height * 0.84f * 0.5f)) / PTM_RATIO);
}
pocket = _world->CreateBody(&bodyDef);
fixtureDef.isSensor = true;
circle.m_radius = (float)(1.5 * BALL_RADIUS) / PTM_RATIO;
fixtureDef.shape = &circle;
pocket->CreateFixture(&fixtureDef);
pocketData = new b2Sprite(this, kSpritePocket);
pocket->SetUserData(pocketData);
_pockets->addObject(pocketData);
}
b2BodyDef tableBodyDef;
tableBodyDef.position.Set(0, 0);
b2Body *tableBody = _world->CreateBody(&tableBodyDef);
b2EdgeShape tableBox;
//bottom
tableBox.Set(b2Vec2(_screenSize.width * 0.14f / PTM_RATIO, _screenSize.height * 0.09f / PTM_RATIO),
b2Vec2(_screenSize.width * 0.86f / PTM_RATIO, _screenSize.height * 0.09f / PTM_RATIO));
tableBody->CreateFixture(&tableBox, 0);
// top
tableBox.Set(b2Vec2(_screenSize.width * 0.14f/PTM_RATIO, _screenSize.height * 0.91f/PTM_RATIO),
b2Vec2(_screenSize.width * 0.86f/PTM_RATIO, _screenSize.height * 0.91f/PTM_RATIO));
tableBody->CreateFixture(&tableBox,0);
//left
tableBox.Set(b2Vec2(_screenSize.width * 0.09f / PTM_RATIO, _screenSize.height * 0.12f / PTM_RATIO),
b2Vec2(_screenSize.width * 0.09f / PTM_RATIO, _screenSize.height * 0.46f / PTM_RATIO));
tableBody->CreateFixture(&tableBox, 0);
tableBox.Set(b2Vec2(_screenSize.width * 0.91f / PTM_RATIO, _screenSize.height * 0.12f / PTM_RATIO),
b2Vec2(_screenSize.width * 0.91f / PTM_RATIO, _screenSize.height * 0.46f / PTM_RATIO));
tableBody->CreateFixture(&tableBox, 0);
//right
tableBox.Set(b2Vec2(_screenSize.width * 0.09f/PTM_RATIO, _screenSize.height * 0.54f/PTM_RATIO),
b2Vec2(_screenSize.width * 0.09f/PTM_RATIO, _screenSize.height * 0.88f/PTM_RATIO));
tableBody->CreateFixture(&tableBox,0);
tableBox.Set(b2Vec2(_screenSize.width * 0.91f/PTM_RATIO, _screenSize.height * 0.54f/PTM_RATIO),
b2Vec2(_screenSize.width * 0.91f/PTM_RATIO, _screenSize.height * 0.88f/PTM_RATIO));
tableBody->CreateFixture(&tableBox, 0);
_balls = CCArray::createWithCapacity(15);
_balls->retain();
Ball *ball;
int col = 5;
int colCnt = 0;
startX = (_screenSize.width - 8 * BALL_RADIUS) * 0.5f;
startY = _screenSize.height * 0.82f;
float newX;
float newY;
int color;
for (int i = 0; i < 15; i++) {
if (i == 10) {
color = kColorBlack;
} else if (i % 2 == 0) {
color = kColorYellow;
} else {
color = kColorRed;
}
if (colCnt < col) {
newX = startX + colCnt * 2 * BALL_RADIUS;
colCnt++;
} else {
startX += BALL_RADIUS;
startY -= 2 * BALL_RADIUS;
newX = startX;
col--;
colCnt = 1;
}
newY = startY;
ball = Ball::create(this, kSpriteBall, ccp(newX, newY), color);
_gameBatchNode->addChild(ball, kMiddleground);
_balls->addObject(ball);
}
//add cue ball
_player = Ball::create(this, kSpritePlayer, ccp(_screenSize.width * 0.5f, _screenSize.height * 0.3f), kColorWhite);
_gameBatchNode->addChild(_player, kMiddleground);
_cue = Cue::create(this);
_cue->setSpritePosition(ccp(_screenSize.width * 0.2f, _screenSize.height * 0.3f));
_cue->getBody()->SetTransform(_cue->getBody()->GetPosition(), M_PI*0.5);
_gameBatchNode->addChild(_cue, kForeground);
}
void GameLayer::draw(){
CCLayer::draw();
ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position);
kmGLPushMatrix();
_world->DrawDebugData();
kmGLPopMatrix();
}
void GameLayer::update(float dt) {
if(!_running) return;
if(_gameState == kGameOver) return;
_world->Step(dt, 10, 10);
int count = _balls->count();
Ball *ball;
for(int i = 0; i < count; ++i){
ball = (Ball *)_balls->objectAtIndex(i);
if(!ball->isVisible() && ball->getInPlay()){
ball->setInPlay(false);
ball->hide();
_ballsInPlay--;
if(_ballsInPlay == 0){
_gameState = kGameOver;
_gameOver->setVisible(true);
}
}else{
ball->update(dt);
}
}
if(!_cue->isVisible()){
_cue->hide();
}else{
_cue->update(dt);
}
if(!_player->isVisible())