2017-11-25 83 views
0

我想將2D精靈縮放爲與節點的碰撞框一樣大。如何在不重新縮放整個節點的情況下在Urho3D中縮放Sprite2D?

我只能用Node::SetScale和一些手動縮放計算來做到這一點,但我寧願不使用這種方法做它,因爲它是錯綜複雜的,因爲我也必須考慮物理身體的比例因子。

但是,我找不到StaticSprite2D類的SetScale方法。

關鍵碼部分是:

#if 0 
     // Sprite and collision have the same size, 
     // like I want it, but I feel this is very convoluted. 
     auto rect = boxSprite->GetRectangle(); 
     auto scaleX = PIXEL_SIZE * rect.Width(); 
     auto scaleY = PIXEL_SIZE * rect.Height(); 
     node->SetScale(Vector3(groundWidth/scaleX, groundHeight/scaleY, 0.0f)); 
     shape->SetSize(Vector2(scaleX, scaleY)); 
#else 
     // Collision shape is correct, but the sprite is smaller 
     // so not what I want. 
     shape->SetSize(Vector2(groundWidth, groundHeight)); 
#endif 

完整的可運行下面的代碼,用下面的樣板進行測試:https://github.com/cirosantilli/Urho3D-cheat/blob/8c785b38481aa5af48837c5bc3706e46f704ef37/scale_sprite.cpp和Urho3D @ 5e8a275:

#include <Urho3D/Core/CoreEvents.h> 
#include <Urho3D/Core/Object.h> 
#include <Urho3D/Engine/Application.h> 
#include <Urho3D/Engine/Engine.h> 
#include <Urho3D/Engine/EngineDefs.h> 
#include <Urho3D/Graphics/Camera.h> 
#include <Urho3D/Graphics/DebugRenderer.h> 
#include <Urho3D/Graphics/Graphics.h> 
#include <Urho3D/Graphics/Octree.h> 
#include <Urho3D/Graphics/Renderer.h> 
#include <Urho3D/Input/Input.h> 
#include <Urho3D/Input/InputEvents.h> 
#include <Urho3D/Physics/PhysicsEvents.h> 
#include <Urho3D/Resource/ResourceCache.h> 
#include <Urho3D/Scene/Scene.h> 
#include <Urho3D/Scene/SceneEvents.h> 
#include <Urho3D/Urho2D/CollisionBox2D.h> 
#include <Urho3D/Urho2D/CollisionCircle2D.h> 
#include <Urho3D/Urho2D/Drawable2D.h> 
#include <Urho3D/Urho2D/PhysicsWorld2D.h> 
#include <Urho3D/Urho2D/RigidBody2D.h> 
#include <Urho3D/Urho2D/Sprite2D.h> 
#include <Urho3D/Urho2D/StaticSprite2D.h> 

using namespace Urho3D; 

class Main : public Application { 
    URHO3D_OBJECT(Main, Application); 
public: 
    Main(Context* context) : Application(context) { 
    } 
    virtual void Setup() override { 
     engineParameters_[EP_FULL_SCREEN] = false; 
    } 
    void Start() { 
     SubscribeToEvent(E_POSTRENDERUPDATE, URHO3D_HANDLER(Main, HandlePostRenderUpdate)); 
     this->scene_ = new Scene(this->context_); 
     scene_->CreateComponent<Octree>(); 
     scene_->CreateComponent<DebugRenderer>(); 
     scene_->CreateComponent<PhysicsWorld2D>(); 
     auto physicsWorld = scene_->GetComponent<PhysicsWorld2D>(); 
     auto cameraNode_ = scene_->CreateChild("camera"); 
     cameraNode_->SetPosition(Vector3(0.0f, 0.0f, -1.0f)); 
     auto camera = cameraNode_->CreateComponent<Camera>(); 
     camera->SetOrthographic(true); 
     camera->SetOrthoSize(4.0); 
     auto graphics = GetSubsystem<Graphics>(); 
     auto renderer = GetSubsystem<Renderer>(); 
     SharedPtr<Viewport> viewport(new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>())); 
     renderer->SetViewport(0, viewport); 
     auto cache = GetSubsystem<ResourceCache>(); 
     auto boxSprite = cache->GetResource<Sprite2D>("Urho2D/Box.png"); 

     auto groundWidth = 2.0; 
     auto groundHeight = 2.0; 
     auto node = this->scene_->CreateChild("ground"); 
     node->SetPosition(Vector3(0.0f, 0.0f, 0.0f)); 
     node->CreateComponent<RigidBody2D>(); 
     auto shape = node->CreateComponent<CollisionBox2D>(); 
#if 0 
     // Sprite and collision have the same size, 
     // like I want it, but I feel this is very convoluted. 
     auto rect = boxSprite->GetRectangle(); 
     auto scaleX = PIXEL_SIZE * rect.Width(); 
     auto scaleY = PIXEL_SIZE * rect.Height(); 
     node->SetScale(Vector3(groundWidth/scaleX, groundHeight/scaleY, 0.0f)); 
     shape->SetSize(Vector2(scaleX, scaleY)); 
#else 
     // Collision shape is correct, but the sprite is smaller 
     // so not what I want. 
     shape->SetSize(Vector2(groundWidth, groundHeight)); 
#endif 
     auto staticSprite = node->CreateComponent<StaticSprite2D>(); 
     staticSprite->SetSprite(boxSprite); 
    } 
    void Stop() {} 
private: 
    SharedPtr<Scene> scene_; 
    void HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData) { 
     auto physicsWorld = this->scene_->GetComponent<PhysicsWorld2D>(); 
     physicsWorld->DrawDebugGeometry(); 
    } 
}; 

URHO3D_DEFINE_APPLICATION_MAIN(Main); 

有趣的是,存在用於Sprite一個SetScale類,就像我在示例中看到的那樣,它用於3D場景中的UI。

超集:在2D任意着色器:

同時要求在:https://discourse.urho3d.io/t/how-to-scale-a-sprite2d-in-urho3d-without-rescaling-the-entire-node/3785/1

回答

0

StaticSprite2D::SetDrawRect

這是我需要的方法,它設置精靈在世界座標中的大小。

它需要的矩形以原點爲中心,我們只給出物體長度並忽略位置。

完整更新的工作代碼存在於:https://github.com/cirosantilli/Urho3D-cheat/blob/1905d1f4824c6b88aca867c5be8ccb5dfae957f3/scale_sprite.cpp

關鍵行是:https://discourse.urho3d.io/t/how-to-scale-a-sprite2d-in-urho3d-without-rescaling-the-entire-node/3785/2

:從瞭解到

void CreateBox(float x, float y, float width, float height) { 
    auto node = this->scene->CreateChild("Box"); 
    node->SetPosition(Vector3(x, y, 0.0f)); 
    node->SetRotation(Quaternion(0.0f, 0.0f, 30.0f)); 
    auto box = node->CreateComponent<CollisionBox2D>(); 
    box->SetSize(Vector2(width, height)); 
    box->SetRestitution(0.8); 
    box->SetFriction(0.5f); 
    box->SetDensity(1.0f); 
    auto body = node->CreateComponent<RigidBody2D>(); 
    body->SetBodyType(BT_DYNAMIC); 
    auto staticSprite = node->CreateComponent<StaticSprite2D>(); 
    staticSprite->SetSprite(this->boxSprite); 
    staticSprite->SetDrawRect(Rect(
     width/2.0f, 
     -height/2.0f, 
     -width/2.0f, 
     height/2.0f 
    )); 
    staticSprite->SetUseDrawRect(true); 
} 

相關問題