虚拟手柄_skybeauty_新浪博客

#ifndef __SNEAKY_BUTTON_H__

#define __SNEAKY_BUTTON_H__


#include "cocos2d.h"


class SneakyButton : public cocos2d::CCNode, public cocos2d::CCTargetedTouchDelegate

{

protected:

cocos2d::CCPoint center;

float radiusSq;


cocos2d::CCRect bounds;


CC_SYNTHESIZE(bool, status, Status);

CC_SYNTHESIZE_READONLY(bool, active, IsActive);

CC_SYNTHESIZE_READONLY(bool, value, Value);

CC_SYNTHESIZE(bool, isHoldable, IsHoldable);

CC_SYNTHESIZE(bool, isToggleable, IsToggleable);

CC_SYNTHESIZE(float, rateLimit, RateLimit);


CC_SYNTHESIZE_READONLY(float, radius, Radius);


//Public methods

virtual void onEnterTransitionDidFinish();

virtual void onExit();

bool initWithRect(cocos2d::CCRect rect);

void limiter(float delta);

void setRadius(float r);

virtual bool ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);

virtual void ccTouchMoved(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);

virtual void ccTouchEnded(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);

virtual void ccTouchCancelled(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);


void touchDelegateRelease();

void touchDelegateRetain();

};


#endif



 

#include "SneakyButton.h"


using namespace cocos2d;


void SneakyButton::onEnterTransitionDidFinish()

{

CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, true);

}


void SneakyButton::onExit()

{

CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);

}


bool SneakyButton::initWithRect(CCRect rect)

{

bool pRet = false;

//if(CCSprite::init()){

 

bounds = CCRectMake(0, 0, rect.size.width, rect.size.height);

center = CCPointMake(rect.size.width/2, rect.size.height/2);

status = 1; //defaults to enabled

active = false;

value = 0;

isHoldable = 0;

isToggleable = 0;

radius = 32.0f;

rateLimit = 1.0f/120.0f;

 

setPosition(rect.origin); //not sure about this

pRet = true;

//}

return pRet;

}


void SneakyButton::limiter(float delta)

{

value = 0;

this->unschedule(schedule_selector(SneakyButton::limiter));

active = false;

}


void SneakyButton::setRadius(float r)

{

radius = r;

radiusSq = r*r;

}


bool SneakyButton::ccTouchBegan(CCTouch *touch, CCEvent *event)

{

if (active) return false;

 

CCPoint location = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());

location = this->convertToNodeSpace(location);

//Do a fast rect check before doing a circle hit check:

if(location.x < -radius || location.x > radius || location.y < -radius || location.y > radius){

return false;

}else{

float dSq = location.x*location.x + location.y*location.y;

if(radiusSq > dSq){

active = true;

if (!isHoldable && !isToggleable){

value = 1;

this->schedule(schedule_selector(SneakyButton::limiter), rateLimit);

}

if (isHoldable) value = 1;

if (isToggleable) value = !value;

return true;

}

}

return false;

}


void SneakyButton::ccTouchMoved(CCTouch *touch, CCEvent *event)

{

if (!active) return;

 

CCPoint location = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());

location = this->convertToNodeSpace(location);

//Do a fast rect check before doing a circle hit check:

if(location.x < -radius || location.x > radius || location.y < -radius || location.y > radius){

return;

}else{

float dSq = location.x*location.x + location.y*location.y;

if(radiusSq > dSq){

if (isHoldable) value = 1;

}

else {

if (isHoldable) value = 0; active = false;

}

}

}


void SneakyButton::ccTouchEnded(CCTouch *touch, CCEvent *event)

{

if (!active) return;

if (isHoldable) value = 0;

if (isHoldable||isToggleable) active = false;

}


void SneakyButton::ccTouchCancelled(CCTouch *touch, CCEvent *event)

{

this->ccTouchEnded(touch, event);

}


void SneakyButton::touchDelegateRelease()

{

this->release();

}


void SneakyButton::touchDelegateRetain()

{

this->retain();

}





#ifndef __SNEAKY_BUTTON_SKINNED_H__

#define __SNEAKY_BUTTON_SKINNED_H__


#include "SneakyButton.h"


class SneakyButtonSkinnedBase : public cocos2d::CCLayer 

{

CC_SYNTHESIZE_READONLY(cocos2d::CCSprite *, defaultSprite, DefaultSprite);

CC_SYNTHESIZE_READONLY(cocos2d::CCSprite *, activatedSprite, ActivatedSprite);

CC_SYNTHESIZE_READONLY(cocos2d::CCSprite *, disabledSprite, DisabledSprite);

CC_SYNTHESIZE_READONLY(cocos2d::CCSprite *, pressSprite, PressSprite);


CC_SYNTHESIZE_READONLY(SneakyButton *, button, Button); //Not sure about this


//Public methods

CREATE_FUNC(SneakyButtonSkinnedBase);

virtual ~SneakyButtonSkinnedBase();

bool init();

void watchSelf(float delta);

void setContentSize(cocos2d::CCSize s);

void setDefaultSprite(cocos2d::CCSprite *aSprite);

void setActivatedSprite(cocos2d::CCSprite *aSprite);

void setDisabledSprite(cocos2d::CCSprite *aSprite);

void setPressSprite(cocos2d::CCSprite *aSprite);

void setButton(SneakyButton *aButton);

};


#endif





#include "SneakyButtonSkinnedBase.h"


using namespace cocos2d;


SneakyButtonSkinnedBase::~SneakyButtonSkinnedBase()

{

if (defaultSprite)

{

defaultSprite->release();

defaultSprite = NULL;

}

if (activatedSprite)

{

activatedSprite->release();

activatedSprite = NULL;

}

if (disabledSprite)

{

disabledSprite->release();

disabledSprite = NULL;

}

if (pressSprite)

{

pressSprite->release();

pressSprite = NULL;

}

if (button)

{

button->release();

button = NULL;

}

}


bool SneakyButtonSkinnedBase::init() //Possible errors here

{

bool pRet = false;

if(CCLayer::init()){

this->defaultSprite = NULL;

//defaultSprite->retain();

this->activatedSprite = NULL;

//activatedSprite->retain();

this->disabledSprite = NULL;

//disabledSprite->retain();

this->pressSprite = NULL;

//pressSprite->retain();

this->button = NULL;

//button->retain();


this->schedule(schedule_selector(SneakyButtonSkinnedBase::watchSelf));

pRet = true;

}

return pRet;

}


void SneakyButtonSkinnedBase::watchSelf(float delta) //Be Careful Here

{

if (!this->button->getStatus()){

if(disabledSprite){

disabledSprite->setVisible(true);

}

else {

disabledSprite->setVisible(false);

}

}

else {

if(!this->button->getIsActive()){

pressSprite->setVisible(false);

if(this->button->getValue() == 0){

activatedSprite->setVisible(false);

if(defaultSprite){

defaultSprite->setVisible(true);

}

}

else {

activatedSprite->setVisible(true);

}

}

else {

defaultSprite->setVisible(false);

if(pressSprite){

pressSprite->setVisible(true);

}

}

}

}


void SneakyButtonSkinnedBase::setContentSize(CCSize s)

{

CCLayer::setContentSize(s);

defaultSprite->setContentSize(s);

//button->setRadius(s.width/2);

}


void SneakyButtonSkinnedBase::setDefaultSprite(CCSprite *aSprite)

{

if(defaultSprite){

if(defaultSprite->getParent())

defaultSprite->getParent()->removeChild(defaultSprite, true);

defaultSprite->release();

}

aSprite->retain();

defaultSprite = aSprite; //Check again here

if(aSprite){

this->addChild(defaultSprite, 0);


this->setContentSize(defaultSprite->getContentSize());

}

}


void SneakyButtonSkinnedBase::setActivatedSprite(CCSprite *aSprite)

{

if(activatedSprite){

if(activatedSprite->getParent())

activatedSprite->getParent()->removeChild(activatedSprite, true);

activatedSprite->release();

}

aSprite->retain();

activatedSprite = aSprite;

if(aSprite){

this->addChild(activatedSprite, 1);

 

this->setContentSize(activatedSprite->getContentSize());

}

}


void SneakyButtonSkinnedBase::setDisabledSprite(CCSprite *aSprite)

{

if(disabledSprite){

if(disabledSprite->getParent())

disabledSprite->getParent()->removeChild(disabledSprite, true);

disabledSprite->release();

}

aSprite->retain();

disabledSprite = aSprite;

if(aSprite){

this->addChild(disabledSprite, 2);

 

this->setContentSize(disabledSprite->getContentSize());

}

}


void SneakyButtonSkinnedBase::setPressSprite(CCSprite *aSprite)

{

if(pressSprite){

if(pressSprite->getParent())

pressSprite->getParent()->removeChild(pressSprite, true);

pressSprite->release();

}

aSprite->retain();

pressSprite = aSprite;

if(aSprite){

this->addChild(pressSprite, 3);

 

this->setContentSize(pressSprite->getContentSize());

}

}


void SneakyButtonSkinnedBase::setButton(SneakyButton *aButton)

{

if(button){

if(button->getParent())

button->getParent()->removeChild(button, true);

button->release();

}

aButton->retain();

button = aButton;

if(aButton){

this->addChild(button, 4);

if(defaultSprite)

button->setRadius(defaultSprite->boundingBox().size.width/2);

}

}




#ifndef __SNEAKY_JOYSTICK_H__

#define __SNEAKY_JOYSTICK_H__


#include "cocos2d.h"


class SneakyJoystick : public cocos2d::CCNode, public cocos2d::CCTargetedTouchDelegate 

{

protected:

float joystickRadiusSq;

float thumbRadiusSq;

float deadRadiusSq;


CC_SYNTHESIZE_READONLY(cocos2d::CCPoint, stickPosition, StickPosition);

CC_SYNTHESIZE_READONLY(float, degrees, Degrees);

CC_SYNTHESIZE_READONLY(cocos2d::CCPoint, velocity, Velocity);

CC_SYNTHESIZE(bool, autoCenter, AutoCenter);

CC_SYNTHESIZE_READONLY(bool, isDPad, IsDPad);

CC_SYNTHESIZE(bool, hasDeadzone, HasDeadzone);

CC_SYNTHESIZE(int, numberOfDirections, NumberOfDirections);


CC_SYNTHESIZE_READONLY(float, joystickRadius, JoystickRadius);

CC_SYNTHESIZE_READONLY(float, thumbRadius, ThumbRadius);

CC_SYNTHESIZE_READONLY(float, deadRadius, DeadRadius);


virtual ~SneakyJoystick();


bool initWithRect(cocos2d::CCRect rect);

virtual void onEnterTransitionDidFinish();

virtual void onExit();

void setIsDPad(bool b);

void setJoystickRadius(float r);

void setThumbRadius(float r);

void setDeadRadius(float r);

virtual bool ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);

virtual void ccTouchMoved(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);

virtual void ccTouchEnded(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);

virtual void ccTouchCancelled(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);


void touchDelegateRelease();

void touchDelegateRetain();


private:

void updateVelocity(cocos2d::CCPoint point);

void setTouchRadius();


};

#endif




#include "SneakyJoystick.h"


using namespace cocos2d;


#define SJ_PI 3.14159265359f

#define SJ_PI_X_2 6.28318530718f

#define SJ_RAD2DEG 180.0f/SJ_PI

#define SJ_DEG2RAD SJ_PI/180.0f


SneakyJoystick::~SneakyJoystick()

{

}


bool SneakyJoystick::initWithRect(CCRect rect)

{

bool pRet = false;

//if(CCSprite::init()){

stickPosition = CCPointZero;

degrees = 0.0f;

velocity = CCPointZero;

autoCenter = true;

isDPad = false;

hasDeadzone = false;

numberOfDirections = 4;

 

this->setJoystickRadius(rect.size.width/2);

this->setThumbRadius(32.0f);

this->setDeadRadius(0.0f);

 

//Cocos node stuff

setPosition(rect.origin);

pRet = true;

//}

return pRet;

}


void SneakyJoystick::onEnterTransitionDidFinish()

{

CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, true);

}


void SneakyJoystick::onExit()

{

CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);

}


float round(float r) {

   return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);

}


void SneakyJoystick::updateVelocity(CCPoint point)

{

// Calculate distance and angle from the center.

float dx = point.x;

float dy = point.y;

float dSq = dx * dx + dy * dy;

 

if(dSq <= deadRadiusSq){

velocity = CCPointZero;

degrees = 0.0f;

stickPosition = point;

return;

}


float angle = atan2f(dy, dx); // in radians

if(angle < 0){

angle += SJ_PI_X_2;

}

float cosAngle;

float sinAngle;

 

if(isDPad){

float anglePerSector = 360.0f / numberOfDirections * SJ_DEG2RAD;

angle = round(angle/anglePerSector) * anglePerSector;

}

 

cosAngle = cosf(angle);

sinAngle = sinf(angle);

 

// NOTE: Velocity goes from -1.0 to 1.0.

if (dSq > joystickRadiusSq || isDPad) {

dx = cosAngle * joystickRadius;

dy = sinAngle * joystickRadius;

}

 

velocity = CCPointMake(dx/joystickRadius, dy/joystickRadius);

degrees = angle * SJ_RAD2DEG;

 

// Update the thumb's position

stickPosition = ccp(dx, dy);

}


void SneakyJoystick::setIsDPad(bool b)

{

isDPad = b;

if(isDPad){

hasDeadzone = true;

this->setDeadRadius(10.0f);

}

}


void SneakyJoystick::setJoystickRadius(float r)

{

joystickRadius = r;

joystickRadiusSq = r*r;

}


void SneakyJoystick::setThumbRadius(float r)

{

thumbRadius = r;

thumbRadiusSq = r*r;

}


void SneakyJoystick::setDeadRadius(float r)

{

deadRadius = r;

deadRadiusSq = r*r;

}


bool SneakyJoystick::ccTouchBegan(CCTouch *touch, CCEvent *event)

{

CCPoint location = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());


//if([background containsPoint:[background convertToNodeSpace:location]]){

location = this->convertToNodeSpace(location);

//Do a fast rect check before doing a circle hit check:

if(location.x < -joystickRadius || location.x > joystickRadius || location.y < -joystickRadius || location.y > joystickRadius){

return false;

}else{

float dSq = location.x*location.x + location.y*location.y;

if(joystickRadiusSq > dSq){

this->updateVelocity(location);

return true;

}

}

return false;

}


void SneakyJoystick::ccTouchMoved(CCTouch *touch, CCEvent *event)

{

CCPoint location = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());

location = this->convertToNodeSpace(location);

this->updateVelocity(location);

}


void SneakyJoystick::ccTouchEnded(CCTouch *touch, CCEvent *event)

{

CCPoint location = CCPointZero;

if(!autoCenter){

CCPoint location = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());

location = this->convertToNodeSpace(location);

}

this->updateVelocity(location);

}


void SneakyJoystick::ccTouchCancelled(CCTouch *touch, CCEvent *event)

{

this->ccTouchEnded(touch, event);

}


void SneakyJoystick::touchDelegateRelease()

{

this->release();

}


void SneakyJoystick::touchDelegateRetain()

{

this->retain();

}



 

#ifndef __JOYSTICK_SKINNED_H__

#define __JOYSTICK_SKINNED_H__


#include "cocos2d.h"

#include "SneakyJoystick.h"


class SneakyJoystickSkinnedBase : public cocos2d::CCLayer

{

public:

CC_SYNTHESIZE_READONLY(cocos2d::CCSprite *, backgroundSprite, BackgroundSprite);

CC_SYNTHESIZE_READONLY(cocos2d::CCSprite *, thumbSprite, ThumbSprite);

CC_SYNTHESIZE_READONLY(SneakyJoystick *, joystick, Joystick);


//Public methods

CREATE_FUNC(SneakyJoystickSkinnedBase);

virtual ~SneakyJoystickSkinnedBase();

bool init();

void updatePositions(float delta);

void setContentSize(cocos2d::CCSize s);

void setBackgroundSprite(cocos2d::CCSprite *aSprite);

void setThumbSprite(cocos2d::CCSprite *aSprite);

void setJoystick(SneakyJoystick *aJoystick);

};

#endif



 

#include "SneakyJoystickSkinnedBase.h"


using namespace cocos2d;


SneakyJoystickSkinnedBase::~SneakyJoystickSkinnedBase()

{

if (backgroundSprite)

{

backgroundSprite->release();

backgroundSprite = NULL;

}

if (thumbSprite)

{

thumbSprite->release();

thumbSprite = NULL;

}


if (joystick)

{

joystick->release();

joystick = NULL;

}

}


bool SneakyJoystickSkinnedBase::init()

{

bool pRet = false;

if(CCLayer::init()){

this->backgroundSprite = NULL;


this->thumbSprite = NULL;


this->joystick = NULL;


this->schedule(schedule_selector(SneakyJoystickSkinnedBase::updatePositions));

pRet = true;

}

return pRet;

}


void SneakyJoystickSkinnedBase::updatePositions(float delta)

{

if(joystick && thumbSprite)

thumbSprite->setPosition(joystick->getStickPosition());

}


void SneakyJoystickSkinnedBase::setContentSize(CCSize s)

{

CCLayer::setContentSize(s);

backgroundSprite->setContentSize(s);

//joystick.joystickRadius = s.width/2;

}


void SneakyJoystickSkinnedBase::setBackgroundSprite(CCSprite *aSprite)

{

if(backgroundSprite){

if(backgroundSprite->getParent())

backgroundSprite->getParent()->removeChild(backgroundSprite, true);

backgroundSprite->release();

}

aSprite->retain();

backgroundSprite = aSprite;

if(aSprite){

this->addChild(backgroundSprite, 0);

 

this->setContentSize(backgroundSprite->getContentSize());

}

}


void SneakyJoystickSkinnedBase::setThumbSprite(CCSprite *aSprite)

{

if(thumbSprite){

if(thumbSprite->getParent())

thumbSprite->getParent()->removeChild(thumbSprite, true);

thumbSprite->release();

}

aSprite->retain();

thumbSprite = aSprite;

if(aSprite){

this->addChild(thumbSprite, 1);

 

//joystick->setThumbRadius(thumbSprite->getContentSize().width/2);

}

}


void SneakyJoystickSkinnedBase::setJoystick(SneakyJoystick *aJoystick)

{

if(joystick){

if(joystick->getParent())

joystick->getParent()->removeChild(joystick, true);

joystick->release();

}

aJoystick->retain();

joystick = aJoystick;

if(aJoystick){

this->addChild(aJoystick, 2);

if(thumbSprite)

joystick->setThumbRadius(thumbSprite->boundingBox().size.width/2);

else

joystick->setThumbRadius(0);

 

if(backgroundSprite)

joystick->setJoystickRadius(backgroundSprite->boundingBox().size.width/2);

}

}




 

#ifndef __TankDemo__World__

#define __TankDemo__World__



#include "cocos2d.h"

#include "HPlayer.h"


#include "SneakyButton.h"

#include "SneakyJoystick.h"

#include "SneakyButtonSkinnedBase.h"

#include "SneakyJoystickSkinnedBase.h"


typedef enum{

    tag_player,//主角

    tag_playerHp1,//血量1

    tag_playerHp2,//血量2

    tag_playerHp3,//血量3

    tag_scoreTTF,//分数

    tag_killsCountTTF,//杀敌数

}tagWorld;//枚举变量


class HWorld : public cocos2d::CCLayer

{

public:

   static cocos2d::CCScene* scene();

    

    //获取当前HWorld的静态实例

   static HWorld * sharedWorld();

    //获取主角

    HPlayer* getPlayer();

    //获取存放敌怪的数组

    CCArray* getArrayForEnemy();

   void winGame();

   void lostGame();

    

   virtual void update(float time);

    

private:

   virtual bool init();

    CREATE_FUNC(HWorld);

    

    CCArray * arrayEnemy;//存放敌怪的数组

   void autoCreateBullet();//自动创建子弹

   void autoCreateEnemy();//自动创建敌怪

   void backMenu();//返回主菜单

   virtual ~HWorld();//析构函数

    

    SneakyButton * fireButton;

SneakyJoystick * joystick;

    

   float totalTime;

float nextShotTime;

};


#endif



#include "HWorld.h"

#include "HMap.h"

#include "HBullet.h"

#include "HEnemy.h"

#include "HMenu.h"

#include "SimpleAudioEngine.h"


using namespace CocosDenshion;

using namespace cocos2d;


static HWorld * sh;


HWorld * HWorld::sharedWorld(){

   if(sh!=NULL){

       return sh;

    }

    return NULL;

}


CCScene* HWorld::scene()

{

    CCScene *scene = CCScene::create();

    HWorld *layer = HWorld::create();

    scene->addChild(layer);

   return scene;

}


bool HWorld::init()

{

   if ( !CCLayer::init() )

    {

        return false;

    }

    sh=this;

    

    CCSpriteFrameCache * cache = CCSpriteFrameCache::sharedSpriteFrameCache();

    cache->addSpriteFramesWithFile("game-art.plist","game-art.pvr.ccz");

    

    //播放游戏中的音乐

    SimpleAudioEngine::sharedEngine()->playBackgroundMusic("gameMusic.mp3",true);

    

    //初始化敌人数组

    arrayEnemy= CCArray::create();

    CC_SAFE_RETAIN(arrayEnemy);

    

   //地图

    HMap * map  = HMap::createMap("map.png");

    addChild(map);

    

   //主角

    //HPlayer * player=HPlayer::createPlayer("player.png");

    //addChild(player,0,tag_player);

    

    

    //虚拟手柄

    //方向键

   float stickRadius = 50;

    

joystick = new SneakyJoystick();

    joystick->initWithRect(CCRectMake(0, 0, stickRadius, stickRadius));

    joystick->autorelease();

    

    joystick->setAutoCenter(true);

 

// Now with fewer directions

    joystick->setIsDPad(true);

    joystick->setNumberOfDirections(8);

 

SneakyJoystickSkinnedBase * skinStick = SneakyJoystickSkinnedBase::create();

    

skinStick->setPosition(CCPointMake(stickRadius * 1.5f, stickRadius * 1.5f));

    

    skinStick->setBackgroundSprite(CCSprite::createWithSpriteFrameName("joystick-back.png"));

skinStick->setThumbSprite(CCSprite::createWithSpriteFrameName("joystick-stick.png"));

    skinStick->setJoystick(joystick);

   this->addChild(skinStick);

    

   //A

   float buttonRadius = 50;

CCSize screenSize = CCDirector::sharedDirector()->getWinSize();

    

fireButton = new SneakyButton();

    //fireButton->autorelease();

fireButton->setIsHoldable(true);

 

SneakyButtonSkinnedBase * skinFireButton = SneakyButtonSkinnedBase::create();

skinFireButton->setPosition(CCPointMake(screenSize.width - buttonRadius * 1.5f, buttonRadius * 1.5f));

    

    

    skinFireButton->setDefaultSprite(CCSprite::createWithSpriteFrameName("fire-button-idle.png"));

    skinFireButton->setPressSprite(CCSprite::createWithSpriteFrameName("fire-button-pressed.png"));

    skinFireButton->setDisabledSprite(CCSprite::createWithSpriteFrameName("fire-button-idle.png"));

    

skinFireButton->setButton(fireButton);

    

this->addChild(skinFireButton);

    

   this->scheduleUpdate();

    

    //创建子弹逻辑(创建间隔0.37秒)

    //this->schedule(schedule_selector(HWorld::autoCreateBullet),0.37);

    //创建敌怪逻辑(创建间隔1秒)

    //this->schedule(schedule_selector(HWorld::autoCreateEnemy),1);

    

    return true;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值