cocos2D iOS tutorial 5

November 4, 2011

Tutorial 5A: State Machine

Let’s create a StateMachine class that controls the behaviour (BaseState) of GameObject. Each GameObject should have at least one state machine. You can use 3 buttons to change the behaviour of a game object. For now, just create one object to test your StateMachine class.

Note that there are multiple files here.

Sample code 1

BaseState.h
@class StateMachine
@interface BaseState : NSObject {
NSString *myName; //name of state
StateMachine *mySM; //the state machine this state belongs to
}
@property(nonatomic, readonly) NSString *myName;

@property(nonatomic, readonly) StateMachine *mySM;

- (id)initWithName:(NSString *)name stateMachine:(StateMachine *)sm;
- (void)enter;
- (void)update:(float)dt;
- (void)exit;
@end
BaseState.m
#include “StateMachine.h”
@implementation
@synthesize myName, mySM;
- (id)initWithName:(NSString *)name stateMachine:(StateMachine *)sm {
if((self = [super init])) {
myName = name;
mySM = sm;
[mySM addState:self];
}
return self;
}
- (void)enter {
}
- (void)update:(float)dt {
}
- (void)exit {
}
@end
StateMachine.h
#include “BaseState.h”
@class GameObject
@interface StateMachine : NSObject {
BaseState *currState; //current state that is running
BaseState *nextState; //the next state to run
NSMutableDictionary *stateList; //to store all states
GameObject *myGO; //the game object this state machine belongs to
}
@property(nonatomic, readonly) GameObject *myGO;
- (id)initWithGO:(GameObject *)go;
- (void)addState:(BaseState *)state;
- (void)setInitialState:(NSString *)name;
- (void)setNextState:(NSString *)name;
- (void)enter;
- (void)update:(float)dt;
- (void)exit;
@end
StateMachine.m
@implementation
@synthesize myGO;
- (id)initWithGO:(GameObject *)go {
if((self = [super init])) {
myGO = go;
stateList = [[NSMutableDictionary alloc] initWithCapacity:1];
}
return self;
}
- (void)dealloc {
[stateList release]; //anything we alloc in this file, we must release ourselves. In general, no alloc = no release
[super dealloc];
}
- (void)addState:(BaseState *)state {
[stateList setObject:state forKey:state.myName];
if(currState == nil)
currState = nextState = state;
}
- (void)setInitialState:(NSString *)name {
BaseState *state = [stateList objectForKey:name];
if(state != nil) {
currState = nextState = state;
}
}
- (void)setNextState:(NSString *)name {
BaseState *state = [stateList objectForKey:name];
if(state != nil) {
nextState = state;
}
- (void)enter {
[currState enter];
}
- (void)update:(float)dt {
if(nextState != currState) {
[currState exit];
currState = nextState;
[currState enter];
}
[currState update:dt];
}
- (void)exit {
[currState exit];
}
@end
LeftRightState.h
@interface LeftRightState : BaseState {
}
@end
LeftRightState.m
@implementation
- (void)update:(float)dt {
static float timer = 0;
static float vel = 50;
timer += dt;
if(timer >= 1.0) {
timer -= 1.0;
vel = -vel;
}
self.mySM.myGO.position = vel * dt;
}
@end
RoundAboutState.h
@interface RoundAboutState : BaseState {
CGPoint centerP; //RounAboutState specific member variable
}
@end
RoundAboutState.m
@implementation
- (void)enter {
centerP = ccp(self.mySM.myGO.position.x – 50, self.mySM.myGO.position.y);
}
- (void)update:(float)dt {
static float timer = 0;
static float vel = 50;
timer += dt;
self.mySM.myGO.position = ccp(centerP.x + 50 * cos(timer), centerP.y + 50 * sin(timer));
}
@end
GameScene.m
@include “GameData.h”
- (void)init {
//your scene initialization
//GameObject initialization
go = [[GameObject alloc] init…]; //declared in GameScene.h
StateMachine *sm = [[StateMachine alloc] initWithGO:go];
BaseState *state = [[LeftRightState alloc] initWithName:@”leftright” stateMachine:sm];

state = [[RoundAboutState alloc] initWithName:@”roundabout” stateMachine:sm];

//create 3 buttons with doSomethingOne/Two/Three
}
- (void)doSomethingOne {
[go.sm setNextState:@"leftright"];
}
- (void)doSomethingTwo {
[go.sm setNextState:@"roundabout"];
}
- (void)doSomethingThree {
[go.sm setNextState:@"_your_own_state"];
}
- (void)update:(float)dt {
[go.sm update];
}
//remember to dealloc your go, sm and states!
@end

cocos2D iOS tutorial 4

November 4, 2011

Tutorial 4A: Shared Data Singleton

Create a class call GameData (inherit from NSObject) that is to be shared across the game, between multiple scenes. GameData should contain member variables such as player’s life, score, level, experience points, gold, state and so on. These data are persistent throughout the game and not just in a scene (those local data only used in a scene should be under the scene’s member variable). You may want to store the pointer to your Object Manager in GameData, so that it can be used in multiple scenes.

Sample code 1

GameData.h
@interface GameData : NSObject {
int hp;
int score;
int level;
int xp;
int gold;
int state;
};
@property(nonatomic) int hp;

+ (GameData *)sharedData;
@end

GameData.m
static GameData *data = nil;
@implementation GameData
+ (GameData *)sharedData {
if(data == nil) {
data = [[GameData alloc] init];
gold = 100;
hp = 20;
score = 0;

}
return data;
}

@end


cocos2D iOS tutorial 3

November 3, 2011

Tutorial 3A: Game Object

GameObject are the screen objects found in our game. They can be player, enemies, gold coins, obstacles, exits and so on.

At this stage, your game object will probably be a CCSprite with no other information. Nevertheless, you should put the CCSprite class into a GameObject class and add some other variables like float speed, int type, bool active, etc.

Tutorial 3B: Game Object Manager

Multiple instances (e.g. 30x) of GameObject class (inherit from CCNode) should be pre-allocated and store in a Game Object Manager (ObjectManager) class, using an NSMutableArray. Every time you need a GameObject, simply request one from ObjectManager, i.e. [om getObjectOfType:type]. This is to move the object allocation task from runtime to load time.

In the scene, let’s assume you have 3 buttons on the screen. Touching each button will get the object of a corresponding type from the object manager, add it to the scene and move it. The object will drop from the top to the bottom of the screen at a random speed. When it falls out of the screen, set the object.active to NO and remove from the scene such that it is released back to the ObjectManager.


cocos2D iOS tutorial 2

November 3, 2011

[iOS device required]

Tutorial 2A(i): Accelerometer

Make use of the iOS devices’ accelerometer. Using a CCSprite and the update:dt method, update the sprite’s position with the accelerometer readings, i.e. when you tilt left/right, the sprite moves left/right; when you tilt up/down, the sprite moves up/down. Both axes should be updated simultaneously. You should turn off the auto screen rotation when you use the accelerometer. Allow your sprite to pass through the side of the screen and appear at the opposite side when it touches the edge.

Tutorial 2A(ii): Direction of sprite

Now that you have a moving sprite, now use a top-view (aero)plane image as your sprite. When you tilt, the plane should also turn towards to the direction of travel.

Tutorial 2A(iii): Velocity and acceleration (Pre-requisite: Vector math)

Note that you might want to store the previous velocity of your plane. To add realism, the plane should not react sharply to the tilt, it should gradually change its velocity. Your plane also should have acceleration. When you tilt the device on one side long enough, it should gradually pick up speed. But remember to cap the speed, otherwise it may go to infinity.


cocos2D iOS tutorial 1

November 3, 2011

Tutorial 1A: Path-finding (how to use update:)

The landscape screen is 480×320 pixels. Sub-divide the screen into grids of 40×40 pixels, and there should be 12 by 8 grids. Find a suitable image for the background.

Using update or nextFrame method, move a sprite from grid ( 1, 1 ) at bottom-left to grid ( 12, 8 ) at top-right, at a constant speed. See below for the path.

O O O O O O G G G O G G
O O G G G O G O G O G O
O O G O G O G O G O G O
O O G O G G G O G O G G
O O G O O O O O G O O G
O O G G G G G O G O O G
O O O O O O G O G G G G
G G G G G G G O O O O O

Tutorial 1B: Touch Input (how to capture touch)

Subdivide the screen into 3×3 grid for a tic-tac-toe game. Use a suitable image for the background. The scene should register 9 touch area. Whenever any of them is touched, ‘O’ or ‘X’ should be shown (alternately, if touched again).


Mahjong HD for iPad is here!

September 10, 2010

Mahjong HD for iPad is here.

The game is based on SG Mahjong, with HD graphics and a new mode – 4 players can play on the iPad simultaneously.

Download on iPad AppStore now


iPhone OS 4.0 RoundTable

April 14, 2010

Local iPhone developers and enthusiasts met over 2 days and trashed out iPhone OS 4.0 features and limitations.

The topics discussed were:

  • Multitasking
  • iAd
  • Game Center
  • Section 3.3.1 on Apple new T & C
  • iPad

With iAd, Apple has become a 1st party advertising network with the advertisement API built into the OS. No doubt Steve Jobs was trying to put across iAd as a new generation ad platform, but existing 3rd party ad network already has many of those features. The ad war will depends more on the advertisers base of each platform. The bigger the advertisers base, the better monetization will be on that platform. The ad quality is not the only factor that matters.

Game Center, the XBox Live of iPhone, will bring social networking functionality. It allows games to connect devices peer2peer, without the need of a game server. This is important for game developers.

And for Section 3.3.1 of the T & C, most of the developers present are in support of Apple. The existing group developers will not benefit with an influx of millions of flash apps.

On the 2nd day of the RoundTable, developers from SomaticContact and gothere.sg brought their iPads along. Woo! The iPads became the spotlight of the conference and SomaticContact has already launched an iPad app called Korean keyboard and is right now No. 1 at the Korean store. We got a preview of Plants vs Zombies HD, iWork apps, Youtube HD, iBooks, Kindle app, mail app, Safari, and so on.

We look forward to more of these sessions soon. Hopefully, we can get more technical discussion in the future. e27 says they will organise a iPad hackathon soon.


SG Mahjong 2.4

April 14, 2010

We have just launched with some bug fixes and new features:

  • Bigger player tiles
  • Unlockable Pays For All mode, a.k.a. true 包 mode
  • Unlockable Unlimited Rounds mode, i.e. play until someone busts
  • Unlockable Higher Starting Money, up to $1000
  • Multiplayer bluetooth stabilized
  • In-app purchase to Unlock All Mode

Please report any bugs you found.

We know that our music and graphics sucks, we are currently looking for free-lancers to help.


KL Mahjong launched

April 4, 2010

KL Mahjong comes to the AppStore! The first game on iPhone & iPod Touch that features Mahjong with Kuala Lumpur / Malaysia rules.

KL Mahjong is the fastest of all Mahjong. Each game should only take 30 seconds.

It features 84 tiles consisting of:
- 36 circle tiles
- 28 honor tiles
- 8 flower tiles
- 4 animal tiles
- 4 face tiles
- 4 joker tiles

Yes, there are 4 jokers in this game!

Other features include:
1) Bluetooth enabled local multiplayer game.
2) Unlockable rounds limit and starting money.
3) Minimum 5 points to win. Double reward on 10 points.
4) Joker, bites & gongs bring extra rewards.
5) Jokers can be swapped back into the hand.

KL吉隆坡麻将第一次来到iPhone!
KL麻将是全世界最快的麻将,每盘游戏30秒。
KL麻将总共有84张牌:
- 36张筒子
- 28张字牌
- 8张花牌
- 4张动物牌
- 4张人头
- 4张飞牌

KL麻将的特征:
1)多人蓝牙系统游戏。
2)最少5台胡牌。10台满,并且奖金x2。
3)飞牌、咬牌、杠牌、胡尾都有钱拿。
4)飞牌碰了字牌可以起飞。

Download KL Mahjong today!

Update: version 1.1 is out. Multiplayer crash bug solved.


Percentage of iPhone connected to Internet per country

January 20, 2010

As iPhone developers, we have access to some very important data in the mobile industry, through our apps. With the launch of our new game Magic Ludo, we’re seeing some interesting trends. For example, Singapore has one of the highest internet enabled iPhone population, while surprisingly US has one of the lowest. See below for some of the countries that came under our radar.

*Internet enabled iPhone means iPhones with data plans or connected via WiFi.

Country Connected Downloaded Percentage
Germany 74 69 107.25
Australia 73 94 77.66
Netherlands 11 17 64.71
Singapore 150 252 59.52
France 41 70 58.57
Denmark 171 297 57.58
Norway 99 176 56.25
Japan 12 22 54.55
Spain 42 82 51.22
United Kingdom 291 580 50.17
Italy 19 43 44.19
Canada 38 91 41.76
United Arab Emirates 11 27 40.74
China 16 42 38.10
Hong Kong 23 61 37.70
United States 183 493 37.12
Pakistan 22 76 28.95
Venezuela 55 216 25.46

Note:

  1. Connected figures are iPhones with Magic Ludo connected to our analytic server, and is based on their IP addresses, while downloaded figures are from AppStore.
  2. There are people in Germany using iTunes account of other countries.

We’ll update this table with more countries once we aggregate them.

52:06.7 1/18/2010 Connected data is via IP addresses, while downloaded data is from AppStore
Country Connected Downloaded Percentage Remarks
Germany 74 69 107.25 There are people in Germany using iTunes account of other countries
Australia 73 94 77.66
Netherlands 11 17 64.71
Singapore 150 252 59.52
France 41 70 58.57
Denmark 171 297 57.58
Norway 99 176 56.25
Japan 12 22 54.55
Spain 42 82 51.22
United Kingdom 291 580 50.17
Italy 19 43 44.19
Canada 38 91 41.76
United Arab Emirates 11 27 40.74
China 16 42 38.10
Hong Kong 23 61 37.70
United States 183 493 37.12
Pakistan 22 76 28.95
Venezuela 55 216 25.46

Follow

Get every new post delivered to your Inbox.