Das ist ein Testprogramm für Grafikgeschwindigkeit. Für eine in Entwcklung befindliche WATOR-Simulation.
Hier kann man mal ausprobieren, wieviele “Wesen” hier so gleichzeitig rumwuseln dürfen, ohne das der Rechner stehenbleibt. 🙂
Die Wesen kennen den Rand der Welt (noch) nicht – sie bewegen sich zufallsgeneriert einfach auf und davon.
Jedenfalls bin ich zufrieden mit der Geschwindigkeit, auch bei einigen 1000 “Wesen”.
* * * Player * * *
Wer sich für das "WIE" interessiert:
Den Code kann man hier ausklappen.
<div class="wrapper_div">
<div class="output_div" id="output">
</div>
<div class="input_div">
<br><label for="world-dimension"> Welt Dimension: </label>
<input type="number" id="world-dimension" value="50"> <br>
<br>
<label for="fish-amount"> Fische Anzahl: </label>
<input type="number" id="fish-amount" value="1000"> <br>
<label for="shark-amount"> Hai Anzahl: </label>
<input type="number" id="shark-amount" value="1000"> <br>
<br>
<button onclick="initScene();"> reSTART </button><br>
<br>
<button onclick="simulationRunning=true;"> Play </button>
<button onclick="simulationRunning=false;"> Pause </button>
<button onclick="simulationRunning=false; Zeitschritt();"> Schritt </button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js">
</script>
<script>
let scene, camera, renderer, controls;
let fishMesh, sharkMesh;
let worldDimension;
let fishAmount;
let fishBirth;
let sharkAmount;
let sharkBirth;
let sharkEnergy;
let worldBoundary;
let neighborSides;
let neighborEdges;
let neighborCorners;
let simulationRunning;
function isMobileDevice() {
return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
}
function initScene() {
worldDimension = parseInt(document.getElementById('world-dimension').value);
fishAmount = parseInt(document.getElementById('fish-amount').value);
sharkAmount = parseInt(document.getElementById('shark-amount').value);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, 1, 0.1, 10000);
renderer = new THREE.WebGLRenderer({ antialias: true });
if (isMobileDevice()) {
// Code für Mobilgeräte hier ausführen
renderer.setSize(300, 300);
} else {
// Code für Desktop-Geräte hier ausführen
renderer.setSize(600, 600);
}
const output = document.getElementById('output');
output.innerHTML = '';
output.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(0, 0, 100000);
scene.add(directionalLight);
const fishGeometry = new THREE.BoxGeometry(1, 1, 1);
const fishMaterial = new THREE.MeshPhongMaterial({ color: 0x00ff00 });
fishMesh = new THREE.InstancedMesh(fishGeometry, fishMaterial, fishAmount);
scene.add(fishMesh);
const sharkGeometry = new THREE.BoxGeometry(1, 1, 1);
const sharkMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000 });
sharkMesh = new THREE.InstancedMesh(sharkGeometry, sharkMaterial, sharkAmount);
scene.add(sharkMesh);
for (let i = 0; i < fishAmount; i++) {
const position = new THREE.Vector3(
Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2),
Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2),
Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2)
);
fishMesh.setMatrixAt(i, new THREE.Matrix4().makeTranslation(position.x, position.y, position.z));
}
fishMesh.instanceMatrix.needsUpdate = true;
for (let i = 0; i < sharkAmount; i++) {
const position = new THREE.Vector3(
Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2),
Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2),
Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2)
);
sharkMesh.setMatrixAt(i, new THREE.Matrix4().makeTranslation(position.x, position.y, position.z));
}
sharkMesh.instanceMatrix.needsUpdate = true;
camera.position.x = worldDimension;
camera.position.y = worldDimension;
camera.position.z = worldDimension;
}
function rnd_int(von, bis) {
const x = Math.floor(Math.random() * (bis - von + 1)) + von;
return x;
}
function rnd_vector_int(von, bis) {
const x = rnd_int(von, bis);
const y = rnd_int(von, bis);
const z = rnd_int(von, bis);
return new THREE.Vector3(x, y, z);
}
function Zeitschritt() {
for (let i = 0; i < fishAmount; i++) {
const fishMatrix = new THREE.Matrix4().fromArray(fishMesh.instanceMatrix.array, i * 16);
const fishPosition = new THREE.Vector3();
fishPosition.setFromMatrixPosition(fishMatrix);
// Manipulate fish position here using "fishPosition"
fishPosition.x = fishPosition.x + rnd_int(-1, 1);
fishPosition.y = fishPosition.y + rnd_int(-1, 1);
fishPosition.z = fishPosition.z + rnd_int(-1, 1);
fishMesh.setMatrixAt(i, fishMatrix.makeTranslation(fishPosition.x, fishPosition.y, fishPosition.z));
}
fishMesh.instanceMatrix.needsUpdate = true;
}
function animate() {
if (simulationRunning) { Zeitschritt() }
controls.update();
renderer.render(scene, camera);
}
simulationRunning = true;
initScene();
setInterval(animate, 30);
</script>
Für Interessierte: Der aktuelle Stand: www.irrbert.de/wator