我们要想实现主机的移动以及主机的射击我们就必须先理清逻辑。在这里我们需要创建两个类,一个是hero
主机类,bullet
子弹类。主机类和子弹类我们需要继承Sprite
类,因为我们可以理解为主机和子弹都是一个精灵,我们把他们封装好,给外界使用的时候就很方便了。
hero.h
#ifndef __Hero_H__
#define __Hero_H__
#include "cocos2d.h"
using namespace cocos2d;
class Hero : public Sprite{
public:
Hero();
~Hero();
static Hero* create();
bool init();
void shoot(float dt);
//当触摸开始时,要执行的函数
bool onTouchBegan(Touch* touch, Event* event);
//当触摸移动时,要执行的函数
void onTouchMoved(Touch* touch, Event* event);
void heroAction();
private:
int speed;
};
#endif // !__Hero_H__
hero.cpp
#include "Hero.h"
#include "Bullet.h"
Hero::Hero() :speed(80){
}
Hero::~Hero() {
}
/*
英雄创建
*/
Hero* Hero::create() {
Hero* ret = new(std::nothrow) Hero();
if (ret && ret->init()) {
ret->autorelease();
return ret;
}
delete ret;
ret = nullptr;
return ret;
}
/*
初始化
*/
bool Hero::init() {
if (!Sprite::initWithFile("image/hero/hero0_1.png")) {
return false;
}
//开启触摸监听事件
//创建单点触摸
EventListenerTouchOneByOne* eventListener = EventListenerTouchOneByOne::create();
eventListener->onTouchBegan = CC_CALLBACK_2(Hero::onTouchBegan, this);
eventListener->onTouchMoved = CC_CALLBACK_2(Hero::onTouchMoved, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(eventListener, this);
//开启英雄飞行动画
heroAction();
//开启英雄射击自定义调度器
schedule(schedule_selector(Hero::shoot), 0.3, -1, 0);
return true;
}
/*
当触摸开始时,要执行的函数
*/
bool Hero::onTouchBegan(Touch* touch, Event* event) {
Vec2 touchPoint = touch->getLocation();
bool isContain = getBoundingBox().containsPoint(touchPoint);
//判断触摸的那个点是否在英雄的身上
if (isContain) {
return true;
}
return false;
}
/*
当触摸移动时,要执行的函数
*/
void Hero::onTouchMoved(Touch* touch, Event* event) {
//获取当前移动的值
Vec2 pos = touch->getLocation();
//判断飞机的位置应该在(0-480)之间
if (pos.x >= 480) {
pos = Vec2(480 - getContentSize().width / 2, pos.y);
} else if (pos.x <= 0) {
pos = Vec2(getContentSize().width / 2, pos.y);
}
//判断飞机的y轴可移动的值应该在(0-800)之间
if (pos.y >= (800 - getContentSize().height / 2)) {
pos = Vec2(pos.x, (800 - getContentSize().height / 2));
} else if (pos.y <= getContentSize().height / 4) {
pos = Vec2(pos.x, getContentSize().height / 4);
}
setPosition(pos);
}
/*
英雄射击调度器
*/
void Hero::shoot(float dt) {
//创建子弹
Bullet* bullet = Bullet::create();
float h = getContentSize().height / 2;
//设置子弹的位置:英雄的坐标 + 英雄图片高度的一半
bullet->setPosition(getPosition() + Vec2(0, 0));
//将子弹添加到父节点上
_parent->addChild(bullet);
}
/*
主机飞行动画
*/
void Hero::heroAction() {
Animation* animation = Animation::create();
char fileName[40];
for (int i = 1; i <= 6; i++) {
sprintf_s(fileName, "image/hero/hero0_%d.png", i);
animation->addSpriteFrameWithFile(fileName);
}
//间隔时间
animation->setDelayPerUnit(0.2f);
animation->setLoops(-1);
//开启动画
Animate* animate = Animate::create(animation);
animate->setTag(15);
this->runAction(animate);
}
bullet.h
#ifndef __Buttle_H__
#define __Buttle_H__
#include "cocos2d.h"
using namespace cocos2d;
class Bullet : public Sprite{
public:
Bullet();
~Bullet();
static Bullet* create();
bool init();
void update(float dt) override;
void bulletRun();
private:
int speed;
};
#endif // !__Buttle_H__
bullet.cpp
#include "Bullet.h"
Bullet::Bullet():speed(200){
}
Bullet::~Bullet() {
}
Bullet* Bullet::create() {
Bullet* ret = new(std::nothrow) Bullet();
if (ret && ret->init()) {
ret->autorelease();
return ret;
}
delete ret;
ret = nullptr;
return ret;
}
/*
初始化
*/
bool Bullet::init() {
if (!Sprite::initWithFile("image/bullet_effect/bullet_0_1.png")) {
return false;
}
bulletRun();
//设置子弹的锚点
setAnchorPoint(Vec2(0.5, 0));
scheduleUpdate();
return true;
}
/*
子弹动画
*/
void Bullet::bulletRun() {
Animation* animation = Animation::create();
for (int i = 1; i <= 2; i++) {
char filename[40];
sprintf(filename, "image/bullet_effect/bullet_%d_%d.png", 0, i);
animation->addSpriteFrameWithFileName(filename);
}
//间隔时间
animation->setDelayPerUnit(0.2f);
animation->setLoops(-1);
//开启动画
Animate* animate = Animate::create(animation);
this->runAction(animate);
}
/*
子弹调度器
*/
void Bullet::update(float dt) {
Vec2 pos = getPosition();//获取原先的坐标
setPosition(pos.x, pos.y + speed * dt);
float h = Director::getInstance()->getVisibleSize().height;
float w = Director::getInstance()->getVisibleSize().width;
float y = getPositionY();
float x = getPositionX();
//当超出屏幕时
if (y >= h + 20 || x <= -20 || x >= w + 20) {
removeFromParent();//从父节点上移除
}
}
最后我们在HelloWorldScene
类中的init
方法中添加主机
bool HelloWorld::init() {
if (!Layer::init()) {
return false;
}
Size size = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
//创建背景
for (int i = 0; i < 2; i++) {
Bg* bg = Bg::create();
float h = bg->getContentSize().height;
bg->setPositionY(i * h);
this->addChild(bg, -1);
}
//创建英雄
Hero *hero = Hero::create();
hero->setPosition(Vec2(size.width / 2, hero->getContentSize().height + 20));
this->addChild(hero);
return true;
}
现在我们来看看效果
