Tuesday, October 20, 2026

#3 Animating Characters .sb3 file from python

To animate the letters of "MANIKUMARI" in Scratch dynamically via Python, the script below creates an independent sprite for each letter, assigns it a vector graphic text costume, spreads them horizontally across the stage (x = -200 to x = 205), and embeds an automated animation loop into each sprite (when green flag clicked → forever → change y by 15 → wait → change y by -15 → wait).

=======================================================================

Python :

import json

import zipfile

import hashlib

import os


def create_animated_text_project(text="MANIKUMARI", output_filename="generated/animate_manikumari.sb3"):

    targets = []

    

    # 1. Base Setup for the Stage

    stage = {

        "isStage": True,

        "name": "Stage",

        "variables": {}, "lists": {}, "broadcasts": {}, "blocks": {}, "comments": {},

        "currentCostume": 0,

        "costumes": [{

            "name": "backdrop1",

            "dataFormat": "svg",

            "assetId": "cd2151ac61ecaa654d0aa79046a8041c",

            "md5ext": "cd2151ac61ecaa654d0aa79046a8041c.svg",

            "rotationCenterX": 240, "rotationCenterY": 180

        }],

        "sounds": [], "volume": 100, "layerOrder": 0, "tempo": 60, "videoState": "on", "videoTransparency": 50

    }

    targets.append(stage)

    

    costumes_data = {}

    

    # 2. Generate a separate Sprite and Code Stack for each letter

    for i, char in enumerate(text):

        # Generate custom SVG asset for the letter block

        svg_content = f'<svg version="1.1" xmlns="http://w3.org" width="60" height="60"><text x="10" y="45" font-family="sans-serif" font-size="50" fill="#8A2BE2" font-weight="bold">{char}</text></svg>'

        md5_hash = hashlib.md5(svg_content.encode('utf-8')).hexdigest()

        costumes_data[md5_hash] = svg_content

        

        # Calculate individual X positions so the letters don't stack on top of each other

        x_pos = -200 + (i * 45)

        

        # Generate JSON representation of Scratch block stacks

        sprite_blocks = {

            "when_clicked": {

                "opcode": "event_whenflagclicked",

                "next": "forever_loop",

                "parent": None, "inputs": {}, "fields": {}, "shadow": False, "topLevel": True, "x": 100, "y": 100

            },

            "forever_loop": {

                "opcode": "control_forever",

                "next": None,

                "parent": "when_clicked",

                "inputs": {"SUBSTACK": [2, "change_y_up"]},

                "fields": {}, "shadow": False, "topLevel": False

            },

            "change_y_up": {

                "opcode": "motion_changeyby",

                "next": "wait_1",

                "parent": "forever_loop",

                "inputs": {"DY": [1, [4, "15"]]},

                "fields": {}, "shadow": False, "topLevel": False

            },

            "wait_1": {

                "opcode": "control_wait",

                "next": "change_y_down",

                "parent": "change_y_up",

                "inputs": {"DURATION": [1, [5, "0.2"]]},

                "fields": {}, "shadow": False, "topLevel": False

            },

            "change_y_down": {

                "opcode": "motion_changeyby",

                "next": "wait_2",

                "parent": "wait_1",

                "inputs": {"DY": [1, [4, "-15"]]},

                "fields": {}, "shadow": False, "topLevel": False

            },

            "wait_2": {

                "opcode": "control_wait",

                "next": None,

                "parent": "change_y_down",

                "inputs": {"DURATION": [1, [5, "0.2"]]},

                "fields": {}, "shadow": False, "topLevel": False

            }

        }

        

        sprite = {

            "isStage": False,

            "name": f"Letter_{char}_{i+1}",

            "variables": {}, "lists": {}, "broadcasts": {},

            "blocks": sprite_blocks,

            "comments": {}, "currentCostume": 0,

            "costumes": [{

                "name": char, "dataFormat": "svg", "assetId": md5_hash, "md5ext": f"{md5_hash}.svg", "rotationCenterX": 30, "rotationCenterY": 30

            }],

            "sounds": [], "volume": 100, "layerOrder": i + 1, "visible": True,

            "x": x_pos, "y": 0, "size": 100, "direction": 90, "draggable": False, "rotationStyle": "all around"

        }

        targets.append(sprite)

        

    project_json = {

        "targets": targets, "monitors": [], "extensions": [],

        "meta": {"semver": "3.0.0", "vm": "0.2.0", "agent": "Python Scratch Text Generator"}

    }

    

    # 3. Assemble and compress into .sb3 archive

    os.makedirs(os.path.dirname(output_filename), exist_ok=True)

    with zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED) as sb3:

        sb3.writestr('project.json', json.dumps(project_json, indent=2))

        sb3.writestr('cd2151ac61ecaa654d0aa79046a8041c.svg', '<svg version="1.1" xmlns="http://w3.org" width="1" height="1"></svg>')

        for md5, svg in costumes_data.items():

            sb3.writestr(f"{md5}.svg", svg)


    print(f"Project built successfully at: {output_filename}")


if __name__ == "__main__":

    create_animated_text_project()

=======================================================================
How to use this project:
  1. Run the Python script to build the package.
  2. Open the online Scratch Editor.
  3. Click File → Load from your computer and select animate_manikumari.sb3.
  4. Click the Green Flag to watch the letters bob up and down sequentially!

No comments:

Post a Comment

#4 Convert sb3 files to exe files

You can convert a Scratch file ( .sb3 ) into a standalone Windows executable ( .exe ) using a free web tool called TurboWarp Packager . This...