用Cocos2d-x 3.4实现《雷电大战》-精灵随手指移,你点哪我走哪!

2015年03月16日 13:12 0 点赞 0 评论 更新于 2025-11-21 17:17

大家应该都知道《雷电大战》这款游戏。本教程将实现游戏中飞机跟随手指移动的功能,即当手指按在手机屏幕上飞机图片的位置,并持续按住屏幕移动手指时,飞机就会随之移动,且飞机只会在视野范围内移动,实现效果与常见的手机飞机游戏一致。

开发环境

  • Cocos2d-x版本:3.4
  • 工程环境:VS2013

代码编写

1. 头文件 GameMain.h

/**
* @作者 林炳文(邮箱:ling20081005@126.com)
* @博客 http://blog.csdn.net/evankaka
* @时间 2015.3.8
* @功能 游戏的主界面
*/
#ifndef __GameMain_H__
#define __GameMain_H__

#include "BackLayerDown.h"
#include "BackLayerUp.h"
#include "cocos2d.h"

USING_NS_CC;

class GameMain : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();

virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);
virtual void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event);
// 原代码此处拼写错误,修正为 onTouchEnded
virtual void onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event);
virtual void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_event);

CREATE_FUNC(GameMain);

private:
bool isHeroPlaneControl; // 飞机是否被控制着
float mDeltaX; // 英雄飞机随手指移动时的X偏移量
float mDeltaY; // 英雄飞机随手指移动时的Y偏移量
Sprite *mHeroPlane; // 英雄飞机
};

#endif // __GameMain_H__

2. GameMain.cpp 文件

#include "GameMain.h"
USING_NS_CC;

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

bool GameMain::init()
{
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();

// 这是地面图层
this->addChild(BackLayerUp::create());
// 这是白云图层
this->addChild(BackLayerDown::create());

// 加个飞机
mHeroPlane = Sprite::create("air1.png");
mHeroPlane->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 5));
this->addChild(mHeroPlane, 1, 100);
isHeroPlaneControl = false;

// 打开触摸,增加触摸监听事件
this->setTouchEnabled(true);
auto listen = EventListenerTouchOneByOne::create();
listen->onTouchBegan = CC_CALLBACK_2(GameMain::onTouchBegan, this);
listen->onTouchMoved = CC_CALLBACK_2(GameMain::onTouchMoved, this);
listen->onTouchEnded = CC_CALLBACK_2(GameMain::onTouchEnded, this);
listen->onTouchCancelled = CC_CALLBACK_2(GameMain::onTouchCancelled, this);
listen->setSwallowTouches(false); // 不截取触摸事件
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen, this);

return true;
}

bool GameMain::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event)
{
Point mHeroPos = mHeroPlane->getPosition();
Point mBeganPos = touch->getLocationInView();
mBeganPos = Director::getInstance()->convertToGL(mBeganPos);

// 判断当前手指按下区域是否是英雄飞机的区域,并且计算飞机要移动时的偏移量
if (mBeganPos.x > mHeroPos.x - mHeroPlane->getContentSize().width / 2 && mBeganPos.x < mHeroPos.x + mHeroPlane->getContentSize().width / 2 &&
mBeganPos.y > mHeroPos.y - mHeroPlane->getContentSize().height / 2 && mBeganPos.y < mHeroPos.y + mHeroPlane->getContentSize().height / 2)
{
isHeroPlaneControl = true;
// 计算偏移量
mDeltaX = mBeganPos.x - mHeroPos.x;
mDeltaY = mBeganPos.y - mHeroPos.y;
}

return true;
}

void GameMain::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event)
{
if (isHeroPlaneControl)
{
Point mMovedPos = touch->getLocationInView();
mMovedPos = Director::getInstance()->convertToGL(mMovedPos);

Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
float x = mMovedPos.x - mDeltaX; // 记得减去偏移量
float y = mMovedPos.y - mDeltaY;

if (x <= mHeroPlane->getContentSize().width / 2 + origin.x) // x到达屏幕左边界
x = mHeroPlane->getContentSize().width / 2 + origin.x;
else if (x >= visibleSize.width - mHeroPlane->getContentSize().width / 2) // x到达屏幕右边界
x = visibleSize.width - mHeroPlane->getContentSize().width / 2;

if (y <= mHeroPlane->getContentSize().height / 2 + origin.y) // y到达屏幕下边界
y = mHeroPlane->getContentSize().height / 2 + origin.y;
else if (y >= visibleSize.height - mHeroPlane->getContentSize().height / 2) // y到达屏幕上边界
y = visibleSize.height - mHeroPlane->getContentSize().height / 2;

// 飞机跟随手指移动
mHeroPlane->setPosition(Vec2(x, y));
}
}

void GameMain::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event)
{
isHeroPlaneControl = false;
}

void GameMain::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_event)
{
isHeroPlaneControl = false;
}

以上代码通过 GameMain 类实现了飞机随手指移动的功能。在 init 方法中初始化场景和飞机,并开启触摸监听;在 onTouchBegan 方法中判断手指是否按在飞机上并计算偏移量;在 onTouchMoved 方法中根据手指移动更新飞机位置,同时限制飞机在屏幕内移动;在 onTouchEndedonTouchCancelled 方法中取消飞机的控制状态。

作者信息

boke

boke

共发布了 3994 篇文章