Community RPG Developer’s Diary, Part One

First, I want to congratulate all the coders, level designers, and artists who are collaborating to make Quexlor: Lands of Fate a fun RPG! You guys have already started making your maps and have discovered and fixed a few bugs. Way to go! There’s quite a few community members I will be thanking throughout this post.

I want to start documenting the progress on our game with a developer’s diary. This will be the first post. It will go into detail about how some of the new items and effects were made. Get ready to explore the ambience effect, doors, and counters.

Community Project Example Level
This Level Map (lof-example.tmx) Illustrates Some of the New Items and Effects

Ambience

Think about making an audio ambience effect. All it does is play a sound file with proximity to the player. It’s got to have a few properties that it loads from the TMX level file like the sound file to play, the radius of the ambience, and whether or not to loop it. Once we’ve got the properties loaded it’s simply a matter of coding an update method to play the sound file when the player walks within the radius and to vary the volume while the player is close enough.

To emulate decibels, a logarithmic curve could be applied to the sound’s volume based on distance. Or it could be linear. It all depended on what felt better. This particular case depended on how the CocosDenshion sound engine (a part of Cocos2D and included in the iPhone Game Kit) handles volume. Is it in decibels already?

After creating a “birds chirping” sound loop based on a wonderful effect submitted by users of Freesound.org, the first ambience was born. It turned out that using a linear volume drop-off sounded best. However, a hurdle had to be overcome. CocosDenshion had no way of changing a sound’s volume once it had been played.

This had actually been nagging at me for quite some time. How to change an already-playing sound’s volume on an iPhone? The clue was in the OpenAL ALuint sound identifier which was returned from CocosDension’s playSound method.

After digging through CocosDension for a bit, it became apparent that indeed it’s quite easy to mess with an already-playing sound. I added the following method to the iPhone Game Kit’s Sound layer to be able to change a sound’s volume on the fly. This method was then utilized to make ambiences sound silky smooth.


-(void) setVolume:(ALuint)fx volume:(ALfloat)volume
{
	alSourcef(fx, AL_GAIN, volume > 1.0f ? 1.0f : (volume < 0.0f ? 0.0f : volume));
}

After releasing the iPhone Game Kit 3.2, the community found a little bug with the ambiences. The sound kept on playing even after the player had switched from one level to another. Hat tip to stahlmanDesign for finding the bug and CyberGreg for fixing it so quick! Here's the method CyberGreg submitted which stops the ambience playing when the old level is destroyed:


-(void) onExit
{
	[super onExit];
	// stop the ambience because of TMX unloading
	if( ambience != CD_MUTE )
	{
		[[Sound get] stopSound:ambience];
		NSLog(@"Stopped playing ambience %@", soundName);
		ambience = CD_MUTE;
	}
}

Doors

Doors are a pretty simple concept. The player gathers a key and then swings his sword at a door to open it. If the player doesn't have a key a "this ain't workin" sound effect is played. If he does have a key then it is decremented from his inventory and the door opens with a poof of smoke.

The biggest challenge I ran into regarding making doors was one of bounding boxes and anchor points. When I first made a door, put it inside a level, and walked up next to it there seemed to be a small issue with the door image being higher than the collision bounding box. To start debugging this issue, I added the following method to the LevelObject class which draws a white square around each level object and a red circle around the attack point for characters. (The red attack point was added later when I was debugging touch-based movement.)


-(void) draw
{
	CGPoint points[4];
	[self getCorners:points dest:CGPointZero];
	glLineWidth(2.0f);
	glColor4f(1, 1, 1, 1);
	ccDrawPoly(points, 4, YES);
	// draw attack point
	if( [self isKindOf:@"Character"] )
	{
		Character* c = (Character*)self;
		if( [c isAttacking] )
		{
			CGPoint p = [c getAttackPoint];
			p = ccpSub(p, [c position]);
			glColor4f(1, 0, 0, 1);
			ccDrawCircle(p, 3.0f, 0.0f, 8, NO);
		}
	}
	// reset line width & color as to not interfere with draw code in other nodes that draw lines
	glLineWidth(1.0f);
	glColor4f(1, 1, 1, 1);
	[super draw];
}

This made everything clear. Back when I first wrote the QuexlorLite game I had messed with each LevelObject's collision bounding box. It was shifted upwards to account for characters appearing taller than their actual collision box. This was now causing a problem with the doors because they also inherit from LevelObject.

Think about the collision boxes. It wasn't very natural for the hero's head to collide with rocks above him. To give the 3D feel, the box worked best as a smaller rectangle aligning more with the hero's feet. Check out this screenshot to see where the natural-feeling collision boxes fall:

Sprite Collision Boxes
Showing Sprite Collision Boxes With an Overridden draw Method

To fix the doors it became clear that not all level objects required messing with the collision box. The code managing the extent of the boxes was refactored and anchorPoints were used to shift the Character sprites a little higher. Using anchor points had been on my list for awhile anyway. It was the "proper" thing to do.


// create sprite
sprite = [[CCZSprite spriteWithSpriteFrame:[profile getSpriteFrame:@"standing" index:0]] retain];
// move the anchor point a little lower to make the character seem taller
sprite.anchorPoint = ccp(0.5f, 0.31f);

Counters

Remember the game Zelda? Sometimes you get locked in a room and have to defeat all the monsters before a door magically opens. We wanted our community RPG to have this feature and it was actually really, really, really easy to implement.

Open up your 3.2 Kit's Quexlor/art/lof-example.tmx to follow along, or see the screenshot at the top of this post.

There are two skeletons locked inside a small room. A door blocks the way into the room and another door blocks the way to a final room with a big chest. The first door has no special properties and it opens with a regular key. The second door, however, has a few tricks up its sleeve and will not open with a key. Its tricks are the properties counter=alpha and count=2. This means the door opens only after its counter (codename alpha) has been decremented twice.

But how does the door's counter get decremented? Both of the skeletons have a special property counter=alpha that corresponds with the door. When an enemy dies a piece of code looks for a door with the corresponding counter. If a door is found, then its count is decremented. Here's the code that makes that happen:


// reduce counter
if( counter != nil )
{
	for( Door* door in [[self getLevel] children] )
	{
		if( [door isKindOf:@"Door"]
		&& [door hitCounter:counter] )
			break;
	}
}

Simple, eh? You just give the enemies a counter property and the door the same counter as well as a count.

I hope the counter object makes designing your levels a bit more fun!

Credits

Thanks to Mow-Mow for noticing another little bug. The flame animation accidentally had a white background. It's fixed.

Thanks again to stahlmanDesign for proposing to name all level objects so they can be easily identified at a glance. Thanks to CyberGreg for organizing all the level filenames, and thanks to juancasanueva for taking the reins with the troll AI. Props to everybody, and congratulations community for all the positive collaboration!

That's all for now.

Comments

Leave a Reply


− two = 3

Subscribe via email

Subscribe in a reader


iPhone Game Creation for Beginners

Learn to make games by example, using the actual source code to a published title. You'll understand Xcode, Objective C, the iOS SDK and start your own game project. Includes an ebook and bonus art package full of thousands of royalty-free graphics.
More info…


Quexlor Action-RPG Engine Code And Tutorial for iOS

Rapidly create your own action, RPG, adventure or RTS game with this complete starter kit. Includes a drag-and-drop ready RPG engine, complete example game project, a helpful ebook tutorial and a gigantic royalty-free art package.
More info…

Featured Posts

5 Cocos2D iPhone Game Source Code Kits to Revolutionize Your Game Development - 4/5/12

How to Make Games With the iPhone Game Kit 5.0 - 2/19/12

Learn to Make iPhone Games with the iPhone Game Kit 4.0 - 12/10/11

The Cocos2D Family of Game Engines, Their Platforms & Languages - 11/2/11

Game Design Lessons: Introducing Flow - 9/23/11

What is Cocos2D and Why is it One of the Best iPhone Game Engines? - 6/3/11

Community RPG Developer’s Diary, Part One - 1/20/11

CCZSprite and HudLevelSprite, Two Cocos2D Extensions You Need to Know About - 8/10/10

How to Program Dpad Joystick Touch Controls for iPhone Games - 6/7/10

Other Posts

An Awesome Review of our RPG Engine from a Customer - 4/26/12

Making Cross-Platform iPhone & Android Games – Don’t Get Left Behind! - 4/16/12

ShakeMidi: A Wireless MIDI Controller That You Can Shake - 12/1/11

Download Monster Checkers Updated Source Code Soon - 7/29/11

iPhone Game Kit Discussed on the Cocos2D Podcast - 7/8/11

New iPhone Game Kit 3.4 Update - 4/28/11

Quexlor LoF Hits the App Store - 4/8/11

The iPhone Game Kit Community Project – A Newcomer’s Perspective - 3/29/11

AI: What Cocos2D Cannot Do - 2/9/11

Cocos2D Community Game, Developer’s Diary, Part Two - 1/28/11

3.2 Kit is Out, Cocos2D 0.99.5 Compatible - 1/13/11

3.1 Kit is Out! Let’s Start the Community RPG - 12/9/10

Develop the Game Kit’s Community RPG and be a part of gaming history! - 11/23/10

iPhone Game Kit 3.0 Released - 10/14/10

New Game Added to the iPhone Game Kit! - 9/21/10

New Tiled Map Editor 0.5.1 Works Like a Charm! - 9/10/10

Four Interesting Things We Are Working To Improve The iPhone Game Kit - 8/25/10

iOS4 Compatible iPhone or iPad Game Source Code - 8/2/10

Making High Resolution Graphics For iPad and iPhone4 Games - 7/16/10

Game Starter Kits


iPhone Game Creation for Beginners

Learn to make games by example, using the actual source code to a published title. You'll understand Xcode, Objective C, the iOS SDK and start your own game project. Includes an ebook and bonus art package full of thousands of royalty-free graphics.
More Info...

Quexlor Action-RPG Engine Code And Tutorial for iOS

Rapidly create your own action, RPG, adventure or RTS game with this complete starter kit. Includes a drag-and-drop ready RPG engine, complete example game project, a helpful ebook tutorial and a gigantic royalty-free art package.
More Info...