Cocos2d项目实战之飞机大战(三)----创建主机以及主机射击

190 阅读3分钟

我们要想实现主机的移动以及主机的射击我们就必须先理清逻辑。在这里我们需要创建两个类,一个是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;
}

现在我们来看看效果