首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在不重新缩放整个节点的情况下在Sprite2D中缩放Urho3D?

如何在不重新缩放整个节点的情况下在Sprite2D中缩放Urho3D?
EN

Stack Overflow用户
提问于 2017-11-25 16:54:52
回答 1查看 320关注 0票数 0

我想要缩放一个2D精灵,使其与节点的碰撞框一样大。

我只使用了Node::SetScale和一些手工标度计算,但我不想用这种方法做,因为它是复杂的,因为我也必须考虑到物理体的缩放因子。

但是,我无法为SetScale类找到一个StaticSprite2D方法。

关键代码部分是:

代码语言:javascript
复制
#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

下面的全部可运行代码,用以下样板进行测试:sprite.cpp和Urho3D @ 5e8a275:

代码语言:javascript
复制
#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);

有趣的是,有一个SetScale用于Sprite类,据我在示例中所见,它用于3D场景中的UI。

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

还询问:https://discourse.urho3d.io/t/how-to-scale-a-sprite2d-in-urho3d-without-rescaling-the-entire-node/3785/1

EN

回答 1

Stack Overflow用户

发布于 2017-12-05 23:07:52

StaticSprite2D::SetDrawRect

这是我需要的方法,它设定了雪碧在世界坐标下的大小。

它所取的矩形是以原点为中心的,我们只需给出对象的长度,而忽略位置。

完整更新的工作代码出现在:sprite.cpp

主要内容如下:

代码语言:javascript
复制
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);
}

从以下网站了解:https://discourse.urho3d.io/t/how-to-scale-a-sprite2d-in-urho3d-without-rescaling-the-entire-node/3785/2

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47488411

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档