added Robot class, robot module can send move and turn commands to player robot, no connection to AI robots yet

master
Jake 2025-03-24 12:25:55 +08:00
parent 2bfdcf1957
commit 58e65b2967
3 changed files with 121 additions and 18 deletions

View File

@ -17,6 +17,10 @@
overflow-y: auto;
border: 1px solid #ccc;
}
#gameCanvas {
border: 1px solid black;
}
</style>
</head>
@ -29,10 +33,25 @@
<h2>Console Output:</h2>
<div id="console"></div>
<script>
<!-- Game canvas -->
<h2>2D Tank Simulation</h2>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script type="module">
import { Robot } from "./robot.js"; // ✅ Import Robot class
const consoleElement = document.getElementById("console");
const gameCanvas = document.getElementById("gameCanvas");
const ctx = gameCanvas.getContext("2d");
let pyodideWorker = new Worker("pyodide-worker.js");
// ✅ Create tanks using the class
let robots = {
"player": new Robot("player", 50, 50, "blue"),
"enemy1": new Robot("enemy1", 200, 150, "red"),
"enemy2": new Robot("enemy2", 400, 250, "red")
};
pyodideWorker.onmessage = (event) => {
switch (event.data.type) {
case "console":
@ -47,6 +66,9 @@
case "turn":
turn(event.data.data); // Call the JavaScript turn(deg) function
break;
case "move":
move(event.data.data); // Call the JavaScript turn(deg) function
break;
}
};
@ -62,20 +84,16 @@
}
function turn(deg) {
logToConsole(`<b>🔄 Turned ${deg} degrees</b>`);
robots["player"].turn(deg);
}
// Send code to worker
document.getElementById("compile-button").addEventListener("click", () => {
const code = document.getElementById("python-code").value;
consoleElement.innerHTML = ""; // Clear console before running new code
pyodideWorker.postMessage({
type: "execute",
code: code
});
});
function move(distance) {
robots["player"].move(distance);
}
// ✅ Update "distance" and "speed" every 2 seconds with random values
// Update the sensor data
function updateSensorData() {
const distance = Math.random() * 100; // Random distance (0-100)
const speed = Math.random() * 10; // Random speed (0-10)
@ -88,8 +106,35 @@
//logToConsole(`📡 Sensor Update - Distance: ${distance.toFixed(2)}, Speed: ${speed.toFixed(2)}`);
}
setInterval(updateSensorData, 2000); // Call every 2 seconds
// Game loop: Update and draw everything
function gameLoop() {
// Clear the canvas
ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
for (let id in robots) {
robots[id].update(ctx);
}
// Call the game loop recursively
requestAnimationFrame(gameLoop);
}
// Start the game loop
gameLoop();
// Send code to worker
document.getElementById("compile-button").addEventListener("click", () => {
const code = document.getElementById("python-code").value;
consoleElement.innerHTML = ""; // Clear console before running new code
pyodideWorker.postMessage({
type: "execute",
code: code
});
});
// Update "distance" and "speed" every 2 seconds with random values
setInterval(updateSensorData, 2000); // Call every 2 seconds
</script>
</body>

View File

@ -27,14 +27,18 @@ class RobotModule:
def get_sensor(self, name):
return get_sensor_data(name)
robot = RobotModule()
def move(self, speed):
send_to_main("move", speed)
def fire():
def fire(self):
send_to_main("fire", None)
def turn(deg):
def turn(self, deg):
send_to_main("turn", deg)
robot = RobotModule()
class ConsoleOutput:
def write(self, text):
if text.strip():

54
robot.js Normal file
View File

@ -0,0 +1,54 @@
export class Robot {
constructor(id, x, y, color = "blue") {
this.id = id;
this.x = x;
this.y = y;
this.velocity = 0;
this.direction = 0; // Degrees
this.width = 20;
this.height = 20;
this.color = color;
}
update(ctx){
this.update_position();
this.draw(ctx);
}
update_position() {
const radians = (this.direction * Math.PI) / 180;
this.x += Math.cos(radians) * this.velocity;
this.y += Math.sin(radians) * this.velocity;
}
move(velocity) {
this.velocity = velocity;
}
turn(degrees) {
this.direction += degrees;
}
draw(ctx) {
ctx.fillStyle = this.color;
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate((this.direction * Math.PI) / 180);
// Draw the rectangle (tank body)
ctx.fillRect(-this.width / 2, -this.height / 2, this.width, this.height);
// Draw the triangle (direction indicator)
ctx.beginPath();
ctx.moveTo(this.width / 2, -this.height / 2); // Tip of the triangle (front)
ctx.lineTo(this.width, 0); // Bottom left of triangle
ctx.lineTo(this.width / 2, this.height / 2); // Bottom right of triangle
ctx.closePath();
ctx.fill(); // Fill both the rectangle and the triangle
ctx.restore();
}
}