awacke1's picture
Update index.html
1574a0c verified
<!DOCTYPE html>
<html>
<head>
<style>
body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #1a1a1a; }
.controls { position: fixed; top: 10px; left: 10px; color: white; }
button { margin: 5px; padding: 5px 10px; }
#gameArea { cursor: crosshair; }
.info-panel {
position: fixed;
top: 10px;
right: 10px;
color: white;
background: rgba(0,0,0,0.7);
padding: 15px;
border-radius: 5px;
font-family: Arial, sans-serif;
}
.score {
font-size: 24px;
font-weight: bold;
margin-bottom: 10px;
}
.points-popup {
position: absolute;
color: #4CAF50;
font-weight: bold;
font-family: Arial, sans-serif;
pointer-events: none;
animation: floatUp 1s ease-out forwards;
}
@keyframes floatUp {
0% { transform: translateY(0); opacity: 1; }
100% { transform: translateY(-50px); opacity: 0; }
}
.drawing-guide {
position: fixed;
bottom: 10px;
left: 10px;
color: white;
background: rgba(0,0,0,0.7);
padding: 10px;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="controls">
<button onclick="addRobot()">Add Random Robot (+5 pts)</button>
<button onclick="togglePause()">Pause/Play</button>
</div>
<div class="info-panel">
<div class="score">Score: <span id="scoreDisplay">0</span></div>
<div>Robots: <span id="robotCount">0</span></div>
</div>
<div class="drawing-guide">
Click and drag to draw new robots (+5 pts). Collisions give +5 pts and growth!
</div>
<svg id="gameArea" width="800" height="600" style="background: #000;">
<rect width="800" height="600" fill="none" stroke="#333" stroke-width="4"/>
<line id="drawingLine" stroke="white" stroke-width="2" stroke-dasharray="5,5" visibility="hidden"/>
</svg>
<script>
const svg = document.getElementById('gameArea');
const drawingLine = document.getElementById('drawingLine');
const robots = [];
let paused = false;
let isDrawing = false;
let startX, startY;
let score = 0;
function updateScore(points, x, y) {
score += points;
document.getElementById('scoreDisplay').textContent = score;
document.getElementById('robotCount').textContent = robots.length;
// Create and animate points popup
const popup = document.createElement('div');
popup.className = 'points-popup';
popup.textContent = `+${points}`;
popup.style.left = `${x}px`;
popup.style.top = `${y}px`;
document.body.appendChild(popup);
// Remove popup after animation
setTimeout(() => popup.remove(), 1000);
}
class Robot {
constructor(x, y, speed, direction, length) {
this.segments = [];
this.speed = speed || 2 + Math.random() * 2;
this.direction = direction || Math.random() * Math.PI * 2;
this.length = length || 5 + Math.floor(Math.random() * 5);
this.color = `hsl(${Math.random() * 360}, 80%, 50%)`;
this.x = x || Math.random() * 700 + 50;
this.y = y || Math.random() * 500 + 50;
this.createSegments();
}
createSegments() {
// Remove old segments if they exist
this.segments.forEach(seg => seg.element.remove());
this.segments = [];
// Create new segments
for (let i = 0; i < this.length; i++) {
const segment = document.createElementNS("http://www.w3.org/2000/svg", "circle");
segment.setAttribute("r", "8");
segment.setAttribute("fill", this.color);
svg.appendChild(segment);
this.segments.push({
element: segment,
x: this.x,
y: this.y
});
}
}
grow() {
this.length += 1;
this.createSegments();
}
update() {
// Update head position
this.x += Math.cos(this.direction) * this.speed;
this.y += Math.sin(this.direction) * this.speed;
// Bounce off walls
if (this.x < 10 || this.x > 790) {
this.direction = Math.PI - this.direction;
this.mutate();
}
if (this.y < 10 || this.y > 590) {
this.direction = -this.direction;
this.mutate();
}
// Update segments
for (let i = this.segments.length - 1; i > 0; i--) {
this.segments[i].x = this.segments[i - 1].x;
this.segments[i].y = this.segments[i - 1].y;
}
this.segments[0].x = this.x;
this.segments[0].y = this.y;
// Update SVG elements
this.segments.forEach(segment => {
segment.element.setAttribute("cx", segment.x);
segment.element.setAttribute("cy", segment.y);
});
}
mutate() {
// Random mutation when bouncing
this.speed = Math.max(1, Math.min(6, this.speed + (Math.random() - 0.5)));
this.color = `hsl(${Math.random() * 360}, 80%, 50%)`;
this.segments.forEach(segment => {
segment.element.setAttribute("fill", this.color);
});
}
checkCollision(other) {
const dx = this.x - other.x;
const dy = this.y - other.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 16) {
// Bounce off each other
const angle = Math.atan2(dy, dx);
this.direction = angle + Math.PI / 2;
other.direction = angle - Math.PI / 2;
// Grow and mutate both robots
this.grow();
other.grow();
this.mutate();
other.mutate();
// Add points and show popup at collision location
const svgRect = svg.getBoundingClientRect();
const popupX = svgRect.left + this.x;
const popupY = svgRect.top + this.y;
updateScore(5, popupX, popupY);
}
}
}
// Mouse event handlers
svg.addEventListener('mousedown', (e) => {
const rect = svg.getBoundingClientRect();
startX = e.clientX - rect.left;
startY = e.clientY - rect.top;
isDrawing = true;
drawingLine.setAttribute('x1', startX);
drawingLine.setAttribute('y1', startY);
drawingLine.setAttribute('x2', startX);
drawingLine.setAttribute('y2', startY);
drawingLine.setAttribute('visibility', 'visible');
});
svg.addEventListener('mousemove', (e) => {
if (isDrawing) {
const rect = svg.getBoundingClientRect();
const currentX = e.clientX - rect.left;
const currentY = e.clientY - rect.top;
drawingLine.setAttribute('x2', currentX);
drawingLine.setAttribute('y2', currentY);
}
});
svg.addEventListener('mouseup', (e) => {
if (isDrawing) {
const rect = svg.getBoundingClientRect();
const endX = e.clientX - rect.left;
const endY = e.clientY - rect.top;
const dx = endX - startX;
const dy = endY - startY;
const distance = Math.sqrt(dx * dx + dy * dy);
const direction = Math.atan2(dy, dx);
const speed = Math.min(6, distance / 50);
const length = Math.max(3, Math.min(12, Math.floor(distance / 30)));
robots.push(new Robot(startX, startY, speed, direction, length));
// Add points for new robot
updateScore(5, e.clientX, e.clientY);
drawingLine.setAttribute('visibility', 'hidden');
isDrawing = false;
}
});
svg.addEventListener('mouseleave', () => {
if (isDrawing) {
drawingLine.setAttribute('visibility', 'hidden');
isDrawing = false;
}
});
function addRobot() {
const robot = new Robot();
robots.push(robot);
// Add points for new random robot
const svgRect = svg.getBoundingClientRect();
updateScore(5, svgRect.left + robot.x, svgRect.top + robot.y);
}
function togglePause() {
paused = !paused;
}
function update() {
if (!paused) {
robots.forEach(robot => robot.update());
for (let i = 0; i < robots.length; i++) {
for (let j = i + 1; j < robots.length; j++) {
robots[i].checkCollision(robots[j]);
}
}
}
requestAnimationFrame(update);
}
// Start with 3 robots
for (let i = 0; i < 3; i++) {
addRobot();
}
update();
</script>
</body>
</html>