官术网_书友最值得收藏!

Time for action – handling multitouches

There are three methods we need to implement in this game to handle touches. Each method receives, as one of its parameters, a vector of Touch objects:

  1. So add our onTouchesBegan method:
    void GameLayer::onTouchesBegan(const std::vector<Touch*> &touches, Event* event)
    {
       for( auto touch : touches) {
         if(touch != nullptr) {
            auto tap = touch->getLocation();
            for (auto player : _players) {
             if (player->boundingBox().containsPoint(tap)) {
                player->setTouch(touch);
             }
           }
         }
       }
    }

    Each GameSprite, if you recall, has a _touch property.

    So we iterate through the touches, grab their location on screen, loop through the players in the vector, and determine if the touch lands on one of the players. If so, we store the touch inside the player's _touch property (from the GameSprite class).

    A similar process is repeated for onTouchesMoved and onTouchesEnded, so you can copy and paste the code and just replace what goes on inside the _players array for loop.

  2. In TouchesMoved, when we loop through the players, we do this:
    for (auto player : _players) {
      if (player->getTouch() != nullptr && player->getTouch() ==  touch) {
        Point nextPosition = tap;
       if (nextPosition.x < player->radius())
          nextPosition.x = player->radius();
       if (nextPosition.x > _screenSize.width - player->radius())
          nextPosition.x = _screenSize.width - player->radius();
       if (nextPosition.y < player->radius())
          nextPosition.y  = player->radius();
       if (nextPosition.y > _screenSize.height - player->radius())
          nextPosition.y = _screenSize.height - player->radius();
                        
       //keep player inside its court
       if (player->getPositionY() < _screenSize.height* 0.5f) {
          if (nextPosition.y > _screenSize.height* 0.5 -  player->radius()) {
             nextPosition.y = _screenSize.height* 0.5 -  player->radius();
            }
       } else {
          if (nextPosition.y < _screenSize.height* 0.5 +  player->radius()) {
             nextPosition.y = _screenSize.height* 0.5 +  player->radius();
          }
       }              
       player->setNextPosition(nextPosition);
       player->setVector(Vec2(tap.x - player->getPositionX(),  tap.y - player->getPositionY()));
     }   
    }

    We check to see if the _touch property stored inside the player is the being moved now. If so, we update the player's position with the touch's current position, but we check to see if the new position is valid: a player cannot move outside the screen and cannot enter its opponent's court. We also update the player's vector of movement; we'll need this when we collide the player with the puck. The vector is based on the player's displacement.

  3. In onTouchesEnded, we add this:
    for (auto player : _players) {
       if (player->getTouch() != nullptr && player->getTouch() == touch) {
         //if touch ending belongs to this player, clear it
         player->setTouch(nullptr);
         player->setVector(Vec2(0,0));
       }
    }

We clear the _touch property stored inside the player if this touch is the one just ending. The player also stops moving, so its vector is set to 0. Notice that we don't need the location of the touch anymore; so in TouchesEnded you can skip that bit of logic.

What just happened?

When you implement logic for multitouch this is pretty much what you will have to do: store the individual touches inside either an array or individual sprites, so you can keep tracking these touches.

Now, for the heart and soul of the game—the main loop.

主站蜘蛛池模板: 崇仁县| 永仁县| 贵阳市| 石台县| 延庆县| 额尔古纳市| 克东县| 安西县| 赫章县| 顺昌县| 江孜县| 克什克腾旗| 华阴市| 新巴尔虎左旗| 泾阳县| 黔西| 铜川市| 常熟市| 全州县| 织金县| 宁化县| 紫云| 德庆县| 赣州市| 陆良县| 丹阳市| 阿鲁科尔沁旗| 吉林省| 徐汇区| 台山市| 闽清县| 商河县| 鄂尔多斯市| 绵竹市| 莫力| 措美县| 广水市| 商丘市| 波密县| 措勤县| 专栏|