cocos2dx-简单的飞机大战

1.先要为飞机创建触摸移动事件

auto listener = EventListenerTouchOneByOne::create();
	listener->onTouchMoved = CC_CALLBACK_2(SecondScene::onTouchMoved, this);
	listener->onTouchBegan = CC_CALLBACK_2(SecondScene::onTouchBegin, this);
	listener->onTouchEnded = CC_CALLBACK_2(SecondScene::onTouchEnd, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
	this->addChild(primesprite,1);
void SecondScene::onTouchMoved(Touch* touch, Event* event) {
	Rect ballRect = primesprite->getBoundingBox();
	//获取精灵的区域
	Vec2 beginPoint = touch->getLocation();
	//获取触摸的开始位置
	if (ballRect.containsPoint(beginPoint)) {
		Point endPoint = touch->getPreviousLocation();
		//获取触摸的结束位置
		Point offSet = beginPoint - endPoint;
		//计算出两个位置的差
		Point newPosition = primesprite->getPosition() + offSet;
		//计算出精灵现在应该在的位置
		primesprite->setPosition(newPosition);
		//把精灵的位置设置到它应该在的位置
	}
}

2.创建物理世界

Scene* SecondScene::createScene()
{
	Scene* scene = Scene::createWithPhysics();
	SecondScene* layer = SecondScene::create();
	scene->addChild(layer);
	return scene;
}

3.创建刚体并与精灵结合

	//创建刚体
	auto playphysicsbody = PhysicsBody::createBox(visibleSize);
	playphysicsbody->setGravityEnable(false);//不受重力影响
	playphysicsbody->setContactTestBitmask(0xFFFFFFFF);
	//
	primesprite->addComponent(playphysicsbody);

1.当一个身体的CategoryBitmask并与另一主体的ContactTestBitmask其结果不等于零时,接触事件将被发出,相反接触的事件将不被发送。在默认情况下,CategoryBitmask值为0xFFFFFFFF,ContactTestBitmask值是00000000
4.创建物理碰撞事件

	auto contactlistener = EventListenerPhysicsContact::create();
	contactlistener->onContactBegin = CC_CALLBACK_1(SecondScene::onContactBegin, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(contactlistener,this);
	bool SecondScene::onContactBegin(PhysicsContact& contact)
{
	auto nodeA = contact.getShapeA()->getBody()->getNode();//两个碰撞刚体相对应的节点之A
	auto nodeB = contact.getShapeB()->getBody()->getNode();
//两个碰撞刚体相对应的节点之B
	if (nodeA&&nodeB)
	{
		//当节点为敌人和子弹时,则移除子弹和敌人
		if (nodeA->getName() == "enemy"&&nodeB->getName() == "bullet")
		{
			this->removeChild(nodeA);
			this->removeChild(nodeB);
			grade++;
			gradeLabel->setString("分数:" + std::to_string(grade*100));
		}
		else if (nodeA->getName() == "bullet" && nodeB->getName() == "enemy") {
			this->removeChild(nodeA);
			this->removeChild(nodeB);
			grade++;
			gradeLabel->setString("分数 : " + std::to_string(grade * 100));
		}
		//当为飞机和敌人时,场景跳转游戏结束
		else if (nodeA->getName() == "play" && nodeB->getName() == "enemy") {
			auto gameOver = HelloWorld::create();
			/*gameOver->setGrade(gradeLabel->getString());
			Director::getInstance()->replaceScene(gameOver);*/
		}
		else if (nodeA->getName() == "enemy" && nodeB->getName() == "play") {
			auto gameOver = HelloWorld::create();
			/*gameOver->setGrade(gradeLabel->getString());
			Director::getInstance()->replaceScene(gameOver);*/
		}
	}
	return false;

}

5.最后设置子弹和敌机的轨迹即可,
很明显子弹的x坐标与飞机一样,而敌机从屏幕最上方下落,x用rand()函数即可,其中任要为子弹和敌机与刚体结合。

全代码:
SecondScene.h


#ifndef __SecendScene_H__
#define __SecendScene_H__

#include "cocos2d.h"

USING_NS_CC;
class SecondScene : public cocos2d::Scene
{
public:
	static cocos2d::Scene* createScene();
	cocos2d::Size visibleSize;
	Vec2 origin;
	Sprite* sprite;
	Sprite* sprite1;
	Sprite* primesprite;
	int grade = 0;
	LabelTTF* gradeLabel;//分数板
	virtual bool init();
	bool onContactBegin(PhysicsContact & contact);
	void update(float delta);
	void creatEnemySpriteAction(float delta);
	void playFireAction(float delta);
	void imgrotate(float a);
	void removeBulletSprite(cocos2d::Node * bullet);
	bool onTouchBegin(Touch * touch, Event * event);
	void onTouchEnd(Touch * touch, Event * event);
	void onTouchMoved(Touch * touch, Event * event);
	// a selector callback
	void menuCloseCallback(cocos2d::Ref* pSender);

	//char * FontToUTF8(const char * font);

	// implement the "static create()" method manually
	CREATE_FUNC(SecondScene);
};

#endif // __HELLOWORLD_SCENE_H__

BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize);

SecondScene.cpp

#include "SecondScene.h"
#include "SimpleAudioEngine.h"
#include "HelloWorldScene.h"
USING_NS_CC;

Scene* SecondScene::createScene()
{
	Scene* scene = Scene::createWithPhysics();
	SecondScene* layer = SecondScene::create();
	scene->addChild(layer);
	return scene;
}

// on "init" you need to initialize your instance
bool SecondScene::init()
{
	//
	// 1. super init first
	if (!Scene::init())
	{
		return false;
	}
	if (!Scene::initWithPhysics())
	{
		return false;
	}
	visibleSize = Director::getInstance()->getVisibleSize();
	origin = Director::getInstance()->getVisibleOrigin();
	
	 sprite = Sprite::create("background.png");
	sprite->setContentSize(visibleSize);
	sprite->setAnchorPoint(Point::ZERO);
	sprite->setPosition(origin);
	this->addChild(sprite, 0);
	
	 sprite1 = Sprite::create("background.png");
	sprite1->setContentSize(visibleSize);
	sprite1->setAnchorPoint(Point::ZERO);
	sprite1->setPosition(Vec2(origin.x, origin.y + visibleSize.height));
	this->addChild(sprite1, 0);	
	Size playsize = sprite->getContentSize();
	 primesprite = Sprite::create("donhua/1.png");
	SpriteFrame* frame = NULL;
	Vector<SpriteFrame*>aniframe;
	for (int i = 1; i <= 7; i++)
	{
		frame = SpriteFrame::create(String::createWithFormat("donhua/%d.png", i)
			->getCString(), CCRectMake(0, 0, 132, 105));
		aniframe.pushBack(frame);
	}
	CCAnimation* animation = CCAnimation::createWithSpriteFrames(aniframe, 0.1f, -1);
	//1.图片数组2.帧动画间隔时间3.动画次数,为-1是重复
	Animate* animate = Animate::create(animation);
	//RepeatForever* forever = RepeatForever::create(animate);
	primesprite->runAction(animate);
	primesprite->setPosition(ccp(visibleSize.width / 2+ origin.x, visibleSize.height / 2+ origin.x-200));
	//创建刚体
	auto playphysicsbody = PhysicsBody::createBox(visibleSize);
	playphysicsbody->setGravityEnable(false);
	playphysicsbody->setContactTestBitmask(0xFFFFFFFF);
	primesprite->addComponent(playphysicsbody);

	auto listener = EventListenerTouchOneByOne::create();
	listener->onTouchMoved = CC_CALLBACK_2(SecondScene::onTouchMoved, this);
	listener->onTouchBegan = CC_CALLBACK_2(SecondScene::onTouchBegin, this);
	listener->onTouchEnded = CC_CALLBACK_2(SecondScene::onTouchEnd, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
	this->addChild(primesprite,1);

	wchar_t str[100] = { L"number:" };
	char strs[200] = { 0 };
	WCharToMByte(str, strs, sizeof(str) / sizeof(strs[0]));
	gradeLabel = LabelTTF::create(strs, "Felt", 24);
	gradeLabel->setAnchorPoint(Vec2(0, 0));
	gradeLabel->setPosition(Vec2(origin.x,
		origin.y + visibleSize.height - gradeLabel->getContentSize().height));
	this->addChild(gradeLabel, 3);
	
	auto contactlistener = EventListenerPhysicsContact::create();
	contactlistener->onContactBegin = CC_CALLBACK_1(SecondScene::onContactBegin, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(contactlistener,this);
	
	this->scheduleUpdate();
	this->schedule(schedule_selector(SecondScene::playFireAction), 0.5f);
	this->schedule(schedule_selector(SecondScene::creatEnemySpriteAction), 0.5f);
	this->schedule(schedule_selector(SecondScene::imgrotate), 0.001);
	return true;
}
bool SecondScene::onContactBegin(PhysicsContact& contact)
{
	auto nodeA = contact.getShapeA()->getBody()->getNode();//两个碰撞刚体相对应的节点之A
	auto nodeB = contact.getShapeB()->getBody()->getNode();

	if (nodeA&&nodeB)
	{
		if (nodeA->getName() == "enemy"&&nodeB->getName() == "bullet")
		{
			this->removeChild(nodeA);
			this->removeChild(nodeB);
			grade++;
			gradeLabel->setString("分数:" + std::to_string(grade*100));
		}
		else if (nodeA->getName() == "bullet" && nodeB->getName() == "enemy") {
			this->removeChild(nodeA);
			this->removeChild(nodeB);
			grade++;
			gradeLabel->setString("分数 : " + std::to_string(grade * 100));
		}
		else if (nodeA->getName() == "play" && nodeB->getName() == "enemy") {
			auto gameOver = HelloWorld::create();
			/*gameOver->setGrade(gradeLabel->getString());
			Director::getInstance()->replaceScene(gameOver);*/
		}
		else if (nodeA->getName() == "enemy" && nodeB->getName() == "play") {
			auto gameOver = HelloWorld::create();
			/*gameOver->setGrade(gradeLabel->getString());
			Director::getInstance()->replaceScene(gameOver);*/
		}
	}
	return false;

}
void SecondScene::update(float delta)
{

}
void SecondScene::creatEnemySpriteAction(float delta) {
	auto enemy = Sprite::create("diren.png");
	int x = rand() % ((int)(visibleSize.width + origin.x) + 1);
	enemy->setPosition(ccp(x, origin.y + visibleSize.height));
	enemy->setName("enemy");
	auto enemyphysicsbody = PhysicsBody::createBox(enemy->getContentSize());
	enemyphysicsbody->setGravityEnable(false);
	enemyphysicsbody->setContactTestBitmask(0xFFFFFFFF);
	enemy->addComponent(enemyphysicsbody);
	auto moveto = MoveTo::create(3.0, Vec2(enemy->getPosition().x, 0));
	auto funn = CallFuncN::create(this, callfuncN_selector(
		SecondScene::removeBulletSprite));
	FiniteTimeAction* movefinite = Sequence::create(moveto, funn, NULL);
	enemy->runAction(movefinite);
	this->addChild(enemy, 1);

}
void SecondScene::playFireAction(float delta) {
	Size playSize = primesprite->getContentSize();
	Point playPoint = primesprite->getPosition();
	auto bulletSprite = Sprite::create("zidan.png");
	
		bulletSprite->setPosition(Vec2(playPoint.x, playPoint.y + playSize.height / 2.0 + 5));
		bulletSprite->setName("bullet");
		auto bulletPhysicsBody = PhysicsBody::createBox(bulletSprite->getContentSize());
		bulletPhysicsBody->setGravityEnable(false);//不受重力影响
		bulletPhysicsBody->setContactTestBitmask(0xFFFFFFFF);
		bulletSprite->addComponent(bulletPhysicsBody);
		auto visibleSize = Director::getInstance()->getVisibleSize();
		auto moveTo = MoveTo::create(0.5, Vec2(bulletSprite->getPosition().x, visibleSize.height));
		CallFuncN *funN = CallFuncN::create(this, callfuncN_selector(SecondScene::removeBulletSprite));
		FiniteTimeAction *moveFiniteTimeAction = Sequence::create(moveTo, funN, NULL);
		bulletSprite->runAction(moveFiniteTimeAction);
		this->addChild(bulletSprite, 1);
	
}

//销毁子弹
void SecondScene::removeBulletSprite(cocos2d::Node *bullet) {
	this->removeChild(bullet);
}

bool SecondScene::onTouchBegin(Touch* touch, Event* event) {
	return true;
}

void SecondScene::onTouchMoved(Touch* touch, Event* event) {
	Rect ballRect = primesprite->getBoundingBox();
	//获取精灵的区域
	Vec2 beginPoint = touch->getLocation();
	//获取触摸的开始位置
	if (ballRect.containsPoint(beginPoint)) {
		Point endPoint = touch->getPreviousLocation();
		//获取触摸的结束位置
		Point offSet = beginPoint - endPoint;
		//计算出两个位置的差
		Point newPosition = primesprite->getPosition() + offSet;
		//计算出精灵现在应该在的位置
		primesprite->setPosition(newPosition);
		//把精灵的位置设置到它应该在的位置
	}
}
void SecondScene::onTouchEnd(Touch* touch, Event* event) {

}
void SecondScene::imgrotate(float a)
{
	
	visibleSize = Director::getInstance()->getVisibleSize();
	origin = Director::getInstance()->getVisibleOrigin();
	sprite->setPositionY(sprite->getPositionY() - 0.3);//-0.3使精灵之间衔接自然
	sprite1->setPositionY(sprite->getPositionY() + visibleSize.height);//精灵2与精灵1始终保持1个屏幕的距离
	if (sprite1->getPositionY() <= 0)
	{
		sprite->setPositionY(0);//精灵2到底后,重置精灵1
	}
}

void SecondScene::menuCloseCallback(Ref* pSender)
{
	//Director::getInstance()->end();
}
//中午显示
BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize)
{
	DWORD dwMinSize;
	dwMinSize = WideCharToMultiByte(CP_UTF8, NULL, lpcwszStr, -1, NULL, 0, NULL, FALSE);
	if (dwSize < dwMinSize)
	{
		return false;
	}
	WideCharToMultiByte(CP_UTF8, NULL, lpcwszStr, -1, lpszStr, dwSize, NULL, FALSE);
	return true;
}

效果图:在这里插入图片描述
缺点:中文无法显示,任有较多功能未实现

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页