cocos2d-x 3.x学习之虚拟摇杆

摇杆类

#ifndef Joystick_hpp
#define Joystick_hpp

#include <stdio.h>
#include "cocos2d.h"
USING_NS_CC;
enum TagDirection{
    ROCKER_START = 0,
    ROCKER_UP,
    ROCKER_DOWN,
    ROCKER_LEFT,
    ROCKER_RIGHT,
    ROCKER_LEFT_UP,
    ROCKER_LEFT_DOWN,
    ROCKER_RIGHT_UP,
    ROCKER_RIGHT_DOWN
};
class JoyStick:public Layer{
public:
    //static Scene *createScene();
    virtual bool init();
    bool onTouchBegan(Touch *touch,Event *event);
    void onTouchMoved(Touch *touch,Event *event);
    void onTouchEnded(Touch *touch,Event *event);
    //检查角度
    void CheckDirection(double ag,Vec2 pos);
 
    CREATE_FUNC(JoyStick);
    //摇点背景的半径
    double RockerBGRadius;
    //摇点的坐标
    Vec2 RockerPoint;
    //摇杆背景的ContentSize
    Size RockerBGS;
    //摇杆背景的坐标
    Vec2 RockerBGP;
    Sprite *rocker;
    Sprite *rockerbg;
    Sprite *hero;
    enum TagDirection direction;
};
#include "Joystick.hpp"
bool JoyStick::init(){
    if (!Layer::init()) {
        return false;
    }
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    rockerbg = Sprite::create("circlebg.png");
    rockerbg->setPosition(origin + Vec2(150, 150));
    this->addChild(rockerbg);
    
    rocker = Sprite::create("stick.png");
    rocker->setPosition(rockerbg->getPosition());
    this->addChild(rocker);
    RockerBGP = rockerbg->getPosition();//背景位置
    RockerPoint = rocker->getPosition();//摇杆位置
    RockerBGS = rockerbg->getContentSize();//背景的大小
    //背景的一半即为半径
    RockerBGRadius = rockerbg->getContentSize().width / 2;
    //触摸事件
    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = CC_CALLBACK_2(JoyStick::onTouchBegan ,this);
    listener->onTouchMoved = CC_CALLBACK_2(JoyStick::onTouchMoved, this);
    listener->onTouchEnded = CC_CALLBACK_2(JoyStick::onTouchEnded, this);
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
    return true;
}
//检查角度在哪个区域内,八个方向
void JoyStick::CheckDirection(double ag,Vec2 pos){
    log("ag = %f",ag);
    log("pos(%f,%f)",pos.x,pos.y);
    double angle = 3.1415926 / 8;
    if (pos.y > RockerBGP.y) {
        if (ag < angle) {
            direction = ROCKER_RIGHT;
            log("右");
        }
        else if(ag > angle && ag < angle * 3){
            direction = ROCKER_RIGHT_UP;
            log("右上");
        }
        else if(ag > angle * 3 && ag < angle * 5){
            direction = ROCKER_UP;
            log("上");
        }
        else if(ag > angle * 5 && ag < angle * 7){
            direction = ROCKER_LEFT_UP;
            log("左上");
        }
        else if(ag > angle * 7){
            direction = ROCKER_LEFT;
            log("左");
        }

    }else{
        if (ag < angle) {
            direction = ROCKER_RIGHT;
            log("右");
        }
        else if(ag > angle && ag < angle * 3){
            direction = ROCKER_RIGHT_DOWN;
            log("右下");
        }
        else if (ag > angle * 3 && ag < angle * 5){
            direction = ROCKER_DOWN;
            log("下");
        }
        else if (ag > angle * 5 &&  ag < angle * 7){
            direction = ROCKER_LEFT_DOWN;
            log("左下");
        }
        else if(ag > angle * 7){
            direction = ROCKER_LEFT;
            log("左");
        }
    }
}
bool JoyStick::onTouchBegan(Touch *touch, Event *event){
    //判断触摸点
    Vec2 pos = touch->getLocation();
    //触摸点与圆心点的距离
    double d = pos.distance(RockerBGP);
    if (d > RockerBGRadius) {
        return false;
    }else{
        //让摇点移动到触摸点位置,设置坐标
        rocker->setPosition(pos);
        return true;
    }
}
void JoyStick::onTouchMoved(Touch *touch, Event *event){
   
    
    //获得触摸点的坐标
    Vec2 pos = touch->getLocation();
    double pdis = pos.x - RockerBGP.x;
    //距离
    double d = pos.distance(RockerBGP);
    double angle = acos(pdis / d);
    CheckDirection(angle, pos);
    if (d > RockerBGRadius) {
        double xx = (pos.x - RockerBGP.x) / d * RockerBGRadius +                                                                                                                                                                                                                                                                    RockerBGP.x;//差值为负
        double yy = (pos.y - RockerBGP.y) * RockerBGRadius / d + RockerBGP.y;
        rocker->setPosition(Vec2(xx, yy));
        log("xx = %f,yy = %f",xx,yy);
        log("rockerp:(%f,%f)",RockerBGP.x, RockerBGP.y);
    }else{
        rocker->setPosition(pos);
    }
}
void JoyStick::onTouchEnded(Touch *touch, Event *event){
    //方向复位
    direction = ROCKER_START;
    //让摇点复位,一撒手回到中心点
    rocker->setPosition(RockerBGP);
}

英雄类

 

#include "cocos2d.h"
USING_NS_CC;
class Hero : public Layer
{
public:
	bool isRun;
	int direction;
	Point position;
	Sprite* sprite;
	static Hero* createHeroSprite(Point position, int direction, const char* name);
	void heroInit(Point position, int direction, const char* name);
	virtual bool init();
	Animate* createAnimate(int direction, const char *action, int num);
	void setAction(int direction, const char *action, int num);
	void moveTo(float x,float y);
	CREATE_FUNC(Hero);
};
#include "Hero.h"
USING_NS_CC;
Hero* Hero::createHeroSprite(Point position, int direction, const char* name)
{
	Hero* hero = new Hero();
	if (hero && hero->init())
	{
		hero->autorelease();
		hero->heroInit(position, direction, name);
		return hero;
	}
	CC_SAFE_DELETE(hero);
	return NULL;
}
bool Hero::init()
{
	if (!Layer::init())
	{
		return false;
	}
	return true;
}
void Hero::heroInit(Point position, int direction, const char* name)
{
	this->isRun = false;
	this->position = position;
	sprite = Sprite::create(String::createWithFormat("%s11.png",name)->getCString());
	sprite->setPosition(position);
	addChild(sprite);
	auto* action = createAnimate(1, "stand", 7);
	action->setTag(100);
	sprite->runAction(action);
}
Animate* Hero::createAnimate(int direction, const char *action, int num)
{
	auto* m_frameCache = SpriteFrameCache::getInstance();
	m_frameCache->addSpriteFramesWithFile("hero.plist", "hero.png");
	Vector<SpriteFrame*> frameArray;
	for (int i = 1; i <= num; i++)
	{
		auto* frame = m_frameCache->getSpriteFrameByName(String::createWithFormat("%s%d%d.png", action, direction, i)->getCString());
		frameArray.pushBack(frame);
	}
	Animation* animation = Animation::createWithSpriteFrames(frameArray);
	animation->setLoops(-1);//±Ì æŒfiœfi—≠ª∑≤•∑≈
	animation->setDelayPerUnit(0.1f);//√ø¡Ω’≈Õº∆¨µƒ ±º‰∏Ù£¨Õº∆¨ ˝ƒø‘Ω…Ÿ£¨º‰∏Ù◊Ó–°æÕ‘Ω–°

	//Ω´∂ت≠∞¸◊∞≥…“ª∏ˆ∂Ø◊˜
	return Animate::create(animation);
}
void Hero::setAction(int direction, const char *action, int num)
{
	sprite->stopActionByTag(100);
	auto* animate = createAnimate(direction, action, num);
	animate->setTag(100);
	sprite->runAction(animate);
}
void Hero::moveTo(float x, float y)
{
	float r = sqrt(x*x + y*y);
	position.x += x / r;
	position.y += y / r;
	sprite->setPosition(position);
}
主场景类

#include <stdio.h>
#include "cocos2d.h"
#include "Joystick.hpp"
#include "Hero.h"
USING_NS_CC;
class MainScene:public Layer{
public:
    static Scene *createScene();
    virtual bool init();
    CREATE_FUNC(MainScene);
    void update(float dt);
    void setViewPointCenter(Vec2 p);
    //JoyStick *rockerlayer;
    Sprite *sp;
    Hero *hero;
    Sprite *bg;
};
#include "MainScene.hpp"
Scene * MainScene::createScene(){
    auto scene = Scene::create();
    auto layer = MainScene::create();
     scene->addChild(layer);
    
    JoyStick * rockerlayer = JoyStick::create();
    rockerlayer->setPosition(Vec2::ZERO);
    rockerlayer->setTag(110);
    scene->addChild(rockerlayer);
   
    return scene;
}
bool MainScene::init(){
    if (!Layer::init()) {
        return false;
    }
    Size visibleSize = Director::getInstance()->getVisibleSize();
    bg = Sprite::create("bg.png");
    
    bg->setPosition(Vec2(0,0));
    bg->setAnchorPoint(Vec2::ZERO);
    this->addChild(bg);

    hero = Hero::createHeroSprite(Vec2(300, 300), 1, "stand");
    this->addChild(hero);
    scheduleUpdate();
    return true;
}
//游戏地图与屏幕适配,需要英雄的坐标
void MainScene::setViewPointCenter(Vec2 p){
    Size visibleSize = Director::getInstance()->getVisibleSize();
    //让地图跟随英雄移动,超过屏幕中心的一半的时候需要移动
    double x = MAX(p.x, visibleSize.width / 2);
    double y = MAX(p.y, visibleSize.height / 2);
    //不让显示区域超出地图边界
    double a = MIN(x, bg->getContentSize().width - visibleSize.width / 2);
    double b = MIN(y, bg->getContentSize().height - visibleSize.height / 2);
    Vec2 pp = Vec2(visibleSize.width / 2 - a, visibleSize.height / 2 - b);
    this->setPosition(pp);
}
void MainScene::update(float dt){
    JoyStick *rockerlayer = (JoyStick*)this->getParent()->getChildByTag(110);
     
    if (rockerlayer->direction == ROCKER_UP) {
        hero->setPositionY(hero->getPositionY() + 5);
        log("英雄向上移动");
    }
    if (rockerlayer->direction == ROCKER_DOWN) {
        hero->setPositionY(hero->getPositionY() - 5);
        log("英雄向下运动");
    }
    if (rockerlayer->direction == ROCKER_LEFT) {
        hero->setPositionX(hero->getPositionX() - 5);
        log("英雄向左移动");
    }
    if (rockerlayer->direction == ROCKER_RIGHT) {
        hero->setPositionX(hero->getPositionX() + 5);
        log("英雄向右移动");
    }
    if (rockerlayer->direction == ROCKER_LEFT_UP) {
        hero->setPositionX(hero->getPositionX() - 5);
        hero->setPositionY(hero->getPositionY() + 5);
      
        log("英雄向左上移动");
    }
    if (rockerlayer->direction == ROCKER_LEFT_DOWN) {
        hero->setPositionX(hero->getPositionX() - 5);
        hero->setPositionY(hero->getPositionY() - 5);
        log("英雄向左下移动");
    }
    if (rockerlayer->direction == ROCKER_RIGHT_UP) {
        hero->setPositionX(hero->getPositionX() + 5);
        hero->setPositionY(hero->getPositionY() + 5);
        log("英雄向右上移动");
    }
    if (rockerlayer->direction == ROCKER_RIGHT_DOWN) {
        hero->setPositionX(hero->getPositionX() + 5);
        hero->setPositionY(hero->getPositionY() - 5);
        log("英雄向右下移动");
    }
    if (rockerlayer->direction == ROCKER_START) {
        
        log("英雄不动");
    }
    setViewPointCenter(hero->getPosition());
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值