{"id":1006,"date":"2012-02-27T20:58:04","date_gmt":"2012-02-27T19:58:04","guid":{"rendered":"http:\/\/www.frozax.com\/blog\/?p=1006"},"modified":"2012-02-27T20:58:04","modified_gmt":"2012-02-27T19:58:04","slug":"how-to-create-shake-action-cocos2d-x-source-code","status":"publish","type":"post","link":"https:\/\/www.frozax.com\/blog\/2012\/02\/how-to-create-shake-action-cocos2d-x-source-code\/","title":{"rendered":"How to create a shake action in Cocos2d-x (with source code)"},"content":{"rendered":"<p>While working on my next game <a href=\"http:\/\/www.frozax.com\/blog\/2012\/02\/dont-feed-the-trolls-coming-to-ios-and-android\/\">Don&#8217;t Feed the Trolls<\/a>, I was looking for a &#8220;shake effect&#8221;. When the player feeds a troll, I want the whole screen to shake to improve visual feedback.<br \/>\nA shake effect is very easy to implement, so I quickly hacked in my code to see if it was un interesting feature. After a quick test on the Android version of the game, I could see it really does improve the game. So I wrote a proper <a href=\"http:\/\/www.cocos2d-x.org\">cocos2d-x<\/a> action to integrate the effect in a clean way. I&#8217;m releasing the code here hoping other developers will find it useful for their own games.<\/p>\n<h3>The effect<\/h3>\n<p>The shake is a small random movement. It can be applied to any cocos2d node (<a href=\"http:\/\/cocos2d-x.org\/embedded\/cocos2d-x\/d0\/ded\/classcocos2d_1_1_c_c_node.html\">CCNode<\/a>). In <em>Don&#8217;t Feed the Trolls<\/em>, I applied the effect to my top-most node, therefore the whole screen is shaking.<\/p>\n<h3>The action<\/h3>\n<p>I derived my <strong>CCShake<\/strong> class from <strong>CCActionInterval<\/strong>. The action is initialized with two parameters:<br \/>\n&#8211; <strong>time<\/strong> : the duration of the effect.<br \/>\n&#8211; <strong>strength<\/strong> : the distance of the shake movement. You can have different strengths in X and Y if you wish.<br \/>\nYou create the action with <strong>CCShake::actionWithDuration<\/strong> and send it as a parameter of <strong>CCNode::runAction<\/strong>.<\/p>\n<pre><code class=\"cpp\">\n\/\/ Shake node_to_shake for 5 seconds.\nnode_to_shake->runAction( CCShake::actionWithDuration( 5.0f, 10.0f ) );\n<\/code><\/pre>\n<p>When the action is completed, the node is moved back to its starting position.<\/p>\n<h3>Source code<\/h3>\n<p>The code is <em>free for personal and commercial<\/em> use. If you plan to use it, feel free to <em>credit<\/em> me, send me an <em>email<\/em> and\/or <em>follow<\/em> me on <a href=\"http:\/\/twitter.com\/frozax\">twitter<\/a>\/<a href=\"http:\/\/www.facebook.com\/frozax\">facebook<\/a>. This is of course not compulsory.<\/p>\n<h4>Header: CCShake.h<\/h4>\n<pre><code class=\"cpp\">\n#ifndef __SHAKE_H__\n#define __SHAKE_H__\n\n#include \"CCActionInterval.h\"\nusing namespace cocos2d;\n\nclass CCShake : public CCActionInterval\n{\n\t\/\/ Code by Francois Guibert\n\t\/\/ Contact: www.frozax.com - http:\/\/twitter.com\/frozax - www.facebook.com\/frozax\npublic:\n\tCCShake();\n\n\t\/\/ Create the action with a time and a strength (same in x and y)\n\tstatic CCShake* actionWithDuration(ccTime d, float strength );\n\t\/\/ Create the action with a time and strengths (different in x and y)\n\tstatic CCShake* actionWithDuration(ccTime d, float strength_x, float strength_y );\n\tbool initWithDuration(ccTime d, float strength_x, float strength_y );\n\n\tvirtual void startWithTarget(CCNode *pTarget);\n\tvirtual void update(ccTime time);\n\tvirtual void stop(void);\n\nprotected:\n\t\/\/ Initial position of the shaked node\n\tfloat _initial_x, _initial_y;\n\t\/\/ Strength of the action\n\tfloat _strength_x, _strength_y;\n};\n\n#endif \/\/__SHAKE_H__\n<\/code><\/pre>\n<h4>Source: CCShake.cpp<\/h4>\n<p><code><\/p>\n<pre>\n\/\/ Code by Francois Guibert\n\/\/ Contact: www.frozax.com - http:\/\/twitter.com\/frozax - www.facebook.com\/frozax\n#include \"cocos2d.h\"\n#include \"CCShake.h\"\n\n\/\/ not really useful, but I like clean default constructors\nCCShake::CCShake() : _strength_x(0), _strength_y(0), _initial_x(0), _initial_y(0)\n{\n}\n\nCCShake* CCShake::actionWithDuration( ccTime d, float strength )\n{\n\t\/\/ call other construction method with twice the same strength\n\treturn actionWithDuration( d, strength, strength );\n}\n\nCCShake* CCShake::actionWithDuration(ccTime duration, float strength_x, float strength_y)\n{\n\tCCShake *p_action = new CCShake();\n\tp_action->initWithDuration(duration, strength_x, strength_y);\n\tp_action->autorelease();\n\n\treturn p_action;\n}\n\nbool CCShake::initWithDuration(ccTime duration, float strength_x, float strength_y)\n{\n\tif (CCActionInterval::initWithDuration(duration))\n\t{\n\t\t_strength_x = strength_x;\n\t\t_strength_y = strength_y;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n\/\/ Helper function. I included it here so that you can compile the whole file\n\/\/ it returns a random value between min and max included\nfloat fgRangeRand( float min, float max )\n{\n\tfloat rnd = ((float)rand()\/(float)RAND_MAX);\n\treturn rnd*(max-min)+min;\n}\n\nvoid CCShake::update(ccTime time)\n{\n\tfloat randx = fgRangeRand( -_strength_x, _strength_x );\n\tfloat randy = fgRangeRand( -_strength_y, _strength_y );\n\n\t\/\/ move the target to a shaked position\n\tm_pTarget->setPosition( ccp( randx, randy) );\n}\n\nvoid CCShake::startWithTarget(CCNode *pTarget)\n{\n\tCCActionInterval::startWithTarget( pTarget );\n\n\t\/\/ save the initial position\n\t_initial_x = pTarget->getPosition().x;\n\t_initial_y = pTarget->getPosition().y;\n}\n\nvoid CCShake::stop(void)\n{\n\t\/\/ Action is done, reset clip position\n\tm_pTarget->setPosition( ccp( _initial_x, _initial_y ) );\n\n\tCCActionInterval::stop();\n}\n<\/code><\/pre>\n<h3>Possible improvements<\/h3>\n<p>This is really a simple class, for a simple effect. You can improve the effect in many ways. For instance, we could animate the strength of the shake over time.<\/p>\n<h3>That's it !<\/h3>\n<p>Have fun with it, feel free to discuss the source code in the comments, <a href=\"http:\/\/twitter.com\/frozax\">twitter<\/a> or <a href=\"http:\/\/www.facebook.com\/frozax\">facebook<\/a>.<\/p>\n<div class=\"addtoany_share_save_container addtoany_content_bottom\"><div class=\"a2a_kit a2a_kit_size_32 addtoany_list a2a_target\" id=\"wpa2a_1\"><a class=\"a2a_button_twitter\" href=\"http:\/\/www.addtoany.com\/add_to\/twitter?linkurl=https%3A%2F%2Fwww.frozax.com%2Fblog%2F2012%2F02%2Fhow-to-create-shake-action-cocos2d-x-source-code%2F&amp;linkname=How%20to%20create%20a%20shake%20action%20in%20Cocos2d-x%20%28with%20source%20code%29\" title=\"Twitter\" rel=\"nofollow\" target=\"_blank\"><\/a><a class=\"a2a_button_facebook\" href=\"http:\/\/www.addtoany.com\/add_to\/facebook?linkurl=https%3A%2F%2Fwww.frozax.com%2Fblog%2F2012%2F02%2Fhow-to-create-shake-action-cocos2d-x-source-code%2F&amp;linkname=How%20to%20create%20a%20shake%20action%20in%20Cocos2d-x%20%28with%20source%20code%29\" title=\"Facebook\" rel=\"nofollow\" target=\"_blank\"><\/a><a class=\"a2a_button_google_plus\" href=\"http:\/\/www.addtoany.com\/add_to\/google_plus?linkurl=https%3A%2F%2Fwww.frozax.com%2Fblog%2F2012%2F02%2Fhow-to-create-shake-action-cocos2d-x-source-code%2F&amp;linkname=How%20to%20create%20a%20shake%20action%20in%20Cocos2d-x%20%28with%20source%20code%29\" title=\"Google+\" rel=\"nofollow\" target=\"_blank\"><\/a><a class=\"a2a_button_reddit\" href=\"http:\/\/www.addtoany.com\/add_to\/reddit?linkurl=https%3A%2F%2Fwww.frozax.com%2Fblog%2F2012%2F02%2Fhow-to-create-shake-action-cocos2d-x-source-code%2F&amp;linkname=How%20to%20create%20a%20shake%20action%20in%20Cocos2d-x%20%28with%20source%20code%29\" title=\"Reddit\" rel=\"nofollow\" target=\"_blank\"><\/a>\n<script type=\"text\/javascript\"><!--\nwpa2a.script_load();\n\/\/--><\/script>\n<\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>While working on my next game Don&#8217;t Feed the Trolls, I was looking for a &#8220;shake effect&#8221;. When the player feeds a troll, I want the whole screen to shake to improve visual feedback. A shake effect is very easy to implement, so I quickly hacked in my code to see if it was un&hellip; <a class=\"more-link\" href=\"https:\/\/www.frozax.com\/blog\/2012\/02\/how-to-create-shake-action-cocos2d-x-source-code\/\">Continue reading <span class=\"screen-reader-text\">How to create a shake action in Cocos2d-x (with source code)<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,3,7,12],"tags":[53,61,66,114,125],"_links":{"self":[{"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/posts\/1006"}],"collection":[{"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/comments?post=1006"}],"version-history":[{"count":0,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/posts\/1006\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/media?parent=1006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/categories?post=1006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.frozax.com\/blog\/wp-json\/wp\/v2\/tags?post=1006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}