{"id":161849,"date":"2012-12-08T11:16:04","date_gmt":"2012-12-08T07:16:04","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=161849"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=161849","title":{"rendered":"<span class=\"post_title\">Framework \u0432 \u041c\u0430\u0440\u043c\u0435\u043b\u0430\u0434\u0435 (\u0447\u0430\u0441\u0442\u044c 2)<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 <a href=\"http:\/\/habrahabr.ru\/post\/161681\/\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e Framework-\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f 2D-\u0438\u0433\u0440, \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b <a href=\"http:\/\/www.madewithmarmalade.com\/\">Marmalade<\/a>, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0440\u044f\u0434\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 iOS \u0438 Android. \u041c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438 \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0431 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043d\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u0445, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f TouchPad, \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0441\u0435\u043d\u0441\u043e\u0440\u043d\u044b\u043c \u044d\u043a\u0440\u0430\u043d\u043e\u043c. \u041d\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f Multitouch, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0441\u0430\u043d\u0438\u0439 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0438\u0433\u0440\u043e\u0432\u043e\u0439 Framework \u0434\u043e\u043b\u0436\u0435\u043d \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c Multitouch-\u0441\u043e\u0431\u044b\u0442\u0438\u044f.<\/p>\n<p>  \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u043d\u0435\u0435 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439 (\u043d\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u0445) \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430. \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u0430 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u043c\u043d\u043e\u0433\u043e \u043a\u043d\u043e\u043f\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043e\u0442 \u043d\u0438\u0445 \u0441\u043a\u043e\u043b\u044c-\u043d\u0438\u0431\u0443\u0434\u044c \u0437\u043d\u0430\u0447\u0438\u043c\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e. \u041d\u043e \u0435\u0441\u0442\u044c \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043e\u0434\u043d\u043e \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u0435\u043b\u043e \u0441\u0435\u0431\u044f \u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e (\u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u043e\u0434 Android). \u0420\u0435\u0447\u044c \u0438\u0434\u0435\u0442 \u043e\u0431 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f s3eKeyAbsBSK, \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0438 \u00ab\u041d\u0430\u0437\u0430\u0434\u00bb. \u041f\u043e \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u044f\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430 Android, \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u044d\u0442\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439.<\/p>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 (\u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0430\u043a\u0441\u0435\u043b\u0435\u0440\u043e\u043c\u0435\u0442\u0440), \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443, \u0445\u043e\u0442\u044f \u043e\u043d\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0438\u0445 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>  \u041d\u0430\u0447\u043d\u0435\u043c \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0443 Marmalade Framework \u0441 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 Touchpad-\u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 mkb-\u0444\u0430\u0439\u043b.<\/p>\n<p>  <u><b>mf.mkb:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#!\/usr\/bin\/env mkb ... files {     [Main]     (source\/Main)     ...     TouchPad.cpp     TouchPad.h } ... <\/code><\/pre>\n<p>  <u><b>TouchPad.h:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#ifndef _TOUCHPAD_H_ #define _TOUCHPAD_H_  #include &quot;IwGeom.h&quot; #include &quot;s3ePointer.h&quot;  #define MAX_TOUCHES\t11  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]; \tpublic:         static bool isTouchDown(int eventCode);         static bool isTouchUp(int eventCode); \t\tbool             isAvailable() const { return IsAvailable; } \t\tbool             isMultiTouch() const { return IsMultiTouch; } \t\tTouch*           getTouchByID(int id); \t\tTouch*           getTouch(int index) { return &Touches[index]; }\t \t\tTouch*           findTouch(int id);\t\t\t\t\t\t\t\t \t\tint              getTouchCount() 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>  <u><b>TouchPad.cpp:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#include &quot;TouchPad.h&quot; #include &quot;Desktop.h&quot;  TouchPad touchPad;  bool TouchPad::isTouchDown(int eventCode) {     return (eventCode & emtTouchMask) == emtTouchDown; }   bool TouchPad::isTouchUp(int eventCode) {     return (eventCode & emtTouchMask) == emtTouchUp; }  void 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 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::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>  \u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0430. \u041c\u043e\u0434\u0443\u043b\u044c Touchpad \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043a\u0440\u044b\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u0430\u043a\u0442 \u043e\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c mkb-\u0444\u0430\u0439\u043b \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043d\u043e\u0432\u0430. \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043c\u043e\u0434\u0443\u043b\u044c TouchPad \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432 C++ \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<p>  \u0412\u043d\u0435\u0441\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432 \u043c\u043e\u0434\u0443\u043b\u044c Desktop.<\/p>\n<p>  <u><b>Desktop.h:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#ifndef _DESKTOP_H_ #define _DESKTOP_H_  #include &lt;set&gt; #include &quot;s3eKeyboard.h&quot; #include &quot;Scene.h&quot;  using namespace std;  enum EMessageType {     emtNothing                                                      = 0x00,      emtTouchEvent                                                   = 0x10,     emtTouchIdMask                                                  = 0x07,     emtTouchMask                                                    = 0x70,     emtMultiTouch                                                   = 0x14,     emtTouchDown                                                    = 0x30,     emtTouchUp                                                      = 0x50,     emtTouchMove                                                    = 0x70,     emtSingleTouchDown                                              = 0x30,     emtSingleTouchUp                                                = 0x50,     emtSingleTouchMove                                              = 0x70,     emtMultiTouchDown                                               = 0x34,     emtMultiTouchUp                                                 = 0x54,     emtMultiTouchMove                                               = 0x74,      emtKeyEvent                                                     = 0x80,     emtKeyAction                                                    = 0x82,     emtKeyDown                                                      = 0x81,     emtKeyPressed                                                   = 0x83,     emtKeyReleased                                                  = 0x82 };  class Desktop {     private:         int width, height;         bool isChanged;         Scene* currentScene;         bool isKeyAvailable;         bool IsQuitMessageReceived;         bool checkBounce(int id, int msg);         void getScreenSizes();         static int32 ScreenSizeChangeCallback(void* systemData, void* userData);     public:         Desktop(): touches() {}         void init();         void release();         void update(uint64 timestamp);         void refresh();         int getWidth() const {return width;}         int getHeight() const {return height;}         Scene* getScene() {return currentScene;}         void setScene(Scene* scene);         void sendQuitMessage() {IsQuitMessageReceived = true;}         bool isQuitMessageReceived();         set&lt;int&gt; touches;     typedef set&lt;int&gt;::iterator TIter; };         extern Desktop desktop;  #endif    \/\/ _DESKTOP_H_ <\/code><\/pre>\n<p>  <u><b>Desktop.cpp:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#include &quot;Desktop.h&quot; #include &quot;Iw2D.h&quot;  #include &quot;TouchPad.h&quot;  Desktop desktop;  void Desktop::init() {     IsQuitMessageReceived = false;     getScreenSizes();     setScene(NULL);     isKeyAvailable = (s3eKeyboardGetInt(S3E_KEYBOARD_HAS_KEYPAD)                                       || s3eKeyboardGetInt(S3E_KEYBOARD_HAS_ALPHA));     s3eSurfaceRegister(S3E_SURFACE_SCREENSIZE, ScreenSizeChangeCallback, NULL); }  void Desktop::release() {     s3eSurfaceUnRegister(S3E_SURFACE_SCREENSIZE, ScreenSizeChangeCallback);     touches.clear(); }  int32 Desktop::ScreenSizeChangeCallback(void* systemData, void* userData) {     desktop.isChanged = true;     return 0; }  void Desktop::setScene(Scene* scene) {     if (scene != NULL) {         scene-&gt;init();     }     currentScene = scene; }  void Desktop::getScreenSizes() {     width = Iw2DGetSurfaceWidth();     height = Iw2DGetSurfaceHeight();     isChanged = false; }  bool Desktop::checkBounce(int id, int msg) {     TIter p = touches.find(id);     if (TouchPad::isTouchDown(msg)) {         if (p != touches.end()) return true;         touches.insert(id);     } else {         if (p == touches.end()) return true;         if (TouchPad::isTouchUp(msg)) {             touches.erase(p);         }     }     return false; }  void Desktop::update(uint64 timestamp) {     if (isChanged) {         getScreenSizes();     }     int cnt = touchPad.getTouchCount(); \tif (cnt &gt; 0) { \t\tfor (int i = 0; i &lt; MAX_TOUCHES; i++) { \t\t\tTouch* t = touchPad.getTouch(i); \t\t\tif (t-&gt;isActive) { \t\t\t\tint msg = (cnt &gt; 1)?emtMultiTouchUp:emtSingleTouchUp; \t\t\t\tif (t-&gt;isMoved) { \t\t\t\t\tmsg = (cnt &gt; 1)?emtMultiTouchMove:emtSingleTouchMove; \t\t\t\t} \t\t\t\tif (t-&gt;isPressed) { \t\t\t\t\tmsg = (cnt &gt; 1)?emtMultiTouchDown:emtSingleTouchDown; \t\t\t\t}                 if (!checkBounce(t-&gt;id, msg)) {                     if (currentScene != NULL) {     \t\t    \t    currentScene-&gt;sendMessage(msg | (t-&gt;id & emtTouchIdMask), t-&gt;x, t-&gt;y);    \t\t    }                 } \t\t\t} \t\t} \t}     if (isKeyAvailable) {         s3eKeyboardUpdate();     }     if (currentScene != NULL) {         currentScene-&gt;update(timestamp);     } }  void Desktop::refresh() {     if (currentScene != NULL) {         currentScene-&gt;refresh();     } } bool Desktop::isQuitMessageReceived() {     if (s3eDeviceCheckQuitRequest()) {         return true;     }     return IsQuitMessageReceived; } <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0440\u044f\u0434 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 TouchPad \u0432 \u043c\u0435\u0442\u043e\u0434 update. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043c\u0435\u0442\u043e\u0434 checkBounce, \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u043d\u0438\u0435 \u00ab\u0434\u0440\u0435\u0431\u0435\u0437\u0433\u0430\u00bb, \u043f\u0443\u0442\u0435\u043c \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u044f TouchPad. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, \u0432 Desktop \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u044d\u043a\u0440\u0430\u043d\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u043e\u0440\u0438\u0435\u043d\u0442\u0430\u0446\u0438\u0438).<\/p>\n<p>  \u041c\u043e\u0434\u0443\u043b\u044c Main \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>  <u><b>Main.cpp:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#include &quot;Main.h&quot;  #include &quot;s3e.h&quot; #include &quot;Iw2D.h&quot; #include &quot;IwGx.h&quot;  #include &quot;TouchPad.h&quot; #include &quot;Desktop.h&quot; #include &quot;Scene.h&quot; #include &quot;Background.h&quot; #include &quot;Sprite.h&quot;  void init() {     \/\/ Initialise Mamrlade graphics system and Iw2D module     IwGxInit();     Iw2DInit();      \/\/ Set the default background clear colour     IwGxSetColClear(0x0, 0x0, 0x0, 0);      touchPad.init();     desktop.init(); }  void release() {     desktop.release();     touchPad.release();      Iw2DTerminate();     IwGxTerminate(); }  int main() {     init();    {          Scene scene;         new Background(&scene, &quot;background.png&quot;, 1);         new Sprite(&scene, &quot;sprite.png&quot;, 122, 100, 2);         desktop.setScene(&scene);          int32 duration = 1000 \/ 25;         \/\/ Main Game Loop         while (!desktop.isQuitMessageReceived()) {             \/\/ Update keyboard system             s3eKeyboardUpdate();             \/\/ Update             touchPad.update();             desktop.update(s3eTimerGetMs());             \/\/ Clear the screen             IwGxClear(IW_GX_COLOUR_BUFFER_F | IW_GX_DEPTH_BUFFER_F);             touchPad.clear();             \/\/ Refresh             desktop.refresh();             \/\/ Show the surface             Iw2DSurfaceShow();             \/\/ Yield to the opearting system             s3eDeviceYield(duration);         }     }     release();     return 0; } <\/code><\/pre>\n<p>  \u041c\u044b \u0443\u0431\u0440\u0430\u043b\u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 s3eKeyAbsBSK \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u043b\u0438 \u0432\u044b\u0437\u043e\u0432 s3eDeviceCheckQuitRequest \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u0438 \u0446\u0438\u043a\u043b\u0430 \u043d\u0430 \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 Desktop::isQuitMessageReceived. \u0412 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432\u044b\u0437\u043e\u0432\u044b \u043c\u0435\u0442\u043e\u0434\u043e\u0432 Touchpad::update \u0438 clear. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432\u044b\u0437\u043e\u0432\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f, \u0434\u043b\u044f \u043c\u043e\u0434\u0443\u043b\u044f TouchPad, \u0432 \u043c\u0435\u0442\u043e\u0434\u044b init \u0438 release \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>  \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0432 \u043c\u043e\u0434\u0443\u043b\u044c Scene.<\/p>\n<p>  <u><b>Scene.h:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#ifndef _SCENE_H_ #define _SCENE_H_  #include &lt;map&gt; #include &lt;set&gt; #include &quot;s3eKeyboard.h&quot;  #include &quot;AbstractSpriteOwner.h&quot; #include &quot;AbstractScreenObject.h&quot;  using namespace std;  class Scene: public AbstractSpriteOwner {     private:         AbstractScreenObject* background;         map&lt;s3eKey, int&gt; keys;         bool isInitialized;         uint64 lastTime;     protected:         virtual bool doKeyMessage(int msg, s3eKey key) {return false;}         virtual void regKey(s3eKey key);     public:         Scene();         virtual bool init();         int getXSize(int xSize);         int getYSize(int ySize);         virtual int getXPos(int x) {return x;}         virtual int getYPos(int y) {return y;}         virtual void refresh();         virtual void update(uint64 timestamp);         virtual bool isBuzy() {return false;}         virtual bool sendMessage(int id, int x, int y);      typedef map&lt;s3eKey, int&gt;::iterator KIter;     typedef pair&lt;s3eKey, int&gt; KPair; };  #endif    \/\/ _SCENE_H_ <\/code><\/pre>\n<p>  <u><b>Scene.cpp:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#include &quot;Scene.h&quot; #include &quot;Desktop.h&quot;  Scene::Scene(): AbstractSpriteOwner()               , isInitialized(false)               , background(NULL)               , keys()               , lastTime(0) {     regKey(s3eKeyBack);     regKey(s3eKeyAbsBSK); }  bool Scene::init() {     bool r = !isInitialized;     isInitialized = true;     return r; }  int Scene::getXSize(int xSize) {     if (background != NULL) {         return (getDesktopWidth() * xSize) \/ background-&gt;getWidth();     }     return xSize; }  int Scene::getYSize(int ySize) {     if (background != NULL) {         return (getDesktopHeight() * ySize) \/ background-&gt;getHeight();     }     return ySize; }  void Scene::refresh() {     init();     if (background == NULL) {         for (ZIter p = zOrder.begin(); p != zOrder.end(); ++p) {             if (p-&gt;second-&gt;isBackground()) {                 background = p-&gt;second;                 break;             }         }     }     AbstractSpriteOwner::refresh(); }  void Scene::regKey(s3eKey key) {     keys.insert(KPair(key, 0)); }  void Scene::update(uint64 timestamp) {     for (KIter p = keys.begin(); p != keys.end(); ++p) {         int msg = 0;         int32 keyState = s3eKeyboardGetState(p-&gt;first);         if (keyState & (S3E_KEY_STATE_DOWN | S3E_KEY_STATE_PRESSED)) {             msg = emtKeyDown;             if (p-&gt;second == 0) {                 msg = emtKeyPressed;                 p-&gt;second = 1;             }         }         if (keyState == S3E_KEY_STATE_UP) {             if (p-&gt;second == 1) {                 msg = emtKeyReleased;                 p-&gt;second = 0;             }         }         if (msg != 0) {             if (doKeyMessage(msg, p-&gt;first)) {                 lastTime = timestamp;             } else {                 if (timestamp - lastTime &gt;= 1000) {                     lastTime = 0;                 }                 if ((lastTime == 0)&&(msg == emtKeyPressed)) {                     switch (p-&gt;first) {                         case s3eKeyBack:                         case s3eKeyAbsBSK:                                 desktop.sendQuitMessage();                                 break;                     }                 }             }         }     }     AbstractSpriteOwner::update(timestamp); }  bool Scene::sendMessage(int id, int x, int y) {     if (AbstractSpriteOwner::sendMessage(id, x, y)) {         return true;     }     if (background != NULL) {         return background-&gt;sendMessage(id, x, y);     }     return false; } <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043b\u0430\u0432\u0438\u0448\u0438, \u0437\u0430\u043d\u0435\u0441\u0435\u043d\u043d\u043e\u0439 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u043a\u043b\u0430\u0432\u0438\u0448 keys, \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 doKeyMessage. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f s3eKeyBack \u0438 s3eKeyAbsBSK, \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0443\u044e\u0441\u044f \u0432 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 desktop.sendQuitMessage, \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043a \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. <\/p>\n<p>  \u0414\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438, \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u043a\u043b\u0430\u0441\u0441 Sprite.<\/p>\n<p>  <u><b>Sprite.h:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#ifndef _SPRITE_H_ #define _SPRITE_H_  #include &quot;AbstractScreenObject.h&quot; #include &quot;ISprite.h&quot; #include &quot;ISpriteOwner.h&quot; #include &quot;Locale.h&quot;  class Sprite: public AbstractScreenObject             , public ISprite {     protected:         ISpriteOwner* owner;         CIw2DImage* img;         int capturedId;     public:         Sprite(ISpriteOwner* owner, int x, int y , int zOrder = 0);         Sprite(ISpriteOwner* owner, const char* res, int x, int y, int zOrder = 0);         virtual ~Sprite();         virtual bool sendMessage(int msg, uint64 timestamp = 0, void* data = NULL);         virtual bool sendMessage(int msg, int x, int y);         virtual void update(uint64 timestamp) {}         virtual void refresh();         virtual void addImage(const char*res, int state = 0);         virtual CIw2DImage* getImage(int id = 0);         virtual int  getState()  {return 0;}         virtual int  getWidth();         virtual int  getHeight(); };  #endif    \/\/ _SPRITE_H_ <\/code><\/pre>\n<p>  <u><b>Sprite.cpp:<\/b><\/u><\/p>\n<pre><code class=\"cpp\">#include &quot;Sprite.h&quot; #include &quot;Locale.h&quot; #include &quot;Desktop.h&quot;  Sprite::Sprite(ISpriteOwner* owner, int x, int y , int zOrder):                                                          AbstractScreenObject(x, y)                                                         , owner(owner)                                                         , capturedId(-1)                                                         , img(NULL) {     owner-&gt;addSprite((AbstractScreenObject*)this, zOrder); }  Sprite::Sprite(ISpriteOwner* owner, const char* res, int x, int y, int zOrder):                                                          AbstractScreenObject(x, y)                                                         , owner(owner)                                                         , capturedId(-1)                                                         , img(NULL) {     addImage(res, 0);     owner-&gt;addSprite((AbstractScreenObject*)this, zOrder); }  Sprite::~Sprite() {     if (img != NULL) {         delete img;     } }  bool Sprite::sendMessage(int msg, uint64 timestamp, void* data) {     return owner-&gt;sendMessage(msg, timestamp, data); }  bool Sprite::sendMessage(int msg, int x, int y) {     if ((msg & emtTouchEvent) != emtTouchEvent) return false;     if (!isVisible) return false;     int id = msg & emtTouchIdMask;     msg &= emtTouchMask;     if (capturedId &gt;= 0) {         if (id != capturedId) return false;         if (msg == emtTouchDown) {             capturedId = -1;         }     }     if (capturedId &lt; 0) {         int X = owner-&gt;getXSize(owner-&gt;getXPos(getXPos()));         int Y = owner-&gt;getYSize(owner-&gt;getYPos(getYPos()));         if ((x &lt; X)||(y &lt; Y)) return false;         X += owner-&gt;getXSize(getWidth());         Y += owner-&gt;getYSize(getHeight());         if ((x &gt; X)||(y &gt; Y)) return false;     }     switch (msg) {         case emtTouchDown:             capturedId = id;             break;         case emtTouchUp:             capturedId = -1;             break;     }     if (isBuzy()) {         return true;     }     return sendMessage(msg) ||            owner-&gt;sendMessage(msg); }  void Sprite::addImage(const char*res, int state) {     img = Iw2DCreateImage(res); }  CIw2DImage* Sprite::getImage(int id) {     return img; }  int Sprite::getWidth() {     CIw2DImage* img = getImage(getState());     if (img != NULL) {         return img-&gt;GetWidth();     } else {         return 0;     } }  int Sprite::getHeight() {     CIw2DImage* img = getImage(getState());     if (img != NULL) {         return img-&gt;GetHeight();     } else {         return 0;     } }  void Sprite::refresh() {     init();     CIw2DImage* img = getImage(getState());     if (isVisible && (img != NULL)) {         CIwMat2D m;         m.SetRot(getAngle());         m.ScaleRot(IW_GEOM_ONE);         m.SetTrans(CIwSVec2(owner-&gt;getXSize(owner-&gt;getXPos(getXPos())),                    owner-&gt;getYSize(owner-&gt;getYPos(getYPos()))));         Iw2DSetTransformMatrix(m);         Iw2DSetAlphaMode(alpha);         Iw2DDrawImage(img, CIwSVec2(0, 0), CIwSVec2(owner-&gt;getXSize(getWidth()),                    owner-&gt;getYSize(getHeight())));     } } <\/code><\/pre>\n<p>  \u0412 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f sendMessage \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043b\u0438 \u0442\u043e\u0447\u043a\u0430 \u043a\u0430\u0441\u0430\u043d\u0438\u044f \u0432 \u0440\u0435\u0433\u0438\u043e\u043d \u0441\u043f\u0440\u0430\u0439\u0442\u0430 \u0438 \u0435\u0441\u043b\u0438 \u0434\u0430, \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043d\u0435\u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441 \u0442\u0435\u043c-\u0436\u0435 \u043a\u043e\u0434\u043e\u043c \u0441\u043f\u0440\u0430\u0439\u0442\u0443. \u041d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u0432 AbstractSpriteOwner::update \u043c\u044b \u043f\u043e\u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c sendMessage \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u043a\u0440\u043e\u043c\u0435 Background-\u0430, \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c Z-order (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u043c\u0443 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432).<\/p>\n<p>  \u0414\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u044f \u043a\u0430\u0441\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u041f\u043e\u043b\u0443\u0447\u0438\u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 emtTouchDown. Sprite \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 id-\u043a\u0430\u0441\u0430\u043d\u0438\u044f \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u0442\u0435\u043c-\u0436\u0435 id \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0442\u043e\u0433\u043e-\u0436\u0435 \u0441\u043f\u0440\u0430\u0439\u0442\u0430, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043a\u0430\u0441\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043d\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u044f\u0432\u0438\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u0437\u0430\u043c\u0435\u0442\u043d\u0443\u044e \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0443\u044e \u0441 \u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439, \u043d\u0430\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u0435\u0449\u0435 \u043d\u0435\u043c\u0430\u043b\u043e \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0437\u0432\u0443\u043a\u043e\u043c.<\/p>\n<p>  \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0442\u0435\u043a\u0441\u0442\u044b \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <a href=\"https:\/\/github.com\/GlukKazan\/mf\">\u0437\u0434\u0435\u0441\u044c<\/a>      \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\/161849\/\"> http:\/\/habrahabr.ru\/post\/161849\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 <a href=\"http:\/\/habrahabr.ru\/post\/161681\/\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e Framework-\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f 2D-\u0438\u0433\u0440, \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b <a href=\"http:\/\/www.madewithmarmalade.com\/\">Marmalade<\/a>, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0440\u044f\u0434\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 iOS \u0438 Android. \u041c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438 \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0431 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439.  <\/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-161849","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/161849","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=161849"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/161849\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=161849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=161849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=161849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}