void TileMapLayer2D::SetObjectGroup(const TmxObjectGroup2D* objectGroup) { objectGroup_ = objectGroup; TmxFile2D* tmxFile = objectGroup->GetTmxFile(); nodes_.Resize(objectGroup->GetNumObjects()); for (unsigned i = 0; i < objectGroup->GetNumObjects(); ++i) { const TileMapObject2D* object = objectGroup->GetObject(i); // Create dummy node for all object SharedPtr<Node> objectNode(GetNode()->CreateTemporaryChild("Object")); objectNode->SetPosition(object->GetPosition()); // If object is tile, create static sprite component if (object->GetObjectType() == OT_TILE && object->GetTileGid() && object->GetTileSprite()) { StaticSprite2D* staticSprite = objectNode->CreateComponent<StaticSprite2D>(); staticSprite->SetSprite(object->GetTileSprite()); staticSprite->SetLayer(drawOrder_); staticSprite->SetOrderInLayer((int)((10.0f - object->GetPosition().y_) * 100)); if (tmxFile->GetInfo().orientation_ == O_ISOMETRIC) { staticSprite->SetUseHotSpot(true); staticSprite->SetHotSpot(Vector2(0.5f, 0.0f)); } } nodes_[i] = objectNode; } }
void AnimatedSprite2D::UpdateAnimation(float timeStep) { if (!animation_) return; currentTime_ += timeStep * speed_; float time; float animtationLength = animation_->GetLength(); if (looped_) { time = fmodf(currentTime_, animtationLength); if (time < 0.0f) time += animation_->GetLength(); } else time = Clamp(currentTime_, 0.0f, animtationLength); for (unsigned i = 0; i < numTracks_; ++i) { trackNodeInfos_[i].worldSpace = false; const AnimationTrack2D& track = animation_->GetTrack(i); const Vector<AnimationKeyFrame2D>& keyFrames = track.keyFrames_; // Time out of range if (time < keyFrames[0].time_ || time > keyFrames.Back().time_) trackNodeInfos_[i].value.enabled_ = false; else { unsigned index = keyFrames.Size() - 1; for (unsigned j = 0; j < keyFrames.Size() - 1; ++j) { if (time <= keyFrames[j + 1].time_) { index = j; break; } } const AnimationKeyFrame2D& currKey = keyFrames[index]; AnimationKeyFrame2D& value = trackNodeInfos_[i].value; value.enabled_ = currKey.enabled_; value.parent_ = currKey.parent_; if (index < keyFrames.Size() - 1) { const AnimationKeyFrame2D& nextKey = keyFrames[index + 1]; float t = (time - currKey.time_) / (nextKey.time_ - currKey.time_); value.transform_ = currKey.transform_.Lerp(nextKey.transform_, t, currKey.spin_); if (trackNodeInfos_[i].hasSprite) value.alpha_ = Urho3D::Lerp(currKey.alpha_, nextKey.alpha_, t); } else { value.transform_ = currKey.transform_; if (trackNodeInfos_[i].hasSprite) value.alpha_ = currKey.alpha_; } if (trackNodeInfos_[i].hasSprite) { value.zIndex_ = currKey.zIndex_; value.sprite_ = currKey.sprite_; value.useHotSpot_ = currKey.useHotSpot_; value.hotSpot_ = currKey.hotSpot_; } } } for (unsigned i = 0; i < numTracks_; ++i) { Node* node = trackNodes_[i]; TrackNodeInfo& nodeInfo = trackNodeInfos_[i]; if (!nodeInfo.value.enabled_) node->SetEnabled(false); else { node->SetEnabled(true); // Calculate world transform. CalculateTimelineWorldTransform(i); // Update node's transform Vector2 position = nodeInfo.value.transform_.position_ * PIXEL_SIZE; if (flipX_) position.x_ = -position.x_; if (flipY_) position.y_ = -position.y_; node->SetPosition(position); float angle = nodeInfo.value.transform_.angle_; if (flipX_ != flipY_) angle = -angle; node->SetRotation(angle); node->SetScale(nodeInfo.value.transform_.scale_); if (nodeInfo.hasSprite) { StaticSprite2D* staticSprite = node->GetComponent<StaticSprite2D>(); if (staticSprite) { staticSprite->SetOrderInLayer(orderInLayer_ + nodeInfo.value.zIndex_); staticSprite->SetSprite(nodeInfo.value.sprite_); staticSprite->SetUseHotSpot(nodeInfo.value.useHotSpot_); staticSprite->SetHotSpot(nodeInfo.value.hotSpot_); } } } } MarkForUpdate(); }
void AnimatedSprite2D::UpdateAnimation(float timeStep) { if (!animation_) return; currentTime_ += timeStep * speed_; float time; float animtationLength = animation_->GetLength(); if (looped_) { time = fmodf(currentTime_, animtationLength); if (time < 0.0f) time += animation_->GetLength(); } else time = Clamp(currentTime_, 0.0f, animtationLength); // Update timeline's local transform for (unsigned i = 0; i < timelineTransformInfos_.Size(); ++i) { const Timeline2D& timeline = animation_->GetTimeline(i); const Vector<TimelineKey2D>& objectKeys = timeline.timelineKeys_; unsigned index = objectKeys.Size() - 1; for (unsigned j = 0; j < objectKeys.Size() - 1; ++j) { if (time <= objectKeys[j + 1].time_) { index = j; break; } } const TimelineKey2D& currKey = objectKeys[index]; if (index < objectKeys.Size() - 1) { const TimelineKey2D& nextKey = objectKeys[index + 1]; float t = (time - currKey.time_) / (nextKey.time_ - currKey.time_); timelineTransformInfos_[i].worldSpace_ = false; timelineTransformInfos_[i].transform_ = currKey.transform_.Lerp(nextKey.transform_, t, currKey.spin_); // Update sprite's sprite and hot spot and color Node* timelineNode = timelineNodes_[i]; if (timelineNode) { StaticSprite2D* staticSprite = timelineNode->GetComponent<StaticSprite2D>(); if (staticSprite) { staticSprite->SetSprite(currKey.sprite_); staticSprite->SetHotSpot(currKey.hotSpot_.Lerp(nextKey.hotSpot_, t)); float alpha = Lerp(currKey.alpha_, nextKey.alpha_, t); staticSprite->SetColor(Color(color_.r_, color_.g_, color_.b_, color_.a_ * alpha)); } } } else { timelineTransformInfos_[i].worldSpace_ = false; timelineTransformInfos_[i].transform_ = currKey.transform_; // Update sprite's sprite and hot spot and color Node* timelineNode = timelineNodes_[i]; if (timelineNode) { StaticSprite2D* staticSprite = timelineNode->GetComponent<StaticSprite2D>(); if (staticSprite) { staticSprite->SetSprite(currKey.sprite_); staticSprite->SetHotSpot(currKey.hotSpot_); staticSprite->SetColor(Color(color_.r_, color_.g_, color_.b_, color_.a_ * currKey.alpha_)); } } } } // Calculate timeline world transform. for (unsigned i = 0; i < timelineTransformInfos_.Size(); ++i) CalculateTimelineWorldTransform(i); // Get mainline key const Vector<MainlineKey2D>& mainlineKeys = animation_->GetMainlineKeys(); const MainlineKey2D* mainlineKey = 0; for (unsigned i = 1; i < mainlineKeys.Size(); ++i) { if (time < mainlineKeys[i].time_) { mainlineKey = &mainlineKeys[i - 1]; break; } } if (!mainlineKey) mainlineKey = &mainlineKeys.Back(); // Update node's transform and sprite's z order for (unsigned i = 0; i < timelineNodes_.Size(); ++i) { Node* timelineNode = timelineNodes_[i]; if (!timelineNode) continue; const Reference2D* ref = mainlineKey->GetReference(i); if (!ref) { // Disable node if (timelineNode->IsEnabled()) timelineNode->SetEnabled(false); } else { // Enable node if (!timelineNode->IsEnabled()) timelineNode->SetEnabled(true); // Update node's transform const Transform2D& transform = timelineTransformInfos_[i].transform_; Vector2 position = transform.position_ * PIXEL_SIZE; if (flipX_) position.x_ = -position.x_; if (flipY_) position.y_ = -position.y_; timelineNode->SetPosition(position); float angle = transform.angle_; if (flipX_ != flipY_) angle = -angle; timelineNode->SetRotation(angle); timelineNode->SetScale(transform.scale_); // Update sprite's z order StaticSprite2D* staticSprite = timelineNode->GetComponent<StaticSprite2D>(); if (staticSprite) staticSprite->SetOrderInLayer(orderInLayer_ + ref->zIndex_); } } MarkForUpdate(); }