Kaynağa Gözat

Implemented property loading for Sprite, TileSet, and Text

Rcmaniac25 11 yıl önce
ebeveyn
işleme
29dd03fa46

+ 323 - 17
gameplay/src/Sprite.cpp

@@ -63,24 +63,307 @@ Sprite* Sprite::create(const char* imagePath, float width, float height,
     return sprite;
     return sprite;
 }
 }
 
 
+static bool parseBlendMode(const char* str, Sprite::BlendMode* blend)
+{
+    GP_ASSERT(blend);
+
+    if (!str)
+    {
+        *blend = Sprite::BLEND_NONE;
+        return false;
+    }
+
+    if (strcmp(str, "BLEND_ALPHA") == 0)
+    {
+        *blend = Sprite::BLEND_ALPHA;
+    }
+    else if (strcmp(str, "BLEND_ADDITIVE") == 0)
+    {
+        *blend = Sprite::BLEND_ADDITIVE;
+    }
+    else if (strcmp(str, "BLEND_MULTIPLIED") == 0)
+    {
+        *blend = Sprite::BLEND_MULTIPLIED;
+    }
+    else if (strcmp(str, "BLEND_NONE") != 0)
+    {
+        GP_ERROR("Failed to get corresponding sprite blend mode for unsupported value '%s'.", str);
+        *blend = Sprite::BLEND_NONE;
+        return false;
+    }
+    else
+    {
+        *blend = Sprite::BLEND_NONE;
+    }
+
+    return true;
+}
+
+static bool parseFlipFlags(const char* str, Sprite::FlipFlags* flip)
+{
+    GP_ASSERT(flip);
+
+    if (!str)
+    {
+        *flip = Sprite::FLIP_NONE;
+        return false;
+    }
+
+    if (strcmp(str, "FLIP_VERTICAL") == 0)
+    {
+        *flip = Sprite::FLIP_VERTICAL;
+    }
+    else if (strcmp(str, "FLIP_HORIZONTAL") == 0)
+    {
+        *flip = Sprite::FLIP_HORIZONTAL;
+    }
+    else if (strcmp(str, "FLIP_VERTICAL_HORIZONTAL") == 0)
+    {
+		*flip = (Sprite::FlipFlags)(Sprite::FLIP_VERTICAL | Sprite::FLIP_HORIZONTAL);
+    }
+    else if (strcmp(str, "FLIP_NONE") != 0)
+    {
+        GP_ERROR("Failed to get corresponding sprite flip flag for unsupported value '%s'.", str);
+        *flip = Sprite::FLIP_NONE;
+        return false;
+    }
+    else
+    {
+        *flip = Sprite::FLIP_NONE;
+    }
+
+    return true;
+}
+
+static bool parseOffset(const char* str, Sprite::Offset* offset)
+{
+    GP_ASSERT(offset);
+
+    if (!str)
+    {
+        *offset = Sprite::OFFSET_LEFT;
+        return false;
+    }
+
+    if (strcmp(str, "OFFSET_LEFT") == 0)
+    {
+        *offset = Sprite::OFFSET_LEFT;
+    }
+    else if (strcmp(str, "OFFSET_HCENTER") == 0)
+    {
+        *offset = Sprite::OFFSET_HCENTER;
+    }
+    else if (strcmp(str, "OFFSET_RIGHT") == 0)
+    {
+        *offset = Sprite::OFFSET_RIGHT;
+    }
+    else if (strcmp(str, "OFFSET_TOP") == 0)
+    {
+        *offset = Sprite::OFFSET_TOP;
+    }
+    else if (strcmp(str, "OFFSET_VCENTER") == 0)
+    {
+        *offset = Sprite::OFFSET_VCENTER;
+    }
+    else if (strcmp(str, "OFFSET_BOTTOM") == 0)
+    {
+        *offset = Sprite::OFFSET_BOTTOM;
+    }
+    else if (strcmp(str, "OFFSET_ANCHOR") == 0)
+    {
+        *offset = Sprite::OFFSET_ANCHOR;
+    }
+    else if (strcmp(str, "OFFSET_TOP_LEFT") == 0)
+    {
+        *offset = Sprite::OFFSET_TOP_LEFT;
+    }
+    else if (strcmp(str, "OFFSET_VCENTER_LEFT") == 0)
+    {
+        *offset = Sprite::OFFSET_VCENTER_LEFT;
+    }
+    else if (strcmp(str, "OFFSET_BOTTOM_LEFT") == 0)
+    {
+        *offset = Sprite::OFFSET_BOTTOM_LEFT;
+    }
+    else if (strcmp(str, "OFFSET_TOP_HCENTER") == 0)
+    {
+        *offset = Sprite::OFFSET_TOP_HCENTER;
+    }
+    else if (strcmp(str, "OFFSET_VCENTER_HCENTER") == 0)
+    {
+        *offset = Sprite::OFFSET_VCENTER_HCENTER;
+    }
+    else if (strcmp(str, "OFFSET_BOTTOM_HCENTER") == 0)
+    {
+        *offset = Sprite::OFFSET_BOTTOM_HCENTER;
+    }
+    else if (strcmp(str, "OFFSET_TOP_RIGHT") == 0)
+    {
+        *offset = Sprite::OFFSET_TOP_RIGHT;
+    }
+    else if (strcmp(str, "OFFSET_VCENTER_RIGHT") == 0)
+    {
+        *offset = Sprite::OFFSET_VCENTER_RIGHT;
+    }
+    else if (strcmp(str, "OFFSET_BOTTOM_RIGHT") != 0)
+    {
+        GP_ERROR("Failed to get corresponding sprite offset for unsupported value '%s'.", str);
+        *offset = Sprite::OFFSET_LEFT;
+        return false;
+    }
+    else
+    {
+        *offset = Sprite::OFFSET_BOTTOM_RIGHT;
+    }
+
+    return true;
+}
+
 Sprite* Sprite::create(Properties* properties)
 Sprite* Sprite::create(Properties* properties)
-{    
-    /*
-     sprite spaceship
-     {
-         anchor = 0.5, 0.5
-         color = 0,0,0,1
-         opacity = 1.0f
-         blendMode = BLEND_ALPHA
-         path = res/foo/spaceship.png
-         width = 100
-         height = 100
-         source = 0, 0, 70, 70
-         flip = FLIP_VERTICAL
-         frameCount = 1
-     }
-     */
-    return NULL;
+{
+    // Check if the Properties is valid and has a valid namespace.
+    if (!properties || strcmp(properties->getNamespace(), "sprite") != 0)
+    {
+        GP_ERROR("Properties object must be non-null and have namespace equal to 'sprite'.");
+        return NULL;
+    }
+
+    // Get image path.
+    const char* imagePath = properties->getString("path");
+    if (imagePath == NULL || strlen(imagePath) == 0)
+    {
+        GP_ERROR("Sprite is missing required image file path.");
+        return NULL;
+    }
+
+    // Don't support loading custom effects
+    Effect* effect = NULL;
+
+    // Get width and height
+    float width = -1.0f;
+    float height = -1.0f;
+    float widthPercentage = 0.0f;
+    float heightPercentage = 0.0f;
+    if (properties->exists("width"))
+    {
+        if (properties->getType("width") == Properties::NUMBER) //TODO: Verify that this works for "100" but fails for "100%"
+        {
+            width = properties->getFloat("width");
+        }
+        else
+        {
+            widthPercentage = properties->getFloat("width") / 100.0f;
+        }
+    }
+    if (properties->exists("height"))
+    {
+        if (properties->getType("height") == Properties::NUMBER)
+        {
+            height = properties->getFloat("height");
+        }
+        else
+        {
+            heightPercentage = properties->getFloat("height") / 100.0f;
+        }
+    }
+
+    Sprite* sprite;
+    if (properties->exists("source"))
+    {
+        // Get source frame
+        Rectangle source;
+        properties->getVector4("source", (Vector4*)&source);
+
+        // Get frame count
+        int frameCount = properties->getInt("frameCount");
+        if (frameCount < 0)
+        {
+            GP_WARN("Sprites require at least one frame. Defaulting to frame count 1.");
+        }
+        if (frameCount < 1)
+        {
+            frameCount = 1;
+        }
+
+        // Load sprite
+        sprite = Sprite::create(imagePath, width, height, source, frameCount, effect);
+    }
+    else
+    {
+        // Load sprite
+        sprite = Sprite::create(imagePath, width, height, effect);
+    }
+
+    // Edit scaling of sprites if needed
+    if (widthPercentage != 0.0f || heightPercentage != 0.0f)
+    {
+        if (widthPercentage != 0.0f)
+        {
+            sprite->_width *= widthPercentage;
+            sprite->_frames[0].width *= widthPercentage;
+        }
+        if (heightPercentage != 0.0f)
+        {
+            sprite->_height *= heightPercentage;
+            sprite->_frames[0].height *= heightPercentage;
+        }
+    }
+
+    // Get anchor
+    Vector4 vect;
+    if (properties->getVector2("anchor", (Vector2*)&vect))
+    {
+        sprite->setAnchor(*((Vector2*)&vect));
+    }
+
+    // Get color
+    if (properties->exists("color"))
+    {
+        switch (properties->getType("color"))
+        {
+            case Properties::VECTOR3:
+                vect.w = 1.0f;
+                properties->getVector3("color", (Vector3*)&vect);
+                break;
+            case Properties::VECTOR4:
+                properties->getVector4("color", &vect);
+                break;
+            case Properties::STRING:
+            default:
+                properties->getColor("color", &vect);
+                break;
+        }
+        sprite->setColor(vect);
+    }
+
+    // Get opacity
+    if (properties->exists("opacity"))
+    {
+        sprite->setOpacity(properties->getFloat("opacity"));
+    }
+
+    // Get blend mode
+    BlendMode mode;
+    if (parseBlendMode(properties->getString("blendMode"), &mode))
+    {
+        sprite->setBlendMode(mode);
+    }
+
+    // Get flip flags
+    FlipFlags flags;
+    if (parseFlipFlags(properties->getString("flip"), &flags))
+    {
+        sprite->setFlip(flags);
+    }
+
+    // Get sprite offset
+    Offset offset;
+    if (parseOffset(properties->getString("offset"), &offset))
+    {
+        sprite->setOffset(offset);
+    }
+
+    return sprite;
 }
 }
     
     
 float Sprite::getWidth() const
 float Sprite::getWidth() const
@@ -397,6 +680,29 @@ Drawable* Sprite::clone(NodeCloneContext& context)
     return spriteClone;
     return spriteClone;
 }
 }
 
 
+int Sprite::getPropertyId(TargetType type, const char* propertyIdStr)
+{
+    GP_ASSERT(propertyIdStr);
+
+    if (type == AnimationTarget::TRANSFORM)
+    {
+        if (strcmp(propertyIdStr, "ANIMATE_OPACITY") == 0)
+        {
+            return Sprite::ANIMATE_OPACITY;
+        }
+        else if (strcmp(propertyIdStr, "ANIMATE_COLOR") == 0)
+        {
+            return Sprite::ANIMATE_COLOR;
+        }
+        else if (strcmp(propertyIdStr, "ANIMATE_KEYFRAME") == 0)
+        {
+            return Sprite::ANIMATE_KEYFRAME;
+        }
+    }
+
+    return AnimationTarget::getPropertyId(type, propertyIdStr);
+}
+
 unsigned int Sprite::getAnimationPropertyComponentCount(int propertyId) const
 unsigned int Sprite::getAnimationPropertyComponentCount(int propertyId) const
 {
 {
     switch (propertyId)
     switch (propertyId)

+ 5 - 0
gameplay/src/Sprite.h

@@ -355,6 +355,11 @@ protected:
      */
      */
     Drawable* clone(NodeCloneContext& context);
     Drawable* clone(NodeCloneContext& context);
     
     
+    /**
+     * @see AnimationTarget::getPropertyId
+     */
+    int getPropertyId(TargetType type, const char* propertyIdStr);
+
     /**
     /**
      * @see AnimationTarget::getAnimationPropertyComponentCount
      * @see AnimationTarget::getAnimationPropertyComponentCount
      */
      */

+ 71 - 9
gameplay/src/Text.cpp

@@ -55,16 +55,59 @@ Text* Text::create(const char* fontPath, const char* str, const Vector4& color,
     
     
 Text* Text::create(Properties* properties)
 Text* Text::create(Properties* properties)
 {
 {
-    // TODO Load from properties from .scene files
-    /*
-    text level
+    // Check if the Properties is valid and has a valid namespace.
+    if (!properties || strcmp(properties->getNamespace(), "text") != 0)
     {
     {
-        font = res/arial.gpb
-        size = 18
-        text = Player 1
-     }
-     */
-    return NULL;
+        GP_ERROR("Properties object must be non-null and have namespace equal to 'text'.");
+        return NULL;
+    }
+
+    // Get font path.
+    const char* fontPath = properties->getString("font");
+    if (fontPath == NULL || strlen(fontPath) == 0)
+    {
+        GP_ERROR("Text is missing required font file path.");
+        return NULL;
+    }
+
+    // Get text
+    const char* text = properties->getString("text");
+    if (text == NULL || strlen(text) == 0)
+    {
+        GP_ERROR("Text is missing required 'text' value.");
+        return NULL;
+    }
+
+    // Get size
+    int size = properties->getInt("size"); // Default return is 0 if a value doesn't exist
+    if (size < 0)
+    {
+        GP_WARN("Text size must be a positive value, with zero being default font size. Using default font size.");
+        size = 0;
+    }
+
+    // Get text color
+    Vector4 color = Vector4::one();
+    if (properties->exists("color"))
+    {
+        switch (properties->getType("color"))
+        {
+            case Properties::VECTOR3:
+                color.w = 1.0f;
+                properties->getVector3("color", (Vector3*)&color);
+                break;
+            case Properties::VECTOR4:
+                properties->getVector4("color", &color);
+                break;
+            case Properties::STRING:
+            default:
+                properties->getColor("color", &color);
+                break;
+        }
+    }
+
+    // Create
+    return Text::create(fontPath, text, color, size);
 }
 }
     
     
 void Text::setText(const char* str)
 void Text::setText(const char* str)
@@ -223,6 +266,25 @@ unsigned int Text::draw(bool wireframe)
     return 1;
     return 1;
 }
 }
     
     
+int Text::getPropertyId(TargetType type, const char* propertyIdStr)
+{
+    GP_ASSERT(propertyIdStr);
+
+    if (type == AnimationTarget::TRANSFORM)
+    {
+        if (strcmp(propertyIdStr, "ANIMATE_OPACITY") == 0)
+        {
+            return Text::ANIMATE_OPACITY;
+        }
+        else if (strcmp(propertyIdStr, "ANIMATE_COLOR") == 0)
+        {
+            return Text::ANIMATE_COLOR;
+        }
+    }
+
+    return AnimationTarget::getPropertyId(type, propertyIdStr);
+}
+    
 unsigned int Text::getAnimationPropertyComponentCount(int propertyId) const
 unsigned int Text::getAnimationPropertyComponentCount(int propertyId) const
 {
 {
     switch (propertyId)
     switch (propertyId)

+ 5 - 0
gameplay/src/Text.h

@@ -229,6 +229,11 @@ protected:
      * @see Drawable::clone
      * @see Drawable::clone
      */
      */
     Drawable* clone(NodeCloneContext &context);
     Drawable* clone(NodeCloneContext &context);
+
+    /**
+     * @see AnimationTarget::getPropertyId
+     */
+    int getPropertyId(TargetType type, const char* propertyIdStr);
     
     
     /**
     /**
      * @see AnimationTarget::getAnimationPropertyComponentCount
      * @see AnimationTarget::getAnimationPropertyComponentCount

+ 86 - 14
gameplay/src/TileSet.cpp

@@ -53,25 +53,97 @@ TileSet* TileSet::create(const char* imagePath,
     
     
 TileSet* TileSet::create(Properties* properties)
 TileSet* TileSet::create(Properties* properties)
 {
 {
-    // TODO Load from properties
-    /*
-    tileset level
+    // Check if the Properties is valid and has a valid namespace.
+    if (!properties || strcmp(properties->getNamespace(), "tileset") != 0)
     {
     {
-        path = res/foo/level.png
-        tileWidth = 72
-        tileHeight = 72
-        tile
+        GP_ERROR("Properties object must be non-null and have namespace equal to 'tileset'.");
+        return NULL;
+    }
+
+    // Get image path.
+    const char* imagePath = properties->getString("path");
+    if (imagePath == NULL || strlen(imagePath) == 0)
+    {
+        GP_ERROR("TileSet is missing required image file path.");
+        return NULL;
+    }
+
+    // Get set size
+    int rows = properties->getInt("rows");
+    if (rows <= 0)
+    {
+        GP_ERROR("TileSet row count must be greater then zero.");
+        return NULL;
+    }
+    int columns = properties->getInt("columns");
+    if (columns <= 0)
+    {
+        GP_ERROR("TileSet column count must be greater then zero.");
+        return NULL;
+    }
+
+    // Get tile size
+    float tileWidth = properties->getFloat("tileWidth");
+    if (tileWidth <= 0)
+    {
+        GP_ERROR("TileSet tile width must be greater then zero.");
+        return NULL;
+    }
+    float tileHeight = properties->getFloat("tileHeight");
+    if (tileHeight <= 0)
+    {
+        GP_ERROR("TileSet tile height must be greater then zero.");
+        return NULL;
+    }
+
+    // Create tile set
+    TileSet* set = TileSet::create(imagePath, tileWidth, tileHeight, rows, columns);
+
+    // Get color
+    if (properties->exists("color"))
+    {
+        Vector4 color;
+        switch (properties->getType("color"))
         {
         {
-            cell = col, row
-            source = x, y
+        case Properties::VECTOR3:
+            color.w = 1.0f;
+            properties->getVector3("color", (Vector3*)&color);
+            break;
+        case Properties::VECTOR4:
+            properties->getVector4("color", &color);
+            break;
+        case Properties::STRING:
+        default:
+            properties->getColor("color", &color);
+            break;
         }
         }
-        tile
+        set->setColor(color);
+    }
+
+    // Get opacity
+    if (properties->exists("opacity"))
+    {
+        set->setOpacity(properties->getFloat("opacity"));
+    }
+
+    // Get tile sources
+    properties->rewind();
+    Properties* tileProperties = NULL;
+    while ((tileProperties = properties->getNextNamespace()))
+    {
+        if (strcmp(tileProperties->getNamespace(), "tile") == 0)
         {
         {
-            ...
+            Vector2 cell;
+            Vector2 source;
+            if (tileProperties->getVector2("cell", &cell) && tileProperties->getVector2("source", &source) &&
+                (cell.x > 0 && cell.y > 0 && cell.x < set->_columnCount && cell.y < set->_rowCount))
+            {
+                set->_tiles[(int)cell.y * set->_columnCount + (int)cell.x] = source;
+            }
         }
         }
-     }
-     */
-    return NULL;
+    }
+
+    return set;
 }
 }
 
 
 void TileSet::setTileSource(unsigned int column, unsigned int row, const Vector2& source)
 void TileSet::setTileSource(unsigned int column, unsigned int row, const Vector2& source)