Ccscene Gamelevellayer Ccscene Ccscene Gamelevellayer Gamelevellayer
Ccscene Gamelevellayer Ccscene Ccscene Gamelevellayer Gamelevellayer
Ccscene Gamelevellayer Ccscene Ccscene Gamelevellayer Gamelevellayer
h"
CCScene *GameLevelLayer::scene(){
CCScene *scene = CCScene::create();
GameLevelLayer *layer = GameLevelLayer::create();
scene->addChild(layer);
return scene;
}
bool GameLevelLayer::init(){
if(!CCLayer::init())
return false;
this->setTouchEnabled(true);
screensize = CCDirector::sharedDirector()->getWinSize();//get screen size
initGameLevel();//goi ham init khoi tao cac doi tuong
return true;
}
void GameLevelLayer::initGameLevel(){
//init bool
isGameOver = false;
//load sound
loadSound();
//play background music
CocosDenshion::SimpleAudioEngine::sharedEngine()-
>playBackgroundMusic("musics/backgrounds/level1.mp3");
//add map
tiledmap = new CCTMXTiledMap();
tiledmap->initWithTMXFile("level1.tmx");
tiledmap->setAnchorPoint(ccp(0, 0));
tiledmap->setPosition(CCPointZero);
this->addChild(tiledmap);
//tinh toan scale
scale = screensize.height/tiledmap->boundingBox().size.height;
tiledSizeScale = scale*tiledSize;
tiledmap->setScaleY(scale);
//get layer
walls = tiledmap->layerNamed("walls");
hazards = tiledmap->layerNamed("hazards");
addPlayer();//add player
listEnemy = new CCArray();
//addEnemyGroup();//add enemy
//create button
addMenuItem();
scheduleUpdate();//goi ham update
}
void GameLevelLayer::update(float dt){
if(isGameOver)
return;
addEnemyGroup();
player->update(dt);
handleHazardCollisions(player);//check collisions hazard
checkForWin();
checkForAndResolveCollisions(player);//check collisions wall
setViewPointCenter(player->getPosition());//di chuyen view screen theo player
checkButtonSelected();
CCObject *ob;
CCARRAY_FOREACH(listEnemy, ob){
Enemy *enemy = (Enemy*)ob;
enemy->update(dt);
checkForAndResolveCollisionsEnemy(enemy);
}
//set lai position button
turnleft->setPositionX(-this->getPositionX());
turnright->setPositionX(-this->getPositionX()+1.5*turnleft-
>boundingBox().size.width);
//player->setPositionY(screensize.height*0.8);
}
//pre sound
void GameLevelLayer::loadSound(){
CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect(effectJump);
CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect(effectHurt);
}
//play sound
void GameLevelLayer::playSound(std::string name){
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(name.c_str());
}
//add cc button iu khin
void GameLevelLayer::addMenuItem(){
turnleft = CCMenuItemImage::create("buttons/controls/left.png",
"buttons/controls/left.png", this, menu_selector(GameLevelLayer::menuCallBack));
turnleft->setAnchorPoint(ccp(0, 0));
turnleft->setScale(screensize.height/8/turnleft->boundingBox().size.height);
turnleft->setPosition(ccp(0, 0));
turnleft->setTag(tagButtonTurnLeft);
turnright = CCMenuItemImage::create("buttons/controls/right.png",
"buttons/controls/right.png", this, menu_selector(GameLevelLayer::menuCallBack));
turnright->setAnchorPoint(ccp(0, 0));
turnright->setScale(screensize.height/8/turnright->boundingBox().size.height);
turnright->setPosition(ccp(turnleft->boundingBox().size.width, 0));
turnright->setTag(tagButtonTurnRight);
pMenu = CCMenu::create(turnleft, turnright, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu);
}
void GameLevelLayer::menuCallBack(CCObject *pSender){//handle buttons
CCMenuItem *item = (CCMenuItem*)pSender;
switch ((int)item->getTag()){
case tagButtonTurnLeft:{
}break;
case tagButtonTurnRight:{
}break;
default:
break;
}
}
void GameLevelLayer::checkButtonSelected(){//kiem tra cac button duoc press
if(turnright->isSelected()){
//player->forwardMarch = true;
//player->mightAsWallJump = true;
}else{
//player->forwardMarch = false;
//player->mightAsWallJump = false;
}
}
CCPoint GameLevelLayer::tileCoordForPosition(CCPoint position){
float x = floor(position.x/tiledSizeScale);
float levelHeightInPixels = tiledmap->boundingBox().size.height;
float y = floor((levelHeightInPixels - position.y)/tiledmap-
>getTileSize().height);
return ccp(x, y);
}
CCRect GameLevelLayer::tileRectFromTileCoords(CCPoint tileCoords){
float levelHeightInPixels = tiledmap->boundingBox().size.height;
CCPoint origin = ccp(tileCoords.x*tiledmap->getTileSize().width,
levelHeightInPixels - ((tileCoords.y+1)*tiledmap->getTileSize().height));
return CCRectMake(origin.x, origin.y, tiledmap->getTileSize().width, tiledmap-
>getTileSize().height);
}
CCArray* GameLevelLayer::getSurroundingTilesAtPosition(CCPoint position, CCTMXLayer*
layer, int tag){
CCPoint plPos = tileCoordForPosition(position);
CCArray *gids = new CCArray();
for(int i=0; i<9; i++){
int c = i%3;
int r = (int)(i/3);
CCPoint tilePos = ccp(plPos.x + (c-1), plPos.y + (r-1));
//check khi roi xuong day man hinh
if(tilePos.y > (tiledmap->getMapSize().height -1)){
//fallen in a hole
if(tag == tagPlayer)//neu player roi xuong ho thi gameover
gameOver(0);
else{//neu enemy roi xuog ho thi huy
this->removeChildByTag(tag);
CCObject *ob;
CCARRAY_FOREACH(listEnemy, ob){
Enemy* enemy = (Enemy*)ob;
if(enemy->getTag()==tag){
listEnemy->removeObject(enemy);
break;
}
}
}
return NULL;
}
int tgid = layer->tileGIDAt(tilePos);
CCRect tileRect = tileRectFromTileCoords(tilePos);
CCDictionary *tileDict = CCDictionary::create();
tileDict->setObject(CCNumber<int>::numberWithValue(tgid), "gid");
tileDict->setObject(CCNumber<float>::numberWithValue(tileRect.origin.x),
"x");
tileDict->setObject(CCNumber<float>::numberWithValue(tileRect.origin.y),
"y");
tileDict->setObject(CCValue<CCPoint>::valueWithValue(tilePos), "tilePos");
gids->addObject(tileDict);
}
gids->removeObjectAtIndex(4);
gids->insertObject(gids->objectAtIndex(2), 6);
gids->removeObjectAtIndex(2);
gids->exchangeObjectAtIndex(4, 6);
gids->exchangeObjectAtIndex(0, 4);
return gids;
}
CCRect GameLevelLayer::rectIntersection(CCRect rect1, CCRect rect2){
CCRect intersection = CCRectMake(
MAX(rect1.getMinX(), rect2.getMinX()),
MAX(rect1.getMinY(), rect2.getMinY()),
0, 0
);
intersection.size.width = MIN(rect1.getMaxX()-intersection.getMinX(),
rect2.getMaxX()-intersection.getMinX());
intersection.size.height = MIN(rect1.getMaxY()-intersection.getMinY(),
rect2.getMaxY()-intersection.getMinY());
return intersection;
}
//check collision player
void GameLevelLayer::checkForAndResolveCollisions(Player *p){
CCArray *tiles = this->getSurroundingTilesAtPosition(p->getPosition(), walls, p-
>getTag());
if(isGameOver)
return;
//quan ly va cham vs map
p->onGround = false;
CCObject *ob;
CCARRAY_FOREACH(tiles, ob){
CCDictionary *dic = (CCDictionary*) ob;
CCRect pRect = p->collisionBoundingBox();
int gid = ((CCInteger*)dic->objectForKey("gid"))->getValue();
if(gid){
CCRect tileRect = CCRectMake(((CCFloat*)dic->objectForKey("x"))-
>getValue(), ((CCFloat*)dic->objectForKey("y"))->getValue(), tiledmap-
>getTileSize().width, tiledmap->getTileSize().height);
if(pRect.intersectsRect(tileRect)){
CCRect intersection = rectIntersection(pRect, tileRect);//get
vung giao nhau
int tileIndx = tiles->indexOfObject(dic);
if(tileIndx==0){
//tile is directly below player
p->desiredPosition = ccp(p->desiredPosition.x, p-
>desiredPosition.y + intersection.size.height);
p->velocity = ccp(p->velocity.x, 0.0);//here
p->onGround = true;
}else if(tileIndx==1){
//tile is directly above player
p->desiredPosition = ccp(p->desiredPosition.x, p-
>desiredPosition.y - intersection.size.height);
p->velocity = ccp(p->velocity.x, 0.0);//here
}else if(tileIndx ==2){
//tile is left of player
p->desiredPosition = ccp(p->desiredPosition.x +
intersection.size.width, p->desiredPosition.y);
}else if(tileIndx ==3){
//tile is right of player
p->desiredPosition = ccp(p->desiredPosition.x -
intersection.size.width, p->desiredPosition.y);
}else{
if(intersection.size.width>intersection.size.height){
//tile is diagonal, but resolving collision
vertially
p->velocity = ccp(p->velocity.x, 0.0);//here
float resolutionHeight;
if(tileIndx>5){
resolutionHeight =
intersection.size.height;
p->onGround = true;//here
}else{
resolutionHeight = -
intersection.size.height;
}
p->desiredPosition = ccp(p->desiredPosition.x,
p->desiredPosition.y + resolutionHeight);
}else{
float resolutionWidth;
if(tileIndx == 6 || tileIndx == 4){
resolutionWidth =
intersection.size.width;
}else{
resolutionWidth = -
intersection.size.width;
}
p->desiredPosition = ccp(p->desiredPosition.x +
resolutionWidth, p->desiredPosition.y);
}
}
}
}
}
//quan ly va cham vs enemy
CCObject *en;
CCARRAY_FOREACH(listEnemy, en){
Enemy* enemy = (Enemy*)en;
CCRect enemyRect = enemy->boundingBox();
CCRect pRect = p->boundingBox();
if(pRect.intersectsRect(enemyRect)){
CCRect intersection = rectIntersection(pRect, enemyRect);//get vung
giao nhau
if((p->getPositionY()>enemy->getPositionY()) &&
(intersection.size.width>intersection.size.height) && (p->velocity.y<0)){
this->removeChildByTag(enemy->getTag());
listEnemy->removeObject(enemy);
CCLOG("Enemy died!");
}else{
CCLOG("You died!");
}
}
}
p->setPosition(p->desiredPosition);
}
//check collision enemy
void GameLevelLayer::checkForAndResolveCollisionsEnemy(Enemy *p){
CCArray *tiles = this->getSurroundingTilesAtPosition(p->getPosition(), walls, p-
>getTag());
if(isGameOver)
return;
p->onGround = false;
CCObject *ob;
CCARRAY_FOREACH(tiles, ob){
CCDictionary *dic = (CCDictionary*) ob;
CCRect pRect = p->collisionBoundingBox();
int gid = ((CCInteger*)dic->objectForKey("gid"))->getValue();
if(gid){
CCRect tileRect = CCRectMake(((CCFloat*)dic->objectForKey("x"))-
>getValue(), ((CCFloat*)dic->objectForKey("y"))->getValue(), tiledmap-
>getTileSize().width, tiledmap->getTileSize().height);
if(pRect.intersectsRect(tileRect)){
CCRect intersection = rectIntersection(pRect, tileRect);//get
vung giao nhau
int tileIndx = tiles->indexOfObject(dic);
if(tileIndx==0){
//tile is directly below player
p->desiredPosition = ccp(p->desiredPosition.x, p-
>desiredPosition.y + intersection.size.height);
p->velocity = ccp(p->velocity.x, 0.0);//here
p->onGround = true;
}else if(tileIndx==1){
//tile is directly above player
p->desiredPosition = ccp(p->desiredPosition.x, p-
>desiredPosition.y - intersection.size.height);
p->velocity = ccp(p->velocity.x, 0.0);//here
}else if(tileIndx ==2){
//tile is left of player
p->faceRight = true;//dung vao tuong ben trai thi quay
mat lai
p->desiredPosition = ccp(p->desiredPosition.x +
intersection.size.width, p->desiredPosition.y);
}else if(tileIndx ==3){
//tile is right of player
p->faceRight = false;//dung vao tuong ben phai thi quay
mat lai ben trai
p->desiredPosition = ccp(p->desiredPosition.x -
intersection.size.width, p->desiredPosition.y);
}else{
if(intersection.size.width>intersection.size.height){
//tile is diagonal, but resolving collision
vertially
p->velocity = ccp(p->velocity.x, 0.0);//here
float resolutionHeight;
if(tileIndx>5){
resolutionHeight =
intersection.size.height;
p->onGround = true;//here
}else{
resolutionHeight = -
intersection.size.height;
}
p->desiredPosition = ccp(p->desiredPosition.x,
p->desiredPosition.y + resolutionHeight);
}else{
float resolutionWidth;
if(tileIndx == 6 || tileIndx == 4){
resolutionWidth =
intersection.size.width;
}else{
resolutionWidth = -
intersection.size.width;
}
p->desiredPosition = ccp(p->desiredPosition.x +
resolutionWidth, p->desiredPosition.y);
}
}
}
}
}
p->setPosition(p->desiredPosition);
}
//set view theo nhan vat
void GameLevelLayer::setViewPointCenter(CCPoint position){
int x = MAX(position.x, screensize.width/2);
int y = MAX(position.y, screensize.height/2);
x = MIN(x, (tiledmap->boundingBox().size.width)-screensize.width/2);
y = MIN(y, (tiledmap->boundingBox().size.height)-screensize.height/2);
CCPoint actualPosition = ccp(x, y);
CCPoint centerOfView = ccp(screensize.width/2, screensize.height/2);
CCPoint viewPoint = ccpSub(centerOfView, actualPosition);
this->setPosition(viewPoint);
}
//handle hazard collisions
void GameLevelLayer::handleHazardCollisions(Player *p){
CCArray *tiles = getSurroundingTilesAtPosition(p->getPosition(), hazards, p-
>getTag());
CCObject *ob;
CCARRAY_FOREACH(tiles, ob){
CCDictionary *dic = (CCDictionary*) ob;
CCRect tileRect = CCRectMake(((CCFloat*)dic->objectForKey("x"))-
>getValue(), ((CCFloat*)dic->objectForKey("y"))->getValue(), tiledmap-
>getTileSize().width, tiledmap->getTileSize().height);
CCRect pRect = p->collisionBoundingBox();
if(((CCInteger*)dic->objectForKey("gid"))->getValue() &&
pRect.intersectsRect(tileRect)){
gameOver(0);//call end
}
}
}
//check is Win
void GameLevelLayer::checkForWin(){
//if(player->getPositionX()>3130.0)
//gameOver(1);//win
}
//call when gameover
void GameLevelLayer::gameOver(bool won){
isGameOver = true;
playSound(effectHurt);
if(won){
CCLOG("You won!");
}else{
CCLOG("You have died!");
}
}
void GameLevelLayer::registerWithTouchDispatcher(void)
{
CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0);
}
void GameLevelLayer::ccTouchesBegan(CCSet* pTouches, CCEvent *pEvent){
CCSetIterator iter = pTouches->begin();
for(; iter != pTouches->end(); iter++){
CCTouch *pTouch = (CCTouch*)(*iter);
CCPoint location = pTouch->getLocationInView();
CCPoint touchLocation = CCDirector::sharedDirector()-
>convertToGL(location);
if(touchLocation.x>240){
player->mightAsWallJump = true;
}else{
player->forwardMarch = true;
}
}
}
void GameLevelLayer::ccTouchesMoved(CCSet* pTouches, CCEvent *pEvent){
CCSetIterator iter = pTouches->begin();
for(; iter != pTouches->end(); iter++){
CCTouch *pTouch = (CCTouch*)(*iter);
CCPoint location = pTouch->getLocationInView();
CCPoint touchLocation = CCDirector::sharedDirector()-
>convertToGL(location);
CCPoint previousLocation = pTouch->getPreviousLocationInView();
CCPoint previousTouchLocation = CCDirector::sharedDirector()-
>convertToGL(previousLocation);
if(touchLocation.x>240 && previousTouchLocation.x<=240){
player->mightAsWallJump = true;
player->forwardMarch = false;
}else if(touchLocation.x<=240 && previousTouchLocation.x>240){
player->mightAsWallJump = false;
player->forwardMarch = true;
}
}
}
void GameLevelLayer::ccTouchesEnded(CCSet* pTouches, CCEvent *pEvent){
CCSetIterator iter = pTouches->begin();
for(; iter != pTouches->end(); iter++){
CCTouch *pTouch = (CCTouch*)(*iter);
CCPoint location = pTouch->getLocationInView();
CCPoint touchLocation = CCDirector::sharedDirector()-
>convertToGL(location);
if(touchLocation.x>240){
player->forwardMarch = false;
player->mightAsWallJump = false;
}else{
player->forwardMarch = false;
player->mightAsWallJump = false;
}
}
}
//add player
void GameLevelLayer::addPlayer(){
//create player
player = new Player();
player->initWithFile("players/run1.png");
player->setPosition(ccp(900, 300));
player->setTag(tagPlayer);
this->addChild(player, 2);
}
//add enemy
void GameLevelLayer::addEnemyGroup(){
//get object in map
CCTMXObjectGroup *enemyObjectGroup = tiledmap->objectGroupNamed("enemys");
CCArray* obArray = enemyObjectGroup->getObjects();
CCObject* ob;
CCARRAY_FOREACH(obArray, ob){
CCDictionary *enemyDic = dynamic_cast<CCDictionary*>(ob);
float x = ((CCString)*enemyDic->valueForKey("x")).floatValue();
float y = ((CCString)*enemyDic->valueForKey("y")).floatValue();
bool isAdd = true;//dung de kiem tra xem da duoc add hay chua
CCObject* en;
CCARRAY_FOREACH(listEnemy, en){//kiem tra xem enemy da duoc add chua, kiem
tra xem tai vi tri do co enemy nao di qua khong
Enemy *enemy = (Enemy*)en;
CCRect rect = CCRectMake(x, y, enemy->boundingBox().size.width,
enemy->boundingBox().size.height);
if(rect.intersectsRect(enemy->boundingBox())){//neu tai vi tri nay
da bi vuong' 1 enemy khac thi tam thoi chua add
isAdd = false;
break;
}
if(enemy->getTag()==(tagEnemyZero + obArray-
>indexOfObject(ob))){//neu da duoc add roi thi k add nua
isAdd = false;
break;
}
}
if((isAdd == true) && (x<-this->getPositionX()+screensize.width) && (x>-
this->getPositionX()))
addEnemy(x, y, tagEnemyZero + obArray->indexOfObject(ob));//add them
1 enemy vao
}
}
void GameLevelLayer::addEnemy(float x, float y, int tag){
Enemy *enemy = new Enemy();
enemy->initWithFile("enemys/enemy_run1.png");
enemy->setPosition(ccp(x, y));
enemy->setTag(tag);
this->addChild(enemy);
listEnemy->addObject(enemy);//add to list
}