void Player::Initialize(Graphics *graphics) { _moveSpeed = 3.0f; BodyNode *head = new BodyNode(); head->Initialize(graphics); head->SetDirection(BodyNode::LEFT); head->moveSpeed = _moveSpeed; head->active = true; numCubes = 1; // Create first node for the player. _body.push_back(head); _difference = 0.0f; }
void Player::Update(float dt) { bool canTurn = false; _difference += dt; if (_difference > 0.5f) { _difference -= 0.5f; canTurn = true; } // If we've moved enough to warrant a turn, let's see what direction we'll be going in. if (canTurn && _nextDirection.size() > 0) { // Get the new direction. BodyNode::Direction newDirection = _nextDirection[0]; BodyNode::Direction oldHeadDirection = GetHeadDirection(); _nextDirection.erase(_nextDirection.begin()); // Set the head's direction. _body[0]->SetDirection(newDirection); // If we've got nodes, and we're moving in a new direction, we have to update the body! if (_body.size() > 1 && oldHeadDirection != newDirection) { BodyNode::DirectionPair pair; pair.direction = newDirection; pair.pivot = _body[0]->GetTransform().position; // Update the body. for (int bodyIndex = 1; bodyIndex < _body.size(); bodyIndex++) { _body[bodyIndex]->directionChange.push_back(pair); } } } // Move player based on current direction. for (int bodyIndex = _body.size() - 1; bodyIndex >= 0; bodyIndex--) { BodyNode *currentNode = _body[bodyIndex]; bool canMove = true; if (_body.size() > 1 && bodyIndex > 0) { BodyNode *nextNode = _body[bodyIndex - 1]; Vector3 currentPosition = currentNode->GetTransform().position; /* If we're at the last piece of the body and it's just been added, we don't want it to move until the previous piece is * far enough away so we don't risk colliding with it. */ if (bodyIndex == _body.size() - 1 && currentNode->active == false) { Vector3 nextBodyPiecePosition = nextNode->GetTransform().position; float distance = Vector3::Magnitude(Vector3::Difference(currentPosition, nextBodyPiecePosition)); // Make sure it's far enough away before we say it's okay. if (distance >= 1.0f) { currentNode->active = true; currentNode->SetDirection(nextNode->GetDirection()); switch (nextNode->GetDirection()) { case BodyNode::UP: currentNode->GetTransform().position.x = nextNode->GetTransform().position.x; currentNode->GetTransform().position.y = nextNode->GetTransform().position.y - 1.0f; break; case BodyNode::DOWN: currentNode->GetTransform().position.x = nextNode->GetTransform().position.x; currentNode->GetTransform().position.y = nextNode->GetTransform().position.y + 1.0f; break; case BodyNode::LEFT: currentNode->GetTransform().position.x = nextNode->GetTransform().position.x + 1.0f; currentNode->GetTransform().position.y = nextNode->GetTransform().position.y; break; case BodyNode::RIGHT: currentNode->GetTransform().position.x = nextNode->GetTransform().position.x - 1.0f; currentNode->GetTransform().position.y = nextNode->GetTransform().position.y; break; } } } else { float nextNodeDifference = Vector3::Magnitude(Vector3::Difference(nextNode->GetTransform().position, currentNode->GetTransform().position)); // Move other pieces. if (currentNode->directionChange.size() > 0) { BodyNode::DirectionPair pair = currentNode->directionChange[0]; Vector3 directionChange = pair.pivot; float difference = Vector3::Magnitude(Vector3::Difference(directionChange, currentNode->GetTransform().position)); // Ensure that we're close enough to the pivot. if (difference <= 0.05f) { currentNode->SetDirection(BodyNode::NONE); currentNode->GetTransform().position = directionChange; // Ensure that we're far enough away from the previous node before moving. if (nextNodeDifference >= 1.0f) { currentNode->SetDirection(pair.direction); currentNode->directionChange.erase(currentNode->directionChange.begin()); } } } if (nextNodeDifference > 1.25f) { switch (nextNode->GetDirection()) { case BodyNode::UP: currentNode->GetTransform().position.x = nextNode->GetTransform().position.x; currentNode->GetTransform().position.y = nextNode->GetTransform().position.y - 1.0f; break; case BodyNode::DOWN: currentNode->GetTransform().position.x = nextNode->GetTransform().position.x; currentNode->GetTransform().position.y = nextNode->GetTransform().position.y + 1.0f; break; case BodyNode::LEFT: currentNode->GetTransform().position.x = nextNode->GetTransform().position.x + 1.0f; currentNode->GetTransform().position.y = nextNode->GetTransform().position.y; break; case BodyNode::RIGHT: currentNode->GetTransform().position.x = nextNode->GetTransform().position.x - 1.0f; currentNode->GetTransform().position.y = nextNode->GetTransform().position.y; break; } currentNode->directionChange.clear(); currentNode->directionChange = nextNode->directionChange; currentNode->SetDirection(nextNode->GetDirection()); } } } currentNode->Update(dt); } }