ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

cocos2dx-简单的飞机大战

2020-12-03 17:30:19  阅读:243  来源: 互联网

标签:enemy 飞机 cocos2dx SecondScene nodeA auto create 大战 void


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;
}

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

标签:enemy,飞机,cocos2dx,SecondScene,nodeA,auto,create,大战,void
来源: https://blog.csdn.net/weixin_44453949/article/details/110549103

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有