我想将2D精灵缩放到与节点的碰撞盒一样大。
我只是设法使用Node::SetScale
和一些手动缩放计算,但我宁愿不使用此方法,因为它是复杂的,因为我必须考虑身体的缩放因子同样。
但是,我找不到SetScale
类的StaticSprite2D
方法。
关键代码部分是:
#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);
有趣的是,SetScale
类有一个Sprite
,就我在示例中看到的而言,它用于3D场景中的用户界面。
Superset:2D中的任意着色器:
答案 0 :(得分:0)
<强> StaticSprite2D::SetDrawRect
强>
这是我需要的方法,它设定精灵在世界坐标中的大小。
它所采用的矩形以原点为中心,我们只给出物体长度并忽略位置。
完整更新的工作代码位于:https://github.com/cirosantilli/Urho3D-cheat/blob/1905d1f4824c6b88aca867c5be8ccb5dfae957f3/scale_sprite.cpp
关键是:
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);
}