My online tech scrapbook where I keep my notes in case I need to look them up later
Wednesday, November 6, 2013
Hosting a Static Website on AWS S3
Step by step guide provided by AWS here: http://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html
MongoDB vs MongoLab for Early Stage Live Apps
MongoDB and MongoLab are the 2 main MongoDB hosted service providers who provide their servers within the AWS network and in all regions. For a startup just going live with a new product, volume is initially expected to be low but HA may also be a requirement. Obviously cost is also an issue.
With these in mind the shared instances sound like the way to go, unfortunately with MongoLab this option is not available in all AWS regions. It also comes at a big jump in price from the single server shared plan (i.e. $15 -> $89 for same storage). Bump up the budget to $200 a month and you can get a dedicated instance with much more storage and dedicated RAM. With MongoHQ it gets worse with no cluster / replica-set options available.
So moving on to dedicated instances, MongoLab provides cluster / replica-set options for as little as $200 a month, while MongoHQ doesn't do so until you reach the $1345 a month price plan. For a startup just starting out trying to save costs and not wanting to compromise on HA, seems like MongoLab is the obvious choice purely basing on the packages and price plans.
References:
With these in mind the shared instances sound like the way to go, unfortunately with MongoLab this option is not available in all AWS regions. It also comes at a big jump in price from the single server shared plan (i.e. $15 -> $89 for same storage). Bump up the budget to $200 a month and you can get a dedicated instance with much more storage and dedicated RAM. With MongoHQ it gets worse with no cluster / replica-set options available.
So moving on to dedicated instances, MongoLab provides cluster / replica-set options for as little as $200 a month, while MongoHQ doesn't do so until you reach the $1345 a month price plan. For a startup just starting out trying to save costs and not wanting to compromise on HA, seems like MongoLab is the obvious choice purely basing on the packages and price plans.
References:
DynamoDB Hash and Range
Hash doesn't have to be unique if "Hash and Range" PK is selected. In this case, it is used for evenly sharding the data under-the-hood.
However, the Hash and Range combination should be unique (not mentioned specifically but obvious and implied).
More details in the following references:
However, the Hash and Range combination should be unique (not mentioned specifically but obvious and implied).
More details in the following references:
Handling Complex Objects in DynamoDB
Apparently AWS's Java APIs provide means to handle this.
Link: https://java.awsblog.com/post/Tx1K7U34AOZBLJ2/Using-Custom-Marshallers-to-Store-Complex-Objects-in-Amazon-DynamoDB
Link: https://java.awsblog.com/post/Tx1K7U34AOZBLJ2/Using-Custom-Marshallers-to-Store-Complex-Objects-in-Amazon-DynamoDB
Articles With Comparison Between DynamoDB and MongoDB (Part 2)
Tuesday, November 5, 2013
Cocos2D-X: Drawing Rectangle with Border
This needs to be done in 2 draws, one to draw the border and the other to draw a solid rectangle.
Example code:
p1 being the bottom left corner of the rectangle and p2 being the top right.
In order for this to be called, the function needs to be override the "draw" function of the parent.
Example code:
void MyLayer::draw()
{
CCPoint p1 = ccp(x1,y1); CCPoint p2 = ccp(x2,y2);
ccColor4F color;
color.a = 1.0;
color.r = 0;
color.g = 0;
color.b = 0;
ccDrawSolidRect(p1,p2, color);
ccDrawColor4B(255, 255, 255, 255);
ccDrawRect(p1,p2);
}
|
p1 being the bottom left corner of the rectangle and p2 being the top right.
In order for this to be called, the function needs to be override the "draw" function of the parent.
Thursday, October 31, 2013
Cocos2D-X: Useful Code Saving Memory Management Macros
CC_SAFE_RELEASE: Checks whether the object is valid before calling "release" on it.
CC_SAFE_RELEASE_NULL: Checks whether the object is valid before calling "release" on it, and then also sets the variable to NULL.
CC_SAFE_RETAIN: Use when it's possible that the return value from a function can be NULL and you don't want to call retain on a NULL value.
#define CC_SAFE_RELEASE(p) do { if(p) { (p)->release(); } } while(0)
#define CC_SAFE_RELEASE_NULL(p) do { if(p) { (p)->release(); (p) = 0; } } while(0)
#define CC_SAFE_RETAIN(p) do { if(p) { (p)->retain(); } } while(0) |
Wednesday, October 30, 2013
iOS Autorelease After Creating New Object
It is recommended to call "autorelease" after create a new object via the "new" operator (or any other method that leaves the retain count set at 1 but doesn't call "autorelease"). This is because after a "new" operator, the retain count of the object is set to "1" to ensure that it doesn't get destroyed. If "autorelease" is not called, the object will continue to take up memory until "release" is called on the object. Calling "autorelease" will ensure that the object's retain count is set to reduced by one (important!) after the current event loop is completed and the autorelease pool is drained. This means that if "retain" is called subsequently, the object will still not be destroyed if that is not matched with a corresponding "release".
Note: I ran my tests on Cocos2D-X's implementation of the autorelease pool system but as I understand, it behaves the same as the iOS one.
References:
Note: I ran my tests on Cocos2D-X's implementation of the autorelease pool system but as I understand, it behaves the same as the iOS one.
References:
- http://stackoverflow.com/questions/2076402/what-is-the-difference-between-releasing-and-autoreleasing
- https://developer.apple.com/library/mac/DOCUMENTATION/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html#//apple_ref/doc/uid/10000011-SW1
- http://www.cocoanetics.com/2009/08/understanding-autoreleasing/
Cocos2D Cropping Sprites
Useful trick for features like graphical health bars etc.
Reference: http://www.cocos2d-x.org/forums/6/topics/32721
theSprite->setTextureRect(CCRectMake(x,y,w,h));
|
Reference: http://www.cocos2d-x.org/forums/6/topics/32721
Cocos2D Draw Order
In summary:
- If within same parent and same Z order, then nodes that are added first will be drawn first, followed by the ones added later in sequence.
- If within the same parent and different Z order, then it's according to Z order. The higher the Z order, the later it will be drawn. Note: negative Z order will be drawn before the parent, and positive Z order will be drawn after the parent.
- If different parents, then the Z order of the parent decides first, then Z order within each parent.
- The only way for nodes with different parents to be ordered with each other independently of parent is using VertexZ. (However, I could not get it to work with Cocos2D-X Isometric tile maps across map layers. I ended up removing all the objects (e.g. buildings) on the other layers in runtime and re-inserting them in the same layer as the other sprites as sprites, and then ordering via Z order.
C++ Static Variables
Other than the usual differences in scope, there are some unique aspects of the syntax that will stump a developer from a Java background.
While instance variables only require declaration in the header file, a static variable in C++ needs to be declared twice, once in the header file and another in the CPP file. Otherwise you'll get a linker error.
See here for example: http://stackoverflow.com/questions/9282354/static-variable-link-error
While instance variables only require declaration in the header file, a static variable in C++ needs to be declared twice, once in the header file and another in the CPP file. Otherwise you'll get a linker error.
See here for example: http://stackoverflow.com/questions/9282354/static-variable-link-error
Wednesday, October 23, 2013
Cocos2D-X: Tile Map Layer Empty Gotcha
With Cocos2D-X, if you leave a layer with no tiles, there will be a crash that look like this:
This is due to the CCTexture2D object being undefined when initialising the layer. This can occur when the layer does not have a tile defined.
It is sometimes necessary to have a layer with no tiles defined initially and then define them in code during runtime. However, due to this crash, it is necessary to define those tiles and remove them in code prior to the game starting. Same problem might happen in Cocos2D also.
bool CCTexture2D::hasPremultipliedAlpha()
{
return m_bHasPremultipliedAlpha; <-------- EXC_BAD_ACCESS HERE
}
|
This is due to the CCTexture2D object being undefined when initialising the layer. This can occur when the layer does not have a tile defined.
It is sometimes necessary to have a layer with no tiles defined initially and then define them in code during runtime. However, due to this crash, it is necessary to define those tiles and remove them in code prior to the game starting. Same problem might happen in Cocos2D also.
Tuesday, October 22, 2013
Cocos2D: Checking if Animation Currently Running
Check that "bear->numberOfRunningActions()" returns 0.
Reference: http://stackoverflow.com/questions/12582481/check-if-animation-is-running-in-cocos2d-x
Reference: http://stackoverflow.com/questions/12582481/check-if-animation-is-running-in-cocos2d-x
Cocos2D Sprite Sheets: To Use CCSpriteBatchNode Or Not
Examples such as the one here use CCSpriteBatchNode as it is apparently some form of "best practice" to do so due to apparent performance benefits by batching draw operations.
However, the benefits of doing this is debatable, with the following articles claiming only marginal benefits in most use cases, and with significant benefits only in certain situations:
However, the benefits of doing this is debatable, with the following articles claiming only marginal benefits in most use cases, and with significant benefits only in certain situations:
Obviously if using CCSpriteBatchNode is easy then it's a no brainer to use it. But unfortunately it gets pretty complicated when you have a sprite that requires multiple sprite sheets. Rather than to have to figure out how it all has to work, or if it can even work in the first place, it's a pretty straightforward decision instead to not use it.
So from the sprite sheet tutorial, instead of using CCSpriteBatchNode:
- Load all the various sprite sheets into the sharedSpriteFrameCache
- Create one CCAction for every animation sequence using the frame names
- Create a Sprite directly using 1 of the frames
- Call runAction on the sprite whenever a new animation sequence needs to be run
Other References:
Thursday, October 17, 2013
Tiled / Cocos2D: Using Objects
- Go to Tiled, create an object layer
- On the object layer, add objects by using the drawing shapes
- If you are using rectangular shapes to represent tiles, you can open the object properties sub-menu after selecting the object and adjust the position and size to fit perfectly the tile
- Load the map in Cocos2D and read it with the following code (Example is C++ using Cocos2D-X):
CCTMXObjectGroup* objectGroup = map->objectGroupNamed(objGroupName);
CCArray* objects = objectGroup->getObjects();
CCDictionary* objectAsDict;
CCObject* obj;
CCARRAY_FOREACH(objects, obj)
{
objectAsDict = (CCDictionary*)obj;
if(!objectAsDict)
{
break;
}
const char* key = "x";
int x = ((CCString*)objectAsDict->objectForKey(key))->intValue();
key = "y";
int y = ((CCString*)objectAsDict->objectForKey(key))->intValue();
key = "width";
int width = ((CCString*)objectAsDict->objectForKey(key))->intValue();
key = "height";
int height = ((CCString*)objectAsDict->objectForKey(key))->intValue();
// figure out which tiles are covered the rectangle here
}
|
Note that the coordinates for the rectangle are based on the coordinate system of an ortho tile map (with origin at bottom left). If you are using an iso tile map in Cocos2D, the origin is at the top of the diamond. You'll have to do the necessary conversion.
Cocos2D Sprite Sheets
Guide: http://www.raywenderlich.com/32045/how-to-use-animations-and-sprite-sheets-in-cocos2d-2-x
This is based on sprite sheets generated by Texture Packer, which will also generate plist files for each frame, and also uses offset to minimize white space.
I had to change the following before I could get this to work in Cocos2D-X 2.2.0
Cocos2D-X didn't accept the "CCSpriteFrame" entered here. It was expected "CCAnimationFrame" objects. As such, I had to do this:
This is based on sprite sheets generated by Texture Packer, which will also generate plist files for each frame, and also uses offset to minimize white space.
I had to change the following before I could get this to work in Cocos2D-X 2.2.0
[walkAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:@"bear%d.png",i]]];
|
Cocos2D-X didn't accept the "CCSpriteFrame" entered here. It was expected "CCAnimationFrame" objects. As such, I had to do this:
CCSpriteFrame* spriteFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(frameName);
CCAnimationFrame* animationFrame = new CCAnimationFrame();
animationFrame->initWithSpriteFrame(spriteFrame, 1.0f, CCDictionary::create());
walkAnimFrames->addObject(animationFrame);
|
Large Objects in Tiled Map Editor
This article includes a section describing how to include a large object e.g. a large tree or a building in a Tiled map. Basically this involves having a tileset with large tiles and placing them on the map as a separate layer, and then using object layer to specific collision boxes.
Link: http://gamedev.tutsplus.com/tutorials/level-design/introduction-to-tiled-map-editor/
Link: http://gamedev.tutsplus.com/tutorials/level-design/introduction-to-tiled-map-editor/
Twitter $10m Pay Cheque, Engineering Talent Wars and the 10x Engineer
Tuesday, October 15, 2013
C++ Warning "Deprecated conversion from string literal to 'char*'"
This post in StackOverflow provides a good explanation and solution for it.
http://stackoverflow.com/questions/9650058/deprecated-conversion-from-string-literal-to-char
http://stackoverflow.com/questions/9650058/deprecated-conversion-from-string-literal-to-char
Subscribe to:
Posts (Atom)