#include "GameLayer.h"
#include "SimpleAudioEngine.h"
#include "MyUtility.h"
using namespace CocosDenshion;
USING_NS_CC;
Scene* GameLayer::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = GameLayer::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool GameLayer::init()
{
// 1. super init first
if (!Layer::init())
{
return false;
}
initData();
resetBullet();
this->scheduleUpdate();
//单点触摸
this->setTouchEnabled(true);
this->setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
return true;
}
//初始化背景、战机、战机飞行动画、子弹
void GameLayer::initData()
{
visibleSize = Director::getInstance()->getVisibleSize();
bgHeight = visibleSize.height;
//分数
scoreLabel = MyUtility::createBMF("000", Vec2(90, visibleSize.height - 50));
this->addChild(scoreLabel, 4);
bg1 = Sprite::createWithSpriteFrameName("background_2.png");
bg1->setAnchorPoint(Vec2(0.5, 0));
bg1->setPosition(Vec2(visibleSize.width / 2, 0));
this->addChild(bg1, 0);
bg2 = Sprite::createWithSpriteFrameName("background_2.png");
bg2->setAnchorPoint(Vec2(0.5, 0));
bg2->setPosition(Vec2(visibleSize.width / 2, visibleSize.height));
this->addChild(bg2, 0);
//暂停
pauseToggleMenuItem = MyUtility::initToggleMenuItem(
CC_CALLBACK_1(GameLayer::pauseGameCallback, this),
"game_pause.png",
"game_pause_hl.png",
40,
visibleSize.height - 50
);
//炸弹
auto bombSprite = Sprite::createWithSpriteFrameName("bomb.png");
auto toggleMenuItem = MenuItemSprite::create(bombSprite, bombSprite);
useBombToggleMenuItem = MenuItemToggle::createWithCallback(
CC_CALLBACK_1(GameLayer::useBombCallback, this),
toggleMenuItem,
toggleMenuItem,
NULL
);
useBombToggleMenuItem->setPosition(Vec2(bombSprite->getContentSize().width / 2, bombSprite->getContentSize().height / 2));
useBombToggleMenuItem->setVisible(false);
//炸弹数量
bombNumLabel = MyUtility::createMenuItem(CC_CALLBACK_1(GameLayer::useBombCallback, this), "游戏");
bombNumLabel->setVisible(false);
auto bombMenu = Menu::create(pauseToggleMenuItem, useBombToggleMenuItem, bombNumLabel, NULL);
bombMenu->setPosition(Vec2::ZERO);
this->addChild(bombMenu, 4);
player = Sprite::createWithSpriteFrameName("hero_fly_1.png");
player->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2 - 200));
this->addChild(player, 3);
//战机动画
Animation* animation = Animation::create();
for (int i = 1; i <= PLAN_COUNT; i++)
{
__String* str = __String::createWithFormat("hero_fly_%d.png", i);
SpriteFrame* frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(str->getCString());
animation->addSpriteFrame(frame);
}
//战机大小
playerSize = Vec2(player->getContentSize().width, player->getContentSize().height);
//每个帧的间隔
animation->setDelayPerUnit(0.1f);
Animate* animate = Animate::create(animation);
player->runAction(RepeatForever::create(animate));
madeBullet();
}
//子弹
void GameLayer::madeBullet()
{
bullet = Sprite::createWithSpriteFrameName(!isBigBulletTime ? "bullet1.png" : "bullet2.png");
this->addChild(bullet);
}
//滚屏
void GameLayer::scrollBg()
{
if (!isGameOver)
{
if (0 >= bgHeight)
{
bgHeight = visibleSize.height;
}
bg1->setPosition(Vec2(bg1->getPosition().x, bgHeight - visibleSize.height));
bg2->setPosition(Vec2(bg2->getPosition().x, bgHeight - 1));
bgHeight--;
}
}
void GameLayer::update(float dt)
{
if (!isGamePause)
{
scrollBg();
fire();
addEnemyPlane();
moveEnemyPlane();
collisionDetection();
addChangeBullet();
bigBulletLastTime();
}
}
//背景音乐
void GameLayer::onEnterTransitionDidFinish()
{
Layer::onEnterTransitionDidFinish();
SimpleAudioEngine::getInstance()->playBackgroundMusic("music/game_music.mp3", true);
SimpleAudioEngine::getInstance()->playEffect("music/shoot.mp3", true);
}
bool GameLayer::onTouchBegan(Touch* touch, Event* event)
{
//检测触摸的屏幕点是否在一个范围内
//Vec2 nodeWorld = touch->getLocation();
//Vec2 nodeLocal = player->convertToNodeSpace(nodeWorld);
//Size planeSize = player->getContentSize();
//Rect planeRect = Rect(0, 0, planeSize.width, planeSize.height);
//if (planeRect.containsPoint(nodeLocal))
//{
// return true;
//}
//return false;
return !isGameOver;
}
//移动战机
void GameLayer::onTouchMoved(Touch* touch, Event* event)
{
if (!isGameOver && !isGamePause)
{
////当前触摸点OpenGL坐标
//Vec2 touchPos = touch->getLocation();
////战机位置
Vec2 playerPos = player->getPosition();
////上一个触摸点OpenGL坐标
//Vec2 oldTouchPos = touch->getPreviousLocation();
//偏移量
Vec2 diff = touch->getDelta();// touchPos - oldTouchPos;
bulletWidthSpeed = diff.x;
//战机偏移后的位置
Vec2 newPos = Vec2(playerPos.x + diff.x, playerPos.y + diff.y);
/*保证战机偏移后位置还在屏幕内*/
//左边界
if (newPos.x < playerSize.width / 2)
{
newPos.x = playerSize.width / 2;
}
else if (newPos.x > visibleSize.width - playerSize.width / 2)//右边界
{
newPos.x = visibleSize.width - playerSize.width / 2;
}
//下边界
if (newPos.y < playerSize.height / 2)
{
newPos.y = playerSize.height / 2;
}
else if (newPos.y > visibleSize.height - playerSize.height / 2 - 20)//上边界
{
newPos.y = visibleSize.height - playerSize.height / 2 - 20;
}
player->setPosition(newPos);
}
}
//重置子弹
void GameLayer::resetBullet()
{
//根据双子弹状态变换子弹
if (isChangeBullet)
{
//从父节点中删除当前子节点 如果Cleanup为true则删除当前节点的所有动作
bullet->removeFromParentAndCleanup(false);
//重新制造子弹
madeBullet();
//停止变换子弹
isChangeBullet = false;
}
//子弹速度
bulletSpeed = (visibleSize.height - (player->getPosition().y + 50)) / 10;
if (10 > bulletSpeed)
{
bulletSpeed = 10;
}
//子弹初始位置
bullet->setPosition(Vec2(player->getPosition().x, player->getPosition().y + 50));
}
//开火
void GameLayer::fire()
{
if (!isGameOver)
{
//子弹加速度
bullet->setPosition(Vec2(bullet->getPosition().x + bulletWidthSpeed / 1.5, bullet->getPosition().y + bulletSpeed));
//达到屏幕高度重置子弹到初始位置
if (bullet->getPosition().y > visibleSize.height + 10)
{
this->resetBullet();
}
}
}
/*===============添加敌机=======================*/
void GameLayer::addEnemyPlane()
{
if (!isGameOver)
{
/*间隔不同的时间出现不同的敌机*/
smallPlaneTime++;
mediumPlaneTime++;
bigPlaneTime++;
if (SMALLPLANE_TIME < smallPlaneTime)
{
//获得敌机精灵
EnemyPlane* smallPlane = EnemyPlane::createEnemyPlane(
"enemy1_fly_1.png",
EnemyPlaneType::kSmallPane, visibleSize,
1, CCRANDOM_0_1() * 2 + 2
);
this->addChild(smallPlane, 3);
//添加到敌机集合
planeList.pushBack(smallPlane);
smallPlaneTime = 0;
}
if (MEDIUMPLANE_TIME < mediumPlaneTime)
{
EnemyPlane* mediumPlane = EnemyPlane::createEnemyPlane(
"enemy3_fly_1.png",
EnemyPlaneType::kMediumPlane, visibleSize,
30, 3
);
this->addChild(mediumPlane, 3);
planeList.pushBack(mediumPlane);
mediumPlaneTime = 0;
}
if (BIGPLANE_TIME < bigPlaneTime)
{
EnemyPlane* bigPlane = EnemyPlane::createEnemyPlane(
"enemy2_fly_1.png",
EnemyPlaneType::kBigPlane, visibleSize,
55, 2
);
this->addChild(bigPlane, 3);
planeList.pushBack(bigPlane);
bigPlaneAction(bigPlane);
bigPlaneTime = 0;
}
}
}
//大敌机的动画
void GameLayer::bigPlaneAction(EnemyPlane* plane)
{
Animation* animation = Animation::create();
for (int i = 1; i <= PLAN_COUNT; i++)
{
__String* str = __String::createWithFormat("enemy2_fly_%i.png", i);
SpriteFrame* frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(str->getCString());
animation->addSpriteFrame(frame);
}
animation->setDelayPerUnit(0.1f);
Animate* animate = Animate::create(animation);
plane->runAction(RepeatForever::create(animate));
}
//超过屏幕底部移除集合里的敌机
void GameLayer::moveEne