Cocos2d-x《雷电大战》(2)-精灵随手指移动,你点哪我走哪!

         林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

        本文要实现飞机游戏中,人的手指按着飞机,就能拖着飞机走动,这里实现了当你手指按在手机的图片上,手指一直按着屏幕,飞机就会跟着你走。同时,还加入了边界判断条件,让飞机在你的视野内移动,实现的效果完全和我们手机上的飞机游戏一样。

效果:

Cocos2d-x版本:3.4

工程环境:VS30213


一、代码编写

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);
	virtual void onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event);
	virtual void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even);
   
    CREATE_FUNC(GameMain);
private:
	bool isHeroPlaneControl;//飞机是否被控制着
	float mDeltaX;//英雄飞机随手指移动时的X偏移量
	float mDeltaY;//英雄飞机随手指移动时的Y偏移量
	Sprite *mHeroPlane;//英雄飞机
};

#endif // __GameMain_H__


然后在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::onTouchEened, 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)//x到达屏幕上边界
			y = visibleSize.height - mHeroPlane->getContentSize().height/ 2;

		//飞机跟随手指移动
		mHeroPlane->setPosition(Vec2(x,y));
	}
}
void  GameMain::onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event){
	isHeroPlaneControl = false;
}
void  GameMain::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even){
	isHeroPlaneControl = false;
}




这里再说一写主要函数:

头文件增加触摸事件:

	virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);
	virtual void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event);
	virtual void onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event);
	virtual void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even);
实现文件开启触摸事件监听:

//打开触摸,增加触摸监听事件
	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::onTouchEened, this);
	listen->onTouchCancelled = CC_CALLBACK_2(GameMain::onTouchCancelled, this);
	listen->setSwallowTouches(false);//不截取触摸事件
	Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen,this);

然后就是触摸事件 的处理了:

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)//x到达屏幕上边界
			y = visibleSize.height - mHeroPlane->getContentSize().height/ 2;

		//飞机跟随手指移动
		mHeroPlane->setPosition(Vec2(x,y));
	}
}
void  GameMain::onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event){
	isHeroPlaneControl = false;
}
void  GameMain::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even){
	isHeroPlaneControl = false;
}

     方法很简单,代码量也很少,有需要的把上面的自己拿过去,把图片改改,把类名改改就可以了。

     其实这里应该把英雄和移动事件单独写一个类,然后在GameMain里头来调用,因为英雄这个类我还构思好,所以先这样写,后头会把英雄飞机单独提取出来成为一个类,就不会在GameMain里头写这么多了;

效果:


\

效果很好,飞机能跟随移动并且不会跑出屏幕范围

二、思路说明

1、首先在onTouchBegan判断触摸点是否在英雄飞机的图片矩形内,若在这个范围内,刚将布尔型的mHeroPlaneControl设置为true,并且计算触摸点的横纵坐标与英雄飞机的锚点坐标的差值。

2、因为要让英雄飞机移动,要修改锚点位置,必须知道锚点位置与触摸位置的偏移量,之后才可以通过这个偏移量设置主角的位置。

3、判断英雄飞机是否跑出屏幕范围了,如果是,就将它设置在边界处,详看上面的两个if判断。

4、在onTouchMoved中,若mHeroPlaneControl为true,说明可以移动英雄飞机。

           林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

                若你觉得此文对你有用,那就帮我顶一下~~谢谢啦!

  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
实现手指在屏幕上移动,飞机跟随手指移动的效果,可以通过以下步骤实现: 1. 在布局文件中添加一个 ImageView 控件,用于显示飞机的图片。 2. 在 Java 代码中获取 ImageView 控件的实例,并为其设置触摸监听器。 3. 在触摸监听器中实现飞机跟随手指移动的逻辑: - 当手指按下时,记录下当前手指所在的坐标位置。 - 当手指移动时,计算出手指移动的距离,并根据距离调整飞机的位置。 - 当手指抬起时,取消触摸监听器。 下面是一个示例代码,可以参考实现: 首先,在布局文件中添加 ImageView 控件: ``` <ImageView android:id="@+id/ivPlane" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/plane" /> ``` 然后,在 Java 代码中获取 ImageView 控件的实例,并为其设置触摸监听器: ``` ImageView ivPlane = findViewById(R.id.ivPlane); ivPlane.setOnTouchListener(new View.OnTouchListener() { float startX, startY; float offsetX, offsetY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startX = event.getX(); startY = event.getY(); break; case MotionEvent.ACTION_MOVE: float endX = event.getX(); float endY = event.getY(); offsetX = endX - startX; offsetY = endY - startY; ivPlane.setX(ivPlane.getX() + offsetX); ivPlane.setY(ivPlane.getY() + offsetY); startX = endX; startY = endY; break; case MotionEvent.ACTION_UP: v.setOnTouchListener(null); break; } return true; } }); ``` 在触摸监听器中,我们记录下手指按下时的坐标位置(startX、startY),并在手指移动时计算出手指移动的距离(offsetX、offsetY),然后根据距离调整飞机的位置(ivPlane.setX()、ivPlane.setY())。最后,在手指抬起时取消触摸监听器,避免继续响应触摸事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值