Browse Source

Synchronize float and integer position of sprites.
Added sprite example application.

Lasse Öörni 12 years ago
parent
commit
1c7f970e30

+ 102 - 0
Bin/Data/Scripts/SpriteTest.as

@@ -0,0 +1,102 @@
+uint numSprites = 100;
+Array<Sprite@> sprites;
+Array<Vector2> speeds;
+
+void Start()
+{
+    if (engine.headless)
+    {
+        ErrorDialog("SpriteTest", "Headless mode is not supported. The program will now exit.");
+        engine.Exit();
+        return;
+    }
+
+    InitUI();
+    InitSprites();
+
+    SubscribeToEvent("Update", "HandleUpdate");
+    SubscribeToEvent("KeyDown", "HandleKeyDown");
+}
+
+void InitUI()
+{
+    XMLFile@ uiStyle = cache.GetResource("XMLFile", "UI/DefaultStyle.xml");
+
+    engine.CreateDebugHud();
+    debugHud.style = uiStyle;
+    debugHud.mode = DEBUGHUD_SHOW_ALL;
+
+    engine.CreateConsole();
+    console.style = uiStyle;
+
+    Cursor@ cursor = Cursor("Cursor");
+    cursor.style = uiStyle;
+    cursor.position = IntVector2(graphics.width / 2, graphics.height / 2);
+    ui.cursor = cursor;
+    if (GetPlatform() == "Android" || GetPlatform() == "iOS")
+        ui.cursor.visible = false;
+}
+
+void InitSprites()
+{
+    Texture2D@ decalTex = cache.GetResource("Texture2D", "Textures/UrhoDecal.dds");
+
+    for (uint i = 0; i < numSprites; ++i)
+    {
+        Sprite@ sprite = Sprite();
+        sprite.texture = decalTex;
+        sprite.SetFullImageRect();
+        sprite.position = Vector2(Random(graphics.width), Random(graphics.height));
+        sprite.size = IntVector2(128, 128);
+        sprite.hotSpot = IntVector2(64, 64);
+        sprite.rotation = Random(360);
+        sprite.SetScale(Random(1) + 0.5);
+        sprite.color = Color(Random(0.5) + 0.5, Random(0.5) + 0.5, Random(0.5) + 0.5, 1.0);
+        sprite.blendMode = BLEND_ADD;
+
+        ui.root.AddChild(sprite);
+
+        sprites.Push(sprite);
+        speeds.Push(Vector2(Random(200) - 100, Random(200) - 100));
+    }
+}
+
+void HandleUpdate(StringHash eventType, VariantMap& eventData)
+{
+    float timeStep = eventData["TimeStep"].GetFloat();
+
+    for (uint i = 0; i < numSprites; ++i)
+    {
+        sprites[i].rotation = sprites[i].rotation + timeStep * 30;
+        Vector2 newPos = sprites[i].position;
+        newPos += speeds[i] * timeStep;
+        if (newPos.x >= graphics.width)
+            newPos.x -= graphics.width;
+        else if (newPos.x < 0)
+            newPos.x += graphics.width;
+        if (newPos.y >= graphics.height)
+            newPos.y -= graphics.height;
+        else if (newPos.y < 0)
+            newPos.y += graphics.height;
+        sprites[i].position = newPos;
+    }
+}
+
+void HandleKeyDown(StringHash eventType, VariantMap& eventData)
+{
+    int key = eventData["Key"].GetInt();
+
+    if (key == KEY_ESC)
+    {
+        if (ui.focusElement is null)
+            engine.Exit();
+        else
+            console.visible = false;
+    }
+    
+    if (key == KEY_F1)
+        console.Toggle();
+        
+    if (key == 'T')
+        debugHud.Toggle(DEBUGHUD_SHOW_PROFILER);
+}

+ 1 - 0
Bin/SpriteTest.bat

@@ -0,0 +1 @@
+Urho3D.exe Scripts/SpriteTest.as %1 %2 %3 %4 %5 %6 %7 %8

+ 1 - 0
Bin/SpriteTest.sh

@@ -0,0 +1 @@
+./Urho3D Scripts/SpriteTest.as $@

+ 12 - 1
Docs/GettingStarted.dox

@@ -93,7 +93,7 @@ The scripting language used is AngelScript (http://www.angelcode.com/angelscript
 
 On Android and iOS there are no command line options, so running the NinjaSnowWar example is hardcoded. This can be changed from the file Urho3D/Urho3D.cpp.
 
-Currently eight example application scripts exist:
+Currently nine example application scripts exist:
 
 \section Running_NinjaSnowWar NinjaSnowWar
 
@@ -196,6 +196,17 @@ either press return or click "Send" to send them. Press ESC to exit.
 
 To connect automatically, the server address can also be given on the command line, for example Chat.bat 127.0.0.1
 
+\section Running_SpriteTest SpriteTest
+
+Simple example of using sprites in the user interface. To start, run SpriteTest.bat in the Bin directory, or use the command Urho3D.exe Scripts\SpriteTest.as
+
+Key controls:
+
+\verbatim
+F1          Toggle AngelScript console
+T           Toggle profiling display
+\endverbatim
+
 \section Running_Commandline Command line options
 
 Urho3D.exe understands the following command line options:

+ 8 - 0
Engine/UI/Sprite.cpp

@@ -110,11 +110,19 @@ void Sprite::GetBatches(PODVector<UIBatch>& batches, PODVector<UIQuad>& quads, c
     hovering_ = false;
 }
 
+void Sprite::OnPositionSet()
+{
+    // If the integer position was set (layout update?), copy to the float position
+    floatPosition_ = Vector2((float)position_.x_, (float)position_.y_);
+}
+
 void Sprite::SetPosition(const Vector2& position)
 {
     if (position != floatPosition_)
     {
         floatPosition_ = position;
+        // Copy to the integer position
+        position_ = IntVector2((int)position.x_, (int)position.y_);
         MarkDirty();
     }
 }

+ 2 - 0
Engine/UI/Sprite.h

@@ -47,6 +47,8 @@ public:
     virtual const IntVector2& GetScreenPosition() const;
     /// Return UI rendering batches.
     virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<UIQuad>& quads, const IntRect& currentScissor);
+    /// React to position change.
+    virtual void OnPositionSet();
     
     /// Set floating point position.
     void SetPosition(const Vector2& position);

+ 6 - 1
Engine/UI/UIElement.cpp

@@ -131,8 +131,8 @@ UIElement::UIElement(Context* context) :
     layoutMinSize_(0),
     indent_(0),
     indentSpacing_(16),
-    positionDirty_(true),
     position_(IntVector2::ZERO),
+    positionDirty_(true),
     size_(IntVector2::ZERO),
     minSize_(IntVector2::ZERO),
     maxSize_(M_MAX_INT, M_MAX_INT),
@@ -417,6 +417,10 @@ void UIElement::OnResize()
 {
 }
 
+void UIElement::OnPositionSet()
+{
+}
+
 bool UIElement::LoadXML(Deserializer& source)
 {
     SharedPtr<XMLFile> xml(new XMLFile(context_));
@@ -446,6 +450,7 @@ void UIElement::SetPosition(const IntVector2& position)
     if (position != position_)
     {
         position_ = position;
+        OnPositionSet();
         MarkDirty();
     }
 }

+ 4 - 2
Engine/UI/UIElement.h

@@ -151,6 +151,8 @@ public:
     virtual void OnChar(unsigned c, int buttons, int qualifiers);
     /// React to resize.
     virtual void OnResize();
+    /// React to position change.
+    virtual void OnPositionSet();
     
     /// Load from an XML file. Return true if successful.
     bool LoadXML(Deserializer& source);
@@ -472,6 +474,8 @@ protected:
     int indent_;
     /// Indent spacing (number of pixels per indentation level).
     int indentSpacing_;
+    /// Position.
+    IntVector2 position_;
     /// Screen position.
     mutable IntVector2 screenPosition_;
     /// Screen position dirty flag.
@@ -489,8 +493,6 @@ private:
     /// Detach from parent.
     void Detach();
     
-    /// Position.
-    IntVector2 position_;
     /// Size.
     IntVector2 size_;
     /// Minimum size.