#include "GameScene.h"
#include "GameOverScene.h"
USING_NS_CC;
using namespace CocosDenshion;
Scene* GameScene::createScene()
{
// //创建物理世界的场景
auto scene = Scene::createWithPhysics();
//PhysicsWorld* phyWorld = scene->getPhysicsWorld();
//phyWorld->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
auto layer = GameScene::create();
scene->addChild(layer);
return scene;
}
bool GameScene::init()
{
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
status = 1 ; //初始化游戏状态
//创建滚动背景
//背景精灵
auto bg1 = Sprite::create("background.png");
bg1->setPosition(Vec2(origin.x + visibleSize.width/2,0));
bg1->setAnchorPoint(Vec2(0.5,0));
bg1->setTag(101);
this->addChild(bg1,0);
//第二张背景图,是跟在第一张的上面,无缝连接,两张图形成不间断的地图滚动
auto bg2 = Sprite::create("background.png");
bg2->setPosition(Vec2(origin.x + visibleSize.width/2, bg1->getPositionY()+bg1->getContentSize().height));
bg2->setAnchorPoint(Vec2(0.5,0));
bg2->setTag(102);
this->addChild(bg2,0);
//背景滚动的定时器,0.01执行一次传入的函数
this->schedule(schedule_selector(GameScene::backgroundMove),0.01);
//创建我机
auto plane = Sprite::create("hero1.png");
plane->setPosition(visibleSize.width/2+origin.x,200);
plane->setTag(103);
//设置碰撞属性
//碰撞掩码,用于判断是否可以与其他物体碰撞,判断逻辑为两者的碰撞掩码进行逻辑与,如为零则不会碰撞,否则会
//这里只有我机、敌机、子弹,子弹和敌机可以碰撞,敌机和我机可以碰撞,我机和子弹不可以碰撞,以次可以设置它们的掩码分别为0x01(0001)、0x03(0011)、0x02(0010)
auto planeBody = PhysicsBody::createBox(plane->getContentSize());
planeBody->setContactTestBitmask(0x0003);
planeBody->setCategoryBitmask(0x0001);
planeBody->setCollisionBitmask(0x0007);
planeBody->setGravityEnable(false);
plane->setPhysicsBody(planeBody);
this->addChild(plane);
Animation * animation = Animation::create();
SpriteFrame * spriteFrame1 = SpriteFrame::create("hero1.png",Rect(0,0,102,126));
SpriteFrame * spriteFrame2 = SpriteFrame::create("hero2.png",Rect(0,0,102,126));
animation->addSpriteFrame(spriteFrame1);
animation->addSpriteFrame(spriteFrame2);
animation->setDelayPerUnit(0.15f);
Animate * animate = Animate::create(animation);
plane->runAction(RepeatForever::create(animate));
//触摸事件注册,要通过回调函数来控制飞机的坐标
setTouchEnabled(true);
//设置为单点触碰
setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
//我机发射子弹
this->schedule(schedule_selector(GameScene::bulletCreate),0.3);
//让子弹飞和让敌机飞
this->schedule(schedule_selector(GameScene::objectMove),0.01);
//敌机创建
this->schedule(schedule_selector(GameScene::enemyCreate),0.5);
return true;
}
//背景滚动回调函数的实现
void GameScene::backgroundMove(float f)
{
//背景滚动逻辑
auto bg1 = this->getChildByTag(101);
auto bg2 = this->getChildByTag(102);
//当第二张图片退出屏幕时,把第一张图片设置到屏幕中,由于背景图片的高度是大于屏幕的高度的,所以判断逻辑要复杂点
if(bg2 -> getPositionY() + bg2->getContentSize().height <= Director::getInstance()->getVisibleSize().height)
{
bg1->setPositionY(-bg1->getContentSize().height + Director::getInstance()->getVisibleSize().height);
}
bg1->setPositionY(bg1->getPositionY()-4);
bg2->setPositionY(bg1->getPositionY()+bg1->getContentSize().height);
}
//手指点击下时,记录该点的位置,该点为起点
bool GameScene::onTouchBegan(Touch * touch, Event * event)
{
if(status == 1)
{
fx=touch->getLocation().x;
fy=touch->getLocation().y;
}
return true;
}
//每次移动把移动的位置(终点)记录下来,并与之前记录下的位置相减,得到飞机该位移的相对量(x、y轴移动多少),并刷新起点位置
void GameScene::onTouchMoved(Touch * touch, Event * event)
{
if(status == 1)
{
int mx=(touch->getLocation().x-fx);
int my=(touch->getLocation().y-fy);
auto spPlane=this->getChildByTag(103);
spPlane->runAction(MoveBy::create(0,Point(mx,my)));
fx=touch->getLocation().x;
fy=touch->getLocation().y;
}
}
//创建子弹
void GameScene::bulletCreate(float f)
{
SimpleAudioEngine::getInstance()->playEffect("sounds/bullet.wav");
auto plane=this->getChildByTag(103);
Sprite * bullet=Sprite::create("bullet.png");
bullet->setPosition(plane->getPosition().x,plane->getPosition().y+60);
bullet->setTag(106);
auto bulletBody = PhysicsBody::createBox(bullet->getContentSize());
bulletBody->setContactTestBitmask(0x0002);
bulletBody->setCategoryBitmask(0x0005);
bulletBody->setCollisionBitmask(0x0002);
bulletBody->setGravityEnable(false);
bullet->setPhysicsBody(bulletBody);
this->addChild(bullet);
this->bulletList.pushBack(bullet);
}
//让子弹飞
void GameScene::objectMove(float f)
{
//遍历vector取出所有的子弹,让子弹的位置往上移,水往低处流,子弹向上飞嘛
for(int i = 0; i < bulletList.size() ; i++)
{
auto bullet = bulletList.at(i);
bullet->setPositionY(bullet->getPositionY()+3);
//如果该子弹已经超出屏幕范围,则移除它
if(bullet->getPositionY()>Director::getInstance()->getWinSize().height)
{
bullet->removeFromParent(); //从层中移除
bulletList.eraseObject(bullet); //从记录所有子弹的vector中移除
//移除后上一个对象会移到当前这个对象的位置,实际还是当前这个i,所以要i--才能访问到下一个对象
i--;
}
}
//取出所有的敌机,让敌机往下移动
for(int i = 0; i < enemyList.size() ; i++)
{
auto enemy = enemyList.at(i);
enemy->setPositionY(enemy->getPositionY()-5);
//如果该子弹已经超出屏幕范围,则移除它
if(enemy->getPositionY() < -enemy->getContentSize().height)
{
enemy->removeFromParent(); //从层中移除
enemyList.eraseObject(enemy); //从记录所有子弹的vector中移除
//移除后上一个对象会移到当前这个对象的位置,实际还是当前这个i,所以要i--才能访问到下一个对象
i--;
}
}
}
//敌机创建
void GameScene::enemyCreate(float f)
{
//随机出现敌机1或敌机2
int ranDom = rand()%2+1;
auto string = cocos2d::__String::createWithFormat("enemy%d.png",ranDom);
auto enemy = Sprite::create(string->getCString());
if(ranDom == 1)
{
enemy->setTag(104); //敌机的类型,由这个来判断,用于分数计算
}
else
{
enemy->setTag(105);
}
enemy->setPosition(Vec2(rand()%(int)(Director::getInstance()->getVisibleSize().width),Director::getInstance()->getVisibleSize().height+enemy->getContentSize().height)); //随机在屏幕最上方的出现敌机
auto enemyBody = PhysicsBody::createBox(enemy->getContentSize());
enemyBody->setContactTestBitmask(0x0003);
enemyBody->setCategoryBitmask(0x0002);
enemyBody->setCollisionBitmask(0x0001);
enemyBody->setGravityEnable(false);
enemy->setPhysicsBody(enemyBody);
this->addChild(enemy);
this->enemyList.pushBack(enemy);
}