存档

2011年3月 的存档

Help Logically setting up Layers for Good Game Design (involving SpaceManager Physics, Music, and Game Logic)

2011年3月25日 没有评论

Im in the middle of creating my first iPhone game – I have a background in OOP and in particular C++ so I had some questions with regards to how best to logically setup layers while maintaining functionality.

Currently I WANT for my game to have three main layers:

  • HUDLayer (All static objects on the screen are here – game controls, User score, pause button etc.)
  • PlayLayer (The Player, the main game loop and all of the game logic here)
  • Level Layer (The level images and the level physics objects that the player interacts with, and the background music specific to this level)

Notice I used the word WANT here – because for the life of me im constantly having to move logical objects around just to work within what appears to be Cocos2d’s and spacemanagers structure.

Below are just some of the issues that I’m facing

  • I would like for my PlayLayer to be the scene thats loaded by the director – but if I do that then all of the HUDLayer objects get covered behind the PlayLayer, and dont stay in place like they should, hence the HUDLayer is my scene and I have had to do that just to make it work
  • I would like to play the background music (via simpleAudioEngine playBackgroundMusic) in the LEVEL layer because I want different levels to have different music. So far the ONLY way I have gotten background music to work is to have it in the TOP most layer i.e. in this case the HUDLayer
  • Because of the fact that I have to use an instance of the SpaceManagerCocos2d object to create physics bodies – it seems like my level layer has to be killed and just incorporated within my PlayLayer otherwise im having a nightmare of a time attempting to detect collisions between the player and the level.

Am I missing something very obvious here? is there a core understanding of layers that Im just not getting? More and more I feel like im being pushed by the framework to build the whole game inside of a single class and just to use layers as scenes.

Is anyone else having these problems? Am I approaching the architecture of the game wrong? Any help would really be appreciated.

Thanks in advance guys!

Well, each game is different. There are many good discussions on the cocos2d forums about architecture, some people prefer to use an MVC approach, some like using an Actor metaphor to contain physics objects, etc.

Here’s my approach:

  1. Use two CCLayer objects (GameLayer and HUDLayer) as child nodes of one CCScene (GameScene). These are the “view” objects.
  2. Create a GameController singleton that can make changes to the game state (also stored in GameController, or in a separate file.) You could also subclass CCScene and call that your controller.
  3. GameLayer is in charge of rendering the graphics of the game level and all actors in it; it also handles getting game input via touch events.
  4. HUDLayer is placed at a higher z-index than the GameLayer and obviously has all of the CCSprite objects for the HUD and buttons.
  5. Interaction between the HUDLayer and the GameLayer is managed via the GameController.
  6. GameController does all of the state changing and game actions.

That’s just my approach because it worked for my current game, and it by no means is the definitive answer.

I’d suggest that you look into using an Actor paradigm for your physics objects — SpaceManager does a decent job, but you don’t necessarily always want physics objects to extend CCSprite.

分类: cocos2d, stackoverflow精选 标签:

Android games development SDK? [closed]

2011年3月19日 没有评论

Can someone recommend a widely used free/open source game API/ GameEngine for the android platform?

I think you meant for a good open source and free to use Gaming Engine for the Android Platform. Well there are many free and open source gaming engines now available, but they are still a work in progress. At the moment I’ll recommend you to use AndEngine Gaming Engine for the Android.

AndEngine Gaming Engine for the Android

Website: http://www.andengine.org

Blog: http://www.andengine.org/blog

Download Source Code:
http://code.google.com/p/andengine/

Tips and Tutorials:
http://theorynine.com/labs/andengine-tips-and-tutorials/

Forum:
http://www.andengine.org/forums/

Features of AndEngine

Free Android 2D OpenGL Game Engine AndEngine is an open source Android game engine project which is a free 2D OpenGL Game Engine for the Android platform. The main features include:

  • Android-Optimized

  • Android 1.6 Compatibility

  • SplitScreen

  • Network Multiplayer

  • Live-Wallpapers

  • MultiTouch

  • Physics-Engine (Box2D)

Other Gaming Engines

1) Rokon: The open source 2D game engine for Android
Rokon is an open source, extensive, powerful and flexible 2D game engine for Android. Rokon has been rewritten from the ground up. Many more features are integrated, and the future promises a lot of things. Examples, tutorials and documentation will follow this release. Rokon is an open source (New BSD license) 2D OpenGL game engine for Android. With the help of libgdx and Box2D the developers bring you a full, detailed physics engine written in native code.

Project home: http://rokonandroid.com/ and http://code.google.com/p/rokon/

2) Libgdx: Android game development framework
Libgdx is an open source Android project which is the developer’s attempt at a cross-platform game development library written in Java with some JNI code for performance hungry sections. It abstracts away the differences between writting desktop and Android games based on OpenGL. This allows you to prototype and develop your application entirely on the desktop and only needing 6 lines of code to make it run on Android.

Project home: http://code.google.com/p/libgdx/

3) Android-2D-Engine: Engine for 2d games written for android in c++/java
Android-2d-engine is an open source Android 2D game engine which is currently under construction, the project born for serve as base for games. Actually there are two projects:
trunk/bullet: Contains the c++ source code for bullet and the jni class to communicate with android. This code is not really needed since the sample contains the compiled lib.
trunk/androgine: Contains the rest of the code needed to communicate with bullet plus a sample with profiling purposes.

Project home: http://code.google.com/p/android-2d-engine/

4) jMonkeyEngine: jMonkey Engine (jME) is a leading Java Based 3D Game Engine

jMonkey Engine (jME) is a high-performance 3D game engine, written entirely in Java. OpenGL is supported via LWJGL, with JOGL support in development. For sound, OpenAL is supported. Input via the keyboard, mouse, and other controllers is also supported.

jME is a community-driven open source project released under the ‘new BSD license’. It is currently being used by several commercial game studios as well as by university game classes. While the project will continue to support and develop its most popular 2.0 branch for years still to come, a 3.0 branch is quickly emerging in response to higher standards of the next generation in performance and hardware.

Now, Android platform has been surpported by jME3: Android Support Confirmed for jME3. So jMonkeyEngine may be one of the most important Android game engines.

Project home:
http://code.google.com/p/jmonkeyengine/

http://www.jmonkeyengine.com/

5). Cocos2d-android: A framework for building 2D games for the Android platform.

Cocos2d for Android is an open source Android game related project which is a framework for building 2D games, demos and other graphical/interactive applications. It is based on the cocos2d-iphone design: it uses the same API, but instead of using objective-c, it uses Java. And Cocos2d for iPhone is a framework for building 2D games, demos, and other graphical/interactive applications. It is based on the cocos2d design: it uses the same API, but instead of using python it uses objective-c.

Project Home: http://code.google.com/p/cocos2d-android/

分类: cocos2d, stackoverflow精选 标签:

dealloc not fired when replacing scenes in Cocos2d

2011年3月8日 没有评论

For some reason the dealloc of my CCLayer is not fired when replacing the scene. Here is the code to replace the scene:

[[CCDirector sharedDirector] replaceScene:[CCFadeTransition transitionWithDuration:2.0f scene:[HelloWorld scene]]];

The above code is triggered when I press a button.

I have placed a NSLog inside the dealloc method which is never triggered.

UPDATE 1:

I ended up solving the problem by manually releasing the memory just before replacing the scene.

When I first time begun to use cocos2d I had encountered this exactly same problem.
In my case I’m added as targeted delegate the self and that means that reference count to the self was increased.


[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:2]swallowsTouches:NO];

And I solved this by removing all delegates(also you can specify particular delegate) :


[[CCTouchDispatcher sharedDispatcher] removeAllDelegates];

According to this post at cocos2d-iphone forum, you just need to call self.isTouchEnabled = YES; in the init method to enable Cocos2D’s to automatically call removeDelegate: method on the CCTouchDispatcher. Basically the following code should suffice:

- (void)init {
   // do the usual [super init] stuff


   self.isTouchEnabled = YES; // don't forget the self prefix!

   return self;
}

- (void)registerWithTouchDispatcher {
   [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:2 swallowsTouches:NO]; 
}

No need for onEnter and onExit as they should be handled automatically if you use self.isTouchEnabled = YES;

分类: stackoverflow精选, unity3d 标签:

How to wait finish current audio for playing next audio?

2011年3月3日 没有评论

I’m working with cocos2d. How to wait finish current audio for playing next audio? I can’t make it with SimpleAudioEngine.

http://www.cocos2d-iphone.org/api-ref/0.99.0/interface_c_d_sound_engine.html

use CDAudioEngine. It have the method you want. By the way SimpleAudioEngine is using CDAudioEngine to play sounds.

EDIT

When your button is clicked first time – play the sound and save the sound’s interval to some of your lass variable. Then in next click use this variable to determine the “enough interval”. Or just use some maximum.

EDIT 2
If you’ll take a look at SimpleAudioEngine implementation you will notice that it’s using CDSoundEngine to play sounds. Here is the init method of SimpleAudioEngine:

static SimpleAudioEngine *sharedEngine = nil;
static CDSoundEngine* soundEngine = nil;
static CDAudioManager *am = nil;
static CDBufferManager *bufferManager = nil;


-(id) init
{
    if((self=[super init])) {
        am = [CDAudioManager sharedManager];
        soundEngine = am.soundEngine;
        bufferManager = [[CDBufferManager alloc] initWithEngine:soundEngine];
        mute_ = NO;
        enabled_ = YES;
    }
    return self;
}

So we can also access to CDSoundEngine:

CDSoundEngine *engine = [CDAudioManager sharedManager].soundEngine;

When calling playEffect method on SimpleAudioEngine (when your button is clicked) save the returned sound id.

ALuint soundId = [[SimpleAudioEngine sharedEngine] playEffect:...];

Now we can get the interval using our CDSoundEngine:

float seconds = [engine bufferDurationInSeconds:soundId];

That’s the answer!

By the way you can also stop a sound with CDSoundEngine if you know the sound id.

From CocosDenshion.h

@class CDSoundSource;
@interface CDSoundEngine : NSObject <CDAudioInterruptProtocol> {

    bufferInfo      *_buffers;
    sourceInfo      *_sources;
    sourceGroup     *_sourceGroups;
    ALCcontext      *context;
    int             _sourceGroupTotal;
    UInt32          _audioSessionCategory;
    BOOL            _handleAudioSession;
    BOOL            mute_;
    BOOL            enabled_;
    ALfloat         _preMuteGain;

    ALenum          lastErrorCode_;
    BOOL            functioning_;
    float           asynchLoadProgress_;
    BOOL            getGainWorks_;

    //For managing dynamic allocation of sources and buffers
    int sourceTotal_;
    int bufferTotal;

}

@property (readwrite, nonatomic) ALfloat masterGain;
@property (readonly)  ALenum lastErrorCode;//Last OpenAL error code that was generated
@property (readonly)  BOOL functioning;//Is the sound engine functioning
@property (readwrite) float asynchLoadProgress;
@property (readonly)  BOOL getGainWorks;//Does getting the gain for a source work
/** Total number of sources available */
@property (readonly) int sourceTotal;
/** Total number of source groups that have been defined */
@property (readonly) int sourceGroupTotal;

/** Sets the sample rate for the audio mixer. For best performance this should match the sample rate of your audio content */
+(void) setMixerSampleRate:(Float32) sampleRate;

/** Initializes the engine with a group definition and a total number of groups */
-(id)init;

/** Plays a sound in a channel group with a pitch, pan and gain. The sound could played looped or not */
-(ALuint) playSound:(int) soundId sourceGroupId:(int)sourceGroupId pitch:(float) pitch pan:(float) pan gain:(float) gain loop:(BOOL) loop;

/** Creates and returns a sound source object for the specified sound within the specified source group.
 */
-(CDSoundSource *) soundSourceForSound:(int) soundId sourceGroupId:(int) sourceGroupId;

/** Stops playing a sound */
- (void) stopSound:(ALuint) sourceId;
/** Stops playing a source group */
- (void) stopSourceGroup:(int) sourceGroupId;
/** Stops all playing sounds */
-(void) stopAllSounds;
-(void) defineSourceGroups:(NSArray*) sourceGroupDefinitions;
-(void) defineSourceGroups:(int[]) sourceGroupDefinitions total:(int) total;
-(void) setSourceGroupNonInterruptible:(int) sourceGroupId isNonInterruptible:(BOOL) isNonInterruptible;
-(void) setSourceGroupEnabled:(int) sourceGroupId enabled:(BOOL) enabled;
-(BOOL) sourceGroupEnabled:(int) sourceGroupId;
-(BOOL) loadBufferFromData:(int) soundId soundData:(ALvoid*) soundData format:(ALenum) format size:(ALsizei) size freq:(ALsizei) freq;
-(BOOL) loadBuffer:(int) soundId filePath:(NSString*) filePath;
-(void) loadBuffersAsynchronously:(NSArray *) loadRequests;
-(BOOL) unloadBuffer:(int) soundId;
-(ALCcontext *) openALContext;

/** Returns the duration of the buffer in seconds or a negative value if the buffer id is invalid */
-(float) bufferDurationInSeconds:(int) soundId;
/** Returns the size of the buffer in bytes or a negative value if the buffer id is invalid */
-(ALsizei) bufferSizeInBytes:(int) soundId;
/** Returns the sampling frequency of the buffer in hertz or a negative value if the buffer id is invalid */
-(ALsizei) bufferFrequencyInHertz:(int) soundId;

/** Used internally, never call unless you know what you are doing */
-(void) _soundSourcePreRelease:(CDSoundSource *) soundSource;

@end

I’m using cocos2D 0.99.5

implementation:

-(float) bufferDurationInSeconds:(int) soundId {
    if ([self validateBufferId:soundId]) {
        float factor = 0.0f;
        switch (_buffers[soundId].format) {
            case AL_FORMAT_MONO8:
                factor = 1.0f;
                break;
            case AL_FORMAT_MONO16:
                factor = 0.5f;
                break;
            case AL_FORMAT_STEREO8:
                factor = 0.5f;
                break;
            case AL_FORMAT_STEREO16:
                factor = 0.25f;
                break;
        }   
        return (float)_buffers[soundId].sizeInBytes/(float)_buffers[soundId].frequencyInHertz * factor;
    } else {
        return -1.0f;
    }   
}

// to Play the sound
Aluint soundID = [[SimpleAudioEngine sharedEngine] playEffect:@”sound.mp3″];

// to stop the sound you need to use the same soundID when you play it
[[SimpleAudioEngine sharedEngine] stopEffect:soundID];

分类: cocos2d, stackoverflow精选 标签: