ZhouWeikuan / cocos2d

cocos2d for android, based on cocos2d-android-0.82, and now ported from cocos2d-iphone 0.99.4. The googlecode address is here: http://code.google.com/p/cocos2d-android-1/ . There are several demos to watch.
610 stars 291 forks source link

random crashes when adding a particle effect from my game loop #38

Closed ShadowMare closed 12 years ago

ShadowMare commented 12 years ago

First of all - thank you for your great work!

I get (often but not always) this exception when I call the method beneath it:

exception:

09-20 23:11:07.226: ERROR/AndroidRuntime(19287): FATAL EXCEPTION: GLThread 10
09-20 23:11:07.226: ERROR/AndroidRuntime(19287): java.lang.IllegalArgumentException: remaining() < size
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at com.google.android.gles_jni.GLImpl.glBufferData(Native Method)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at org.cocos2d.particlesystem.CCQuadParticleSystem$1.load(CCQuadParticleSystem.java:88)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at org.cocos2d.opengl.GLResourceHelper$1.perform(GLResourceHelper.java:68)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at org.cocos2d.opengl.GLResourceHelper.update(GLResourceHelper.java:128)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at org.cocos2d.nodes.CCDirector.drawCCScene(CCDirector.java:700)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at org.cocos2d.nodes.CCDirector.onDrawFrame(CCDirector.java:665)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at org.cocos2d.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1245)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at org.cocos2d.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1056)

method (class is a CCLayer):

    public void explode(float x, float y)
    {
        CCParticleSystem emitter;
        emitter = CCParticleExplosion.node();
        emitter.setTexture(CCTextureCache.sharedTextureCache().addImage("fire.png"));
        emitter.setAutoRemoveOnFinish(true);
        emitter.setPosition(x, y);
        emitter.setSpeedVar(300);
        emitter.setDuration(2.2f);
        emitter.setSpeed(600);
        addChild(emitter);
    }

It works every time when I call this in ccTouchesBegan but calling this from my game loop leads most of the time (but strangely enough not everytime) to the posted exception. Can you tell me what I am probably doing wrong?

ZhouWeikuan commented 12 years ago

Particle System are not fully implemented/tested. If it works always in ccTouchesBegan, does this mean we should run it in UIThread only?

2011/9/21, ShadowMare reply@reply.github.com:

First of all - thank you for your great work!

I get (often but not always) this exception when I call the method beneath it:

exception:

09-20 23:11:07.226: ERROR/AndroidRuntime(19287): FATAL EXCEPTION: GLThread
10
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):
java.lang.IllegalArgumentException: remaining() < size
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at
com.google.android.gles_jni.GLImpl.glBufferData(Native Method)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at
org.cocos2d.particlesystem.CCQuadParticleSystem$1.load(CCQuadParticleSystem.java:88)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at
org.cocos2d.opengl.GLResourceHelper$1.perform(GLResourceHelper.java:68)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at
org.cocos2d.opengl.GLResourceHelper.update(GLResourceHelper.java:128)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at
org.cocos2d.nodes.CCDirector.drawCCScene(CCDirector.java:700)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at
org.cocos2d.nodes.CCDirector.onDrawFrame(CCDirector.java:665)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at
org.cocos2d.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1245)
09-20 23:11:07.226: ERROR/AndroidRuntime(19287):     at
org.cocos2d.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1056)

method (class is a CCLayer):

  public void explode(float x, float y)
  {
      CCParticleSystem emitter;
      emitter = CCParticleExplosion.node();

emitter.setTexture(CCTextureCache.sharedTextureCache().addImage("fire.png"));
      emitter.setAutoRemoveOnFinish(true);
      emitter.setPosition(x, y);
      emitter.setSpeedVar(300);
      emitter.setDuration(2.2f);
      emitter.setSpeed(600);
        addChild(emitter);
  }

It works every time when I call this in ccTouchesBegan but calling this from my game loop leads most of the time (but strangely enough not everytime) to the posted exception. Can you tell me what I am probably doing wrong?

Reply to this email directly or view it on GitHub: https://github.com/ZhouWeikuan/cocos2d/issues/38

This is Zhou, Weikuan(周为宽)

ShadowMare commented 12 years ago

Thank you for your reply. It works 100% from ccTouchesBegan, maybe it should indeed be called only from the UIThread.

Another thing is that calling my simple method via CCLayer.schedule() does work from the Game Loop. I am confused!

opengenius commented 12 years ago

Random crashes are almost always caused by multithreding. Let's see: ccTouchesBegan in cocosis not UIThread at all, as schedule, they both are executed in GLThread actually. Your game loop seem to run in another thread (and buffer update is called before buffer is initialzed in deffered task), and this will lead you to lot's off troubles with cocos2d. You should move your logic to some cocos2d scheduling routine.

opengenius commented 12 years ago

and this is some kind of bug too, before each glBufferData we should call buffer.position(0). I can push this fix tomorrow.

ShadowMare commented 12 years ago

Thank you both for your kind help!

texCoords.position(0);  // <-- added
gl.glBufferData(GL11.GL_ARRAY_BUFFER, texCoords.capacity() * 4, texCoords.bytes, GL11.GL_DYNAMIC_DRAW);

This helps! (Additionally: I will try to move my game logic to a cocos2d thread as soon as I have figured out how ;))