|
import gradio as gr |
|
import random |
|
import base64 |
|
|
|
|
|
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_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> |
|
""" |
|
|
|
|
|
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 |
|
|
|
|
|
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) |
|
|
|
|
|
if __name__ == "__main__": |
|
demo.launch() |