如何在android 刷新activity的activity中重置cocos2d-x游戏

cocos2d-x与Android混编实现游戏支付功能
游戏支付平台付实际上就是买卖双方交易过程中的“第三方中介”,也可以说是“技术中介”。这里我选择豌豆荚SDK平台,实现游戏支付功能。
支付流程:配置游戏服务器端回调地址URL游戏客户端使用申请好的Appkey_id,secretkey游戏客户端使用doLogin方法调用豌豆荚登录登录成功(onSuccess)后,游戏客户端提交用户信息(uid,nick,token)到游戏服务器游戏服务器提交uid,token到豌豆荚服务器进行验证,验证通过后游戏完成登录如果有角色创建,游戏客户端调用createRole方法创建角色,注册到豌豆荚服务器,可选调用游戏客户端创建订单,设置游戏订单号(order.out_trade_no),发起支付(pay)玩家完成支付,返回游戏客户端只有支付成功的订单,豌豆荚服务器通知游戏服务器回调地址,包含order.out_trade_no游戏服务器端验证回调信息中的签名,使用RsaTest项目中的公钥既可,验证通过后发放游戏道给游戏客户端并返回success字符串,处理失败返回fail字符串游戏客户端开始使用道。
有关加入豌豆荚SDK具体操作可以参考《技术文档》。
大家先看下,我的目录结构:vcD48cD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPQ=="/uploadfile/Collfiles/.jpg" alt="\" />
是不是和上次博文类似呢?就是cocos2d-x与Android混编实现换“头像图片”!对了,基本实现思路都是一样的,cocos2d-x 控件触发调用android方法实现的。 因它和上篇博文步骤一样,就不多讲了,到时直接上传代码给大家参考吧。
支付功能类:PayDemo.javapackage com.wandoujia.wdpaydemo.
import android.app.A
import android.os.B
import android.os.H
import android.os.L
import android.util.L
import android.view.V
import android.view.View.OnClickL
import android.widget.B
import android.widget.TextV
import com.wandoujia.sdk.plugin.paydef.LoginCallB
import com.wandoujia.sdk.plugin.paydef.PayCallB
import com.wandoujia.sdk.plugin.paydef.U
import com.wandoujia.sdk.plugin.paydef.WandouA
import com.wandoujia.sdk.plugin.paydef.WandouO
import com.wandoujia.sdk.plugin.paydef.WandouP
import com.wandoujia.sdk.plugin.paysdkimpl.PayC
import com.wandoujia.sdk.plugin.paysdkimpl.WandouAccountI
import com.wandoujia.sdk.plugin.paysdkimpl.WandouPayI
import com.wandoujia.wandoujiapaymentplugin.utils.MSG;
public class PayDemo extends Activity implements OnClickListener {
private static final String TAG = "PayDemo";
final String appkey_id = "";
// 开发者 安全秘钥
final String secretkey = "99b4efb45dbe7a1431511";
private WandouAccount account = new WandouAccountImpl();
private WandouPay wandoupay = new WandouPayImpl();
protected void onCreate(Bundle savedInstanceState) {
Log.e(TAG, "start onCreate~~~" + android.os.Build.VERSION.RELEASE);
super.onCreate(savedInstanceState);
//在onCreate中调用PayConfig.init初始化
PayConfig.init(this, appkey_id, secretkey);
gameLayout();
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "start onDestroy~~~" + android.os.Build.VERSION.RELEASE);
public void gameLayout() {
setContentView(R.layout.activity_main);
((Button) findViewById(R.id.pay)).setOnClickListener(this);
((Button) findViewById(R.id.login_button)).setOnClickListener(this);
((Button) findViewById(R.id.logout_button)).setOnClickListener(this);
public String textString(int id) {
return ((TextView) findViewById(id)).getText().toString();
public void setText(final int id, final String str) {
// Request UI update on main thread.
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
((TextView) findViewById(id)).setText(str);
public void onClick(View v) {
int viewId = v.getId();
if (R.id.pay == viewId) {
Log.w(TAG, "doPayment!");
float money = Float.parseFloat(textString(R.id.money));
long moneyInFen = (long) (money * 100);
WandouOrder order =
new WandouOrder(textString(R.id.subject), textString(R.id.desc), moneyInFen);
// 设置游戏订单号,最长50个字符
order.setOut_trade_no("GameOrderIdMaxLenth50");
// 触发支付
wandoupay.pay(PayDemo.this, order, new PayCallBack() {
public void onSuccess(User user, WandouOrder order) {
Log.w("DemoPay", "onSuccess:" + order);
setText(R.id.orderInfo, user.getNick() + " 支付成功!" + order);
public void onError(User user, WandouOrder order) {
Log.w("DemoPay", "onError:" + order);
setText(R.id.orderInfo, user.getNick() + " 支付失败!" + order);
} else if (R.id.login_button == viewId) {
Log.i(TAG, "PaySdk init.");
// PayConfig.init(this, appkey_id, secretkey);
Log.w(TAG, "doLogin!");
//触发登录
account.doLogin(PayDemo.this, new LoginCallBack() {
public void onSuccess(User user, int type) {
Log.w("login", "success:+" + user);
setText(R.id.account, user.toString());
// 豌豆荚账户UID
Long uid = user.getUid();
// 豌豆荚账户昵称
String nick = user.getNick();
// 豌豆荚账户登录验证 Token ,15分钟内有效
String token = user.getToken();
// 1.请把uid,token 提交游戏服务器
// 2.游戏服务器收到uid,token后提交给豌豆荚服务器验证
// 3.验证通过后,游戏服务器生成一个 cookie 给游戏客户端使用
// 4.游戏客户端得到游戏的cookie 与游戏服务器进行交互通信,保证身份验证安全
public void onError(int returnCode, String info) {
// 请不要在这里重新调用 doLogin
// 游戏界面上应该留有一个登录按钮,来触发 doLogin登录
setText(R.id.account, "Demo中登陆失败:" + MSG.trans(info));
Log.e(TAG, MSG.trans(info));
} else if (R.id.logout_button == viewId) {
Log.w(TAG, "doLogout!");
// doLogout无需处理回掉方法
account.doLogout(getApplicationContext(), null);
// Do the subsequent directly after doLogut was called.
// i.e. Finish your application.
// Then when launching your app next time, user will see the login UI again.
最终运行效果:代码:http://download.csdn.net/detail/my38085首先还是就我个人的理解,讲讲游戏引擎的处理流程。
其实游戏逻辑简单化就是一个死循环,如下:
2 bool game_is_running = true;
while( game_is_running ) {
update_game();
display_game();
我们所看到的游戏画面,游戏音乐,以及一些触控,输入等。在逻辑上就是这么一个死循环。这个循环一直在跑,期间会处理一些列的事件,简化之就是上面的两个函数。
cocos2d-x引擎也是如此,所有的逻辑都是在这个主循环下实现的。下面看看cocos2dx在各平台上的主循环实现。
看它的main.cpp
1 #include "main.h"
2 #include "../Classes/AppDelegate.h"
3 #include "CCEGLView.h"
5 USING_NS_CC;
7 int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
lpCmdLine,
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// create the application instance
CCEGLView* eglView = CCEGLView::sharedOpenGLView();
eglView-&setFrameSize(2048, 1536);
// The resolution of ipad3 is very large. In general, PC's resolution is smaller than it.
// So we need to invoke 'setFrameZoomFactor'(only valid on desktop(win32, mac, linux)) to make the window smaller.
eglView-&setFrameZoomFactor(0.4f);
return CCApplication::sharedApplication()-&run();// 注意这里
前面都不要关心,只是用来传递OpenGL窗口的,关键是最后一句,CCApplication::sharedApplication()-&run()。看这个run函数:
1 int CCApplication::run()
PVRFrameEnableControlWindow(false);
// Main message loop:
LARGE_INTEGER nF
LARGE_INTEGER nL
LARGE_INTEGER nN
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nLast);
// Initialize instance and cocos2d.
if (!applicationDidFinishLaunching())
CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView();
pMainWnd-&centerWindow();
ShowWindow(pMainWnd-&getHWnd(), SW_SHOW);
while (1)// 注意这里,主循环来了
if (! PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
// Get current time tick.
QueryPerformanceCounter(&nNow);
// If it's the time to draw next frame, draw it, else sleep a while.
if (nNow.QuadPart - nLast.QuadPart & m_nAnimationInterval.QuadPart)
nLast.QuadPart = nNow.QuadP
CCDirector::sharedDirector()-&mainLoop(); //看看这是神马
if (WM_QUIT == msg.message)
// Quit message loop.
// Deal with windows message.
if (! m_hAccelTable || ! TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg))
TranslateMessage(&msg);
DispatchMessage(&msg);
return (int) msg.wP
不熟悉windows的童鞋估计都知道windows是消息驱动的。这个死循环就是用来处理windows的消息循环的,在其中处理了FPS逻辑,消息分发等。注意看其中红色标标注的
1 CCDirector::sharedDirector()-&mainLoop();
这是神马东西啊!这个就是cocos2d-x的主循环了,由导演负责维护。从此就进入了cocos2d-x的世界,跟windows没有一毛钱关系了。
Android平台的游戏是从一个Activity开始的。(话说好像Android的所有应用都是从Activity开始的吧)。
在引擎源码下有个目录是android的java代码,是模板代码,几乎所有的游戏都用这个,不怎么变。不信可以你可以看
YourCocos2dxDir/cocos2dx/platform/android/java这个目录,就是创建android工程的时候会去这个目录拷贝java代码作为模板。
来看看HelloCpp的代码
1 package org.cocos2dx.
3 import org.cocos2dx.lib.Cocos2dxA
5 import android.os.B
7 public class HelloCpp extends Cocos2dxActivity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
System.loadLibrary("hellocpp");
很简单,对吧。几行代码而已,这里说明了两个问题
1. Cocos2dxActivity才是核心的Activity。
2. 游戏的C++部分包括引擎部分,被编译成了动态链接库hellocpp。这里就是加载了hellocpp动态链接库。
这个动态链接库是在用NDK编译的时候生成的,就是libs/armeabi/libhellocpp.so。(扯远了)
还是来看看Cocos2dxActivity这个Activity。
1 public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener {
// ===========================================================
// Constants
// ===========================================================
private static final String TAG = Cocos2dxActivity.class.getSimpleName();
// ===========================================================
// ===========================================================
private Cocos2dxGLSurfaceView mGLSurfaceV//注意这个SurfaceView
private Cocos2dxHandler mH
// ===========================================================
// Constructors
// ===========================================================
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mHandler = new Cocos2dxHandler(this);
this.init();
Cocos2dxHelper.init(this, this);
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
protected void onResume() {
super.onResume();
Cocos2dxHelper.onResume();
this.mGLSurfaceView.onResume();
protected void onPause() {
super.onPause();
Cocos2dxHelper.onPause();
this.mGLSurfaceView.onPause();
public void showDialog(final String pTitle, final String pMessage) {
Message msg = new Message();
msg.what = Cocos2dxHandler.HANDLER_SHOW_DIALOG;
msg.obj = new Cocos2dxHandler.DialogMessage(pTitle, pMessage);
this.mHandler.sendMessage(msg);
public void showEditTextDialog(final String pTitle, final String pContent, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength) {
Message msg = new Message();
msg.what = Cocos2dxHandler.HANDLER_SHOW_EDITBOX_DIALOG;
msg.obj = new Cocos2dxHandler.EditBoxMessage(pTitle, pContent, pInputMode, pInputFlag, pReturnType, pMaxLength);
this.mHandler.sendMessage(msg);
public void runOnGLThread(final Runnable pRunnable) {
this.mGLSurfaceView.queueEvent(pRunnable);
// ===========================================================
// Methods
// ===========================================================
public void init() {
// FrameLayout
ViewGroup.LayoutParams framelayout_params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
FrameLayout framelayout = new FrameLayout(this); // 帧布局,可一层一层覆盖
framelayout.setLayoutParams(framelayout_params);
// Cocos2dxEditText layout
ViewGroup.LayoutParams edittext_layout_params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
Cocos2dxEditText edittext = new Cocos2dxEditText(this);
edittext.setLayoutParams(edittext_layout_params);
// ...add to FrameLayout
framelayout.addView(edittext);
// Cocos2dxGLSurfaceView
this.mGLSurfaceView = this.onCreateView();
// ...add to FrameLayout
framelayout.addView(this.mGLSurfaceView);// 添加GLSurfaceView
this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());//意这行,一个渲染器
this.mGLSurfaceView.setCocos2dxEditText(edittext);
// Set framelayout as the content view
setContentView(framelayout);
public Cocos2dxGLSurfaceView onCreateView() {
return new Cocos2dxGLSurfaceView(this);
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
代码很多,呵呵。其实核心就是那个mGLSurfaceView和它的渲染器new Cocos2dxRenderer()。在Android上,OpenGL的渲染是由一个GLSurfaceView和其渲染器Render组成。GLSurfaceView显示界面,Render渲染更新。这个Render其实是一个渲染线程,不停再跑,由框架层维护。这里不多讲。
来看这个Cocos2dxRenderer
1 package org.cocos2dx.
3 import javax.microedition.khronos.egl.EGLC
4 import javax.microedition.khronos.opengles.GL10;
6 import android.opengl.GLSurfaceV
8 public class Cocos2dxRenderer implements GLSurfaceView.Renderer {
// ===========================================================
// Constants
// ===========================================================
private final static long NANOSECONDSPERSECOND = L;
private final static long NANOSECONDSPERMICROSECOND = 1000000;
private static long sAnimationInterval = (long) (1.0 / 60 * Cocos2dxRenderer.NANOSECONDSPERSECOND);
// ===========================================================
// ===========================================================
private long mLastTickInNanoS
private int mScreenW
private int mScreenH
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
public static void setAnimationInterval(final double pAnimationInterval) {
Cocos2dxRenderer.sAnimationInterval = (long) (pAnimationInterval * Cocos2dxRenderer.NANOSECONDSPERSECOND);
public void setScreenWidthAndHeight(final int pSurfaceWidth, final int pSurfaceHeight) {
this.mScreenWidth = pSurfaceW
this.mScreenHeight = pSurfaceH
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override //①注意这里
public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig) {
Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);//②初始化窗口
this.mLastTickInNanoSeconds = System.nanoTime();
public void onSurfaceChanged(final GL10 pGL10, final int pWidth, final int pHeight) {
@Override //③注意这里
public void onDrawFrame(final GL10 gl) {
* FPS controlling algorithm is not accurate, and it will slow down FPS
* on some devices. So comment FPS controlling code.
final long nowInNanoSeconds = System.nanoTime();
final long interval = nowInNanoSeconds - this.mLastTickInNanoS
// should render a frame when onDrawFrame() is called or there is a
// "ghost"
Cocos2dxRenderer.nativeRender();//④特别注意这个
// fps controlling
if (interval & Cocos2dxRenderer.sAnimationInterval) {
// because we render it before, so we should sleep twice time interval
Thread.sleep((Cocos2dxRenderer.sAnimationInterval - interval) / Cocos2dxRenderer.NANOSECONDSPERMICROSECOND);
} catch (final Exception e) {
this.mLastTickInNanoSeconds = nowInNanoS
// ===========================================================
// Methods
// ===========================================================
private static native void nativeTouchesBegin(final int pID, final float pX, final float pY);
private static native void nativeTouchesEnd(final int pID, final float pX, final float pY);
private static native void nativeTouchesMove(final int[] pIDs, final float[] pXs, final float[] pYs);
private static native void nativeTouchesCancel(final int[] pIDs, final float[] pXs, final float[] pYs);
private static native boolean nativeKeyDown(final int pKeyCode);
private static native void nativeRender();
private static native void nativeInit(final int pWidth, final int pHeight);
private static native void nativeOnPause();
private static native void nativeOnResume();
public void handleActionDown(final int pID, final float pX, final float pY) {
Cocos2dxRenderer.nativeTouchesBegin(pID, pX, pY);
public void handleActionUp(final int pID, final float pX, final float pY) {
Cocos2dxRenderer.nativeTouchesEnd(pID, pX, pY);
public void handleActionCancel(final int[] pIDs, final float[] pXs, final float[] pYs) {
Cocos2dxRenderer.nativeTouchesCancel(pIDs, pXs, pYs);
public void handleActionMove(final int[] pIDs, final float[] pXs, final float[] pYs) {
Cocos2dxRenderer.nativeTouchesMove(pIDs, pXs, pYs);
public void handleKeyDown(final int pKeyCode) {
Cocos2dxRenderer.nativeKeyDown(pKeyCode);
public void handleOnPause() {
Cocos2dxRenderer.nativeOnPause();
public void handleOnResume() {
Cocos2dxRenderer.nativeOnResume();
private static native void nativeInsertText(final String pText);
private static native void nativeDeleteBackward();
private static native String nativeGetContentText();
public void handleInsertText(final String pText) {
Cocos2dxRenderer.nativeInsertText(pText);
public void handleDeleteBackward() {
Cocos2dxRenderer.nativeDeleteBackward();
public String getContentText() {
return Cocos2dxRenderer.nativeGetContentText();
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
代码很多,一副貌似很复杂的样子。其实脉络很清晰的,我们只看脉络,不考虑细节哈。我们顺藤摸瓜来...
首先要知道GLSurfaceView的渲染器必须实现GLSurfaceView.Renderer接口。就是上面的三个Override方法。
onSurfaceCreated在窗口建立的时候调用,onSurfaceChanged在窗口建立和大小变化是调用,onDrawFrame这个方法就跟普通View的Ondraw方法一样,窗口建立初始化完成后渲染线程不停的调这个方法。这些都是框架决定的,就是这个样子。下面分析下代码几处标记的地方:
看标记①,窗口建立,这个时候要进行初始化。这个时候它调用了一个native函数,就是标记②。看到这个函数形式是不是能想到什么呢,等下再说。
看标记③,前面说了,这个函数会被渲染线程不停调用(像不像主循环的死循环啊)。然后里面有个很牛擦的函数④。
这又是一个native的函数,呵呵。
native的代码是神马啊,就是C++啊。知之为知之,不知谷歌之。
既然是java调用C++,那就是jni调用了。
我们来看看jni/hellocpp/下的main.cpp
1 #include "AppDelegate.h"
2 #include "platform/android/jni/JniHelper.h"
3 #include &jni.h&
4 #include &android/log.h&
6 #include "HelloWorldScene.h"
__android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
11 using namespace cocos2d;
13 extern "C"
16 jint JNI_OnLoad(JavaVM *vm, void *reserved)
JniHelper::setJavaVM(vm);
return JNI_VERSION_1_4;
23 void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*
env, jobject thiz, jint w, jint h)
if (!CCDirector::sharedDirector()-&getOpenGLView())
CCEGLView *view = CCEGLView::sharedOpenGLView();
view-&setFrameSize(w, h);
CCLog("with %d,height %d",w,h);
AppDelegate *pAppDelegate = new AppDelegate();
CCApplication::sharedApplication()-&run(); // 看这里⑤
ccDrawInit();
ccGLInvalidateStateCache();
CCShaderCache::sharedShaderCache()-&reloadDefaultShaders();
CCTextureCache::reloadAllTextures();
CCNotificationCenter::sharedNotificationCenter()-&postNotification(EVNET_COME_TO_FOREGROUND, NULL);
CCDirector::sharedDirector()-&setGLDefaultValues();
根据Jni的命名规则,那个标注②的nativeInit方法就是上面红色一长串(呵呵)。窗口建立起来后调用nativeInit方法,就是调用这个C++的实现。这里做了窗口的初始化处理。
看标注⑤,你以为这个run函数就进入主循环了么,呵呵
1 &span style="font-size:18"&int CCApplication::run()
// Initialize instance and cocos2d.
if (! applicationDidFinishLaunching())
return -1;
10 }&/span&
我们看到了神马!实质上就调了一下applicationDidFinishLaunching,别的什么也没干。所以这里没有进入主循环。
现在再看③和④。这个逻辑貌似就是主循环。
这个nativeRender()函数的实现在Yourcocos2dDir/cocos2dx/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp
1 #include "text_input_node/CCIMEDispatcher.h"
2 #include "CCDirector.h"
3 #include "../CCApplication.h"
4 #include "platform/CCFileUtils.h"
5 #include "CCEventType.h"
6 #include "support/CCNotificationCenter.h"
7 #include "JniHelper.h"
8 #include &jni.h&
10 using namespace cocos2d;
12 extern "C" {
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_&span style="color:#ff0000;"&Cocos2dxRenderer_nativeRender&/span&(JNIEnv* env) {
&span style="color:#ff0000;"&cocos2d::CCDirector::sharedDirector()-&mainLoop();//看到木有,这是什么&/span&
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause() {
CCApplication::sharedApplication()-&applicationDidEnterBackground();
CCNotificationCenter::sharedNotificationCenter()-&postNotification(EVENT_COME_TO_BACKGROUND, NULL);
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnResume() {
if (CCDirector::sharedDirector()-&getOpenGLView()) {
CCApplication::sharedApplication()-&applicationWillEnterForeground();
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInsertText(JNIEnv* env, jobject thiz, jstring text) {
const char* pszText = env-&GetStringUTFChars(text, NULL);
cocos2d::CCIMEDispatcher::sharedDispatcher()-&dispatchInsertText(pszText, strlen(pszText));
env-&ReleaseStringUTFChars(text, pszText);
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeDeleteBackward(JNIEnv* env, jobject thiz) {
cocos2d::CCIMEDispatcher::sharedDispatcher()-&dispatchDeleteBackward();
JNIEXPORT jstring JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeGetContentText() {
JNIEnv * env = 0;
if (JniHelper::getJavaVM()-&GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK || ! env) {
const char * pszText = cocos2d::CCIMEDispatcher::sharedDispatcher()-&getContentText();
return env-&NewStringUTF(pszText);
看上面标注,找到导演了,导演又开始主循环了。真是众里寻他千百度,那人却在灯火阑珊处啊。
到这里可以发现,Android上的主循环跟win上的不太一样,它不是一个简单的while就完了。它是由java的渲染线程发起的,通过不断调用render来驱动。
ios上面和Android上类似。看AppController.mm
1 #import &UIKit/UIKit.h&
2 #import "AppController.h"
3 #import "cocos2d.h"
4 #import "EAGLView.h"
5 #import "AppDelegate.h"
7 #import "RootViewController.h"
9 @implementation AppController
12 @synthesize viewC
14 #pragma mark -
15 #pragma mark Application lifecycle
17 // cocos2d application instance
18 static AppDelegate s_sharedA
20 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]
pixelFormat: kEAGLColorFormatRGBA8
depthFormat: GL_DEPTH_COMPONENT16
preserveBackbuffer: NO
sharegroup: nil
multiSampling: NO
numberOfSamples:0 ];
// Use RootViewController manage EAGLView
viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
viewController.wantsFullScreenLayout = YES;
viewController.view = __glV
// Set RootViewController to window
if ( [[UIDevice currentDevice].systemVersion floatValue] & 6.0)
// warning: addSubView doesn't work on iOS6
[window addSubview: viewController.view];
// use this method on ios6
[window setRootViewController:viewController];
[window makeKeyAndVisible];
[[UIApplication sharedApplication] setStatusBarHidden: YES];
&span style="color:#ff0000;"&cocos2d::CCApplication::sharedApplication()-&run();&/span&//&span style="color:#ff0000;"&看这里&/span&
return YES;
61 - (void)applicationWillResignActive:(UIApplication *)application {
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
cocos2d::CCDirector::sharedDirector()-&pause();
69 - (void)applicationDidBecomeActive:(UIApplication *)application {
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
cocos2d::CCDirector::sharedDirector()-&resume();
76 - (void)applicationDidEnterBackground:(UIApplication *)application {
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
cocos2d::CCApplication::sharedApplication()-&applicationDidEnterBackground();
84 - (void)applicationWillEnterForeground:(UIApplication *)application {
Called as part of
transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
cocos2d::CCApplication::sharedApplication()-&applicationWillEnterForeground();
91 - (void)applicationWillTerminate:(UIApplication *)application {
Called when the application is about to terminate.
See also applicationDidEnterBackground:.
99 #pragma mark -
100 #pragma mark Memory management
102 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
cocos2d::CCDirector::sharedDirector()-&purgeCachedData();
110 - (void)dealloc {
[super dealloc];
直接看标注,跟进run()
1 &span style="font-size:18"&int CCApplication::run()
if (applicationDidFinishLaunching())
&span style="color:#ff0000;"&[[CCDirectorCaller sharedDirectorCaller] startMainLoop]&/span&;
8 }&/span&
再跟标注的startMainLoop()
1 -(void) startMainLoop
// CCDirector::setAnimationInterval() is called, we should invalidate it first
[displayLink invalidate];
displayLink =
NSLog(@"run loop !");
displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];//看这里
[displayLink setFrameInterval: self.interval];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
好了,看红色标注。这个貌似循环不起来啊,呵呵。
仔细看他加载的这个类CADisplayLink,就是这个东西循环起来的。这其实就是个定时器,默认每秒运行60次,其有个属性可以设置FPS。看后面有个回调函数doCaller,跟进
1 -(void) doCaller: (id) sender
cocos2d::CCDirector::sharedDirector()-&mainLoop();//看这里
好了,终于又看到导演了。导演很忙,又开始主循环了。
一旦进入主循环,游戏就开始我们自己设计的游戏逻辑。
原文连接:http://blog.csdn.net/dawn_moon/article/details/8518737
阅读(...) 评论()

我要回帖

更多关于 cocos2dx appactivity 的文章

 

随机推荐