|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>TurbONED - Creative Coding Platform</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
<style> |
|
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap'); |
|
|
|
body { |
|
font-family: 'Roboto', sans-serif; |
|
background-color: #f0f4f8; |
|
margin: 0; |
|
padding: 0; |
|
overflow-x: hidden; |
|
} |
|
|
|
.gradient-bg { |
|
background: linear-gradient(135deg, #6e45e2 0%, #88d3ce 50%, #f9d423 100%); |
|
} |
|
|
|
.block { |
|
background-color: rgba(255, 255, 255, 0.9); |
|
border-radius: 8px; |
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
|
padding: 10px; |
|
margin: 5px; |
|
cursor: move; |
|
user-select: none; |
|
transition: all 0.2s; |
|
position: relative; |
|
} |
|
|
|
.block:hover { |
|
transform: translateY(-2px); |
|
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15); |
|
} |
|
|
|
.block.active { |
|
animation: pulse 1s infinite alternate; |
|
box-shadow: 0 0 10px rgba(255, 165, 0, 0.7); |
|
} |
|
|
|
@keyframes pulse { |
|
from { |
|
box-shadow: 0 0 5px rgba(255, 165, 0, 0.7); |
|
} |
|
to { |
|
box-shadow: 0 0 15px rgba(255, 0, 0, 0.7); |
|
} |
|
} |
|
|
|
.workspace { |
|
background-color: white; |
|
border-radius: 10px; |
|
min-height: 400px; |
|
position: relative; |
|
overflow: hidden; |
|
} |
|
|
|
.sprite { |
|
width: 60px; |
|
height: 60px; |
|
border-radius: 8px; |
|
background-color: #fff; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
cursor: pointer; |
|
transition: all 0.2s; |
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
|
} |
|
|
|
.sprite:hover { |
|
transform: scale(1.05); |
|
} |
|
|
|
.tab-content { |
|
display: none; |
|
} |
|
|
|
.tab-content.active { |
|
display: block; |
|
} |
|
|
|
#stage { |
|
background-color: #f0f0f0; |
|
border-radius: 8px; |
|
overflow: hidden; |
|
position: relative; |
|
} |
|
|
|
.draggable { |
|
position: absolute; |
|
cursor: move; |
|
} |
|
|
|
.modal { |
|
display: none; |
|
position: fixed; |
|
top: 0; |
|
left: 0; |
|
width: 100%; |
|
height: 100%; |
|
background-color: rgba(0, 0, 0, 0.5); |
|
z-index: 1000; |
|
justify-content: center; |
|
align-items: center; |
|
} |
|
|
|
.modal-content { |
|
background-color: white; |
|
padding: 20px; |
|
border-radius: 10px; |
|
max-width: 500px; |
|
width: 90%; |
|
max-height: 90vh; |
|
overflow-y: auto; |
|
} |
|
|
|
.costume-thumbnail { |
|
width: 80px; |
|
height: 80px; |
|
border-radius: 8px; |
|
background-color: #f0f0f0; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
margin: 5px; |
|
cursor: pointer; |
|
transition: all 0.2s; |
|
} |
|
|
|
.costume-thumbnail:hover { |
|
transform: scale(1.05); |
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); |
|
} |
|
|
|
.sound-item { |
|
padding: 10px; |
|
border-radius: 8px; |
|
background-color: #f0f0f0; |
|
margin: 5px 0; |
|
display: flex; |
|
align-items: center; |
|
justify-content: space-between; |
|
} |
|
|
|
.dragging { |
|
opacity: 0.5; |
|
} |
|
|
|
.dropzone { |
|
min-height: 100px; |
|
border: 2px dashed #ccc; |
|
border-radius: 8px; |
|
padding: 10px; |
|
margin: 10px 0; |
|
text-align: center; |
|
} |
|
|
|
.dropzone.highlight { |
|
border-color: #6e45e2; |
|
background-color: rgba(110, 69, 226, 0.1); |
|
} |
|
|
|
.block-container { |
|
position: relative; |
|
margin: 10px 0; |
|
} |
|
|
|
.block-connector { |
|
width: 100%; |
|
height: 15px; |
|
background-color: rgba(110, 69, 226, 0.2); |
|
border-radius: 0 0 8px 8px; |
|
margin-top: -5px; |
|
cursor: pointer; |
|
} |
|
|
|
.block-connector:hover { |
|
background-color: rgba(110, 69, 226, 0.4); |
|
} |
|
|
|
.block-connector-top { |
|
width: 100%; |
|
height: 15px; |
|
background-color: rgba(110, 69, 226, 0.2); |
|
border-radius: 8px 8px 0 0; |
|
margin-bottom: -5px; |
|
cursor: pointer; |
|
} |
|
|
|
.block-connector-top:hover { |
|
background-color: rgba(110, 69, 226, 0.4); |
|
} |
|
|
|
.connected-block { |
|
margin-top: -10px; |
|
} |
|
|
|
.flag-btn { |
|
position: absolute; |
|
top: 10px; |
|
left: 10px; |
|
z-index: 10; |
|
background-color: #f9d423; |
|
color: white; |
|
width: 40px; |
|
height: 40px; |
|
border-radius: 50%; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
cursor: pointer; |
|
box-shadow: 0 2px 5px rgba(0,0,0,0.2); |
|
} |
|
|
|
.flag-btn:hover { |
|
transform: scale(1.1); |
|
} |
|
|
|
.block-slot { |
|
background-color: rgba(110, 69, 226, 0.1); |
|
border-radius: 4px; |
|
padding: 5px; |
|
margin: 5px 0; |
|
min-height: 20px; |
|
} |
|
|
|
.block-slot.highlight { |
|
background-color: rgba(110, 69, 226, 0.3); |
|
border: 1px dashed #6e45e2; |
|
} |
|
|
|
.creator-credit { |
|
position: fixed; |
|
bottom: 10px; |
|
right: 10px; |
|
background-color: rgba(255, 255, 255, 0.8); |
|
padding: 5px 10px; |
|
border-radius: 15px; |
|
font-size: 12px; |
|
z-index: 100; |
|
} |
|
|
|
.block-options { |
|
position: absolute; |
|
top: 100%; |
|
left: 0; |
|
background-color: white; |
|
border-radius: 8px; |
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
|
z-index: 100; |
|
padding: 10px; |
|
min-width: 200px; |
|
display: none; |
|
} |
|
|
|
.block-option { |
|
padding: 8px; |
|
border-radius: 4px; |
|
cursor: pointer; |
|
margin-bottom: 5px; |
|
} |
|
|
|
.block-option:hover { |
|
background-color: #f0f4f8; |
|
} |
|
|
|
.block-with-options { |
|
position: relative; |
|
} |
|
|
|
.block-options-container { |
|
display: none; |
|
position: absolute; |
|
top: 0; |
|
left: 100%; |
|
background-color: white; |
|
border-radius: 8px; |
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
|
z-index: 100; |
|
padding: 10px; |
|
min-width: 200px; |
|
} |
|
|
|
.block-options-container.show { |
|
display: block; |
|
} |
|
|
|
|
|
.block-selection-overlay { |
|
position: fixed; |
|
top: 0; |
|
left: 0; |
|
width: 100%; |
|
height: 100%; |
|
background-color: rgba(0, 0, 0, 0.7); |
|
z-index: 2000; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
display: none; |
|
} |
|
|
|
.block-selection-container { |
|
background-color: white; |
|
border-radius: 12px; |
|
width: 80%; |
|
max-width: 800px; |
|
max-height: 80vh; |
|
overflow-y: auto; |
|
padding: 20px; |
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); |
|
} |
|
|
|
.block-selection-header { |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
margin-bottom: 20px; |
|
padding-bottom: 10px; |
|
border-bottom: 1px solid #eee; |
|
} |
|
|
|
.block-selection-title { |
|
font-size: 1.5rem; |
|
font-weight: bold; |
|
color: #6e45e2; |
|
} |
|
|
|
.block-selection-close { |
|
background: none; |
|
border: none; |
|
font-size: 1.5rem; |
|
cursor: pointer; |
|
color: #666; |
|
} |
|
|
|
.block-selection-grid { |
|
display: grid; |
|
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); |
|
gap: 15px; |
|
} |
|
|
|
.block-selection-item { |
|
background-color: #f8f9fa; |
|
border-radius: 8px; |
|
padding: 15px; |
|
cursor: pointer; |
|
transition: all 0.2s; |
|
border: 2px solid transparent; |
|
} |
|
|
|
.block-selection-item:hover { |
|
transform: translateY(-3px); |
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); |
|
border-color: #6e45e2; |
|
} |
|
|
|
.block-selection-item.active { |
|
border-color: #6e45e2; |
|
background-color: #e9e0ff; |
|
} |
|
|
|
.block-selection-icon { |
|
font-size: 1.5rem; |
|
margin-bottom: 10px; |
|
color: #6e45e2; |
|
} |
|
|
|
.block-selection-name { |
|
font-weight: 500; |
|
margin-bottom: 5px; |
|
} |
|
|
|
.block-selection-description { |
|
font-size: 0.8rem; |
|
color: #666; |
|
} |
|
|
|
.block-selection-footer { |
|
display: flex; |
|
justify-content: space-between; |
|
margin-top: 20px; |
|
padding-top: 15px; |
|
border-top: 1px solid #eee; |
|
} |
|
|
|
.block-selection-btn { |
|
padding: 8px 20px; |
|
border-radius: 6px; |
|
font-weight: 500; |
|
cursor: pointer; |
|
transition: all 0.2s; |
|
} |
|
|
|
.block-selection-back { |
|
background-color: #f0f0f0; |
|
color: #333; |
|
} |
|
|
|
.block-selection-back:hover { |
|
background-color: #e0e0e0; |
|
} |
|
|
|
.block-selection-confirm { |
|
background-color: #6e45e2; |
|
color: white; |
|
} |
|
|
|
.block-selection-confirm:hover { |
|
background-color: #5a35d1; |
|
} |
|
|
|
|
|
.block-category-tabs { |
|
display: flex; |
|
margin-bottom: 15px; |
|
border-bottom: 1px solid #eee; |
|
} |
|
|
|
.block-category-tab { |
|
padding: 8px 15px; |
|
margin-right: 5px; |
|
cursor: pointer; |
|
border-bottom: 3px solid transparent; |
|
font-weight: 500; |
|
color: #666; |
|
} |
|
|
|
.block-category-tab.active { |
|
color: #6e45e2; |
|
border-bottom-color: #6e45e2; |
|
} |
|
</style> |
|
</head> |
|
<body class="min-h-screen"> |
|
|
|
<div class="flex flex-col min-h-screen"> |
|
|
|
<header class="gradient-bg text-white shadow-lg"> |
|
<div class="container mx-auto px-4 py-3 flex justify-between items-center"> |
|
<div class="flex items-center"> |
|
<i class="fas fa-code text-3xl mr-3"></i> |
|
<h1 class="text-2xl font-bold">TurbONED</h1> |
|
</div> |
|
<div class="flex items-center space-x-4"> |
|
<button id="loginBtn" class="bg-white text-purple-600 px-4 py-1 rounded-lg hover:bg-gray-100 transition">Login</button> |
|
<button id="registerBtn" class="bg-white text-blue-600 px-4 py-1 rounded-lg hover:bg-gray-100 transition">Register</button> |
|
<div id="userMenu" class="hidden"> |
|
<div class="relative"> |
|
<button class="flex items-center space-x-2 bg-white bg-opacity-20 px-4 py-1 rounded-lg hover:bg-opacity-30 transition"> |
|
<span id="usernameDisplay">User</span> |
|
<i class="fas fa-chevron-down"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</header> |
|
|
|
|
|
<main class="flex-grow container mx-auto px-4 py-6"> |
|
<div class="flex flex-col lg:flex-row gap-6"> |
|
|
|
<div class="w-full lg:w-1/4 bg-white rounded-xl shadow-md p-4"> |
|
<div class="flex mb-4 border-b pb-2"> |
|
<button onclick="changeTab('blocks')" class="tab-btn active px-4 py-2 font-medium text-purple-600 border-b-2 border-purple-600">Blocks</button> |
|
<button onclick="changeTab('costumes')" class="tab-btn px-4 py-2 font-medium text-blue-600">Costumes</button> |
|
<button onclick="changeTab('sounds')" class="tab-btn px-4 py-2 font-medium text-yellow-600">Sounds</button> |
|
</div> |
|
|
|
<div id="blocks" class="tab-content active"> |
|
<h3 class="font-bold text-lg mb-3 text-purple-700">Events</h3> |
|
<div class="block block-with-options" draggable="true" data-type="events" data-block="whenFlag" onclick="showBlockSelection('whenFlag')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-green-500 mr-2"></div> |
|
<span>when flag clicked</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
<div class="block-connector"></div> |
|
</div> |
|
<div class="block block-with-options" draggable="true" data-type="events" data-block="whenKey" onclick="showBlockSelection('whenKey')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-green-500 mr-2"></div> |
|
<span>when key pressed</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
<div class="block-connector"></div> |
|
</div> |
|
|
|
<h3 class="font-bold text-lg mt-4 mb-3 text-purple-700">Motion</h3> |
|
<div class="block block-with-options" draggable="true" data-type="motion" data-block="move" onclick="showBlockSelection('move')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-purple-500 mr-2"></div> |
|
<span>move steps</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
</div> |
|
<div class="block block-with-options" draggable="true" data-type="motion" data-block="turn" onclick="showBlockSelection('turn')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-purple-500 mr-2"></div> |
|
<span>turn degrees</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
</div> |
|
<div class="block block-with-options" draggable="true" data-type="motion" data-block="goTo" onclick="showBlockSelection('goTo')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-purple-500 mr-2"></div> |
|
<span>go to position</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
</div> |
|
|
|
<h3 class="font-bold text-lg mt-4 mb-3 text-blue-600">Looks</h3> |
|
<div class="block block-with-options" draggable="true" data-type="looks" data-block="say" onclick="showBlockSelection('say')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-blue-500 mr-2"></div> |
|
<span>say message</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
</div> |
|
<div class="block" draggable="true" data-type="looks" data-block="changeCostume"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-blue-500 mr-2"></div> |
|
<span>next costume</span> |
|
</div> |
|
</div> |
|
<div class="block block-with-options" draggable="true" data-type="looks" data-block="changeSize" onclick="showBlockSelection('changeSize')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-blue-500 mr-2"></div> |
|
<span>change size by</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
</div> |
|
|
|
<h3 class="font-bold text-lg mt-4 mb-3 text-yellow-600">Sound</h3> |
|
<div class="block block-with-options" draggable="true" data-type="sound" data-block="playSound" onclick="showBlockSelection('playSound')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-yellow-500 mr-2"></div> |
|
<span>play sound</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
</div> |
|
<div class="block" draggable="true" data-type="sound" data-block="stopSound"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-yellow-500 mr-2"></div> |
|
<span>stop all sounds</span> |
|
</div> |
|
</div> |
|
|
|
<h3 class="font-bold text-lg mt-4 mb-3 text-red-600">Control</h3> |
|
<div class="block block-with-options" draggable="true" data-type="control" data-block="wait" onclick="showBlockSelection('wait')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-red-500 mr-2"></div> |
|
<span>wait seconds</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
</div> |
|
<div class="block block-with-options" draggable="true" data-type="control" data-block="repeat" onclick="showBlockSelection('repeat')"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-red-500 mr-2"></div> |
|
<span>repeat times</span> |
|
<i class="fas fa-chevron-down ml-2 text-gray-500"></i> |
|
</div> |
|
<div class="block-slot"></div> |
|
<div class="block-connector"></div> |
|
</div> |
|
|
|
<h3 class="font-bold text-lg mt-4 mb-3 text-indigo-600">Conditionals</h3> |
|
<div class="block" draggable="true" data-type="control" data-block="if"> |
|
<div class="flex items-center"> |
|
<div class="w-6 h-6 rounded-full bg-indigo-500 mr-2"></div> |
|
<span>if <condition> then</span> |
|
</div> |
|
<div class="block-slot"></div> |
|
<div class="block-connector"></div> |
|
</div> |
|
</div> |
|
|
|
<div id="costumes" class="tab-content"> |
|
<div class="flex flex-wrap justify-center"> |
|
<div class="costume-thumbnail m-2"> |
|
<i class="fas fa-plus text-2xl text-gray-500"></i> |
|
</div> |
|
<div class="costume-thumbnail m-2"> |
|
<i class="fas fa-tshirt text-3xl text-purple-500"></i> |
|
</div> |
|
<div class="costume-thumbnail m-2"> |
|
<i class="fas fa-hat-wizard text-3xl text-blue-500"></i> |
|
</div> |
|
<div class="costume-thumbnail m-2"> |
|
<i class="fas fa-mask text-3xl text-yellow-500"></i> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div id="sounds" class="tab-content"> |
|
<button class="w-full bg-gray-200 hover:bg-gray-300 py-2 rounded-lg mb-4"> |
|
<i class="fas fa-plus mr-2"></i> Add Sound |
|
</button> |
|
<div class="sound-item"> |
|
<div> |
|
<i class="fas fa-music mr-2 text-purple-500"></i> |
|
<span>Pop Sound</span> |
|
</div> |
|
<button class="bg-purple-100 text-purple-700 px-3 py-1 rounded-lg hover:bg-purple-200"> |
|
<i class="fas fa-play"></i> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="w-full lg:w-2/4 flex flex-col gap-4"> |
|
<div class="workspace p-4" id="workspace"> |
|
<div class="flag-btn" onclick="runScripts()"> |
|
<i class="fas fa-flag"></i> |
|
</div> |
|
<p class="text-gray-500 text-center py-10">Drag blocks here to build your script</p> |
|
</div> |
|
|
|
<div id="stage" class="w-full h-64 relative"> |
|
<div id="currentSprite" class="draggable" style="left: 50%; top: 50%; transform: translate(-50%, -50%);"> |
|
<i class="fas fa-cat text-4xl text-purple-600"></i> |
|
</div> |
|
<button class="absolute bottom-2 right-2 bg-white bg-opacity-80 px-3 py-1 rounded-lg hover:bg-opacity-100"> |
|
<i class="fas fa-image mr-1"></i> Background |
|
</button> |
|
</div> |
|
|
|
<div class="flex justify-center space-x-4"> |
|
<button class="bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600" onclick="runScripts()"> |
|
<i class="fas fa-play mr-2"></i> Run |
|
</button> |
|
<button class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600" onclick="stopScripts()"> |
|
<i class="fas fa-stop mr-2"></i> Stop |
|
</button> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="w-full lg:w-1/4 bg-white rounded-xl shadow-md p-4"> |
|
<div class="flex justify-between items-center mb-4"> |
|
<h2 class="font-bold text-lg">Sprites</h2> |
|
<button class="bg-purple-100 text-purple-700 p-2 rounded-lg hover:bg-purple-200"> |
|
<i class="fas fa-plus"></i> |
|
</button> |
|
</div> |
|
|
|
<div class="grid grid-cols-3 gap-3"> |
|
<div class="sprite bg-purple-100"> |
|
<i class="fas fa-cat text-2xl text-purple-600"></i> |
|
</div> |
|
<div class="sprite bg-blue-100"> |
|
<i class="fas fa-dog text-2xl text-blue-600"></i> |
|
</div> |
|
<div class="sprite bg-yellow-100"> |
|
<i class="fas fa-user text-2xl text-yellow-600"></i> |
|
</div> |
|
</div> |
|
|
|
<div class="mt-6"> |
|
<div class="flex mb-4 border-b pb-2"> |
|
<button onclick="changeRightTab('properties')" class="tab-btn active px-4 py-2 font-medium text-purple-600 border-b-2 border-purple-600">Properties</button> |
|
<button onclick="changeRightTab('multiplayer')" class="tab-btn px-4 py-2 font-medium text-blue-600">Multiplayer</button> |
|
<button onclick="changeRightTab('developers')" class="tab-btn px-4 py-2 font-medium text-yellow-600">Developers</button> |
|
</div> |
|
|
|
<div id="properties" class="tab-content active"> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-1">Sprite Name</label> |
|
<input type="text" value="Sprite1" class="w-full px-3 py-2 border rounded-lg"> |
|
</div> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-1">Position</label> |
|
<div class="flex space-x-2"> |
|
<input type="number" value="0" class="w-1/2 px-3 py-2 border rounded-lg" placeholder="X"> |
|
<input type="number" value="0" class="w-1/2 px-3 py-2 border rounded-lg" placeholder="Y"> |
|
</div> |
|
</div> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-1">Size</label> |
|
<input type="range" min="10" max="200" value="100" class="w-full"> |
|
</div> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-1">Direction</label> |
|
<input type="range" min="0" max="360" value="90" class="w-full"> |
|
</div> |
|
</div> |
|
|
|
<div id="multiplayer" class="tab-content"> |
|
<div class="text-center py-4"> |
|
<i class="fas fa-users text-4xl text-blue-500 mb-3"></i> |
|
<h3 class="font-bold text-lg mb-2">Multiplayer VEO1</h3> |
|
<p class="text-gray-600 mb-4">Connect with friends to code together in real-time</p> |
|
<button class="bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 w-full"> |
|
<i class="fas fa-plug mr-2"></i> Connect |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div id="developers" class="tab-content"> |
|
<div class="text-center py-4"> |
|
<i class="fas fa-code text-4xl text-yellow-500 mb-3"></i> |
|
<h3 class="font-bold text-lg mb-2">TurbONED Developers</h3> |
|
<div class="bg-yellow-100 p-3 rounded-lg mt-3"> |
|
<div class="font-semibold">Diamond5diamond</div> |
|
<div class="text-sm text-gray-600">Lead Developer</div> |
|
</div> |
|
<p class="text-gray-600 mt-4">TurbONED is developed by a passionate team of coders who love creative programming.</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</main> |
|
|
|
|
|
<footer class="gradient-bg text-white py-4"> |
|
<div class="container mx-auto px-4 text-center"> |
|
<p>© 2023 TurbONED - A creative coding platform</p> |
|
<div class="flex justify-center space-x-4 mt-2"> |
|
<a href="#" class="hover:text-gray-200"><i class="fab fa-twitter"></i></a> |
|
<a href="#" class="hover:text-gray-200"><i class="fab fa-github"></i></a> |
|
<a href="#" class="hover:text-gray-200"><i class="fab fa-discord"></i></a> |
|
</div> |
|
</div> |
|
</footer> |
|
</div> |
|
|
|
|
|
<div class="block-selection-overlay" id="blockSelectionOverlay"> |
|
<div class="block-selection-container"> |
|
<div class="block-selection-header"> |
|
<div class="block-selection-title" id="blockSelectionTitle">Select Block Options</div> |
|
<button class="block-selection-close" onclick="hideBlockSelection()">×</button> |
|
</div> |
|
|
|
<div class="block-category-tabs" id="blockCategoryTabs"> |
|
<div class="block-category-tab active" data-category="all">All</div> |
|
<div class="block-category-tab" data-category="motion">Motion</div> |
|
<div class="block-category-tab" data-category="looks">Looks</div> |
|
<div class="block-category-tab" data-category="sound">Sound</div> |
|
<div class="block-category-tab" data-category="control">Control</div> |
|
</div> |
|
|
|
<div class="block-selection-grid" id="blockSelectionGrid"> |
|
|
|
</div> |
|
|
|
<div class="block-selection-footer"> |
|
<button class="block-selection-btn block-selection-back" onclick="goBackInSelection()"> |
|
<i class="fas fa-arrow-left mr-2"></i> Back |
|
</button> |
|
<button class="block-selection-btn block-selection-confirm" onclick="confirmBlockSelection()"> |
|
Confirm Selection |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="creator-credit"> |
|
Created by Google Veo Generation |
|
</div> |
|
|
|
<script> |
|
|
|
let currentUser = null; |
|
let isRunning = false; |
|
let activeScripts = []; |
|
let draggedBlock = null; |
|
let activeBlock = null; |
|
let blockInstances = new Set(); |
|
let currentBlockType = null; |
|
let selectedBlockOption = null; |
|
let selectionHistory = []; |
|
|
|
|
|
const blockOptions = { |
|
whenFlag: [ |
|
{ name: "All Blocks", value: "all", description: "Execute all connected blocks", icon: "fa-code" }, |
|
{ name: "Motion Blocks", value: "motion", description: "Execute only motion blocks", icon: "fa-arrows-alt" }, |
|
{ name: "Looks Blocks", value: "looks", description: "Execute only looks blocks", icon: "fa-eye" }, |
|
{ name: "Sound Blocks", value: "sound", description: "Execute only sound blocks", icon: "fa-music" }, |
|
{ name: "Control Blocks", value: "control", description: "Execute only control blocks", icon: "fa-cogs" } |
|
], |
|
whenKey: [ |
|
{ name: "Space", value: "space", description: "Trigger when space key is pressed", icon: "fa-keyboard" }, |
|
{ name: "Up Arrow", value: "up", description: "Trigger when up arrow is pressed", icon: "fa-arrow-up" }, |
|
{ name: "Down Arrow", value: "down", description: "Trigger when down arrow is pressed", icon: "fa-arrow-down" }, |
|
{ name: "Left Arrow", value: "left", description: "Trigger when left arrow is pressed", icon: "fa-arrow-left" }, |
|
{ name: "Right Arrow", value: "right", description: "Trigger when right arrow is pressed", icon: "fa-arrow-right" } |
|
], |
|
move: [ |
|
{ name: "10 Steps", value: "10", description: "Move forward 10 steps", icon: "fa-arrow-right" }, |
|
{ name: "20 Steps", value: "20", description: "Move forward 20 steps", icon: "fa-arrow-right" }, |
|
{ name: "50 Steps", value: "50", description: "Move forward 50 steps", icon: "fa-arrow-right" }, |
|
{ name: "100 Steps", value: "100", description: "Move forward 100 steps", icon: "fa-arrow-right" }, |
|
{ name: "10 Steps Back", value: "-10", description: "Move backward 10 steps", icon: "fa-arrow-left" }, |
|
{ name: "20 Steps Back", value: "-20", description: "Move backward 20 steps", icon: "fa-arrow-left" }, |
|
{ name: "50 Steps Back", value: "-50", description: "Move backward 50 steps", icon: "fa-arrow-left" } |
|
], |
|
turn: [ |
|
{ name: "15 Degrees Right", value: "15", description: "Turn 15 degrees to the right", icon: "fa-redo" }, |
|
{ name: "30 Degrees Right", value: "30", description: "Turn 30 degrees to the right", icon: "fa-redo" }, |
|
{ name: "45 Degrees Right", value: "45", description: "Turn 45 degrees to the right", icon: "fa-redo" }, |
|
{ name: "90 Degrees Right", value: "90", description: "Turn 90 degrees to the right", icon: "fa-redo" }, |
|
{ name: "15 Degrees Left", value: "-15", description: "Turn 15 degrees to the left", icon: "fa-undo" }, |
|
{ name: "30 Degrees Left", value: "-30", description: "Turn 30 degrees to the left", icon: "fa-undo" } |
|
], |
|
goTo: [ |
|
{ name: "Random Position", value: "random", description: "Go to a random position on stage", icon: "fa-random" }, |
|
{ name: "Mouse Pointer", value: "mouse", description: "Go to current mouse position", icon: "fa-mouse-pointer" }, |
|
{ name: "Center", value: "center", description: "Go to center of stage", icon: "fa-crosshairs" } |
|
], |
|
say: [ |
|
{ name: "Hello!", value: "Hello!", description: "Say 'Hello!' for 2 seconds", icon: "fa-comment" }, |
|
{ name: "Hi there!", value: "Hi there!", description: "Say 'Hi there!' for 2 seconds", icon: "fa-comment" }, |
|
{ name: "Welcome!", value: "Welcome!", description: "Say 'Welcome!' for 2 seconds", icon: "fa-comment" } |
|
], |
|
changeSize: [ |
|
{ name: "Increase by 10", value: "10", description: "Increase size by 10%", icon: "fa-search-plus" }, |
|
{ name: "Increase by 20", value: "20", description: "Increase size by 20%", icon: "fa-search-plus" }, |
|
{ name: "Increase by 50", value: "50", description: "Increase size by 50%", icon: "fa-search-plus" }, |
|
{ name: "Decrease by 10", value: "-10", description: "Decrease size by 10%", icon: "fa-search-minus" } |
|
], |
|
playSound: [ |
|
{ name: "Pop Sound", value: "pop", description: "Play the pop sound effect", icon: "fa-volume-up" }, |
|
{ name: "Drum Sound", value: "drum", description: "Play the drum sound effect", icon: "fa-drum" }, |
|
{ name: "Bell Sound", value: "bell", description: "Play the bell sound effect", icon: "fa-bell" } |
|
], |
|
wait: [ |
|
{ name: "1 Second", value: "1", description: "Wait for 1 second", icon: "fa-clock" }, |
|
{ name: "2 Seconds", value: "2", description: "Wait for 2 seconds", icon: "fa-clock" }, |
|
{ name: "5 Seconds", value: "5", description: "Wait for 5 seconds", icon: "fa-clock" } |
|
], |
|
repeat: [ |
|
{ name: "5 Times", value: "5", description: "Repeat 5 times", icon: "fa-sync" }, |
|
{ name: "10 Times", value: "10", description: "Repeat 10 times", icon: "fa-sync" }, |
|
{ name: "20 Times", value: "20", description: "Repeat 20 times", icon: "fa-sync" } |
|
] |
|
}; |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
setupBlockOptions(); |
|
|
|
|
|
const blocks = document.querySelectorAll('[draggable="true"]'); |
|
blocks.forEach(block => { |
|
setupBlockDrag(block); |
|
}); |
|
|
|
|
|
const workspace = document.getElementById('workspace'); |
|
workspace.addEventListener('dragover', function(e) { |
|
e.preventDefault(); |
|
this.classList.add('bg-gray-100'); |
|
}); |
|
|
|
workspace.addEventListener('dragleave', function() { |
|
this.classList.remove('bg-gray-100'); |
|
}); |
|
|
|
workspace.addEventListener('drop', function(e) { |
|
e.preventDefault(); |
|
this.classList.remove('bg-gray-100'); |
|
|
|
if (draggedBlock) { |
|
|
|
const blockId = 'block-' + Date.now() + '-' + Math.floor(Math.random() * 1000); |
|
|
|
const newBlock = draggedBlock.cloneNode(true); |
|
newBlock.id = blockId; |
|
newBlock.style.position = 'absolute'; |
|
newBlock.style.left = (e.clientX - this.getBoundingClientRect().left - 50) + 'px'; |
|
newBlock.style.top = (e.clientY - this.getBoundingClientRect().top - 20) + 'px'; |
|
newBlock.style.margin = '0'; |
|
|
|
|
|
if (!blockInstances.has(blockId)) { |
|
this.appendChild(newBlock); |
|
blockInstances.add(blockId); |
|
setupBlockDrag(newBlock); |
|
setupBlockConnectors(newBlock); |
|
setupBlockClick(newBlock); |
|
|
|
|
|
const message = this.querySelector('p.text-center'); |
|
if (message) { |
|
message.remove(); |
|
} |
|
} |
|
} |
|
}); |
|
|
|
|
|
const sprite = document.getElementById('currentSprite'); |
|
makeDraggable(sprite); |
|
|
|
|
|
document.querySelectorAll('#workspace .block').forEach(block => { |
|
setupBlockClick(block); |
|
}); |
|
|
|
|
|
document.querySelectorAll('.block-category-tab').forEach(tab => { |
|
tab.addEventListener('click', function() { |
|
document.querySelectorAll('.block-category-tab').forEach(t => { |
|
t.classList.remove('active'); |
|
}); |
|
this.classList.add('active'); |
|
|
|
const category = this.getAttribute('data-category'); |
|
filterBlocksByCategory(category); |
|
}); |
|
}); |
|
}); |
|
|
|
|
|
function showBlockSelection(blockType) { |
|
currentBlockType = blockType; |
|
selectionHistory = []; |
|
|
|
const overlay = document.getElementById('blockSelectionOverlay'); |
|
const title = document.getElementById('blockSelectionTitle'); |
|
const grid = document.getElementById('blockSelectionGrid'); |
|
|
|
|
|
switch(blockType) { |
|
case 'whenFlag': |
|
title.textContent = "When Flag Clicked - Select Blocks to Execute"; |
|
break; |
|
case 'whenKey': |
|
title.textContent = "When Key Pressed - Select Key"; |
|
break; |
|
case 'move': |
|
title.textContent = "Move Steps - Select Distance"; |
|
break; |
|
case 'turn': |
|
title.textContent = "Turn Degrees - Select Angle"; |
|
break; |
|
case 'goTo': |
|
title.textContent = "Go To - Select Position"; |
|
break; |
|
case 'say': |
|
title.textContent = "Say Message - Select Text"; |
|
break; |
|
case 'changeSize': |
|
title.textContent = "Change Size - Select Amount"; |
|
break; |
|
case 'playSound': |
|
title.textContent = "Play Sound - Select Sound"; |
|
break; |
|
case 'wait': |
|
title.textContent = "Wait - Select Duration"; |
|
break; |
|
case 'repeat': |
|
title.textContent = "Repeat - Select Times"; |
|
break; |
|
default: |
|
title.textContent = "Select Options"; |
|
} |
|
|
|
|
|
grid.innerHTML = ''; |
|
|
|
|
|
if (blockOptions[blockType]) { |
|
blockOptions[blockType].forEach(option => { |
|
const blockItem = document.createElement('div'); |
|
blockItem.className = 'block-selection-item'; |
|
blockItem.setAttribute('data-value', option.value); |
|
blockItem.innerHTML = ` |
|
<div class="block-selection-icon"> |
|
<i class="fas ${option.icon}"></i> |
|
</div> |
|
<div class="block-selection-name">${option.name}</div> |
|
<div class="block-selection-description">${option.description}</div> |
|
`; |
|
|
|
blockItem.addEventListener('click', function() { |
|
document.querySelectorAll('.block-selection-item').forEach(item => { |
|
item.classList.remove('active'); |
|
}); |
|
this.classList.add('active'); |
|
selectedBlockOption = this.getAttribute('data-value'); |
|
}); |
|
|
|
grid.appendChild(blockItem); |
|
}); |
|
} |
|
|
|
|
|
overlay.style.display = 'flex'; |
|
} |
|
|
|
|
|
function hideBlockSelection() { |
|
document.getElementById('blockSelectionOverlay').style.display = 'none'; |
|
currentBlockType = null; |
|
selectedBlockOption = null; |
|
} |
|
|
|
|
|
function confirmBlockSelection() { |
|
if (selectedBlockOption && activeBlock) { |
|
const blockText = activeBlock.querySelector('span'); |
|
|
|
switch(currentBlockType) { |
|
case 'whenFlag': |
|
if (selectedBlockOption === 'all') { |
|
blockText.textContent = 'when flag clicked (all blocks)'; |
|
} else { |
|
blockText.textContent = `when flag clicked (${selectedBlockOption} blocks)`; |
|
} |
|
break; |
|
case 'whenKey': |
|
blockText.textContent = `when ${selectedBlockOption} pressed`; |
|
break; |
|
case 'move': |
|
if (selectedBlockOption.startsWith('-')) { |
|
blockText.textContent = `move ${selectedBlockOption.substring(1)} steps back`; |
|
} else { |
|
blockText.textContent = `move ${selectedBlockOption} steps`; |
|
} |
|
break; |
|
case 'turn': |
|
if (selectedBlockOption.startsWith('-')) { |
|
blockText.textContent = `turn ${selectedBlockOption.substring(1)} degrees left`; |
|
} else { |
|
blockText.textContent = `turn ${selectedBlockOption} degrees right`; |
|
} |
|
break; |
|
case 'goTo': |
|
blockText.textContent = `go to ${selectedBlockOption}`; |
|
break; |
|
case 'say': |
|
blockText.textContent = `say ${selectedBlockOption} for 2 seconds`; |
|
break; |
|
case 'changeSize': |
|
blockText.textContent = `change size by ${selectedBlockOption}`; |
|
break; |
|
case 'playSound': |
|
blockText.textContent = `play sound ${selectedBlockOption}`; |
|
break; |
|
case 'wait': |
|
blockText.textContent = `wait ${selectedBlockOption} second${selectedBlockOption !== '1' ? 's' : ''}`; |
|
break; |
|
case 'repeat': |
|
blockText.textContent = `repeat ${selectedBlockOption} times`; |
|
break; |
|
} |
|
} |
|
|
|
hideBlockSelection(); |
|
} |
|
|
|
|
|
function goBackInSelection() { |
|
|
|
hideBlockSelection(); |
|
} |
|
|
|
|
|
function filterBlocksByCategory(category) { |
|
if (category === 'all') { |
|
document.querySelectorAll('.block-selection-item').forEach(item => { |
|
item.style.display = 'block'; |
|
}); |
|
return; |
|
} |
|
|
|
document.querySelectorAll('.block-selection-item').forEach(item => { |
|
|
|
|
|
item.style.display = 'block'; |
|
}); |
|
} |
|
|
|
|
|
function setupBlockOptions() { |
|
document.querySelectorAll('.block-with-options').forEach(block => { |
|
const optionsBtn = block.querySelector('.fa-chevron-down'); |
|
const blockType = block.getAttribute('data-block'); |
|
|
|
optionsBtn.addEventListener('click', function(e) { |
|
e.stopPropagation(); |
|
activeBlock = block; |
|
showBlockSelection(blockType); |
|
}); |
|
}); |
|
} |
|
|
|
|
|
function setupBlockDrag(block) { |
|
block.addEventListener('dragstart', function(e) { |
|
draggedBlock = this; |
|
this.classList.add('dragging'); |
|
e.dataTransfer.setData('text/plain', this.outerHTML); |
|
}); |
|
|
|
block.addEventListener('dragend', function() { |
|
this.classList.remove('dragging'); |
|
draggedBlock = null; |
|
}); |
|
} |
|
|
|
|
|
function setupBlockClick(block) { |
|
block.addEventListener('click', function(e) { |
|
|
|
if (e.target.closest('.block-options') || e.target.classList.contains('fa-chevron-down')) { |
|
return; |
|
} |
|
|
|
|
|
if (activeBlock) { |
|
activeBlock.classList.remove('active'); |
|
} |
|
|
|
|
|
this.classList.add('active'); |
|
activeBlock = this; |
|
|
|
|
|
const blockType = this.getAttribute('data-block'); |
|
executeBlock(blockType, this); |
|
}); |
|
} |
|
|
|
|
|
function setupBlockConnectors(block) { |
|
|
|
const connector = block.querySelector('.block-connector'); |
|
if (connector) { |
|
connector.addEventListener('dragover', function(e) { |
|
e.preventDefault(); |
|
this.style.backgroundColor = 'rgba(110, 69, 226, 0.4)'; |
|
}); |
|
|
|
connector.addEventListener('dragleave', function() { |
|
this.style.backgroundColor = 'rgba(110, 69, 226, 0.2)'; |
|
}); |
|
|
|
connector.addEventListener('drop', function(e) { |
|
e.preventDefault(); |
|
this.style.backgroundColor = 'rgba(110, 69, 226, 0.2)'; |
|
|
|
if (draggedBlock) { |
|
|
|
const blockId = 'block-' + Date.now() + '-' + Math.floor(Math.random() * 1000); |
|
|
|
const newBlock = draggedBlock.cloneNode(true); |
|
newBlock.id = blockId; |
|
newBlock.classList.add('connected-block'); |
|
newBlock.style.position = 'relative'; |
|
newBlock.style.left = '0'; |
|
newBlock.style.top = '0'; |
|
newBlock.style.margin = '0'; |
|
|
|
|
|
if (!blockInstances.has(blockId)) { |
|
|
|
block.parentNode.insertBefore(newBlock, block.nextSibling); |
|
blockInstances.add(blockId); |
|
|
|
|
|
setupBlockDrag(newBlock); |
|
|
|
|
|
setupBlockConnectors(newBlock); |
|
|
|
|
|
setupBlockClick(newBlock); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
|
|
const slots = block.querySelectorAll('.block-slot'); |
|
slots.forEach(slot => { |
|
slot.addEventListener('dragover', function(e) { |
|
e.preventDefault(); |
|
this.classList.add('highlight'); |
|
}); |
|
|
|
slot.addEventListener('dragleave', function() { |
|
this.classList.remove('highlight'); |
|
}); |
|
|
|
slot.addEventListener('drop', function(e) { |
|
e.preventDefault(); |
|
this.classList.remove('highlight'); |
|
|
|
if (draggedBlock) { |
|
|
|
const blockId = 'block-' + Date.now() + '-' + Math.floor(Math.random() * 1000); |
|
|
|
const newBlock = draggedBlock.cloneNode(true); |
|
newBlock.id = blockId; |
|
newBlock.style.position = 'relative'; |
|
newBlock.style.left = '0'; |
|
newBlock.style.top = '0'; |
|
newBlock.style.margin = '5px 0'; |
|
|
|
|
|
if (!blockInstances.has(blockId)) { |
|
|
|
this.innerHTML = ''; |
|
this.appendChild(newBlock); |
|
blockInstances.add(blockId); |
|
|
|
|
|
setupBlockDrag(newBlock); |
|
|
|
|
|
setupBlockConnectors(newBlock); |
|
|
|
|
|
setupBlockClick(newBlock); |
|
} |
|
} |
|
}); |
|
}); |
|
} |
|
|
|
|
|
function makeDraggable(element) { |
|
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; |
|
|
|
element.onmousedown = dragMouseDown; |
|
|
|
function dragMouseDown(e) { |
|
e = e || window.event; |
|
e.preventDefault(); |
|
|
|
|
|
pos3 = e.clientX; |
|
pos4 = e.clientY; |
|
|
|
document.onmouseup = closeDragElement; |
|
document.onmousemove = elementDrag; |
|
} |
|
|
|
function elementDrag(e) { |
|
e = e || window.event; |
|
e.preventDefault(); |
|
|
|
|
|
pos1 = pos3 - e.clientX; |
|
pos2 = pos4 - e.clientY; |
|
pos3 = e.clientX; |
|
pos4 = e.clientY; |
|
|
|
|
|
element.style.top = (element.offsetTop - pos2) + "px"; |
|
element.style.left = (element.offsetLeft - pos1) + "px"; |
|
} |
|
|
|
function closeDragElement() { |
|
|
|
document.onmouseup = null; |
|
document.onmousemove = null; |
|
} |
|
} |
|
|
|
|
|
function changeTab(tabName) { |
|
document.querySelectorAll('.tab-btn').forEach(btn => { |
|
btn.classList.remove('active'); |
|
btn.classList.remove('border-b-2'); |
|
btn.classList.remove('border-purple-600'); |
|
}); |
|
|
|
document.querySelectorAll('.tab-content').forEach(content => { |
|
content.classList.remove('active'); |
|
}); |
|
|
|
event.target.classList.add('active'); |
|
event.target.classList.add('border-b-2'); |
|
event.target.classList.add('border-purple-600'); |
|
document.getElementById(tabName).classList.add('active'); |
|
} |
|
|
|
function changeRightTab(tabName) { |
|
document.querySelectorAll('#properties, #multiplayer, #developers').forEach(tab => { |
|
tab.classList.remove('active'); |
|
}); |
|
|
|
document.querySelectorAll('.tab-btn').forEach(btn => { |
|
btn.classList.remove('active'); |
|
btn.classList.remove('border-b-2'); |
|
btn.classList.remove('border-purple-600'); |
|
}); |
|
|
|
event.target.classList.add('active'); |
|
event.target.classList.add('border-b-2'); |
|
event.target.classList.add('border-purple-600'); |
|
document.getElementById(tabName).classList.add('active'); |
|
} |
|
|
|
|
|
function runScripts() { |
|
if (isRunning) { |
|
stopScripts(); |
|
} |
|
|
|
isRunning = true; |
|
activeScripts = []; |
|
|
|
|
|
const flagBlocks = document.querySelectorAll('#workspace [data-block="whenFlag"]'); |
|
|
|
flagBlocks.forEach(block => { |
|
const script = []; |
|
let currentBlock = block; |
|
|
|
|
|
while (currentBlock) { |
|
script.push(currentBlock); |
|
|
|
|
|
const nextBlock = currentBlock.nextElementSibling; |
|
if (nextBlock && nextBlock.classList.contains('connected-block')) { |
|
currentBlock = nextBlock; |
|
} else { |
|
currentBlock = null; |
|
} |
|
} |
|
|
|
if (script.length > 0) { |
|
activeScripts.push(script); |
|
} |
|
}); |
|
|
|
|
|
activeScripts.forEach(script => { |
|
executeScript(script); |
|
}); |
|
} |
|
|
|
function stopScripts() { |
|
isRunning = false; |
|
activeScripts = []; |
|
|
|
|
|
const sprite = document.getElementById('currentSprite'); |
|
sprite.style.left = '50%'; |
|
sprite.style.top = '50%'; |
|
sprite.style.transform = 'translate(-50%, -50%)'; |
|
|
|
|
|
document.querySelectorAll('.block.active').forEach(block => { |
|
block.classList.remove('active'); |
|
}); |
|
activeBlock = null; |
|
} |
|
|
|
function executeScript(script) { |
|
if (!isRunning) return; |
|
|
|
let delay = 0; |
|
|
|
script.forEach((block, index) => { |
|
const blockType = block.getAttribute('data-block'); |
|
|
|
setTimeout(() => { |
|
if (!isRunning) return; |
|
|
|
|
|
block.classList.add('active'); |
|
setTimeout(() => { |
|
block.classList.remove('active'); |
|
}, 500); |
|
|
|
|
|
executeBlock(blockType, block); |
|
|
|
}, delay); |
|
|
|
|
|
delay += 1000; |
|
}); |
|
} |
|
|
|
function executeBlock(blockType, blockElement) { |
|
const sprite = document.getElementById('currentSprite'); |
|
let value = ''; |
|
|
|
|
|
if (blockElement) { |
|
const blockText = blockElement.querySelector('span').textContent; |
|
|
|
switch(blockType) { |
|
case 'whenFlag': |
|
value = blockText.match(/when flag clicked \((.*)\)/)?.[1] || 'all'; |
|
|
|
break; |
|
case 'whenKey': |
|
value = blockText.match(/when (.*) pressed/)[1]; |
|
break; |
|
case 'move': |
|
const moveMatch = blockText.match(/move (.*) steps( back)?/); |
|
value = moveMatch[2] ? '-' + moveMatch[1] : moveMatch[1]; |
|
break; |
|
case 'turn': |
|
const turnMatch = blockText.match(/turn (.*) degrees( left)?/); |
|
value = turnMatch[2] ? '-' + turnMatch[1] : turnMatch[1]; |
|
break; |
|
case 'goTo': |
|
value = blockText.match(/go to (.*)/)[1]; |
|
break; |
|
case 'say': |
|
value = blockText.match(/say (.*) for/)[1]; |
|
break; |
|
case 'changeSize': |
|
value = blockText.match(/change size by (.*)/)[1]; |
|
break; |
|
case 'playSound': |
|
value = blockText.match(/play sound (.*)/)[1]; |
|
break; |
|
case 'wait': |
|
value = blockText.match(/wait (.*) second/)[1]; |
|
break; |
|
case 'repeat': |
|
value = blockText.match(/repeat (.*) times/)[1]; |
|
break; |
|
} |
|
} |
|
|
|
switch(blockType) { |
|
case 'whenFlag': |
|
|
|
break; |
|
|
|
case 'afterThis': |
|
|
|
break; |
|
|
|
case 'move': |
|
const currentLeft = parseInt(sprite.style.left || '50%'); |
|
sprite.style.left = (currentLeft + parseInt(value)) + 'px'; |
|
break; |
|
|
|
case 'turn': |
|
const currentRotation = parseInt(sprite.style.transform.replace(/[^0-9\-]/g, '') || '0'); |
|
sprite.style.transform = `translate(-50%, -50%) rotate(${currentRotation + parseInt(value)}deg)`; |
|
break; |
|
|
|
case 'goTo': |
|
const stage = document.getElementById('stage'); |
|
const stageRect = stage.getBoundingClientRect(); |
|
|
|
if (value === 'random') { |
|
const randomX = Math.floor(Math.random() * (stageRect.width - 50)); |
|
const randomY = Math.floor(Math.random() * (stageRect.height - 50)); |
|
sprite.style.left = randomX + 'px'; |
|
sprite.style.top = randomY + 'px'; |
|
} else if (value === 'center') { |
|
sprite.style.left = '50%'; |
|
sprite.style.top = '50%'; |
|
sprite.style.transform = 'translate(-50%, -50%)'; |
|
} |
|
break; |
|
|
|
case 'say': |
|
|
|
alert(value); |
|
break; |
|
|
|
case 'changeCostume': |
|
|
|
const currentIcon = sprite.querySelector('i'); |
|
if (currentIcon) { |
|
if (currentIcon.classList.contains('fa-cat')) { |
|
currentIcon.className = 'fas fa-dog text-4xl text-blue-600'; |
|
} else if (currentIcon.classList.contains('fa-dog')) { |
|
currentIcon.className = 'fas fa-user text-4xl text-yellow-600'; |
|
} else { |
|
currentIcon.className = 'fas fa-cat text-4xl text-purple-600'; |
|
} |
|
} |
|
break; |
|
|
|
case 'changeSize': |
|
const currentSize = parseInt(sprite.style.fontSize || '40'); |
|
sprite.style.fontSize = (currentSize + parseInt(value)) + 'px'; |
|
break; |
|
|
|
case 'playSound': |
|
|
|
console.log('Playing sound:', value); |
|
alert(`Playing ${value} sound`); |
|
break; |
|
|
|
case 'stopSound': |
|
|
|
console.log('Stopping all sounds'); |
|
break; |
|
|
|
case 'wait': |
|
|
|
break; |
|
|
|
case 'repeat': |
|
|
|
break; |
|
|
|
case 'whenKey': |
|
|
|
break; |
|
|
|
case 'if': |
|
|
|
break; |
|
} |
|
} |
|
</script> |
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=DeepSiteOptional/turboned-developent" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |