{"id":166929,"date":"2013-01-25T12:15:03","date_gmt":"2013-01-25T08:15:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=166929"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=166929","title":{"rendered":"<span class=\"post_title\">\u041c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u043e\u0442\u0432\u0430\u0436\u043d\u044b\u0439 \u0430\u0440\u043a\u0430\u043d\u043e\u0438\u0434 (\u0447\u0430\u0441\u0442\u044c 3 \u2014 Box2D)<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t\u0421\u0435\u0433\u043e\u0434\u043d\u044f, \u043a\u0430\u043a \u044f \u0438 \u043e\u0431\u0435\u0449\u0430\u043b, \u043c\u044b \u0432\u0434\u043e\u0445\u043d\u0435\u043c \u0432 \u043d\u0430\u0448 <a href=\"http:\/\/habrahabr.ru\/post\/165667\/\">Arcanoid<\/a> \u0436\u0438\u0437\u043d\u044c. \u0417\u0430\u0441\u0442\u0430\u0432\u0438\u043c \u0448\u0430\u0440\u0438\u043a \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f, \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044f\u0441\u044c \u0441 \u043a\u0438\u0440\u043f\u0438\u0447\u0430\u043c\u0438, \u0430 \u043a\u0438\u0440\u043f\u0438\u0447\u0438, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u0438\u0433\u0440\u043e\u0432\u0430\u044f \u0444\u0438\u0437\u0438\u043a\u0430 \u0432 arcanoid \u043d\u0435 \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u0430 \u0438 \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u0438\u043b\u0430\u043c\u0438. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432 \u043d\u0435\u0439 \u2014 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0439. \u041d\u043e \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u00ab\u0432\u0437\u0440\u043e\u0441\u043b\u044b\u0435\u00bb \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0434\u0432\u0438\u0436\u043a\u0438 \u0443\u043c\u0435\u044e\u0442 \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u043e!<\/p>\n<p>  \u0422\u0430\u043a \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u0438\u0445 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c? \u041a \u0442\u043e\u043c\u0443-\u0436\u0435, \u0435\u0441\u043b\u0438 \u043c\u044b \u043e\u0444\u043e\u0440\u043c\u0438\u043c Box2D \u0432 \u0432\u0438\u0434\u0435 \u043c\u043e\u0434\u0443\u043b\u044f <a href=\"http:\/\/www.madewithmarmalade.com\/\">Marmalade<\/a>, \u0432\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0438 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0445 \u0431\u043e\u043b\u0435\u0435 \u0438\u0437\u043e\u0449\u0440\u0435\u043d\u043d\u043e\u0439 \u00ab\u0444\u0438\u0437\u0438\u043a\u0438\u00bb. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u0438\u043c \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u041c\u0435\u0442\u043e\u0434\u0438\u043a\u0430 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u044f Box2D \u0432 \u0432\u0438\u0434\u0435 \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430 \u0442\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u043a LibYAML \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 <a href=\"http:\/\/habrahabr.ru\/post\/166357\/\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a>. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 Box2D \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0436\u0435\u043b\u0430\u043d\u0438\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u0440\u0443\u0442\u0438\u043d\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u0435 \u0438\u0445 \u0438\u043c\u0435\u043d \u0432 mkf-\u0444\u0430\u0439\u043b, \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u043e\u0435 \u043c\u043d\u043e\u0439, \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 <a href=\"https:\/\/github.com\/GlukKazan\/mf\/tree\/master\/modules\/box2d\">GitHub<\/a>. \u0414\u0438\u0441\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0432 Box2D \u0432\u0437\u044f\u0442 <a href=\"http:\/\/code.google.com\/p\/box2d\/downloads\/detail?name=Box2D_v2.2.1.zip&amp;can=2&amp;q=\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>.<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Box2D \u0432 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">arcanoid.mkb<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#!\/usr\/bin\/env mkb options {       module_path=&quot;..\/yaml&quot; +     module_path=&quot;..\/box2d&quot; } subprojects {     iwgl     yaml +   box2d }  includepath {     .\/source\/Main     .\/source\/Model } files {     [Main]     (source\/Main)     Main.cpp     Main.h     Quads.cpp     Quads.h            Desktop.cpp     Desktop.h     IO.cpp     IO.h      [Model]     (source\/Model)     Bricks.cpp     Bricks.h     Ball.cpp     Ball.h     Board.cpp     Board.h } assets {     (data)     level.json } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u2026 \u0438 \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0432\u0441\u0435 \u044d\u0442\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043f\u043e\u043f\u0443\u0442\u043d\u043e \u0432\u043d\u043e\u0441\u044f \u0432 Box2D \u043a\u043e\u0441\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u0437 \u0440\u0430\u0437\u0440\u044f\u0434\u0430 \u00ab\u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u044b\u043c\u00bb:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Collision\\b2BroadPhase.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">-      for (int32 i = 0; i &lt; m_moveCount; ++i) +      for (int32 j = 0; j &lt; m_moveCount; ++j) \t{ -\t\tm_queryProxyId = m_moveBuffer[i]; +\t\tm_queryProxyId = m_moveBuffer[j];                 ... \t}          ... \twhile (i &lt; m_pairCount) \t{            ... \t} <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Common\\b2Math.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">\/\/\/ A 2D column vector. struct b2Vec2 { \t\/\/\/ Default constructor does nothing (for performance). -\tb2Vec2() {} +\tb2Vec2(): x(0.0f), y(0.0f) {}  \t\/\/\/ Construct using coordinates. \tb2Vec2(float32 x, float32 y) : x(x), y(y) {}  \t... \tfloat32 x, y; }; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0443 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/3.bp.blogspot.com\/-R61pTqwiBzU\/UQIbWifp6vI\/AAAAAAAAAQU\/zqUyhBJ1eI4\/s1600\/0001.PNG\" alt=\"image\"\/><\/p>\n<p>  \u2026 \u0442\u043e \u044d\u0442\u043e, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u0438 \u043c\u043d\u0435, \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f MSVS 2003. GCC, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u043e \u043d\u0430\u043c, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0435\u0433\u043e \u0438 \u043f\u043e\u0434 \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u043e\u043c \u0442\u043e\u0436\u0435. \u041a\u0430\u043a \u0431\u044b \u0442\u0430\u043c \u043d\u0438 \u0431\u044b\u043b\u043e, \u043e\u0442 MSVS 2003 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f. \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 MSVS 2005, \u043d\u043e \u044f \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b MSVS 2010, \u0431\u043b\u0430\u0433\u043e \u043e\u043d\u0430 \u0431\u044b\u043b\u0430 \u043f\u043e\u0434 \u0440\u0443\u043a\u043e\u0439. \u0421\u0430\u043c\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Marmalade Configuration Utility.<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/3.bp.blogspot.com\/-n3qnOkUYh44\/UQIeNiJqo0I\/AAAAAAAAAQs\/qgw3bR5EdC8\/s1600\/0002.PNG\" alt=\"image\"\/><\/p>\n<p>  \u041d\u0443 \u0447\u0442\u043e-\u0436\u0435, \u043f\u043e\u0440\u0430 \u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0437\u0430 \u0434\u0435\u043b\u043e. \u0415\u0441\u043b\u0438 \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0438\u043c\u0435\u043b\u0438 \u0434\u0435\u043b\u043e \u0441 \u00ab\u043c\u0438\u0440\u043e\u043c \u0438\u043b\u043b\u044e\u0437\u0438\u0439\u00bb, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441 \u00ab\u043c\u0438\u0440\u043e\u043c \u0438\u0434\u0435\u0439\u00bb, \u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0448\u043b\u0430 \u043f\u043e\u0440\u0430 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u00ab\u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0438\u0440\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">arcanoid.mkb<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#!\/usr\/bin\/env mkb options { \tmodule_path=&quot;..\/yaml&quot; \tmodule_path=&quot;..\/box2d&quot; } subprojects {     iwgl     yaml     box2d }  includepath {     .\/source\/Main     .\/source\/Model } files {     [Main]     (source\/Main)     Main.cpp     Main.h     Quads.cpp     Quads.h            Desktop.cpp     Desktop.h     IO.cpp     IO.h +   World.cpp +   World.h             [Model]     (source\/Model)     Bricks.cpp     Bricks.h     Ball.cpp     Ball.h     Board.cpp     Board.h +   IBox2DItem.h } assets {     (data)     level.json } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IBox2DItem \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437 Box2D \u0432 \u043d\u0430\u0448\u0443 \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0446\u0435\u043b\u0435\u0439, \u043f\u043e\u043a\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u0434\u0432\u0443\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">IBox2DItem.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#ifndef _I_BOX2D_ITEM_H_ #define _I_BOX2D_ITEM_H_  #include &lt;Box2D.h&gt;  class IBox2DItem { \tpublic: \t\tvirtual void setXY(int X, int Y) {} \t\tvirtual bool impact(b2Body* b) {return false;} };  #endif\t\/\/ _I_BOX2D_ITEM_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u0430, \u044f \u0437\u043d\u0430\u044e, \u0447\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b (\u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0442\u0430\u043a \u043e\u043d\u043e \u0438 \u0431\u044b\u043b\u043e), \u043d\u043e \u043f\u043e\u0442\u043e\u043c \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u00ab\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\u00bb, \u0430 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0431\u044b\u043b\u043e \u043b\u0435\u043d\u044c. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>  \u041c\u0435\u0442\u043e\u0434 setXY \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0434\u0432\u0438\u0436\u0443\u0449\u0438\u0445\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 (\u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435), \u0430 \u043c\u0435\u0442\u043e\u0434 impact \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0443\u0434\u0430\u0440\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#ifndef _WORLD_H_ #define _WORLD_H_  #include &lt;vector&gt; #include &lt;Box2D.h&gt; #include &quot;Desktop.h&quot; #include &quot;IBox2DItem.h&quot;  const int HALF_MARGIN   = 10; const int V_ITERATIONS  = 10; const int P_ITERATIONS  = 10;  const float FRICTION    = 0.0f; const float RESTITUTION = 1.0f; const float DYN_DENSITY = 0.0f; const float R_INVIS     = 0.0f; const float EPS         = 1.0f; const float SPEED_SQ    = 10.0f;  using namespace std;  class World { \tprivate: \t\tbool isStarted; \t\tint  HandleX, HandleH, HandleW; \t\tuint64 timestamp; \t\tint  width, height; \t\tb2World* wp; \t\tb2Body* ground; \t\tb2Body* ball; \t\tb2Body* handle; \t\tb2Body* createBox(int x, int y, int hw, int hh, IBox2DItem* userData = NULL); \t\tfloat32 getTimeStep(); \t\tvoid  start(); \tpublic: \t\tWorld(): width(0), height(0), wp(NULL) {} \t\tvoid init(); \t\tvoid release(); \t\tvoid update(); \t\tvoid refresh(); \t\tb2Body* addBrick(int x, int y, int hw, int hh, IBox2DItem* userData) {return createBox(x, y, hw, hh, userData);} \t\tb2Body* addBall(int x, int y, int r, IBox2DItem* userData); \t\tb2Body* addHandle(int x, int y, int hw, int hh, IBox2DItem* userData); \t\tvoid    moveHandle(int x, int y);  \t\ttypedef vector&lt;b2Body*&gt;::iterator BIter; };  extern World world;  #endif\t\/\/ _WORLD_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &quot;s3e.h&quot; #include &quot;World.h&quot; #include &quot;Ball.h&quot;  World world;  void World::init() { \tisStarted = false; \twidth  = desktop.getWidth(); \theight = desktop.getHeight(); \tb2Vec2 gravity(0.0f, 0.0f); \twp = new b2World(gravity); \tground = createBox(width\/2, -HALF_MARGIN, width\/2, HALF_MARGIN); \tcreateBox(-HALF_MARGIN, height\/2, HALF_MARGIN, height\/2); \tcreateBox(width\/2, height + HALF_MARGIN, width\/2, HALF_MARGIN); \tcreateBox(width + HALF_MARGIN, height\/2, HALF_MARGIN, height\/2); \tball = NULL; \thandle = NULL; }  void World::release() { \tif (wp != NULL) { \t\tdelete wp; \t\twp = NULL; \t\tball = NULL; \t\thandle = NULL; \t} } ... <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041c\u0435\u0442\u043e\u0434\u044b init \u0438 release \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0438 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u00ab\u043c\u0438\u0440\u0430\u00bb. \u041e\u0431\u0440\u0430\u0449\u0430\u044e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0433\u0440\u0430\u0432\u0438\u0442\u0430\u0446\u0438\u044e \u043c\u044b \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432 0 (\u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u0432\u0435\u0441\u043e\u0432\u043c\u043e\u0441\u0442\u044c), \u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u043e\u043a\u0440\u0443\u0436\u0430\u0435\u043c \u0447\u0435\u0442\u044b\u0440\u044c\u043c\u044f \u00ab\u0441\u0442\u0435\u043d\u0430\u043c\u0438\u00bb (\u043e\u0434\u043d\u0443 \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0433\u043a\u043e \u0443\u0431\u0440\u0430\u0442\u044c).<\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">... b2Body* World::createBox(int x, int y, int hw, int hh, IBox2DItem* userData) { \tb2BodyDef def; \tdef.type = b2_staticBody; \tdef.position.Set(x, y); \tb2Body* r = wp-&gt;CreateBody(&def); \tb2PolygonShape box; \tbox.SetAsBox(hw, hh); \tb2FixtureDef fd; \tfd.shape = &box; \tfd.density = 0; \tfd.friction = FRICTION; \tfd.restitution = RESTITUTION; \tr-&gt;CreateFixture(&fd); \tr-&gt;SetUserData(userData); \treturn r; }  b2Body* World::addBall(int x, int y, int r, IBox2DItem* userData) { \tif (ball != NULL) { \t\twp-&gt;DestroyBody(ball); \t} \tb2BodyDef def; \tdef.type = b2_dynamicBody; \tdef.linearDamping = 0.0f; \tdef.angularDamping = 0.0f; \tdef.position.Set(x, y); \tball = wp-&gt;CreateBody(&def); \tb2CircleShape shape; \tshape.m_p.SetZero(); \tshape.m_radius = r + R_INVIS; \tb2FixtureDef fd; \tfd.shape = &shape; \tfd.density = DYN_DENSITY; \tfd.friction = FRICTION; \tfd.restitution = RESTITUTION; \tball-&gt;CreateFixture(&fd); \tball-&gt;SetBullet(true); \tball-&gt;SetUserData(userData); \treturn ball; } ... <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 (\u0441\u0442\u0435\u043d\u0430 \u0438\u043b\u0438 \u043a\u0438\u0440\u043f\u0438\u0447) \u0438 \u0448\u0430\u0440\u0438\u043a. \u041a\u0440\u043e\u043c\u0435 \u0444\u043e\u0440\u043c\u044b \u043e\u043d\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0442\u0438\u043f\u043e\u043c. \u041a\u0438\u0440\u043f\u0438\u0447\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 (\u043d\u0435\u043f\u043e\u0434\u0432\u0438\u0436\u043d\u044b\u043c\u0438) \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438, \u0430 \u0448\u0430\u0440\u0438\u043a \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c. Box2D \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u0438\u0433\u0440\u043e\u0432\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0430 \u0434\u0432\u0430 \u044d\u0442\u0438\u0445 \u0442\u0438\u043f\u0430, \u0438\u0437 \u0441\u043e\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0422\u0430\u043a\u0436\u0435, \u043c\u044b \u0437\u0430\u0434\u0430\u0435\u043c \u0442\u0430\u043a\u0438\u0435 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043a\u0430\u043a \u0443\u043f\u0440\u0443\u0433\u043e\u0441\u0442\u044c, \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0442\u0440\u0435\u043d\u0438\u044f \u0438 \u0442.\u043f. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430, \u043e\u043d\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438 \u0432 h-\u0444\u0430\u0439\u043b\u0435.<\/p>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0443\u043f\u0440\u0443\u0433\u0438\u0435 \u0441\u043e\u0443\u0434\u0430\u0440\u0435\u043d\u0438\u044f (RESTITUTION = 1), \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0442\u0440\u0435\u043d\u0438\u044f (FRICTION = 0). \u0422\u0430\u043a\u0436\u0435 \u0432 \u043d\u043e\u043b\u044c \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b linearDamping \u0438 angularDamping, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0435 \u0437\u0430 \u0442\u043e\u0440\u043c\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u0432\u0438\u0436\u0443\u0449\u0435\u0433\u043e\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u00ab\u0441\u0440\u0435\u0434\u043e\u0439\u00bb. \u041f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e, \u0431\u044b\u043b\u0430 \u0438\u0434\u0435\u044f \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u043d\u0443\u043b\u0435\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 FRICTION, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u00ab\u043f\u043e\u0434\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0442\u044c\u00bb \u0448\u0430\u0440\u0438\u043a \u0440\u0430\u043a\u0435\u0442\u043a\u043e\u0439, \u043d\u043e \u043e\u0442 \u043d\u0435\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f. \u041f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 FRICTION \u0432 \u043b\u044e\u0431\u043e\u0435 \u043d\u0435\u043d\u0443\u043b\u0435\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0448\u0430\u0440\u0438\u043a\u0430 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0432\u044b\u0440\u043e\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0447\u0438\u0441\u0442\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438 \u0438\u043b\u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438.<\/p>\n<p>  \u0412 userData \u0434\u043b\u044f body \u0438 fixture \u043c\u043e\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u0430\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IBox2DItem \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043d\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">... float32 World::getTimeStep() { \tuint64 t = s3eTimerGetMs(); \tint r = (int)(t - timestamp); \ttimestamp = t; \treturn (float32)r \/ 1000.0f; }  void World::start() { \tif (ball != NULL) { \t\tball-&gt;ApplyLinearImpulse(ball-&gt;GetWorldVector(b2Vec2(-10.0f, -10.0f)),  \t\t\t                     ball-&gt;GetWorldPoint(b2Vec2(0.0f, 0.0f))); \t} }  void World::update() { \tif (!isStarted) { \t\tisStarted = true; \t\tstart(); \t\ttimestamp = s3eTimerGetMs(); \t\tsrand((unsigned int)timestamp); \t} else { \t\tfloat32 timeStep = getTimeStep(); \t\twp-&gt;Step(timeStep, V_ITERATIONS, P_ITERATIONS); \t} }  void World::refresh() { \tif (ball != NULL) { \t\tb2Vec2 pos = ball-&gt;GetPosition(); \t\tBall* b = (Ball*)ball-&gt;GetUserData(); \t\tif (b != NULL) { \t\t\tb-&gt;setXY(pos.x, pos.y); \t\t} \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0412 \u043c\u0435\u0442\u043e\u0434\u0435 update \u043c\u044b \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u0443\u044e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u00ab\u043c\u0438\u0440\u0430\u00bb \u043c\u0435\u0442\u043e\u0434\u043e\u043c Step, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0442\u0440\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430. \u041f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u2014 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0430\u0441\u0441\u0447\u0435\u0442. \u0412 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f <a href=\"http:\/\/tigrojop.ru\/files\/translate\/box2d\/box2d-manual-2.1.0-rus.html\">Box2D<\/a> \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b ~1\/60 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u0422\u0430\u043a\u0436\u0435, \u043d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0431\u044b\u043b \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u044b\u043c. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043e\u0432 \u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432\u043b\u0438\u044f\u044e\u0442 \u043d\u0430 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u042f \u043f\u0435\u0440\u0435\u0434\u0430\u044e \u0432 \u043e\u0431\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 10.<\/p>\n<p>  \u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 update, \u043c\u044b \u043f\u0440\u0438\u0434\u0430\u0435\u043c \u0448\u0430\u0440\u0438\u043a\u0443 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u0441\u0435 \u0441\u043e\u0443\u0434\u0430\u0440\u0435\u043d\u0438\u044f \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u0443\u0433\u0438, \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0448\u0430\u0440\u0438\u043a\u0430 \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0443\u0434\u0430\u0440\u0435\u043d\u0438\u0439 \u043d\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442\u0441\u044f \u0438 \u043e\u0434\u043d\u043e\u043a\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043d\u0430\u043c \u0432\u043f\u043e\u043b\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u041f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 update (\u043d\u0438 \u0432 \u043a\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u0430\u043a\u0438\u0445 \u043b\u0438\u0431\u043e \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 b2World.Step, \u044d\u0442\u043e, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u0440\u0430\u0437\u0440\u0443\u0448\u0435\u043d\u0438\u044e \u043f\u0430\u043c\u044f\u0442\u0438).<\/p>\n<p>  \u0417\u0430\u0434\u0430\u0447\u0435\u0439 \u043c\u0435\u0442\u043e\u0434\u0430 refresh \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0448\u0430\u0440\u0438\u043a\u0430 (\u043f\u043e\u0441\u043b\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u0440\u0430\u0441\u0447\u0435\u0442\u043e\u0432) \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 IBox2DItem.<\/p>\n<p>  \u0412\u043d\u0435\u0441\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043c\u043e\u0434\u0435\u043b\u044c:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Bricks.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#ifndef _BRICKS_H_ #define _BRICKS_H_  #include &quot;IwGL.h&quot; #include &quot;s3e.h&quot; #include &quot;Desktop.h&quot; +#include &quot;World.h&quot; +#include &quot;IBox2DItem.h&quot;  #define BRICK_COLOR_1      0xffffff00 #define BRICK_COLOR_2      0xff50ff00 #define BRICK_HALF_WIDTH   20 #define BRICK_HALF_HEIGHT  10  #include &lt;vector&gt;  using namespace std;  -class Bricks { +class Bricks: public IBox2DItem {     private:         struct SBrick {             SBrick(int x, int y): x(x),                                            y(y),  +                                         body(NULL),  +                                         isBroken(false),                                           hw(BRICK_HALF_WIDTH),                                            hh(BRICK_HALF_HEIGHT),                                            ic(BRICK_COLOR_1),                                            oc(BRICK_COLOR_2) {}             SBrick(const SBrick& p): x(p.x),                                            y(p.y),  +                                         body(p.body),  +                                         isBroken(p.isBroken),                                           hw(p.hw),                                            hh(p.hh),                                            ic(p.ic),                                            oc(p.oc) {}             int x, y, hw, hh, ic, oc; +            int isBroken; +            b2Body* body;         };         vector&lt;SBrick&gt; bricks;     public:         Bricks(): bricks() {} +\t\tvoid init() {} +\t\tvoid release() {}         void refresh();         void clear(){bricks.clear();}         void add(SBrick& b);      typedef vector&lt;SBrick&gt;::iterator BIter;  \tfriend class Board; };  #endif\t\/\/ _BRICKS_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Bricks.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#include &quot;Bricks.h&quot; #include &quot;Quads.h&quot;  void Bricks::refresh() {     for (BIter p = bricks.begin(); p != bricks.end(); ++p) { +\t    if (p-&gt;isBroken) continue;             CIwGLPoint point(p-&gt;x, p-&gt;y);             point = IwGLTransform(point);              int16* quadPoints = quads.getQuadPoints();             uint32* quadCols = quads.getQuadCols();             if ((quadPoints == NULL) || (quadCols == NULL)) break;              *quadPoints++ = point.x - p-&gt;hw;             *quadPoints++ = point.y + p-&gt;hh;             *quadCols++   = p-&gt;ic;              *quadPoints++ = point.x + p-&gt;hw;             *quadPoints++ = point.y + p-&gt;hh;             *quadCols++   = p-&gt;oc;              *quadPoints++ = point.x + p-&gt;hw;             *quadPoints++ = point.y - p-&gt;hh;             *quadCols++   = p-&gt;ic;              *quadPoints++ = point.x - p-&gt;hw;             *quadPoints++ = point.y - p-&gt;hh;             *quadCols++   = p-&gt;oc;     } }  void Bricks::add(SBrick& b) {  +   b.body = world.addBrick(b.x, b.y, b.hw, b.hh, (IBox2DItem*)this);     bricks.push_back(b); } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Ball.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#ifndef _BALL_H_ #define _BALL_H_  #include &lt;vector&gt; #include &quot;IwGL.h&quot; #include &quot;s3e.h&quot; #include &quot;Desktop.h&quot; +#include &quot;World.h&quot; +#include &quot;IBox2DItem.h&quot;  #define MAX_SEGMENTS       7 #define BALL_COLOR_1       0x00000000 #define BALL_COLOR_2       0xffffffff #define BALL_RADIUS        15  using namespace std;  -class Ball { +class Ball: public IBox2DItem {     private:         struct Offset {             Offset(int dx, int dy): dx(dx), dy(dy) {}             Offset(const Offset& p): dx(p.dx), dy(p.dy) {}             int dx, dy;         };         vector&lt;Offset&gt; offsets;         int     x;         int     y; +       b2Body*  body;     public:         void init();         void release() {}         void refresh();         virtual void setXY(int X, int Y);      typedef vector&lt;Offset&gt;::iterator OIter; };  #endif\t\/\/ _BALL_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Ball.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#include &quot;Ball.h&quot; #include &quot;Quads.h&quot; #include &quot;Desktop.h&quot; #include &lt;math.h&gt;  #define PI 3.14159265f  void Ball::init(){     x = desktop.getWidth() \/ 2;     y = desktop.getHeight()\/ 2;      float delta = PI \/ (float)MAX_SEGMENTS;     float angle = delta \/ 2.0f;     float r = (float)desktop.toRSize(BALL_RADIUS);     for (int i = 0; i &lt; MAX_SEGMENTS; i++) {         offsets.push_back(Offset((int16)(cos(angle) * r), (int16)(sin(angle) * r)));         angle = angle + delta;         offsets.push_back(Offset((int16)(cos(angle) * r), (int16)(sin(angle) * r)));         angle = angle + delta;         offsets.push_back(Offset((int16)(cos(angle) * r), (int16)(sin(angle) * r)));     } +   body = world.addBall(x, y, (int)r, (IBox2DItem*)this); }  void Ball::setXY(int X, int Y) {     x = X;     y = Y; }  void Ball::refresh() {     CIwGLPoint point(x, y);     point = IwGLTransform(point);     OIter o = offsets.begin();     int r = desktop.toRSize(BALL_RADIUS);     for (int i = 0; i &lt; MAX_SEGMENTS; i++) {              int16* quadPoints = quads.getQuadPoints();             uint32* quadCols = quads.getQuadCols();             if ((quadPoints == NULL) || (quadCols == NULL)) break;              *quadPoints++ = point.x + (r \/ 4);             *quadPoints++ = point.y + (r \/ 4);             *quadCols++   = BALL_COLOR_2;              *quadPoints++ = point.x + o-&gt;dx;             *quadPoints++ = point.y + o-&gt;dy;             *quadCols++   = BALL_COLOR_1;             o++;              *quadPoints++ = point.x + o-&gt;dx;             *quadPoints++ = point.y + o-&gt;dy;             *quadCols++   = BALL_COLOR_1;             o++;              *quadPoints++ = point.x + o-&gt;dx;             *quadPoints++ = point.y + o-&gt;dy;             *quadCols++   = BALL_COLOR_1;             o++;     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b. \u0414\u0430\u043b\u0435\u0435 \u0432\u043d\u043e\u0441\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 Main:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Main.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#include &quot;Main.h&quot;  #include &quot;s3e.h&quot; #include &quot;IwGL.h&quot;  #include &quot;Desktop.h&quot; +#include &quot;World.h&quot; #include &quot;IO.h&quot; #include &quot;Quads.h&quot; #include &quot;Board.h&quot;  Board board;  void init() {     desktop.init();     io.init();     quads.init(); +   world.init();     board.init(); }  void release() { +   world.release();     io.release();     desktop.release(); }  int main() {     init(); {         while (!s3eDeviceCheckQuitRequest()) {             io.update();             if (io.isKeyDown(s3eKeyAbsBSK) || io.isKeyDown(s3eKeyBack)) break; +           world.update();             quads.update();             desktop.update();             board.update();             board.refresh(); +           world.refresh();             quads.refresh();             io.refresh();             desktop.refresh();         }     }     release();     return 0; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435. \u0427\u0442\u043e \u043c\u044b \u0432\u0438\u0434\u0438\u043c? \u0428\u0430\u0440\u0438\u043a \u0434\u0432\u0438\u0436\u0435\u0442\u0441\u044f, \u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e. \u041e\u0442\u0441\u043a\u043e\u043a\u043e\u0432 \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0443\u0434\u0430\u0440\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u0442\u0441\u044f. \u041c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0441 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442 \u0432\u0438\u0434\u0438\u043c\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0448\u0430\u0440\u0438\u043a\u0430. \u0412\u0441\u0435 \u044d\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0447\u0442\u043e-\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435 \u0442\u0430\u043a.<\/p>\n<p>  \u041f\u043e\u0434\u0443\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u0431\u044b \u044d\u0442\u043e \u043c\u043e\u0433\u043b\u043e \u0431\u044b\u0442\u044c? \u041c\u044b \u0437\u0430\u0434\u0430\u0435\u043c \u0432\u0441\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0432 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0435 \u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442. \u0414\u043b\u044f \u0441\u0435\u0431\u044f, \u044f \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u044e, \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0432 Box2D \u0440\u0430\u0432\u043d\u043e\u0439 1 \u043c\u0435\u0442\u0440\u0443. \u0414\u0430\u0436\u0435 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u044d\u043a\u0440\u0430\u043d\u0430 320&#215;480, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0441\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u0440\u043a\u0430\u043d\u043e\u0438\u0434 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435\u0432\u043e\u043e\u0431\u0440\u0430\u0437\u0438\u043c\u043e \u044d\u043f\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 (\u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u0444\u0438\u0437\u0438\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u044d\u043a\u0440\u0430\u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0430 \u044d\u0442\u043e \u0443\u0436\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0438\u043a\u0443\u0434\u0430 \u043d\u0435 \u0433\u043e\u0434\u0438\u0442\u0441\u044f). \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, Box2D \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u0440\u0430\u0441\u0441\u0447\u0435\u0442\u044b \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0442\u0430\u043a\u0438\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432. \u041e\u0431\u044b\u0447\u043d\u043e, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c\u044b\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043c\u0438\u0440\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0442\u044c \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u043c\u0435\u0442\u0440\u043e\u0432. \u0412\u043d\u0435\u0441\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0432\u044b:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#ifndef _WORLD_H_ #define _WORLD_H_  #include &lt;vector&gt; #include &lt;Box2D.h&gt; #include &quot;Desktop.h&quot; #include &quot;IBox2DItem.h&quot;  +const float W_WIDTH     = 10.0f;  const int HALF_MARGIN   = 10; const int V_ITERATIONS  = 10; const int P_ITERATIONS  = 10;  const float FRICTION    = 0.0f; const float RESTITUTION = 1.0f; const float DYN_DENSITY = 0.0f; const float R_INVIS     = 0.0f; const float EPS         = 1.0f; const float SPEED_SQ    = 10.0f;  using namespace std;  class World { \tprivate: \t\tbool isStarted; \t\tint  HandleX, HandleH, HandleW; \t\tuint64 timestamp; \t\tint  width, height; \t\tb2World* wp; \t\tb2Body* ground; \t\tb2Body* ball; \t\tb2Body* handle; \t\tb2Body* createBox(int x, int y, int hw, int hh, IBox2DItem* userData = NULL); \t\tfloat32 getTimeStep(); \t\tvoid  start(); +\tfloat toWorld(int x); +\tint   fromWorld(float x); \tpublic: \t\tWorld(): width(0), height(0), wp(NULL) {} \t\tvoid init(); \t\tvoid release(); \t\tvoid update(); \t\tvoid refresh(); \t\tb2Body* addBrick(int x, int y, int hw, int hh, IBox2DItem* userData) {return createBox(x, y, hw, hh, userData);} \t\tb2Body* addBall(int x, int y, int r, IBox2DItem* userData);  \t\ttypedef vector&lt;b2Body*&gt;::iterator BIter; };  extern World world;  #endif\t\/\/ _WORLD_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#include &quot;s3e.h&quot; #include &quot;World.h&quot; #include &quot;Ball.h&quot;  World world;  void World::init() { \tisStarted = false; \twidth  = desktop.getWidth(); \theight = desktop.getHeight(); \tb2Vec2 gravity(0.0f, 0.0f); \twp = new b2World(gravity); \tground = createBox(width\/2, -HALF_MARGIN, width\/2, HALF_MARGIN); \tcreateBox(-HALF_MARGIN, height\/2, HALF_MARGIN, height\/2); \tcreateBox(width\/2, height + HALF_MARGIN, width\/2, HALF_MARGIN); \tcreateBox(width + HALF_MARGIN, height\/2, HALF_MARGIN, height\/2); \tball = NULL; \thandle = NULL; }  void World::release() { \tif (wp != NULL) { \t\tdelete wp; \t\twp = NULL; \t\tball = NULL; \t\thandle = NULL; \t} }  +float World::toWorld(int x) { +\treturn ((float)x * W_WIDTH) \/ (float)desktop.getWidth(); +}  +int World::fromWorld(float x) { +\treturn (int)((x * (float)desktop.getWidth()) \/ W_WIDTH); +}  b2Body* World::createBox(int x, int y, int hw, int hh, IBox2DItem* userData) { \tb2BodyDef def; \tdef.type = b2_staticBody; -   def.position.Set(x, y); +   def.position.Set(toWorld(x), toWorld(y)); \tb2Body* r = wp-&gt;CreateBody(&def); \tb2PolygonShape box; -   box.SetAsBox(hw, hh); +   box.SetAsBox(toWorld(hw), toWorld(hh)); \tb2FixtureDef fd; \tfd.shape = &box; \tfd.density = 0; \tfd.friction = FRICTION; \tfd.restitution = RESTITUTION; \tr-&gt;CreateFixture(&fd); \tr-&gt;SetUserData(userData); \treturn r; }  b2Body* World::addBall(int x, int y, int r, IBox2DItem* userData) { \tif (ball != NULL) { \t\twp-&gt;DestroyBody(ball); \t} \tb2BodyDef def; \tdef.type = b2_dynamicBody; \tdef.linearDamping = 0.0f; \tdef.angularDamping = 0.0f; -   def.position.Set(x, y); +   def.position.Set(toWorld(x), toWorld(y)); \tball = wp-&gt;CreateBody(&def); \tb2CircleShape shape; \tshape.m_p.SetZero(); -   shape.m_radius = r + R_INVIS; +   shape.m_radius = toWorld(r) + R_INVIS; \tb2FixtureDef fd; \tfd.shape = &shape; \tfd.density = DYN_DENSITY; \tfd.friction = FRICTION; \tfd.restitution = RESTITUTION; \tball-&gt;CreateFixture(&fd); \tball-&gt;SetBullet(true); \tball-&gt;SetUserData(userData); \treturn ball; }  float32 World::getTimeStep() { \tuint64 t = s3eTimerGetMs(); \tint r = (int)(t - timestamp); \ttimestamp = t; \treturn (float32)r \/ 1000.0f; }  void World::start() { \tif (ball != NULL) { \t\tball-&gt;ApplyLinearImpulse(ball-&gt;GetWorldVector(b2Vec2(-10.0f, -10.0f)),  \t\t\t                     ball-&gt;GetWorldPoint(b2Vec2(0.0f, 0.0f))); \t} }  void World::update() { \tif (!isStarted) { \t\tisStarted = true; \t\tstart(); \t\ttimestamp = s3eTimerGetMs(); \t\tsrand((unsigned int)timestamp); \t} else { \t\tfloat32 timeStep = getTimeStep(); \t\twp-&gt;Step(timeStep, V_ITERATIONS, P_ITERATIONS); \t} }  void World::refresh() { \tif (ball != NULL) { \t\tb2Vec2 pos = ball-&gt;GetPosition(); \t\tBall* b = (Ball*)ball-&gt;GetUserData(); \t\tif (b != NULL) { -\t\tb-&gt;setXY(pos.x, pos.y); +\t\tb-&gt;setXY(fromWorld(pos.x), fromWorld(pos.y)); \t\t} \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u044d\u043a\u0440\u0430\u043d\u0430, \u00ab\u0448\u0438\u0440\u0438\u043d\u0430\u00bb \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u0438\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c 10 (\u043c\u0435\u0442\u0440\u043e\u0432). \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438 \u0443\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u0448\u0430\u0440\u0438\u043a \u043d\u0430\u0447\u0430\u043b \u043b\u0435\u0442\u0430\u0442\u044c \u0441 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u0438 \u043e\u0442\u0441\u043a\u0430\u043a\u0438\u0432\u0430\u0442\u044c \u043e\u0442 \u0441\u0442\u0435\u043d. \u0422\u0435\u043f\u0435\u0440\u044c, \u0434\u043e\u0431\u044c\u0435\u043c\u0441\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u00ab\u043a\u0438\u0440\u043f\u0438\u0447\u0438\u00bb \u0438\u0441\u0447\u0435\u0437\u0430\u043b\u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u0441 \u043d\u0438\u043c\u0438 \u0448\u0430\u0440\u0438\u043a\u0430.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Bricks.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#ifndef _BRICKS_H_ #define _BRICKS_H_  #include &quot;IwGL.h&quot; #include &quot;s3e.h&quot; #include &quot;Desktop.h&quot; #include &quot;World.h&quot; #include &quot;IBox2DItem.h&quot;  #define BRICK_COLOR_1      0xffffff00 #define BRICK_COLOR_2      0xff50ff00 #define BRICK_HALF_WIDTH   20 #define BRICK_HALF_HEIGHT  10  #include &lt;vector&gt;  using namespace std;  class Bricks: public IBox2DItem {     private:         struct SBrick {             SBrick(int x, int y): x(x),                                            y(y),                                            body(NULL),  \t\t\t\t\t\t\t\t\t\t  isBroken(false),                                           hw(BRICK_HALF_WIDTH),                                            hh(BRICK_HALF_HEIGHT),                                            ic(BRICK_COLOR_1),                                            oc(BRICK_COLOR_2) {}             SBrick(const SBrick& p): x(p.x),                                            y(p.y),                                            body(p.body),  \t\t\t\t\t\t\t\t\t\t  isBroken(p.isBroken),                                           hw(p.hw),                                            hh(p.hh),                                            ic(p.ic),                                            oc(p.oc) {}             int x, y, hw, hh, ic, oc; \t\t\tint isBroken; \t\t\tb2Body* body;         };         vector&lt;SBrick&gt; bricks; +       virtual bool impact(b2Body* b);     public:         Bricks(): bricks() {} \t\tvoid init() {} \t\tvoid release() {}         void refresh();         void clear(){bricks.clear();}         void add(SBrick& b);      typedef vector&lt;SBrick&gt;::iterator BIter;  \tfriend class Board; };  #endif\t\/\/ _BRICKS_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Bricks.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#include &quot;Bricks.h&quot; #include &quot;Quads.h&quot;  void Bricks::refresh() {     for (BIter p = bricks.begin(); p != bricks.end(); ++p) { \t    if (p-&gt;isBroken) continue;             CIwGLPoint point(p-&gt;x, p-&gt;y);             point = IwGLTransform(point);              int16* quadPoints = quads.getQuadPoints();             uint32* quadCols = quads.getQuadCols();             if ((quadPoints == NULL) || (quadCols == NULL)) break;              *quadPoints++ = point.x - p-&gt;hw;             *quadPoints++ = point.y + p-&gt;hh;             *quadCols++   = p-&gt;ic;              *quadPoints++ = point.x + p-&gt;hw;             *quadPoints++ = point.y + p-&gt;hh;             *quadCols++   = p-&gt;oc;              *quadPoints++ = point.x + p-&gt;hw;             *quadPoints++ = point.y - p-&gt;hh;             *quadCols++   = p-&gt;ic;              *quadPoints++ = point.x - p-&gt;hw;             *quadPoints++ = point.y - p-&gt;hh;             *quadCols++   = p-&gt;oc;     } }  +bool Bricks::impact(b2Body* b) { +    for (BIter p = bricks.begin(); p != bricks.end(); ++p) { +\t\tif (p-&gt;body == b) { +\t\t\tp-&gt;isBroken = true; +\t\t\treturn true; +\t\t} +\t} +\treturn false; +}  void Bricks::add(SBrick& b) {  \tb.body = world.addBrick(b.x, b.y, b.hw, b.hh, (IBox2DItem*)this);     bricks.push_back(b); } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#ifndef _WORLD_H_ #define _WORLD_H_  #include &lt;vector&gt; #include &lt;Box2D.h&gt; #include &quot;Desktop.h&quot; #include &quot;IBox2DItem.h&quot;  const float W_WIDTH     = 10.0f;  const int HALF_MARGIN   = 10; const int V_ITERATIONS  = 10; const int P_ITERATIONS  = 10;  const float FRICTION    = 0.0f; const float RESTITUTION = 1.0f; const float DYN_DENSITY = 0.0f; const float R_INVIS     = 0.0f; const float EPS         = 1.0f; const float SPEED_SQ    = 10.0f;  using namespace std;  -class World { +class World: public b2ContactListener { \tprivate: \t\tbool isStarted; \t\tint  HandleX, HandleH, HandleW; \t\tuint64 timestamp; \t\tint  width, height; \t\tb2World* wp; \t\tb2Body* ground; \t\tb2Body* ball; \t\tb2Body* handle; \t\tb2Body* createBox(int x, int y, int hw, int hh, IBox2DItem* userData = NULL); \t\tfloat32 getTimeStep(); +\tvector&lt;b2Body*&gt;* broken; \t\tvoid  start(); +\tvoid  impact(b2Body* b); +\tvirtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse); \t\tfloat toWorld(int x); \t\tint   fromWorld(float x); \tpublic: \t\tWorld(): broken(), width(0), height(0), wp(NULL) {} \t\tvoid init(); \t\tvoid release(); \t\tvoid update(); \t\tvoid refresh(); \t\tb2Body* addBrick(int x, int y, int hw, int hh, IBox2DItem* userData) {                       return createBox(x, y, hw, hh, userData);                 } \t\tb2Body* addBall(int x, int y, int r, IBox2DItem* userData);  +\ttypedef vector&lt;b2Body*&gt;::iterator BIter; };  extern World world;  #endif\t\/\/ _WORLD_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#include &quot;s3e.h&quot; #include &quot;World.h&quot; #include &quot;Ball.h&quot;  World world;  void World::init() { +   broken = new vector&lt;b2Body*&gt;(); \tisStarted = false; \twidth  = desktop.getWidth(); \theight = desktop.getHeight(); \tb2Vec2 gravity(0.0f, 0.0f); \twp = new b2World(gravity); +   wp-&gt;SetContactListener(this); \tground = createBox(width\/2, -HALF_MARGIN, width\/2, HALF_MARGIN); \tcreateBox(-HALF_MARGIN, height\/2, HALF_MARGIN, height\/2); \tcreateBox(width\/2, height + HALF_MARGIN, width\/2, HALF_MARGIN); \tcreateBox(width + HALF_MARGIN, height\/2, HALF_MARGIN, height\/2); \tball = NULL; \thandle = NULL; }  void World::release() { \tif (wp != NULL) { \t\tdelete wp; \t\twp = NULL; \t\tball = NULL; \t\thandle = NULL; \t} +   delete broken; }  float World::toWorld(int x) { \treturn ((float)x * W_WIDTH) \/ (float)desktop.getWidth(); }  int World::fromWorld(float x) { \treturn (int)((x * (float)desktop.getWidth()) \/ W_WIDTH); }  b2Body* World::createBox(int x, int y, int hw, int hh, IBox2DItem* userData) { \tb2BodyDef def; \tdef.type = b2_staticBody; \tdef.position.Set(toWorld(x), toWorld(y)); \tb2Body* r = wp-&gt;CreateBody(&def); \tb2PolygonShape box; \tbox.SetAsBox(toWorld(hw), toWorld(hh)); \tb2FixtureDef fd; \tfd.shape = &box; \tfd.density = 0; \tfd.friction = FRICTION; \tfd.restitution = RESTITUTION; \tr-&gt;CreateFixture(&fd); \tr-&gt;SetUserData(userData); \treturn r; }  b2Body* World::addBall(int x, int y, int r, IBox2DItem* userData) { \tif (ball != NULL) { \t\twp-&gt;DestroyBody(ball); \t} \tb2BodyDef def; \tdef.type = b2_dynamicBody; \tdef.linearDamping = 0.0f; \tdef.angularDamping = 0.0f; \tdef.position.Set(toWorld(x), toWorld(y)); \tball = wp-&gt;CreateBody(&def); \tb2CircleShape shape; \tshape.m_p.SetZero(); \tshape.m_radius = toWorld(r) + R_INVIS; \tb2FixtureDef fd; \tfd.shape = &shape; \tfd.density = DYN_DENSITY; \tfd.friction = FRICTION; \tfd.restitution = RESTITUTION; \tball-&gt;CreateFixture(&fd); \tball-&gt;SetBullet(true); \tball-&gt;SetUserData(userData); \treturn ball; }  float32 World::getTimeStep() { \tuint64 t = s3eTimerGetMs(); \tint r = (int)(t - timestamp); \ttimestamp = t; \treturn (float32)r \/ 1000.0f; }  void World::start() { \tif (ball != NULL) { \t\tball-&gt;ApplyLinearImpulse(ball-&gt;GetWorldVector(b2Vec2(-10.0f, -10.0f)),  \t\t\t                     ball-&gt;GetWorldPoint(b2Vec2(0.0f, 0.0f))); \t} }  +void World::impact(b2Body* b) { +\tIBox2DItem* it = (IBox2DItem*)b-&gt;GetUserData(); +\tif (it != NULL) { +\t\tif (it-&gt;impact(b)) { +\t\t\tfor (BIter p = broken-&gt;begin(); p != broken-&gt;end(); ++p) { +\t\t\t\tif (*p == b) return; +\t\t\t} +\t\t\tbroken-&gt;push_back(b); +\t\t} +\t} +}  +void World::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) { +\timpact(contact-&gt;GetFixtureA()-&gt;GetBody()); +\timpact(contact-&gt;GetFixtureB()-&gt;GetBody()); +}  void World::update() { \tif (!isStarted) { \t\tisStarted = true; \t\tstart(); \t\ttimestamp = s3eTimerGetMs(); \t\tsrand((unsigned int)timestamp); \t} else { \t\tfloat32 timeStep = getTimeStep(); \t\twp-&gt;Step(timeStep, V_ITERATIONS, P_ITERATIONS); \t} }  void World::refresh() { +   for (BIter p = broken-&gt;begin(); p != broken-&gt;end(); ++p) { +   \twp-&gt;DestroyBody(*p); +   } +   broken-&gt;clear(); \tif (ball != NULL) { \t\tb2Vec2 pos = ball-&gt;GetPosition(); \t\tBall* b = (Ball*)ball-&gt;GetUserData(); \t\tif (b != NULL) { \t\t\tb-&gt;setXY(fromWorld(pos.x), fromWorld(pos.y)); \t\t} \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0434\u0435\u0441\u044c, \u043a\u0430\u043a \u044f \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0432\u044b\u0448\u0435, \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0440\u0438 \u0440\u0430\u0441\u0441\u0447\u0435\u0442\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 b2World.Step (\u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u0435\u0441\u043b\u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 PostSolve). \u0422\u0430\u043a\u0436\u0435, \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e PostSolve \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u043d \u043e\u0434\u043d\u043e\u043a\u0440\u0430\u0442\u043d\u043e. \u0412\u043f\u043e\u043b\u043d\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u0432\u0430\u0436\u0434\u044b \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u00ab\u043a\u0438\u0440\u043f\u0438\u0447\u0430\u00bb. \u0415\u0441\u043b\u0438 \u043c\u044b \u0432\u043d\u0435\u0441\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 briken \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043c\u044b \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0440\u0430\u0437\u0440\u0443\u0448\u0438\u0442\u044c \u0435\u0433\u043e \u0434\u0432\u0430\u0436\u0434\u044b, \u0447\u0442\u043e \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u0440\u0430\u0437\u0440\u0443\u0448\u0435\u043d\u0438\u044e \u043f\u0430\u043c\u044f\u0442\u0438. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 broken \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043a\u043e\u043f\u0438\u0442\u044c\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u043f\u043e\u0438\u0441\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 \u0432\u0435\u043a\u0442\u043e\u0440\u0435 \u043d\u0430\u0441 \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u043f\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0440\u0430\u043a\u0435\u0442\u043a\u0443. \u041f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e, \u044f \u0445\u043e\u0442\u0435\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u043a\u0435\u0442\u043a\u0443 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c, \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432 \u0435\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 PrismaticJoint. \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0435\u0435 \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438, \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e-\u0431\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f MouseJoint. \u041d\u043e \u043f\u043e\u0442\u043e\u043c, \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e <a href=\"http:\/\/ru.wikipedia.org\/wiki\/KISS_%28%D0%BF%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF%29\">\u043d\u0430\u0434\u043e \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0449\u0435<\/a>. <\/p>\n<p>  \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u043a\u0435\u0442\u043a\u0443 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u0430\u0447\u043d\u043e. Box2D \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u0441\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u044d\u0442\u0430 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u043e\u0436\u043d\u0430\u044f, \u0447\u0442\u043e \u0434\u0430\u0436\u0435 Box2D \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e \u0441 \u043d\u0435\u0439 \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 SetBullet \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442, \u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u0441\u043b\u0443\u0447\u0430\u0438 \u043a\u043e\u0433\u0434\u0430 \u0448\u0430\u0440\u0438\u043a \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u043b\u0435\u0442\u0430\u0442\u044c \u0441\u043a\u0432\u043e\u0437\u044c \u0440\u0430\u043a\u0435\u0442\u043a\u0443, \u0447\u0442\u043e, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0440\u0430\u043a\u0435\u0442\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c. \u041c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0442\u044c \u0435\u0435 \u043c\u0435\u0436\u0434\u0443 \u0448\u0430\u0433\u0430\u043c\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432 \u043d\u043e\u0432\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438. \u041f\u043e\u043c\u0438\u043c\u043e \u043f\u0440\u043e\u0447\u0435\u0433\u043e, \u044d\u0442\u043e\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>  \u0412\u043d\u0435\u0441\u0435\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">arcanoid.mkb<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#!\/usr\/bin\/env mkb options {      module_path=&quot;..\/yaml&quot;      module_path=&quot;..\/box2d&quot; } subprojects {     iwgl     yaml     box2d }  includepath {     .\/source\/Main     .\/source\/Model } files {     [Main]     (source\/Main)     Main.cpp     Main.h     Quads.cpp     Quads.h            Desktop.cpp     Desktop.h     IO.cpp     IO.h +   TouchPad.cpp +   TouchPad.h      [Model]     (source\/Model)     Bricks.cpp     Bricks.h     Ball.cpp     Ball.h     Board.cpp     Board.h +   Handle.cpp +   Handle.h } assets {     (data)     level.json } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c TouchPad \u0432\u043e\u0437\u044c\u043c\u0435\u043c <a href=\"http:\/\/www.drmop.com\/index.php\/2011\/09\/24\/marmalade-sdk-tutorial-touch-and-multi-touch\/\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">TouchPad.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#ifndef _TOUCHPAD_H_ #define _TOUCHPAD_H_  #include &quot;s3ePointer.h&quot; #include &quot;Desktop.h&quot;  #define MAX_TOUCHES\t3  enum EMessageType { \temtNothing                                                      = 0x00, \temtTouchEvent                                                   = 0x10, \temtTouchIdMask                                                  = 0x03,     emtTouchMask                                                    = 0x78,     emtMultiTouch                                                   = 0x14,     emtTouchOut                                                     = 0x18, \temtTouchDown                                                    = 0x30, \temtTouchUp                                                      = 0x50, \temtTouchOutUp                                                   = 0x58, \temtTouchMove                                                    = 0x70, \temtSingleTouchDown                                              = 0x30, \temtSingleTouchUp                                                = 0x50, \temtSingleTouchMove                                              = 0x70, \temtMultiTouchDown                                               = 0x34, \temtMultiTouchUp                                                 = 0x54, \temtMultiTouchMove                                               = 0x74 };  struct Touch { \t\tint\t\tx, y; \t\tbool\tisActive, isPressed, isMoved; \t\tint\t\tid;\t };  class TouchPad { \tprivate: \t\tbool\t\tIsAvailable; \t\tbool\t\tIsMultiTouch; \t\tTouch\t\tTouches[MAX_TOUCHES]; \t\tTouch*\t\tfindTouch(int id);\t\t\t\t\t\t\t\t \t\tstatic      void HandleMultiTouchButton(s3ePointerTouchEvent* event); \t\tstatic      void HandleMultiTouchMotion(s3ePointerTouchMotionEvent* event); \tpublic:         static bool isTouchDown(int eventCode);         static bool isTouchUp(int eventCode); \t\tbool\t\tisAvailable() const { return IsAvailable; } \t\tbool\t\tisMultiTouch() const { return IsMultiTouch; } \t\tTouch*\t\tgetTouchByID(int id); \t\tTouch*\t\tgetTouch(int index) { return &Touches[index]; }\t \t\tTouch*\t\tgetTouchPressed(); \t\tint\t\t\tgetTouchCount() const;  \t\tbool\t\tinit(); \t\tvoid\t\trelease(); \t\tvoid\t\tupdate(); \t\tvoid\t\tclear(); };  extern TouchPad touchPad;  #endif\t\/\/ _TOUCHPAD_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">TouchPad.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &quot;TouchPad.h&quot;  TouchPad touchPad;  bool TouchPad::isTouchDown(int eventCode) {     return (eventCode & emtTouchMask) == emtTouchDown; }   bool TouchPad::isTouchUp(int eventCode) {     return (eventCode & emtTouchMask) == emtTouchUp; }  void TouchPad::HandleMultiTouchButton(s3ePointerTouchEvent* event) { \tTouch* touch = touchPad.findTouch(event-&gt;m_TouchID);     if (touch != NULL) {         touch-&gt;isPressed = event-&gt;m_Pressed != 0;          touch-&gt;isActive  = true;         touch-&gt;x  = event-&gt;m_x;         touch-&gt;y  = event-&gt;m_y; \t\ttouch-&gt;id = event-&gt;m_TouchID;     } }  void TouchPad::HandleMultiTouchMotion(s3ePointerTouchMotionEvent* event) { \tTouch* touch = touchPad.findTouch(event-&gt;m_TouchID);     if (touch != NULL) { \t\tif (touch-&gt;isActive) { \t\t\ttouch-&gt;isMoved = true; \t\t}         touch-&gt;isActive  = true;         touch-&gt;x = event-&gt;m_x;         touch-&gt;y = event-&gt;m_y;     } }  void HandleSingleTouchButton(s3ePointerEvent* event) { \tTouch* touch = touchPad.getTouch(0);     touch-&gt;isPressed = event-&gt;m_Pressed != 0;     touch-&gt;isActive  = true;     touch-&gt;x  = event-&gt;m_x;     touch-&gt;y  = event-&gt;m_y; \ttouch-&gt;id = 0; }  void HandleSingleTouchMotion(s3ePointerMotionEvent* event) { \tTouch* touch = touchPad.getTouch(0); \tif (touch-&gt;isActive) { \t\ttouch-&gt;isMoved = true; \t}     touch-&gt;isActive  = true;     touch-&gt;x = event-&gt;m_x;     touch-&gt;y = event-&gt;m_y; }  Touch* TouchPad::getTouchByID(int id) { \tfor (int i = 0; i &lt; MAX_TOUCHES; i++) { \t\tif (Touches[i].isActive && Touches[i].id == id) \t\t\treturn &Touches[i]; \t} \treturn NULL; }  Touch* TouchPad::getTouchPressed() { \tfor (int i = 0; i &lt; MAX_TOUCHES; i++) { \t\tif (Touches[i].isPressed && Touches[i].isActive) \t\t\treturn &Touches[i]; \t} \treturn NULL; }  Touch* TouchPad::findTouch(int id) { \tif (!IsAvailable) \t\treturn NULL; \tfor (int i = 0; i &lt; MAX_TOUCHES; i++) { \t\tif (Touches[i].id == id) \t\t\treturn &Touches[i];     } \tfor (int i = 0; i &lt; MAX_TOUCHES; i++) { \t\tif (!Touches[i].isActive)\t{             Touches[i].id = id; \t\t\treturn &Touches[i]; \t\t} \t} \treturn NULL; }  int\tTouchPad::getTouchCount() const { \tif (!IsAvailable) \t\treturn 0; \tint r = 0; \tfor (int i = 0; i &lt; MAX_TOUCHES; i++) { \t\tif (Touches[i].isActive) {             r++; \t\t} \t} \treturn r; }  void TouchPad::update() { \tfor (int i = 0; i &lt; MAX_TOUCHES; i++) { \t\tTouches[i].isMoved = false; \t} \tif (IsAvailable) { \t\ts3ePointerUpdate(); \t} }  void TouchPad::clear() { \tfor (int i = 0; i &lt; MAX_TOUCHES; i++) { \t\tif (!Touches[i].isPressed) { \t\t\tTouches[i].isActive = false; \t\t} \t\tTouches[i].isMoved = false; \t} }  bool TouchPad::init() {     IsAvailable = s3ePointerGetInt(S3E_POINTER_AVAILABLE) ? true : false; \tif (!IsAvailable) return false; \tfor (int i = 0; i &lt; MAX_TOUCHES; i++) { \t\tTouches[i].isPressed = false; \t\tTouches[i].isActive = false; \t\tTouches[i].isMoved = false; \t\tTouches[i].id = 0; \t}     IsMultiTouch = s3ePointerGetInt(S3E_POINTER_MULTI_TOUCH_AVAILABLE) ? true : false;     if (IsMultiTouch) {         s3ePointerRegister(S3E_POINTER_TOUCH_EVENT, (s3eCallback)HandleMultiTouchButton, NULL);         s3ePointerRegister(S3E_POINTER_TOUCH_MOTION_EVENT, (s3eCallback)HandleMultiTouchMotion, NULL);     } else {         s3ePointerRegister(S3E_POINTER_BUTTON_EVENT, (s3eCallback)HandleSingleTouchButton, NULL);         s3ePointerRegister(S3E_POINTER_MOTION_EVENT, (s3eCallback)HandleSingleTouchMotion, NULL);     } \treturn true; }  void TouchPad::release() { \tif (IsAvailable) { \t\tif (IsMultiTouch) { \t\t\ts3ePointerUnRegister(S3E_POINTER_TOUCH_EVENT, (s3eCallback)HandleMultiTouchButton); \t\t\ts3ePointerUnRegister(S3E_POINTER_TOUCH_MOTION_EVENT, (s3eCallback)HandleMultiTouchMotion); \t\t} else { \t\t\ts3ePointerUnRegister(S3E_POINTER_BUTTON_EVENT, (s3eCallback)HandleSingleTouchButton); \t\t\ts3ePointerUnRegister(S3E_POINTER_MOTION_EVENT, (s3eCallback)HandleSingleTouchMotion); \t\t} \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">IO.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#ifndef _IO_H_ #define _IO_H_  #include &quot;TouchPad.h&quot;  class IO {     private:         bool KeysAvailable;     public:         void init();         void release();         void update();         void refresh(); \t    bool isKeyDown(s3eKey key) const; };  extern IO io;  #endif\t\/\/ _IO_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">IO.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &quot;s3e.h&quot; #include &quot;IO.h&quot;  IO io;  void IO::init() { \ttouchPad.init(); }  void IO::release() { \ttouchPad.release(); }  void IO::update() { \ttouchPad.update();     s3eKeyboardUpdate(); }  void IO::refresh() { \ttouchPad.clear(); }  bool IO::isKeyDown(s3eKey key) const {     return (s3eKeyboardGetState(key) & S3E_KEY_STATE_DOWN) == S3E_KEY_STATE_DOWN; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c Handle:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Handle.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#ifndef _HANDLE_H_ #define _HANDLE_H_  #include &quot;IwGL.h&quot; #include &quot;s3e.h&quot;  #include &quot;Desktop.h&quot; #include &quot;World.h&quot; #include &quot;IBox2DItem.h&quot;  #define HANDLE_COLOR        0xffff3000 #define HANDLE_H_WIDTH      40 #define HANDLE_H_HEIGHT     10 #define HANDLE_H_POS        50  class Handle: public IBox2DItem { \tprivate:         int     x;         int     y; \t\tint     touchId; \tpublic:         void init();         void release() {}         void refresh();         void update(); \t\tvirtual void setXY(int X, int Y); };  #endif\t\/\/ _HANDLE_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Handle.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &quot;Handle.h&quot; #include &quot;Quads.h&quot; #include &quot;TouchPad.h&quot;  void Handle::init() {     x = desktop.getWidth() \/ 2; \ty = desktop.getHeight(); \ttouchId = -1; }  void Handle::setXY(int X, int Y) { \tx = X; \ty = Y; }  void Handle::refresh() {     CIwGLPoint point(x, y);     point = IwGLTransform(point);      int16* quadPoints = quads.getQuadPoints();     uint32* quadCols = quads.getQuadCols();     if ((quadPoints == NULL) || (quadCols == NULL)) return;      *quadPoints++ = point.x - desktop.toRSize(HANDLE_H_WIDTH);     *quadPoints++ = point.y + desktop.toRSize(HANDLE_H_HEIGHT);     *quadCols++   = HANDLE_COLOR;      *quadPoints++ = point.x + desktop.toRSize(HANDLE_H_WIDTH);     *quadPoints++ = point.y + desktop.toRSize(HANDLE_H_HEIGHT);     *quadCols++   = HANDLE_COLOR;      *quadPoints++ = point.x + desktop.toRSize(HANDLE_H_WIDTH);     *quadPoints++ = point.y - desktop.toRSize(HANDLE_H_HEIGHT);     *quadCols++   = HANDLE_COLOR;      *quadPoints++ = point.x - desktop.toRSize(HANDLE_H_WIDTH);     *quadPoints++ = point.y - desktop.toRSize(HANDLE_H_HEIGHT);     *quadCols++   = HANDLE_COLOR;  \tworld.addHandle(x, y, desktop.toRSize(HANDLE_H_WIDTH), desktop.toRSize(HANDLE_H_HEIGHT), (IBox2DItem*)this); }  void Handle::update() { \tTouch* t = NULL; \tif (touchId &gt; 0) { \t\tt = touchPad.getTouchByID(touchId); \t} else { \t\tt = touchPad.getTouchPressed(); \t} \tif (t != NULL) { \t\ttouchId = t-&gt;id; \t\tworld.moveHandle(t-&gt;x, t-&gt;y); \t} else { \t\ttouchId = -1; \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0418 \u0432\u043d\u0435\u0441\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 World \u0438 Board:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#ifndef _WORLD_H_ #define _WORLD_H_  #include &lt;vector&gt; #include &lt;Box2D.h&gt; #include &quot;Desktop.h&quot; #include &quot;IBox2DItem.h&quot;  const float W_WIDTH     = 10.0f;  const int HALF_MARGIN   = 10; const int V_ITERATIONS  = 10; const int P_ITERATIONS  = 10;  const float FRICTION    = 0.0f; const float RESTITUTION = 1.0f; const float DYN_DENSITY = 0.0f; const float R_INVIS     = 0.0f; const float EPS         = 1.0f; const float SPEED_SQ    = 10.0f;  using namespace std;  class World: public b2ContactListener { \tprivate: \t\tbool isStarted; +\tbool isHandleCreated; \t\tint  HandleX, HandleH, HandleW; \t\tuint64 timestamp; \t\tint  width, height; \t\tb2World* wp; \t\tb2Body* ground; \t\tb2Body* ball; \t\tb2Body* handle; \t\tb2Body* createBox(int x, int y, int hw, int hh, IBox2DItem* userData = NULL); \t\tfloat32 getTimeStep(); \t\tvector&lt;b2Body*&gt;* broken; \t\tvoid  start(); \t\tvoid  impact(b2Body* b); \t    virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse); \t\tfloat toWorld(int x); \t\tint   fromWorld(float x); \tpublic: \t\tWorld(): broken(), width(0), height(0), wp(NULL) {} \t\tvoid init(); \t\tvoid release(); \t\tvoid update(); \t\tvoid refresh(); \t\tb2Body* addBrick(int x, int y, int hw, int hh, IBox2DItem* userData) {return createBox(x, y, hw, hh, userData);} \t\tb2Body* addBall(int x, int y, int r, IBox2DItem* userData); +\tb2Body* addHandle(int x, int y, int hw, int hh, IBox2DItem* userData); +\tvoid    moveHandle(int x, int y);  \t\ttypedef vector&lt;b2Body*&gt;::iterator BIter; };  extern World world;  #endif\t\/\/ _WORLD_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">World.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#include &quot;s3e.h&quot; #include &quot;World.h&quot; #include &quot;Ball.h&quot;  World world;  void World::init() { \tbroken = new vector&lt;b2Body*&gt;(); \tisStarted = false; \twidth  = desktop.getWidth(); \theight = desktop.getHeight(); \tb2Vec2 gravity(0.0f, 0.0f); \twp = new b2World(gravity); \twp-&gt;SetContactListener(this); \tground = createBox(width\/2, -HALF_MARGIN, width\/2, HALF_MARGIN); \tcreateBox(-HALF_MARGIN, height\/2, HALF_MARGIN, height\/2); \tcreateBox(width\/2, height + HALF_MARGIN, width\/2, HALF_MARGIN); \tcreateBox(width + HALF_MARGIN, height\/2, HALF_MARGIN, height\/2); \tball = NULL; \thandle = NULL; }  void World::release() { \tif (wp != NULL) { \t\tdelete wp; \t\twp = NULL; \t\tball = NULL; \t\thandle = NULL; \t}     delete broken; }  float World::toWorld(int x) { \treturn ((float)x * W_WIDTH) \/ (float)desktop.getWidth(); }  int World::fromWorld(float x) { \treturn (int)((x * (float)desktop.getWidth()) \/ W_WIDTH); }  b2Body* World::createBox(int x, int y, int hw, int hh, IBox2DItem* userData) { \tb2BodyDef def; \tdef.type = b2_staticBody; \tdef.position.Set(toWorld(x), toWorld(y)); \tb2Body* r = wp-&gt;CreateBody(&def); \tb2PolygonShape box; \tbox.SetAsBox(toWorld(hw), toWorld(hh)); \tb2FixtureDef fd; \tfd.shape = &box; \tfd.density = 0; \tfd.friction = FRICTION; \tfd.restitution = RESTITUTION; \tr-&gt;CreateFixture(&fd); \tr-&gt;SetUserData(userData); \treturn r; }  b2Body* World::addBall(int x, int y, int r, IBox2DItem* userData) { \tif (ball != NULL) { \t\twp-&gt;DestroyBody(ball); \t} \tb2BodyDef def; \tdef.type = b2_dynamicBody; \tdef.linearDamping = 0.0f; \tdef.angularDamping = 0.0f; \tdef.position.Set(toWorld(x), toWorld(y)); \tball = wp-&gt;CreateBody(&def); \tb2CircleShape shape; \tshape.m_p.SetZero(); \tshape.m_radius = toWorld(r) + R_INVIS; \tb2FixtureDef fd; \tfd.shape = &shape; \tfd.density = DYN_DENSITY; \tfd.friction = FRICTION; \tfd.restitution = RESTITUTION; \tball-&gt;CreateFixture(&fd); \tball-&gt;SetBullet(true); \tball-&gt;SetUserData(userData); \treturn ball; }  +b2Body* World::addHandle(int x, int y, int hw, int hh, IBox2DItem* userData) { +\tHandleW = hw; HandleH = hh; +\tif (handle != NULL) { +\t\twp-&gt;DestroyBody(handle); +\t} +\tb2BodyDef def; +\tdef.type = b2_staticBody; +\tdef.position.Set(toWorld(x), toWorld(y)); +\thandle = wp-&gt;CreateBody(&def); +\tb2PolygonShape box; +\tbox.SetAsBox(toWorld(hw), toWorld(hh)); +\tb2FixtureDef fd; +\tfd.shape = &box; +\tfd.density = DYN_DENSITY; +\tfd.friction = FRICTION; +\tfd.restitution = RESTITUTION; +\thandle-&gt;CreateFixture(&fd); +\thandle-&gt;SetUserData(userData); +\treturn handle; +}  +void World::moveHandle(int x, int y) { +\tisHandleCreated = true; +\tHandleX = x; +}  float32 World::getTimeStep() { \tuint64 t = s3eTimerGetMs(); \tint r = (int)(t - timestamp); \ttimestamp = t; \treturn (float32)r \/ 1000.0f; }  void World::start() { \tif (ball != NULL) { \t\tball-&gt;ApplyLinearImpulse(ball-&gt;GetWorldVector(b2Vec2(-10.0f, -10.0f)),  \t\t\t                     ball-&gt;GetWorldPoint(b2Vec2(0.0f, 0.0f))); \t} }  void World::impact(b2Body* b) { \tIBox2DItem* it = (IBox2DItem*)b-&gt;GetUserData(); \tif (it != NULL) { \t\tif (it-&gt;impact(b)) { \t\t\tfor (BIter p = broken-&gt;begin(); p != broken-&gt;end(); ++p) { \t\t\t\tif (*p == b) return; \t\t\t} \t\t\tbroken-&gt;push_back(b); \t\t} \t} }  void World::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) { \timpact(contact-&gt;GetFixtureA()-&gt;GetBody()); \timpact(contact-&gt;GetFixtureB()-&gt;GetBody()); }  void World::update() { \tif (!isStarted) { \t\tisStarted = true; \t\tstart(); \t\ttimestamp = s3eTimerGetMs(); \t\tsrand((unsigned int)timestamp); \t} else { \t\tfloat32 timeStep = getTimeStep(); \t\twp-&gt;Step(timeStep, V_ITERATIONS, P_ITERATIONS); \t} }  void World::refresh() { \tfor (BIter p = broken-&gt;begin(); p != broken-&gt;end(); ++p) { \t\twp-&gt;DestroyBody(*p); \t} \tbroken-&gt;clear(); +\tif (isHandleCreated) { +\t\tif (handle != NULL) { +\t\t\tint y = fromWorld(handle-&gt;GetPosition().y); +\t\t\tIBox2DItem* data = (IBox2DItem*)handle-&gt;GetUserData(); +\t\t\tif (HandleX &lt; HandleW) { +\t\t\t\tHandleX = HandleW; +\t\t\t} +\t\t\tif (HandleX &gt; desktop.getWidth() - HandleW) { +\t\t\t\tHandleX = desktop.getWidth() - HandleW; +\t\t\t} +\t\t\thandle = addHandle(HandleX, y, HandleW, HandleH, data); +\t\t\tb2Vec2 pos = handle-&gt;GetPosition(); +\t\t\tdata-&gt;setXY(fromWorld(pos.x), fromWorld(pos.y)); +\t\t} +\t} \tif (ball != NULL) { \t\tb2Vec2 pos = ball-&gt;GetPosition(); \t\tBall* b = (Ball*)ball-&gt;GetUserData(); \t\tif (b != NULL) { \t\t\tb-&gt;setXY(fromWorld(pos.x), fromWorld(pos.y)); \t\t} \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Board.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#ifndef _BOARD_H_ #define _BOARD_H_  #include &lt;yaml.h&gt; #include &lt;vector&gt; #include &lt;String&gt;  #include &quot;Bricks.h&quot; #include &quot;Ball.h&quot; +#include &quot;Handle.h&quot;  #define MAX_NAME_SZ   100  using namespace std;  enum EBrickMask {     ebmX            = 0x01,     ebmY            = 0x02,     ebmComplete     = 0x03,     ebmWidth        = 0x04,     ebmHeight       = 0x08,     ebmIColor       = 0x10,     ebmOColor       = 0x20 };  class Board {     private:         struct Type {             Type(const char* s, const char* n, const char* v): s(s), n(n), v(v) {}             Type(const Type& p): s(p.s), n(p.n), v(p.v) {}             string s, n, v;         };         Bricks bricks;         Ball ball; +       Handle handle;         yaml_parser_t parser;         yaml_event_t event;         vector&lt;string&gt; scopes;         vector&lt;Type&gt; types;         char currName[MAX_NAME_SZ];         int  brickMask;         int  brickX, brickY, brickW, brickH, brickIC, brickOC;         bool isTypeScope;         void load();         void clear();         void notify();         const char* getScopeName();         void setProperty(const char* scope, const char* name, const char* value);         void closeTag(const char* scope);         int  fromNum(const char* s);     public:         Board(): scopes(), types() {}         void init();         void release();         void refresh();         void update();      typedef vector&lt;string&gt;::iterator SIter;     typedef vector&lt;Type&gt;::iterator TIter; };  #endif\t\/\/ _BOARD_H_ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Board.cpp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">#include &quot;Board.h&quot; #include &quot;Desktop.h&quot;  const char* BOARD_SCOPE      = &quot;board&quot;; const char* LEVEL_SCOPE      = &quot;level&quot;; const char* TYPE_SCOPE       = &quot;types&quot;;  const char* TYPE_PROPERTY    = &quot;type&quot;; const char* WIDTH_PROPERTY   = &quot;width&quot;; const char* HEIGHT_PROPERTY  = &quot;height&quot;; const char* IC_PROPERTY      = &quot;inner_color&quot;; const char* OC_PROPERTY      = &quot;outer_color&quot;; const char* X_PROPERTY       = &quot;x&quot;; const char* Y_PROPERTY       = &quot;y&quot;;  void Board::init() {     ball.init();     bricks.init(); +   handle.init();     load(); }  void Board::release() { +   handle.release();     bricks.release();     ball.release(); }  ... void Board::refresh() {     bricks.refresh();     ball.refresh(); +   handle.refresh(); }  +void Board::update() { +   handle.update(); +} <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435. \u0422\u0435\u043f\u0435\u0440\u044c, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f \u0438\u0433\u0440\u044b Arcanoid, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u043a \u0434\u043b\u044f Android, \u0442\u0430\u043a \u0438 \u043f\u043e\u0434 iPhone.      \t \t\t   \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/166929\/\"> http:\/\/habrahabr.ru\/post\/166929\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t\u0421\u0435\u0433\u043e\u0434\u043d\u044f, \u043a\u0430\u043a \u044f \u0438 \u043e\u0431\u0435\u0449\u0430\u043b, \u043c\u044b \u0432\u0434\u043e\u0445\u043d\u0435\u043c \u0432 \u043d\u0430\u0448 <a href=\"http:\/\/habrahabr.ru\/post\/165667\/\">Arcanoid<\/a> \u0436\u0438\u0437\u043d\u044c. \u0417\u0430\u0441\u0442\u0430\u0432\u0438\u043c \u0448\u0430\u0440\u0438\u043a \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f, \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044f\u0441\u044c \u0441 \u043a\u0438\u0440\u043f\u0438\u0447\u0430\u043c\u0438, \u0430 \u043a\u0438\u0440\u043f\u0438\u0447\u0438, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u0438\u0433\u0440\u043e\u0432\u0430\u044f \u0444\u0438\u0437\u0438\u043a\u0430 \u0432 arcanoid \u043d\u0435 \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u0430 \u0438 \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u0438\u043b\u0430\u043c\u0438. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432 \u043d\u0435\u0439 \u2014 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0439. \u041d\u043e \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u00ab\u0432\u0437\u0440\u043e\u0441\u043b\u044b\u0435\u00bb \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0434\u0432\u0438\u0436\u043a\u0438 \u0443\u043c\u0435\u044e\u0442 \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u043e!<\/p>\n<p>  \u0422\u0430\u043a \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u0438\u0445 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c? \u041a \u0442\u043e\u043c\u0443-\u0436\u0435, \u0435\u0441\u043b\u0438 \u043c\u044b \u043e\u0444\u043e\u0440\u043c\u0438\u043c Box2D \u0432 \u0432\u0438\u0434\u0435 \u043c\u043e\u0434\u0443\u043b\u044f <a href=\"http:\/\/www.madewithmarmalade.com\/\">Marmalade<\/a>, \u0432\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0438 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0445 \u0431\u043e\u043b\u0435\u0435 \u0438\u0437\u043e\u0449\u0440\u0435\u043d\u043d\u043e\u0439 \u00ab\u0444\u0438\u0437\u0438\u043a\u0438\u00bb. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u0438\u043c \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-166929","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/166929","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=166929"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/166929\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=166929"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=166929"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=166929"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}