摇杆类
#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());
}