本站文章均為[?李華明Himi?](http://www.himigame.com/about-himi)原創,轉載務必在明顯處注明:
轉載自[【黑米GameDev街區】](http://www.himigame.com/)?原文鏈接:?[http://www.himigame.com/iphone-cocos2dx/721.html](http://www.himigame.com/iphone-cocos2dx/721.html "【iOS-cocos2d-X")
[? 點擊訂閱 ?](http://list.qq.com/cgi-bin/qf_invite?id=acfc24e272cc4a26debf3b3866edb626a9ea3fc80fd8893c)**?本博客最新動態!及時將最新博文通知您!
對于虛擬搖桿在游戲開發中必不可少,Android方面的是由Himi自己實現封裝的,大家可以移步到這里查看詳細實現機制:
[【Android游戲開發二十四】360°平滑游戲搖桿(觸屏方向導航)?](http://www.himigame.com/android-game/384.html)
那么在Cocos2d引擎已提供此搖桿類(Joystick),所以Himi也就懶得重寫了,但是Cocos2dx中并沒有封裝,那么這里Himi給出Cocos2dx版的Joystick(HRocker類),并且Himi對此類添加了一個跟隨用戶觸點作為搖桿坐標的功能!
這里不多說代碼結構直接貼出源碼,然后重點說下使用與方法參數,具體實現可以參考源碼以及Android部分Himi的實現機制;
~~~
//
// HRocker.h
// RockerPro
//
// Created by Himi on 12-3-30.
// Copyright (c) 2012年 Himi. All rights reserved.
//
#ifndef RockerPro_HRocker_h
#define RockerPro_HRocker_h
#ifndef HRocker_H
#define HRocker_H
#include "cocos2d.h"
using namespace cocos2d;
class HRocker :public CCLayer {
public :
//初始化 aPoint是搖桿中心 aRadius是搖桿半徑 aJsSprite是搖桿控制點 aJsBg是搖桿背景
static HRocker* HRockerWithCenter(CCPoint aPoint ,float aRadius ,CCSprite* aJsSprite,CCSprite* aJsBg,bool _isFollowRole);
//啟動搖桿
void Active();
//解除搖桿
void Inactive();
private:
HRocker * initWithCenter(CCPoint aPoint ,float aRadius ,CCSprite* aJsSprite,CCSprite* aJsBg,bool _isFollowRole);
CCPoint centerPoint;//搖桿中心
CCPoint currentPoint;//搖桿當前位置
bool active;//是否激活搖桿
float radius;//搖桿半徑
CCSprite *jsSprite;
bool isFollowRole;//是否跟隨用戶點擊
CCPoint getDirection();
float getVelocity();
void updatePos(ccTime dt);
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
LAYER_NODE_FUNC(HRocker);
};
#endif
~~~
~~~
//
// HRocker.cpp
// RockerPro
//
// Created by Himi on 12-3-30.
// Copyright (c) 2012年 Himi. All rights reserved.
//
#include "HRocker.h"
void HRocker::updatePos(ccTime dt){
jsSprite->setPosition(ccpAdd(jsSprite->getPosition(),ccpMult(ccpSub(currentPoint, jsSprite->getPosition()),0.5)));
}
//啟動搖桿
void HRocker::Active()
{
if (!active) {
active=true;
schedule(schedule_selector(HRocker::updatePos));//添加刷新函數
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0,false);//添加觸摸委托
}else {
}
}
//解除搖桿
void HRocker::Inactive()
{
if (active) {
active=false;
this->unschedule(schedule_selector(HRocker::updatePos));//刪除刷新
CCTouchDispatcher::sharedDispatcher()->removeDelegate(this);//刪除委托
}else {
}
}
//搖桿方位
CCPoint HRocker::getDirection()
{
return ccpNormalize(ccpSub(centerPoint, currentPoint));
}
//搖桿力度
float HRocker::getVelocity()
{
return ccpDistance(centerPoint, currentPoint);
}
HRocker* HRocker:: HRockerWithCenter(CCPoint aPoint ,float aRadius ,CCSprite* aJsSprite,CCSprite* aJsBg,bool _isFollowRole){
HRocker *jstick=HRocker::node();
jstick->initWithCenter(aPoint,aRadius,aJsSprite,aJsBg,_isFollowRole);
return jstick;
}
bool HRocker::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
if (!active)
return false;
this->setIsVisible(true);
CCPoint touchPoint = touch->locationInView(touch->view());
touchPoint = CCDirector:: sharedDirector()->convertToGL(touchPoint);
if(!isFollowRole){
if (ccpDistance(touchPoint, centerPoint) > radius){
return false;
}
}
currentPoint = touchPoint;
if(isFollowRole){
centerPoint=currentPoint;
jsSprite->setPosition(currentPoint);
this->getChildByTag(88)->setPosition(currentPoint);
}
return true;
}
void HRocker::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
CCPoint touchPoint = touch->locationInView(touch->view());
touchPoint = CCDirector:: sharedDirector()->convertToGL(touchPoint);
if (ccpDistance(touchPoint, centerPoint) > radius)
{
currentPoint =ccpAdd(centerPoint,ccpMult(ccpNormalize(ccpSub(touchPoint, centerPoint)), radius));
}else {
currentPoint = touchPoint;
}
}
void HRocker::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
currentPoint = centerPoint;
if(isFollowRole){
this->setIsVisible(false);
}
}
HRocker* HRocker::initWithCenter(CCPoint aPoint ,float aRadius ,CCSprite* aJsSprite,CCSprite* aJsBg,bool _isFollowRole){
isFollowRole =_isFollowRole;
active = false;
radius = aRadius;
if(!_isFollowRole){
centerPoint =aPoint;
}else{
centerPoint =ccp(0,0);
}
currentPoint = centerPoint;
jsSprite = aJsSprite;
jsSprite->setPosition(centerPoint);
aJsBg->setPosition(centerPoint);
aJsBg->setTag(88);
this->addChild(aJsBg);
this->addChild(jsSprite);
if(isFollowRole){
this->setIsVisible(false);
}
this->Active();//激活搖桿
return this;
}
~~~
創建使用方法很eazy,如下函數:
HRocker* HRocker:: HRockerWithCenter(CCPoint aPoint ,float aRadius ,CCSprite* aJsSprite,CCSprite* aJsBg,bool _isFollowRole);
第一個參數aPoint:搖桿中心點的坐標;
第二個參數aRadius: 搖桿的半徑
第三個參數:aJsSprite :搖桿的圖片資源精靈
第四個參數:aJsBg: 搖桿背景圖片資源精靈
第五個參數:isFollowRole:是否讓搖桿永遠跟隨用戶觸屏點(Himi新添加的功能)
這里對于最后一個參數可能很多童鞋不太理解,那么這里大概描述下:
對于手機游戲而言,虛擬的搖桿并不是一個很好的操作方式,但是為了滿足游戲的必要操作無疑必須使用,但是虛擬搖桿存在兩方面問題:
1.沒有實體感覺,對于用戶來說不能觸覺上明顯分清當前自己有沒有觸摸在虛擬搖桿上或者當前是按下還是按上等;
2.遮擋部分游戲畫面,這一點不僅僅式虛擬搖桿的存在造成遮擋畫面,用戶使用虛擬搖桿時更加的造成游戲畫面被擋住;
3.不容易操作,過于死板,不小心就觸發了虛擬搖桿區域之外;
對于虛擬搖桿存在的第一方面沒有實體感我們沒法改進,但是,是否觸摸到虛擬鍵盤這個可以使用手機震動提示;第二,三方面的問題在當前iOS手機游戲上很多公司采用了讓虛擬搖桿跟隨用戶觸屏點為搖桿中心的方式!并且用戶不觸摸屏幕默認不顯示虛擬搖桿;這么一來不僅讓游戲畫面能在不需要操作的時候盡可能的完美展示外,還能有效避免用戶觸摸不到搖桿判斷區域的問題;搖桿跟隨功能就是Himi封裝Rocker類創建時第五個參數?isFollowRole,傳入true即可跟隨!
如果還有童鞋聽的不是很清楚,那么將Himi這個Rocker類進行拷貝自己項目中,然后使用以下代碼進行創建使用嘗試下吧:
~~~
CCSprite *spRocker=CCSprite::spriteWithFile("CloseSelected.png");//搖桿
CCSprite *spRockerBG=CCSprite::spriteWithFile("rockerBg.png");//搖桿背景
HRocker *rocker=HRocker::HRockerWithCenter(ccp(210.0f,130.0f),50.0f ,spRocker ,spRockerBG,false);//創建搖桿
this->addChild(rocker);//搖桿添加到layer中
//this 是個layer
CCSprite *spRocker2=CCSprite::spriteWithFile("CloseSelected.png");//搖桿
CCSprite *spRockerBG2=CCSprite::spriteWithFile("rockerBg.png");//搖桿背景
HRocker* rocker2=HRocker::HRockerWithCenter(ccp(210.0f,130.0f),50.0f ,spRocker2 ,spRockerBG2,true);//創建搖桿
this->addChild(rocker2);//搖桿添加到layer中
~~~
截圖如下:
[](http://www.himigame.com/wp-content/uploads/2012/03/31123.png)
更多的自定義大家可以自行嘗試,Himi就不添加了,畢竟每款游戲都有不同需求~
- 前言
- 【Iphone 游戲開發】游戲引擎剖析
- [Object-C語言隨筆之一]Mac os 下搭建iOS開發環境
- [Object-C語言隨筆之二] 《NSLog》常用的打印調試語句與自動排版
- [Object-C語言隨筆之三] 類的創建和實例化以及函數的添加和調用!
- [Object-C語言隨筆之四]創建視圖并繪制簡單圖形
- 【iOS-Cocos2d游戲開發之一】搭建cocos2d游戲引擎環境HelloWorld!
- 【iOS-Cocos2d游戲開發之二】Cocos2D 游戲開發資源貼(教程以及源碼)
- 【iOS-Cocos2d游戲開發之三】CCScene切換的所有特效(28種)以及設置屏幕橫豎屏!
- 【iOS-Cocos2d游戲開發之四】獨自收集Cocos2d提供的字體!共57種(有對照的字體圖)
- 【iOS-Cocos2d游戲開發之五】多觸點與觸屏事件詳解(單一監聽、事件分發)【11月28日更新】
- 【iOS-Cocos2d游戲開發之六】對觸屏事件追加講解,解決無法觸發ccTouchMoved事件[重要!]
- 【iOS-Cocos2d游戲開發之七】在cocos2d中添加/刪除系統組件,并解決View設置透明會影響View中的其他組件的問題!【11月28日更新解決添加組件Cocos2d動畫停止播放的BUG】
- 【iOS-Cocos2d游戲開發之八】開啟高清(960*640)模式問題與解答、圖片適配以及設置iphone橫豎屏
- 【iOS-Cocos2d游戲開發之九】講解CCSpriteBatchNode與TP工具的".pvr.ccz",".plist"共用的終極精靈優化及注意事項!
- 【iOS-Cocos2d游戲開發之十】添加粒子系統特效并解決粒子特效與Layer之間的坐標問題;
- 【iOS-Cocos2d游戲開發之十一】使用Box2d物理系統以及在cocos2d框架添加Box2d物理系統lib包的方法
- 【iOS-Cocos2d游戲開發之十二】淺析使用C++/C/OC進行iOS游戲混編出現“failed with exit”問題與小結;
- 【iOS-Cocos2d游戲開發之十三】CCSprite利用Bezier(貝塞爾)做拋物線動作并讓CCSprite同時播放兩個Action動作!
- 【iOS-Cocos2d游戲開發之十四】音頻/音效/視頻播放(利用Cocos2D-iPhone-Extensions嵌入Cocos2d進行視頻播放!)
- 【iOS-Cocos2d游戲開發之十五】詳解CCProgressTimer 進度條并修改cocos2d源碼實現“理想”游戲進度條!
- 【iOS-Cocos2d游戲開發之十六】添加本地通知(UILocalNotification)以及添加系統組件滾動視圖(UIScrollView)!【2011年11月15日更新】
- 【iOS-Cocos2d游戲開發之十七】靈活使用精靈可視區域(TextureRect)與錨點(anchorPoint),并結合可視區域與錨點制作進度條!
- 【iOS開發必備指南合集】申請企業級IDP、真機調試、游戲接入GameCenter 指南(實現仿官方的成就提示)、游戲接入OpenFeint指南;
- 【iOS-Cocos2d游戲開發之十八】解決滾屏背景/拼接地圖有黑邊(縫隙)/動畫播放出現毛邊以及禁止游戲中自動鎖屏問題!【2011年12月18日補充】
- 【iOS開發必收藏】詳解iOS應用程序內使用IAP/StoreKit付費、沙盒(SandBox)測試、創建測試賬號流程!【2012-12-11日更新獲取"產品付費數量等于0的問題"】
- 【iOS-cocos2d-X 游戲開發之一】在Mac下結合Xcode搭建Cocos2d-X開發環境!
- 【iOS-cocos2d-X 游戲開發之二】【必看篇】總結闡述Cocos2d-X與Cocos2d-iphone區別;
- 【iOS-Cocos2d游戲開發之十九】游戲數據存儲的四種常用方式NSKeyedArchiver/NSUserDefaults/Write寫入/SQLite3
- 【iOS-Cocos2d游戲開發之二十】精靈的基礎知識點總匯(位圖操作/貼圖更換/重排z軸等)以及利用CCSprite與CCLayerColor制作簡單遮蓋層!
- 【iOS-Cocos2d游戲開發之二十一 】自定義精靈類并為你的精靈設置攻擊幀(指定開始幀)以及擴展Cocos2d源碼的CCAnimation簡化動畫創建!
- 【iOS-Cocos2d游戲開發之二十二 】CCSpeed實現CCAnimate動畫進行時設置慢動作以及設置游戲加減速進行(塔防游戲必備)!
- 【iOS-cocos2d-X 游戲開發之三】Mac下配置Android NDK環境并搭建Cocos2d-x環境并Eclipse正常編譯運行Cocos2dX自帶TestsDemo項目!
- 【iOS-cocos2d-X 游戲開發之四】Cocos2dX創建Android NDK新項目并編譯導入Eclipse中正常運行!
- 【iOS-cocos2d-X 游戲開發之五】游戲存儲之Cocos2dX自帶CCUserDefault類詳解;
- 【iOS-cocos2d-X 游戲開發之六】使用Base64算法對Cocos2dX自帶CCUserDefault游戲存儲數據編碼!
- 【iOS-cocos2d-X 游戲開發之七】整合Cocos2dX的Android項目到Xcode項目中,Xcode編寫&編譯代碼,Android導入打包運行即可!
- 【iOS-iap防護】驗證用戶付費收據!拒絕iap Cracker!拒絕iap Free!讓iphone越獄用戶無從下手!【2012年5月2日更新防護iap Free的方法】
- 【COCOS2DX-LUA 腳本開發之一】在Cocos2dX游戲中使用Lua腳本進行游戲開發(基礎篇)并介紹腳本在游戲中詳細用途!
- 【iOS-cocos2d-X 游戲開發之九】Cocos2dx利用CCSAXParser解析xml數據&CCMutableDictionary使用與注意!
- 【iOS-cocos2d-X 游戲開發之十】自定義CCSprite/Layer/CCNode及靜態類模版&自定義類細節說明&Cocos2dx觸屏事件講解
- 【iOS-cocos2d-X 游戲開發之十一】New CCSprite()帶來的錯誤&使用CCUserDefault及pvr.ccz在Cocos2dx中要注意!
- 【iOS-cocos2d-X 游戲開發之十二】自定義Cocos2dx搖桿(增強Joystick),增加搖桿跟隨用戶觸點作為搖桿坐標,讓搖桿不再死板!
- 【iOS-cocos2d-X 游戲開發之十三】詳細講解在Xcode中利用預編譯并通過Jni調用Android的Java層代碼(cocos2dx里訪問調用Android函數)!
- 【iOS-cocos2d-X 游戲開發之十四】Xcode中c++&Object-C混編,詳細介紹如何在cocos2dx中訪問object函數以及Apple Api
- 【iOS-cocos2d-X 游戲開發之十五】Cocos2dx中響應Android的Back(返回)與Menu(小房子)事件&&Cocos2dx自動釋放粒子內存函數!
- 【iOS-cocos2d-X 游戲開發之十六】配置你的Cocos2dx項目編譯后的Android自動使用(-hd)高清圖&設置Android自適應屏幕、縮放比例方法!
- 【Cocoa(mac) Application 開發系列之四】動作編輯器(Cocos2dx)制作流程詳解及附上響應鼠標滾軸事件、反轉坐標系、導入/創建資源目錄等知識點代碼!
- 【Cocos2d-X(2.x) 游戲開發系列之一】cocos2dx(v2.x)與(v1.x)的一些常用函數區別講解!在2.x版CCFileData類被去除等
- 【Cocos2d-X(2.x) 游戲開發系列之二】cocos2dx最新2.0.1版本跨平臺整合NDK+Xcode,Xcode編寫&編譯代碼,Android導入打包運行即可!
- 【Cocos2dX(2.x)_Lua開發之三】★重要必看篇★在Lua中使用自定義精靈(Lua腳本與自創建類之間的訪問)及Lua基礎講解
- 【Cocos2d-X(2.x) 游戲開發系列之三】最新版本cocos2d­2.0­x­2.0.2使用新資源加載策略!不再沿用-hd、-ipad、-ipadhd添加后綴方式
- 【Cocos2d-X(1.x 2.x) 修復篇】iOS6 中 libcurl.a 無法通過armv7s編譯以及iOS6中無法正常游戲橫屏的解決方法
- 【Cocos2d-X(1.x 2.x) 】iOS6與iphone5適相關設置隨筆(解決第三方類庫無法通過armv7s編譯的方法、添加Default-568h@2x.png)