File size: 6,865 Bytes
3ffa062
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
import gradio as gr
import random
import base64

# Mad Lib Generator
templates = [
    "The {adjective} {noun} {verb} over the {adjective} {noun}.",
    "In a {adjective} land, a {noun} and a {noun} went on a {adjective} adventure.",
    "The {noun} {verb} {adverb} while the {adjective} {noun} watched in amazement."
]

parts_of_speech = {
    "adjective": ["brave", "mysterious", "colorful", "gigantic", "tiny"],
    "noun": ["wizard", "dragon", "knight", "castle", "forest"],
    "verb": ["flew", "danced", "sang", "fought", "explored"],
    "adverb": ["quickly", "silently", "gracefully", "fiercely", "carefully"]
}

def generate_mad_lib():
    template = random.choice(templates)
    for part in parts_of_speech:
        while "{" + part + "}" in template:
            template = template.replace("{" + part + "}", random.choice(parts_of_speech[part]), 1)
    return template

# Kaboom.js Breakout Game HTML
kaboom_game_html = """
<script src="https://kaboomjs.com/lib/0.6.0/kaboom.js"></script>
<canvas id="game"></canvas>
<script>
kaboom({
    global: true,
    width: 800,
    height: 600,
    scale: 1,
    debug: true,
    canvas: document.getElementById("game")
});

loadSprite("paddle", "https://kaboomjs.com/pub/examples/breakout/paddle.png");
loadSprite("ball", "https://kaboomjs.com/pub/examples/breakout/ball.png");
loadSprite("brick", "https://kaboomjs.com/pub/examples/breakout/brick.png");
loadSprite("brick2", "https://kaboomjs.com/pub/examples/breakout/brick2.png");

scene("main", () => {
    let score = 0;
    let lifePoints = 100;
    
    const scoreLabel = add([
        text(`Score: ${score}`),
        pos(24, 24)
    ]);
    
    const lifeLabel = add([
        text(`Life: ${lifePoints}`),
        pos(24, 48)
    ]);

    const paddle = add([
        sprite("paddle"),
        pos(width() / 2, height() - 48),
        area(),
        scale(3),
        "paddle"
    ]);

    onKeyDown("left", () => {
        paddle.move(-10, 0);
    });

    onKeyDown("right", () => {
        paddle.move(10, 0);
    });

    function spawnBall() {
        const ball = add([
            sprite("ball"),
            pos(width() / 2, height() - 64),
            area(),
            scale(0.5),
            { vel: vec2(300, -300) },
            "ball"
        ]);

        ball.onCollide("paddle", (paddle) => {
            ball.vel = vec2(ball.vel.x, -Math.abs(ball.vel.y));
        });

        ball.onCollide("brick", (brick) => {
            destroy(brick);
            ball.vel = vec2(ball.vel.x, -ball.vel.y);
            score += brick.points;
            scoreLabel.text = `Score: ${score}`;
        });

        return ball;
    }

    let ball = spawnBall();

    function spawnBricks() {
        const brickTypes = [
            { sprite: "brick", points: 1, health: 1 },
            { sprite: "brick2", points: 2, health: 2 },
        ];

        for (let i = 0; i < 8; i++) {
            for (let j = 0; j < 5; j++) {
                const type = choose(brickTypes);
                add([
                    sprite(type.sprite),
                    pos(i * 96 + 64, j * 32 + 64),
                    area(),
                    scale(2),
                    "brick",
                    {
                        points: type.points,
                        health: type.health
                    }
                ]);
            }
        }
    }

    spawnBricks();

    onUpdate("ball", (ball) => {
        if (ball.pos.y > height()) {
            destroy(ball);
            lifePoints -= 10;
            lifeLabel.text = `Life: ${lifePoints}`;
            if (lifePoints <= 0) {
                go("gameOver", score);
            } else {
                ball = spawnBall();
            }
        }
    });
});

scene("gameOver", (score) => {
    add([
        text(`Game Over!\nFinal Score: ${score}`),
        pos(width() / 2, height() / 2),
        origin("center")
    ]);

    onKeyPress("space", () => {
        go("main");
    });
});

start("main");
</script>
"""

# A-Frame 3D Scene HTML
aframe_scene_html = """
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/donmccurdy/[email protected]/dist/aframe-extras.min.js"></script>
<a-scene embedded style="height: 400px;">
    <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
    <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
    <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
    <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
    <a-sky color="#ECECEC"></a-sky>
    <a-entity id="rig" position="0 1.6 0">
        <a-camera></a-camera>
    </a-entity>
    <a-entity id="model-container" position="0 0 -5"></a-entity>
</a-scene>

<script>
function loadModel(url, fileType) {
    const scene = document.querySelector('a-scene');
    const modelContainer = document.getElementById('model-container');
    
    // Remove any existing model
    while (modelContainer.firstChild) {
        modelContainer.removeChild(modelContainer.firstChild);
    }
    
    // Create new entity for the model
    const modelEntity = document.createElement('a-entity');
    if (fileType === 'obj') {
        modelEntity.setAttribute('obj-model', `obj: ${url}`);
    } else if (fileType === 'glb') {
        modelEntity.setAttribute('gltf-model', url);
    }
    
    modelEntity.setAttribute('scale', '0.5 0.5 0.5');
    modelEntity.setAttribute('animation', 'property: rotation; to: 0 360 0; loop: true; dur: 10000');
    
    modelContainer.appendChild(modelEntity);
}
</script>
"""

def upload_model(file):
    if file is not None:
        file_extension = file.name.split('.')[-1].lower()
        encoded_file = base64.b64encode(file.read()).decode()
        data_url = f"data:application/octet-stream;base64,{encoded_file}"
        load_model_js = f"""
        <script>
            loadModel("{data_url}", "{file_extension}");
        </script>
        """
        return aframe_scene_html + load_model_js
    return aframe_scene_html

# Define the Gradio interface
with gr.Blocks() as demo:
    gr.Markdown("# Game Development and 3D Content Showcase")
    
    with gr.Tab("Breakout Game"):
        gr.HTML(kaboom_game_html)
    
    with gr.Tab("Mad Lib Generator"):
        mad_lib_button = gr.Button("Generate Mad Lib")
        mad_lib_output = gr.Textbox(label="Generated Mad Lib")
        mad_lib_button.click(generate_mad_lib, inputs=None, outputs=mad_lib_output)
    
    with gr.Tab("A-Frame 3D Scene"):
        model_upload = gr.File(label="Upload 3D Model (OBJ or GLB)")
        scene_output = gr.HTML(aframe_scene_html)
        model_upload.upload(upload_model, inputs=model_upload, outputs=scene_output)

# Launch the Gradio app
if __name__ == "__main__":
    demo.launch()