voxelamming


Namevoxelamming JSON
Version 0.3.7 PyPI version JSON
download
home_pageNone
SummaryConvert Python code to JSON and send it to the Voxelamming app.
upload_time2024-10-02 07:08:58
maintainerNone
docs_urlNone
authorcreativival
requires_python>=3.9
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ## voxelamming

This Python library converts Python code into JSON format and sends it to the Voxelamming app using WebSockets, allowing users to create 3D voxel models by writing Python scripts.

## What's Voxelamming?

<p align="center"><img src="https://creativival.github.io/voxelamming/image/voxelamming_icon.png" alt="Voxelamming Logo" width="200"/></p>

Voxelamming is an AR programming learning app. Even programming beginners can learn programming visually and enjoyably. Voxelamming supports iPhones and iPads with iOS 16 or later, and Apple Vision Pro.

## Resources

* **Homepage:** https://creativival.github.io/voxelamming_python
* **Samples:** https://github.com/creativival/voxelamming/tree/main/sample/python

## Installation

```bash
pip install voxelamming
```

## Usage

### Modeling

```python
from voxelamming import Voxelamming

# Set your room name. This should match the room name displayed in your Voxelamming app. 
room_name = "1000"

# Create a Voxelamming instance
voxelamming = Voxelamming(room_name)

# Define Python code to create a voxel model
voxelamming.set_box_size(0.5)
voxelamming.set_build_interval(0.01)
voxelamming.transform(0, 0, 0, pitch=0, yaw=0, roll=0)
voxelamming.animate(0, 0, 10, pitch=0, yaw=30, roll=0, scale=2, interval= 10)

for i in range(100):
  voxelamming.create_box(-1, i, 0, r=0, g=1, b=1)
  voxelamming.create_box(0, i, 0, r=1, g=0, b=0)
  voxelamming.create_box(1, i, 0, r=1, g=1, b=0)
  voxelamming.create_box(2, i, 0, r=0, g=1, b=1)

for i in range(50):
  voxelamming.remove_box(0, i * 2 + 1, 0)
  voxelamming.remove_box(1, i * 2, 0)

# Send the Python code to the Voxelamming app
voxelamming.send_data()
```

### Game Mode

```python
import pyxel
import time
import random
# from voxelamming import Voxelamming
from voxelamming_local import Voxelamming  # Use this when developing locally


class Player:
    name = 'spaceship_8x8'
    dot_data = (
        '-1 -1 -1 8 8 -1 -1 -1 -1 -1 3 7 7 3 -1 -1 -1 -1 -1 7 7 -1 -1 -1 -1 -1 7 7 7 7 -1 -1 -1 7 7 7 7 7 7 -1 3 7'
        ' 7 7 7 7 7 3 -1 8 8 7 7 8 8 -1 -1 -1 -1 8 8 -1 -1 -1'
    )

    def __init__(self, x, y, speed):
        self.direction = 0
        self.x = x
        self.y = y
        self.img = 0
        self.u = 0
        self.v = 0
        self.w = 8
        self.h = 8
        self.speed = speed

    def update(self):
        if pyxel.btn(pyxel.KEY_LEFT):
            self.x -= self.speed
        if pyxel.btn(pyxel.KEY_RIGHT):
            self.x += self.speed


class Enemy:
    name = 'enemy_8x8'
    dot_data = (
        '-1 -1 3 -1 -1 3 -1 -1 -1 3 -1 3 3 -1 3 -1 3 -1 3 3 3 3 -1 3 3 3 3 3 3 3 3 3 3 3 -1 3 3 -1 3 3 3 3 3 3 3 3'
        ' 3 3 -1 3 3 -1 -1 3 3 -1 3 -1 -1 -1 -1 -1 -1 3'
    )

    def __init__(self, x, y):
        self.direction = 0
        self.x = x
        self.y = y
        self.img = 0
        self.u = 0
        self.v = 8
        self.w = 8
        self.h = 8


class Missile:
    def __init__(self, x, y, color_id, direction=0, width=1, height=1):
        self.x = x
        self.y = y
        self.direction = direction
        self.color_id = color_id
        self.width = width
        self.height = height


class App:
    def __init__(self):
        # Pyxel settings
        self.window_width = 160  # The width of the AR window becomes the value multiplied by self.dot_size (in centimeters)
        self.window_height = 120  # The height of the AR window becomes the value multiplied by self.dot_size (in centimeters)
        self.score = 0
        self.game_over = False
        self.game_clear = False

        # Player settings
        self.player = Player(self.window_width // 2, self.window_height - 10, 2)
        self.missiles = []
        self.player_missile_speed = 2

        # Enemy settings
        self.enemy_rows = 3
        self.enemy_cols = 6
        self.enemy_speed = 1
        self.enemy_direction = 1
        self.enemies = []
        self.enemy_missiles = []
        self.enemy_missile_speed = 2

        # Initialize enemies
        for row in range(self.enemy_rows):
            for col in range(self.enemy_cols):
                enemy_x = col * 16 + 20
                enemy_y = row * 12 + 20
                enemy = Enemy(enemy_x, enemy_y)
                self.enemies.append(enemy)

        # Voxelamming settings (executed before Pyxel initialization)
        self.dot_size = 1  # The size of the sprite dots displayed in the AR space (in centimeters)
        self.window_angle = 80  # Tilt angle of the AR window (in degrees)
        self.vox = Voxelamming('1000')
        self.init_voxelamming()

        # Pyxel initialization
        pyxel.init(self.window_width, self.window_height, title="Pyxel Invader Game", fps=30)
        pyxel.mouse(True)
        pyxel.load("invader_game.pyxres")
        pyxel.run(self.update, self.draw)

    def update(self):
        if self.game_over or self.game_clear:
            # Show cursor
            pyxel.mouse(True)

            if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
                self.reset_game()
            return

        # Hide cursor
        pyxel.mouse(False)

        # Player controls
        self.player.update()

        if pyxel.btnp(pyxel.KEY_SPACE):
            missile_x = self.player.x + self.player_missile_speed
            missile_y = self.player.y
            missile_clor_id = 10  # Blue
            missile_direction = 0
            missile_width = 2
            missile_height = 4
            self.missiles.append(
                Missile(missile_x, missile_y, missile_clor_id, missile_direction, missile_width, missile_height))

        # Move missiles
        for missile in self.missiles[:]:
            missile.y -= 2
            if missile.y < 0:
                self.missiles.remove(missile)

        # Move enemies
        move_down = False
        for enemy in self.enemies:
            enemy.x += self.enemy_speed * self.enemy_direction

        for enemy in self.enemies:
            if enemy.x > pyxel.width - 8 or enemy.x < 0:
                self.enemy_direction *= -1
                move_down = True
                break  # Change direction immediately when reaching the edge

        if move_down:
            for enemy in self.enemies:
                enemy.y += 8

                # Game over if the enemy reaches the bottom of the screen
                if enemy.y > pyxel.height - 16:
                    self.game_over = True

        # Enemy missile firing
        if random.random() < 0.03 and self.enemies:
            shooting_enemy = random.choice(self.enemies)
            missile_x = shooting_enemy.x + 4
            missile_y = shooting_enemy.y + 8
            missile_clor_id = 8  # Red
            missile_direction = 0
            missile_width = 2
            missile_height = 4
            self.enemy_missiles.append(
                Missile(missile_x, missile_y, missile_clor_id, missile_direction, missile_width, missile_height))

        # Move enemy missiles
        for missile in self.enemy_missiles[:]:
            missile.y += self.enemy_missile_speed
            if missile.y > pyxel.height * 2:
                self.enemy_missiles.remove(missile)

        # Collision detection between missiles and enemies
        for missile in self.missiles[:]:
            for enemy in self.enemies[:]:
                if (enemy.x < missile.x < enemy.x + 16 and
                        enemy.y < missile.y < enemy.y + 12):
                    self.missiles.remove(missile)
                    self.enemies.remove(enemy)
                    self.score += 10
                    break

        # Collision detection between player and enemy missiles
        for missile in self.enemy_missiles[:]:
            if (self.player.x < missile.x < self.player.x + 8 and
                    self.player.y < missile.y < self.player.y + 8):
                self.game_over = True

        # Collision detection between player and enemies
        for enemy in self.enemies:
            if (self.player.x < enemy.x < self.player.x + 8 and
                    self.player.y < enemy.y < self.player.y + 8):
                self.game_over = True

        # Check for game clear
        if not self.enemies:
            self.game_clear = True

        # Update Voxelamming
        self.update_voxelamming()

    def draw(self):
        pyxel.cls(0)
        pyxel.text(5, 4, f"Score: {self.score}", 7)

        if self.game_clear:
            pyxel.text(pyxel.width // 2 - 20, pyxel.height // 2, "GAME CLEAR!", pyxel.frame_count % 16)
            pyxel.text(self.window_width // 2 - 26, self.window_height // 2 + 8, "Click to start",
                       pyxel.frame_count % 16)
        elif self.game_over:
            pyxel.text(pyxel.width // 2 - 20, pyxel.height // 2, "GAME OVER", pyxel.frame_count % 16)
            pyxel.text(self.window_width // 2 - 26, self.window_height // 2 + 8, "Click to start",
                       pyxel.frame_count % 16)
        else:
            # Draw player
            pyxel.blt(self.player.x, self.player.y, self.player.img, self.player.u, self.player.v, self.player.w,
                      self.player.h, 0)

            # Draw enemies
            for enemy in self.enemies:
                pyxel.blt(enemy.x, enemy.y, enemy.img, enemy.u, enemy.v, enemy.w, enemy.h, 0)

            # Draw missiles
            for missile in self.missiles:
                pyxel.rect(missile.x, missile.y, missile.width, missile.height, missile.color_id)

            # Draw enemy missiles
            for missile in self.enemy_missiles:
                pyxel.rect(missile.x, missile.y, missile.width, missile.height, missile.color_id)

    def reset_game(self):
        self.score = 0  # Reset score
        self.game_over = False
        self.game_clear = False

        # Player settings
        self.player = Player(self.window_width // 2, self.window_height - 10, 2)
        self.missiles = []

        # Enemy settings
        self.enemy_rows = 3
        self.enemy_cols = 6
        self.enemy_speed = 1
        self.enemy_direction = 1
        self.enemies = []
        self.enemy_missiles = []
        self.enemy_missile_speed = 2

        # Initialize enemies
        for row in range(self.enemy_rows):
            for col in range(self.enemy_cols):
                enemy_x = col * 16 + 20
                enemy_y = row * 12 + 20
                enemy = Enemy(enemy_x, enemy_y)
                self.enemies.append(enemy)

    def init_voxelamming(self):

        # Initialize Voxelamming
        self.vox.set_box_size(self.dot_size)
        self.vox.set_game_screen(self.window_width, self.window_height, self.window_angle, red=1, green=1, blue=0,
                                 alpha=0.8)
        self.vox.set_game_score(self.score)

        # Display the player's sprite
        vox_x, vox_y = self.convert_sprite_position_to_voxelamming(self.player.x, self.player.y)
        self.vox.create_sprite(self.player.name, self.player.dot_data, vox_x, vox_y, self.player.direction, 1)

        # Since there are multiple enemies, create a template and display it in multiple locations
        self.vox.create_sprite(Enemy.name, Enemy.dot_data)
        for enemy in self.enemies:
            vox_x, vox_y = self.convert_sprite_position_to_voxelamming(enemy.x, enemy.y)
            self.vox.move_sprite(enemy.name, vox_x, vox_y, enemy.direction, 1)

        self.vox.send_data()
        self.vox.clear_data()

    def update_voxelamming(self):
        # Send sprite information every 0.1 seconds
        if pyxel.frame_count % 3 == 0 or self.game_clear or self.game_over:  # Default Pyxel FPS is 30
            self.vox.set_box_size(self.dot_size)
            self.vox.set_game_screen(self.window_width, self.window_height, self.window_angle, red=1, green=1,
                                     blue=0, alpha=0.5)
            self.vox.set_game_score(self.score, -66, 57)

            # Move sprites
            vox_x, vox_y = self.convert_sprite_position_to_voxelamming(self.player.x, self.player.y)
            self.vox.move_sprite(self.player.name, vox_x, vox_y, self.player.direction, 1)

            # Enemy movement is displayed as templates in multiple locations
            for enemy in self.enemies:
                vox_x, vox_y = self.convert_sprite_position_to_voxelamming(enemy.x, enemy.y)
                self.vox.move_sprite_clone(enemy.name, vox_x, vox_y, enemy.direction, 1)

            # Missiles are displayed as dots
            for missile in self.missiles + self.enemy_missiles:
                vox_x, vox_y = self.convert_dot_position_to_voxelamming(missile.x, missile.y, missile.width, missile.height)
                self.vox.display_dot(vox_x, vox_y, missile.direction, missile.color_id, missile.width,
                                     missile.height)

            # Change the screen to blue and display the game clear
            if self.game_clear:
                self.vox.set_game_screen(self.window_width, self.window_height, self.window_angle, red=0, green=0,
                                         blue=1, alpha=0.8)
                self.vox.set_command('gameClear')

            # Change the screen to red and display game over
            if self.game_over:
                self.vox.set_game_screen(self.window_width, self.window_height, self.window_angle, red=1, green=0,
                                         blue=0, alpha=0.8)
                self.vox.set_command('gameOver')

            self.vox.send_data()

            # Wait for 1 second after game clear or game over, then send data again
            if self.game_clear or self.game_over:
                time.sleep(1)
                self.vox.send_data()

            self.vox.clear_data()

    def convert_sprite_position_to_voxelamming(self, x, y):
        return x - self.window_width // 2 + 4, self.window_height // 2 - (y + 4)

    def convert_dot_position_to_voxelamming(self, x, y, width=1, height=1):
        return x - self.window_width // 2 + width / 2, self.window_height // 2 - (y + height / 2)


if __name__ == "__main__":
    App()
```

This code snippet demonstrates a simple example where a red voxel is created at a specific location. You can use various functions provided by the `Voxelamming` class to build more complex models.

#### Method description
| Modeling Method name                                                                                | Description | Arguments |
|--------------------------------------------------------------------------------------------|---|---|
| `set_room_name(room_name)`                                                                 | Sets the room name for communicating with the device. | `room_name`: Room name (string) |
| `set_box_size(size)`                                                                       | Sets the size of the voxel (default: 1.0). | `size`: Size (float) |
| `set_build_interval(interval)`                                                             | Sets the placement interval of the voxels (default: 0.01 seconds). | `interval`: Interval (float) |
| `change_shape(shape)`                                                                      | Changes the shape of the voxel. | `shape`: Shape ("box", "sphere", "plane") |
| `change_material(is_metallic, roughness)`                                                  | Changes the material of the voxel. | `is_metallic`: Whether to make it metallic (boolean), `roughness`: Roughness (float) |
| `create_box(x, y, z, r, g, b, alpha)`                                                      | Places a voxel. | `x`, `y`, `z`: Position (float), `r`, `g`, `b`, `alpha`: Color (float, 0-1) |
| `create_box(x, y, z, texture)`                                                             | Places a voxel with texture. | `x`, `y`, `z`: Position (float), `texture`: Texture name (string) |
| `remove_box(x, y, z)`                                                                      | Removes a voxel. | `x`, `y`, `z`: Position (float) |
| `write_sentence(sentence, x, y, z, r, g, b, alpha)`                                        | Draws a string with voxels. | `sentence`: String (string), `x`, `y`, `z`: Position (float), `r`, `g`, `b`, `alpha`: Color (float, 0-1) |
| `set_light(x, y, z, r, g, b, alpha, intensity, interval, light_type)`                      | Places a light. | `x`, `y`, `z`: Position (float), `r`, `g`, `b`, `alpha`: Color (float, 0-1), `intensity`: Intensity (float), `interval`: Blinking interval (float), `light_type`: Type of light ("point", "spot", "directional") |
| `set_command(command)`                                                                     | Executes a command. | `command`: Command ("axis", "japaneseCastle", "float", "liteRender") |
| `draw_line(x1, y1, z1, x2, y2, z2, r, g, b, alpha)`                                        | Draws a line between two points. | `x1`, `y1`, `z1`: Starting point (float), `x2`, `y2`, `z2`: Ending point (float), `r`, `g`, `b`, `alpha`: Color (float, 0-1) |
| `create_model(model_name, x, y, z, pitch, yaw, roll, scale, entity_name)`                  | Creates a built-in model (USDZ). |  `model_name`: Name of the model (string), `x`, `y`, `z`: Translation values (float), `pitch`, `yaw`, `roll`: Rotation values (float), `scale`: Scale (float), `entity_name`: Name assigned to the created model (string) |
| `move_model(entity_name, x, y, z, pitch, yaw, roll, scale)`                                | Moves the created model (USDZ). |  `entity_name`: Name assigned to the created model (string), `x`, `y`, `z`: Translation values (float), `pitch`, `yaw`, `roll`: Rotation values (float), `scale`: Scale (float) |
| `send_data(name)`                                                                          | Sends voxel data to the device; if the name argument is set, the voxel data can be stored and reproduced as history. | |
| `clear_data()`                                                                             | Initializes voxel data. | |
| `transform(x, y, z, pitch, yaw, roll)`                                                     | Moves and rotates the coordinate system of the voxel. | `x`, `y`, `z`: Translation amount (float), `pitch`, `yaw`, `roll`: Rotation amount (float) |
| `animate(x, y, z, pitch, yaw, roll, scale, interval)`                                      | Animates a voxel. | `x`, `y`, `z`: Translation amount (float), `pitch`, `yaw`, `roll`: Rotation amount (float), `scale`: Scale (float), `interval`: Interval (float) |
| `animate_global(x, y, z, pitch, yaw, roll, scale, interval)`                               | Animates all voxels. | `x`, `y`, `z`: Translation amount (float), `pitch`, `yaw`, `roll`: Rotation amount (float), `scale`: Scale (float), `interval`: Interval (float) |
| `push_matrix()`                                                                            | Saves the current coordinate system to the stack. | |
| `pop_matrix()`                                                                             | Restores the coordinate system from the stack. | |
| `frame_in()`                                                                               | Starts recording a frame. | |
| `frame_out()`                                                                              | Ends recording a frame. | |
| `set_frame_fps(fps)`                                                                       | Sets the frame rate (default: 2). | `fps`: Frame rate (int) |
| `set_frame_repeats(repeats)`                                                               | Sets the number of frame repetitions (default: 10). | `repeats`: Number of repetitions (int) |
| Game Method Name                                                                           | Description | Arguments                                                                                                                                                            |
| `set_game_screen_size(width, height, angle=90, r=1, g=1, b=0, alpha=0.5)`                  | Sets the game screen size. | `width`, `height`: screen size (float), `angle`: angle (float), `r`, `g`, `b`, `alpha`: color (float, 0-1)                                                            |
| `set_game_score(score)`                                                                    | Sets the game score. | `score`: game score (int)                                                                                                                                            |
| `send_game_over()`                                                                         | Triggers game over. |                                                                                                                                                                     |
| `send_game_clear()`                                                                  | Triggers game clear. |                                                                                                                                                                   |
| `create_sprite(sprite_name, color_list, x, y, direction=90, scale=1, visible=True)`        | Creates a sprite. | `sprite_name`: sprite name (string), `color_list`: dot color data (string), `x`, `y`: position (float), `direction`: angle (float), `scale`: scale (float), `visible`: visibility (boolean) |
| `move_sprite(sprite_name, x, y, direction=90, scale=1, visible=True)`                      | Moves a sprite. | `sprite_name`: sprite name (string), `x`, `y`: position (float), `direction`: angle (float), `scale`: scale (float), `visible`: visibility (boolean)                                  |
| `move_sprite_clone(sprite_name, x, y, direction=90, scale=1,)`               | Moves a clone of the sprite. Can be executed multiple times and is used when creating multiple sprites. | `sprite_name`: Sprite name (string), `x`, `y`: Position (float), `direction`: Direction (float), `scale`: Scale (float)                                  |
| `display_dot(sprite_name, x, y, direction=90, scale=1)`               | Used to place multiple dots, such as bullets or particles. | `sprite_name`: Sprite name (string), `x`, `y`: Position (float), `direction`: Direction (float), `scale`: Scale (float)                                  |
| `display_text(sprite_name, x, y, direction=90, scale=1, is_vertical=True)`               | Displays text on the game screen. | `sprite_name`: Sprite name (string), `x`, `y`: Position (float), `direction`: Direction (float), `scale`: Scale (float), `is_vertical`: Vertical display (boolean)                                  |

## Notes

- Ensure that the Voxelamming app is running and connected to the same room name specified in your Python script.
- This library requires Python 3.9 or higher. 
- Executing arbitrary Python code can be a security risk. Be cautious when running code from untrusted sources. 

This library is under active development. More features and improvements are planned for future releases. 

## License

[MIT License](https://github.com/creativival/voxelamming/blob/master/LICENSE)

## Author

creativival

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "voxelamming",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": null,
    "author": "creativival",
    "author_email": null,
    "download_url": null,
    "platform": null,
    "description": "## voxelamming\n\nThis Python library converts Python code into JSON format and sends it to the Voxelamming app using WebSockets, allowing users to create 3D voxel models by writing Python scripts.\n\n## What's Voxelamming?\n\n<p align=\"center\"><img src=\"https://creativival.github.io/voxelamming/image/voxelamming_icon.png\" alt=\"Voxelamming Logo\" width=\"200\"/></p>\n\nVoxelamming is an AR programming learning app. Even programming beginners can learn programming visually and enjoyably. Voxelamming supports iPhones and iPads with iOS 16 or later, and Apple Vision Pro.\n\n## Resources\n\n* **Homepage:** https://creativival.github.io/voxelamming_python\n* **Samples:** https://github.com/creativival/voxelamming/tree/main/sample/python\n\n## Installation\n\n```bash\npip install voxelamming\n```\n\n## Usage\n\n### Modeling\n\n```python\nfrom voxelamming import Voxelamming\n\n# Set your room name. This should match the room name displayed in your Voxelamming app. \nroom_name = \"1000\"\n\n# Create a Voxelamming instance\nvoxelamming = Voxelamming(room_name)\n\n# Define Python code to create a voxel model\nvoxelamming.set_box_size(0.5)\nvoxelamming.set_build_interval(0.01)\nvoxelamming.transform(0, 0, 0, pitch=0, yaw=0, roll=0)\nvoxelamming.animate(0, 0, 10, pitch=0, yaw=30, roll=0, scale=2, interval= 10)\n\nfor i in range(100):\n  voxelamming.create_box(-1, i, 0, r=0, g=1, b=1)\n  voxelamming.create_box(0, i, 0, r=1, g=0, b=0)\n  voxelamming.create_box(1, i, 0, r=1, g=1, b=0)\n  voxelamming.create_box(2, i, 0, r=0, g=1, b=1)\n\nfor i in range(50):\n  voxelamming.remove_box(0, i * 2 + 1, 0)\n  voxelamming.remove_box(1, i * 2, 0)\n\n# Send the Python code to the Voxelamming app\nvoxelamming.send_data()\n```\n\n### Game Mode\n\n```python\nimport pyxel\nimport time\nimport random\n# from voxelamming import Voxelamming\nfrom voxelamming_local import Voxelamming  # Use this when developing locally\n\n\nclass Player:\n    name = 'spaceship_8x8'\n    dot_data = (\n        '-1 -1 -1 8 8 -1 -1 -1 -1 -1 3 7 7 3 -1 -1 -1 -1 -1 7 7 -1 -1 -1 -1 -1 7 7 7 7 -1 -1 -1 7 7 7 7 7 7 -1 3 7'\n        ' 7 7 7 7 7 3 -1 8 8 7 7 8 8 -1 -1 -1 -1 8 8 -1 -1 -1'\n    )\n\n    def __init__(self, x, y, speed):\n        self.direction = 0\n        self.x = x\n        self.y = y\n        self.img = 0\n        self.u = 0\n        self.v = 0\n        self.w = 8\n        self.h = 8\n        self.speed = speed\n\n    def update(self):\n        if pyxel.btn(pyxel.KEY_LEFT):\n            self.x -= self.speed\n        if pyxel.btn(pyxel.KEY_RIGHT):\n            self.x += self.speed\n\n\nclass Enemy:\n    name = 'enemy_8x8'\n    dot_data = (\n        '-1 -1 3 -1 -1 3 -1 -1 -1 3 -1 3 3 -1 3 -1 3 -1 3 3 3 3 -1 3 3 3 3 3 3 3 3 3 3 3 -1 3 3 -1 3 3 3 3 3 3 3 3'\n        ' 3 3 -1 3 3 -1 -1 3 3 -1 3 -1 -1 -1 -1 -1 -1 3'\n    )\n\n    def __init__(self, x, y):\n        self.direction = 0\n        self.x = x\n        self.y = y\n        self.img = 0\n        self.u = 0\n        self.v = 8\n        self.w = 8\n        self.h = 8\n\n\nclass Missile:\n    def __init__(self, x, y, color_id, direction=0, width=1, height=1):\n        self.x = x\n        self.y = y\n        self.direction = direction\n        self.color_id = color_id\n        self.width = width\n        self.height = height\n\n\nclass App:\n    def __init__(self):\n        # Pyxel settings\n        self.window_width = 160  # The width of the AR window becomes the value multiplied by self.dot_size (in centimeters)\n        self.window_height = 120  # The height of the AR window becomes the value multiplied by self.dot_size (in centimeters)\n        self.score = 0\n        self.game_over = False\n        self.game_clear = False\n\n        # Player settings\n        self.player = Player(self.window_width // 2, self.window_height - 10, 2)\n        self.missiles = []\n        self.player_missile_speed = 2\n\n        # Enemy settings\n        self.enemy_rows = 3\n        self.enemy_cols = 6\n        self.enemy_speed = 1\n        self.enemy_direction = 1\n        self.enemies = []\n        self.enemy_missiles = []\n        self.enemy_missile_speed = 2\n\n        # Initialize enemies\n        for row in range(self.enemy_rows):\n            for col in range(self.enemy_cols):\n                enemy_x = col * 16 + 20\n                enemy_y = row * 12 + 20\n                enemy = Enemy(enemy_x, enemy_y)\n                self.enemies.append(enemy)\n\n        # Voxelamming settings (executed before Pyxel initialization)\n        self.dot_size = 1  # The size of the sprite dots displayed in the AR space (in centimeters)\n        self.window_angle = 80  # Tilt angle of the AR window (in degrees)\n        self.vox = Voxelamming('1000')\n        self.init_voxelamming()\n\n        # Pyxel initialization\n        pyxel.init(self.window_width, self.window_height, title=\"Pyxel Invader Game\", fps=30)\n        pyxel.mouse(True)\n        pyxel.load(\"invader_game.pyxres\")\n        pyxel.run(self.update, self.draw)\n\n    def update(self):\n        if self.game_over or self.game_clear:\n            # Show cursor\n            pyxel.mouse(True)\n\n            if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):\n                self.reset_game()\n            return\n\n        # Hide cursor\n        pyxel.mouse(False)\n\n        # Player controls\n        self.player.update()\n\n        if pyxel.btnp(pyxel.KEY_SPACE):\n            missile_x = self.player.x + self.player_missile_speed\n            missile_y = self.player.y\n            missile_clor_id = 10  # Blue\n            missile_direction = 0\n            missile_width = 2\n            missile_height = 4\n            self.missiles.append(\n                Missile(missile_x, missile_y, missile_clor_id, missile_direction, missile_width, missile_height))\n\n        # Move missiles\n        for missile in self.missiles[:]:\n            missile.y -= 2\n            if missile.y < 0:\n                self.missiles.remove(missile)\n\n        # Move enemies\n        move_down = False\n        for enemy in self.enemies:\n            enemy.x += self.enemy_speed * self.enemy_direction\n\n        for enemy in self.enemies:\n            if enemy.x > pyxel.width - 8 or enemy.x < 0:\n                self.enemy_direction *= -1\n                move_down = True\n                break  # Change direction immediately when reaching the edge\n\n        if move_down:\n            for enemy in self.enemies:\n                enemy.y += 8\n\n                # Game over if the enemy reaches the bottom of the screen\n                if enemy.y > pyxel.height - 16:\n                    self.game_over = True\n\n        # Enemy missile firing\n        if random.random() < 0.03 and self.enemies:\n            shooting_enemy = random.choice(self.enemies)\n            missile_x = shooting_enemy.x + 4\n            missile_y = shooting_enemy.y + 8\n            missile_clor_id = 8  # Red\n            missile_direction = 0\n            missile_width = 2\n            missile_height = 4\n            self.enemy_missiles.append(\n                Missile(missile_x, missile_y, missile_clor_id, missile_direction, missile_width, missile_height))\n\n        # Move enemy missiles\n        for missile in self.enemy_missiles[:]:\n            missile.y += self.enemy_missile_speed\n            if missile.y > pyxel.height * 2:\n                self.enemy_missiles.remove(missile)\n\n        # Collision detection between missiles and enemies\n        for missile in self.missiles[:]:\n            for enemy in self.enemies[:]:\n                if (enemy.x < missile.x < enemy.x + 16 and\n                        enemy.y < missile.y < enemy.y + 12):\n                    self.missiles.remove(missile)\n                    self.enemies.remove(enemy)\n                    self.score += 10\n                    break\n\n        # Collision detection between player and enemy missiles\n        for missile in self.enemy_missiles[:]:\n            if (self.player.x < missile.x < self.player.x + 8 and\n                    self.player.y < missile.y < self.player.y + 8):\n                self.game_over = True\n\n        # Collision detection between player and enemies\n        for enemy in self.enemies:\n            if (self.player.x < enemy.x < self.player.x + 8 and\n                    self.player.y < enemy.y < self.player.y + 8):\n                self.game_over = True\n\n        # Check for game clear\n        if not self.enemies:\n            self.game_clear = True\n\n        # Update Voxelamming\n        self.update_voxelamming()\n\n    def draw(self):\n        pyxel.cls(0)\n        pyxel.text(5, 4, f\"Score: {self.score}\", 7)\n\n        if self.game_clear:\n            pyxel.text(pyxel.width // 2 - 20, pyxel.height // 2, \"GAME CLEAR!\", pyxel.frame_count % 16)\n            pyxel.text(self.window_width // 2 - 26, self.window_height // 2 + 8, \"Click to start\",\n                       pyxel.frame_count % 16)\n        elif self.game_over:\n            pyxel.text(pyxel.width // 2 - 20, pyxel.height // 2, \"GAME OVER\", pyxel.frame_count % 16)\n            pyxel.text(self.window_width // 2 - 26, self.window_height // 2 + 8, \"Click to start\",\n                       pyxel.frame_count % 16)\n        else:\n            # Draw player\n            pyxel.blt(self.player.x, self.player.y, self.player.img, self.player.u, self.player.v, self.player.w,\n                      self.player.h, 0)\n\n            # Draw enemies\n            for enemy in self.enemies:\n                pyxel.blt(enemy.x, enemy.y, enemy.img, enemy.u, enemy.v, enemy.w, enemy.h, 0)\n\n            # Draw missiles\n            for missile in self.missiles:\n                pyxel.rect(missile.x, missile.y, missile.width, missile.height, missile.color_id)\n\n            # Draw enemy missiles\n            for missile in self.enemy_missiles:\n                pyxel.rect(missile.x, missile.y, missile.width, missile.height, missile.color_id)\n\n    def reset_game(self):\n        self.score = 0  # Reset score\n        self.game_over = False\n        self.game_clear = False\n\n        # Player settings\n        self.player = Player(self.window_width // 2, self.window_height - 10, 2)\n        self.missiles = []\n\n        # Enemy settings\n        self.enemy_rows = 3\n        self.enemy_cols = 6\n        self.enemy_speed = 1\n        self.enemy_direction = 1\n        self.enemies = []\n        self.enemy_missiles = []\n        self.enemy_missile_speed = 2\n\n        # Initialize enemies\n        for row in range(self.enemy_rows):\n            for col in range(self.enemy_cols):\n                enemy_x = col * 16 + 20\n                enemy_y = row * 12 + 20\n                enemy = Enemy(enemy_x, enemy_y)\n                self.enemies.append(enemy)\n\n    def init_voxelamming(self):\n\n        # Initialize Voxelamming\n        self.vox.set_box_size(self.dot_size)\n        self.vox.set_game_screen(self.window_width, self.window_height, self.window_angle, red=1, green=1, blue=0,\n                                 alpha=0.8)\n        self.vox.set_game_score(self.score)\n\n        # Display the player's sprite\n        vox_x, vox_y = self.convert_sprite_position_to_voxelamming(self.player.x, self.player.y)\n        self.vox.create_sprite(self.player.name, self.player.dot_data, vox_x, vox_y, self.player.direction, 1)\n\n        # Since there are multiple enemies, create a template and display it in multiple locations\n        self.vox.create_sprite(Enemy.name, Enemy.dot_data)\n        for enemy in self.enemies:\n            vox_x, vox_y = self.convert_sprite_position_to_voxelamming(enemy.x, enemy.y)\n            self.vox.move_sprite(enemy.name, vox_x, vox_y, enemy.direction, 1)\n\n        self.vox.send_data()\n        self.vox.clear_data()\n\n    def update_voxelamming(self):\n        # Send sprite information every 0.1 seconds\n        if pyxel.frame_count % 3 == 0 or self.game_clear or self.game_over:  # Default Pyxel FPS is 30\n            self.vox.set_box_size(self.dot_size)\n            self.vox.set_game_screen(self.window_width, self.window_height, self.window_angle, red=1, green=1,\n                                     blue=0, alpha=0.5)\n            self.vox.set_game_score(self.score, -66, 57)\n\n            # Move sprites\n            vox_x, vox_y = self.convert_sprite_position_to_voxelamming(self.player.x, self.player.y)\n            self.vox.move_sprite(self.player.name, vox_x, vox_y, self.player.direction, 1)\n\n            # Enemy movement is displayed as templates in multiple locations\n            for enemy in self.enemies:\n                vox_x, vox_y = self.convert_sprite_position_to_voxelamming(enemy.x, enemy.y)\n                self.vox.move_sprite_clone(enemy.name, vox_x, vox_y, enemy.direction, 1)\n\n            # Missiles are displayed as dots\n            for missile in self.missiles + self.enemy_missiles:\n                vox_x, vox_y = self.convert_dot_position_to_voxelamming(missile.x, missile.y, missile.width, missile.height)\n                self.vox.display_dot(vox_x, vox_y, missile.direction, missile.color_id, missile.width,\n                                     missile.height)\n\n            # Change the screen to blue and display the game clear\n            if self.game_clear:\n                self.vox.set_game_screen(self.window_width, self.window_height, self.window_angle, red=0, green=0,\n                                         blue=1, alpha=0.8)\n                self.vox.set_command('gameClear')\n\n            # Change the screen to red and display game over\n            if self.game_over:\n                self.vox.set_game_screen(self.window_width, self.window_height, self.window_angle, red=1, green=0,\n                                         blue=0, alpha=0.8)\n                self.vox.set_command('gameOver')\n\n            self.vox.send_data()\n\n            # Wait for 1 second after game clear or game over, then send data again\n            if self.game_clear or self.game_over:\n                time.sleep(1)\n                self.vox.send_data()\n\n            self.vox.clear_data()\n\n    def convert_sprite_position_to_voxelamming(self, x, y):\n        return x - self.window_width // 2 + 4, self.window_height // 2 - (y + 4)\n\n    def convert_dot_position_to_voxelamming(self, x, y, width=1, height=1):\n        return x - self.window_width // 2 + width / 2, self.window_height // 2 - (y + height / 2)\n\n\nif __name__ == \"__main__\":\n    App()\n```\n\nThis code snippet demonstrates a simple example where a red voxel is created at a specific location. You can use various functions provided by the `Voxelamming` class to build more complex models.\n\n#### Method description\n| Modeling Method name                                                                                | Description | Arguments |\n|--------------------------------------------------------------------------------------------|---|---|\n| `set_room_name(room_name)`                                                                 | Sets the room name for communicating with the device. | `room_name`: Room name (string) |\n| `set_box_size(size)`                                                                       | Sets the size of the voxel (default: 1.0). | `size`: Size (float) |\n| `set_build_interval(interval)`                                                             | Sets the placement interval of the voxels (default: 0.01 seconds). | `interval`: Interval (float) |\n| `change_shape(shape)`                                                                      | Changes the shape of the voxel. | `shape`: Shape (\"box\", \"sphere\", \"plane\") |\n| `change_material(is_metallic, roughness)`                                                  | Changes the material of the voxel. | `is_metallic`: Whether to make it metallic (boolean), `roughness`: Roughness (float) |\n| `create_box(x, y, z, r, g, b, alpha)`                                                      | Places a voxel. | `x`, `y`, `z`: Position (float), `r`, `g`, `b`, `alpha`: Color (float, 0-1) |\n| `create_box(x, y, z, texture)`                                                             | Places a voxel with texture. | `x`, `y`, `z`: Position (float), `texture`: Texture name (string) |\n| `remove_box(x, y, z)`                                                                      | Removes a voxel. | `x`, `y`, `z`: Position (float) |\n| `write_sentence(sentence, x, y, z, r, g, b, alpha)`                                        | Draws a string with voxels. | `sentence`: String (string), `x`, `y`, `z`: Position (float), `r`, `g`, `b`, `alpha`: Color (float, 0-1) |\n| `set_light(x, y, z, r, g, b, alpha, intensity, interval, light_type)`                      | Places a light. | `x`, `y`, `z`: Position (float), `r`, `g`, `b`, `alpha`: Color (float, 0-1), `intensity`: Intensity (float), `interval`: Blinking interval (float), `light_type`: Type of light (\"point\", \"spot\", \"directional\") |\n| `set_command(command)`                                                                     | Executes a command. | `command`: Command (\"axis\", \"japaneseCastle\", \"float\", \"liteRender\") |\n| `draw_line(x1, y1, z1, x2, y2, z2, r, g, b, alpha)`                                        | Draws a line between two points. | `x1`, `y1`, `z1`: Starting point (float), `x2`, `y2`, `z2`: Ending point (float), `r`, `g`, `b`, `alpha`: Color (float, 0-1) |\n| `create_model(model_name, x, y, z, pitch, yaw, roll, scale, entity_name)`                  | Creates a built-in model (USDZ). |  `model_name`: Name of the model (string), `x`, `y`, `z`: Translation values (float), `pitch`, `yaw`, `roll`: Rotation values (float), `scale`: Scale (float), `entity_name`: Name assigned to the created model (string) |\n| `move_model(entity_name, x, y, z, pitch, yaw, roll, scale)`                                | Moves the created model (USDZ). |  `entity_name`: Name assigned to the created model (string), `x`, `y`, `z`: Translation values (float), `pitch`, `yaw`, `roll`: Rotation values (float), `scale`: Scale (float) |\n| `send_data(name)`                                                                          | Sends voxel data to the device; if the name argument is set, the voxel data can be stored and reproduced as history. | |\n| `clear_data()`                                                                             | Initializes voxel data. | |\n| `transform(x, y, z, pitch, yaw, roll)`                                                     | Moves and rotates the coordinate system of the voxel. | `x`, `y`, `z`: Translation amount (float), `pitch`, `yaw`, `roll`: Rotation amount (float) |\n| `animate(x, y, z, pitch, yaw, roll, scale, interval)`                                      | Animates a voxel. | `x`, `y`, `z`: Translation amount (float), `pitch`, `yaw`, `roll`: Rotation amount (float), `scale`: Scale (float), `interval`: Interval (float) |\n| `animate_global(x, y, z, pitch, yaw, roll, scale, interval)`                               | Animates all voxels. | `x`, `y`, `z`: Translation amount (float), `pitch`, `yaw`, `roll`: Rotation amount (float), `scale`: Scale (float), `interval`: Interval (float) |\n| `push_matrix()`                                                                            | Saves the current coordinate system to the stack. | |\n| `pop_matrix()`                                                                             | Restores the coordinate system from the stack. | |\n| `frame_in()`                                                                               | Starts recording a frame. | |\n| `frame_out()`                                                                              | Ends recording a frame. | |\n| `set_frame_fps(fps)`                                                                       | Sets the frame rate (default: 2). | `fps`: Frame rate (int) |\n| `set_frame_repeats(repeats)`                                                               | Sets the number of frame repetitions (default: 10). | `repeats`: Number of repetitions (int) |\n| Game Method Name                                                                           | Description | Arguments                                                                                                                                                            |\n| `set_game_screen_size(width, height, angle=90, r=1, g=1, b=0, alpha=0.5)`                  | Sets the game screen size. | `width`, `height`: screen size (float), `angle`: angle (float), `r`, `g`, `b`, `alpha`: color (float, 0-1)                                                            |\n| `set_game_score(score)`                                                                    | Sets the game score. | `score`: game score (int)                                                                                                                                            |\n| `send_game_over()`                                                                         | Triggers game over. |                                                                                                                                                                     |\n| `send_game_clear()`                                                                  | Triggers game clear. |                                                                                                                                                                   |\n| `create_sprite(sprite_name, color_list, x, y, direction=90, scale=1, visible=True)`        | Creates a sprite. | `sprite_name`: sprite name (string), `color_list`: dot color data (string), `x`, `y`: position (float), `direction`: angle (float), `scale`: scale (float), `visible`: visibility (boolean) |\n| `move_sprite(sprite_name, x, y, direction=90, scale=1, visible=True)`                      | Moves a sprite. | `sprite_name`: sprite name (string), `x`, `y`: position (float), `direction`: angle (float), `scale`: scale (float), `visible`: visibility (boolean)                                  |\n| `move_sprite_clone(sprite_name, x, y, direction=90, scale=1,)`               | Moves a clone of the sprite. Can be executed multiple times and is used when creating multiple sprites. | `sprite_name`: Sprite name (string), `x`, `y`: Position (float), `direction`: Direction (float), `scale`: Scale (float)                                  |\n| `display_dot(sprite_name, x, y, direction=90, scale=1)`               | Used to place multiple dots, such as bullets or particles. | `sprite_name`: Sprite name (string), `x`, `y`: Position (float), `direction`: Direction (float), `scale`: Scale (float)                                  |\n| `display_text(sprite_name, x, y, direction=90, scale=1, is_vertical=True)`               | Displays text on the game screen. | `sprite_name`: Sprite name (string), `x`, `y`: Position (float), `direction`: Direction (float), `scale`: Scale (float), `is_vertical`: Vertical display (boolean)                                  |\n\n## Notes\n\n- Ensure that the Voxelamming app is running and connected to the same room name specified in your Python script.\n- This library requires Python 3.9 or higher. \n- Executing arbitrary Python code can be a security risk. Be cautious when running code from untrusted sources. \n\nThis library is under active development. More features and improvements are planned for future releases. \n\n## License\n\n[MIT License](https://github.com/creativival/voxelamming/blob/master/LICENSE)\n\n## Author\n\ncreativival\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Convert Python code to JSON and send it to the Voxelamming app.",
    "version": "0.3.7",
    "project_urls": null,
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f16597d61732b3025c31c443fc4a7002e99faaa84f0c0fbc13a90333c20cff20",
                "md5": "f0f894901392f80bccd8368996138ccb",
                "sha256": "6c2fc1868e4d87017572a732cac4fa3f859c3e1bb5b734deb39a1977dabe62b7"
            },
            "downloads": -1,
            "filename": "voxelamming-0.3.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f0f894901392f80bccd8368996138ccb",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 15368,
            "upload_time": "2024-10-02T07:08:58",
            "upload_time_iso_8601": "2024-10-02T07:08:58.830945Z",
            "url": "https://files.pythonhosted.org/packages/f1/65/97d61732b3025c31c443fc4a7002e99faaa84f0c0fbc13a90333c20cff20/voxelamming-0.3.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-02 07:08:58",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "voxelamming"
}
        
Elapsed time: 0.34357s