Files
Neocities/javascript/newsim.js
2025-10-29 16:46:36 -05:00

273 lines
7.8 KiB
JavaScript

let images = {};
let simulator = [];
let maxSpeed = 1;
let backgroundImage;
let worldScale;
let LEFT = [-1,0];
const entityTypes = Object.freeze({
METERORITE_SMALL: "meteorite_small",
METERORITE_LARGE: "meteorite_large",
COMET: "comet",
});
var Settings = {
windowWrap: true,
physics: true,
respawn: true,
devMode: false,
maxSpeed: 1,
backgroundImage: "/media/Art/EmptySpace.png",
entityCount: 200,
emptyEntries: [],
rarity: {
"comet": .99,
"meteorite_small": 500.0,
"meteorite_large": 1000.0,
},
mass: {
"comet": 1400.0,
"meteorite_small": 500.0,
"meteorite_large": 1000.0,
},
}
function distance(entity1, entity2){
return Math.sqrt(
((entity2.x-entity1.x)*(entity2.x-entity1.x)) +
((entity2.y-entity1.y)*(entity2.y-entity1.y))
);
}
function getMass(type){
switch (type){
case entityTypes.COMET: return Settings.mass[entityTypes.COMET]
case entityTypes.METERORITE_SMALL: return Settings.mass[entityTypes.METERORITE_SMALL];
case entityTypes.METERORITE_LARGE: return Settings.mass[entityTypes.METERORITE_LARGE];
}
}
function createEntity(x, y, vx, vy, ax, ay, rot, rotv, type, id=0, iframes=Math.floor(Math.random()*100)){
if (Settings.emptyEntries.length > 1){
var entryID = Settings.emptyEntries.pop();
if (Settings.devMode) console.warn("Creating new enity from old", entryID);
if (entryID <= simulator.length && entryID >= 0){
entity = simulator[entryID];
entity.x = x;
entity.y = y;
entity.vx = vx;
entity.vy = vy;
entity.ax = ax;
entity.ay = ay;
entity.rot = rot;
entity.rotv = rotv;
entity.iframes = 1000;
entity.show = true;
entity.type = type
}else{
if (Settings.devMode) console.error("Entry ID out of bounds", Settings.emptyEntries.length, id, entryID);
}
}else{
simulator.push({
x: x,
y: y,
ax: ax,
ay: ay,
vx: vx,
vy: vy,
rot: rot,
rotv: rotv,
mass: getMass(type),
forcex: 0.0,
forcey: 0.0,
type: type,
show: true,
ueid: id,
iframes: iframes
});
}
}
function getRandomType(){
let rand = Math.random();
if (rand > 0.955){
if(Settings.devMode) console.log("Comet made");
return entityTypes.COMET;
}if(rand > 0.4){
return entityTypes.METERORITE_SMALL;
}else{
return entityTypes.METERORITE_LARGE;
}
}
function physicsUpdate(entity){
if (entity.show){
entity.vx += entity.ax;
entity.vy += entity.ay;
entity.x += entity.vx;
entity.y += entity.vy;
entity.rot += entity.rotv;
if (entity.iframes > 0) entity.iframes -= 1;
if (entity.iframes == 0) simulator.forEach((other_entity) =>{
checkCollision(entity, other_entity);
});
}
}
function checkCollision(entity1, entity2){
if (entity1.type == entityTypes.COMET && entity2.type == entityTypes.COMET){
}else if (entity1.ueid != entity2.ueid
&& entity1.show
&& entity2.show){
var dist = distance(entity1, entity2);
if(dist < 15){
if (Settings.devMode) {
stroke('magenta');
strokeWeight(5);
line(entity1.x,entity1.y, entity2.x, entity2.y);
console.log("Collision at", entity1.x, entity1.y, entity1.iframes, entity2.x, entity2.y, dist);
}
Explode(entity1);
Explode(entity2);
}
}
}
function Explode(entity){
if(entity.type == entityTypes.METERORITE_SMALL){
entity.show = false;
Settings.emptyEntries.push(entity.ueid);
}if(entity.type == entityTypes.METERORITE_LARGE){
entity.type = entityTypes.METERORITE_SMALL
entity.iframes = 1000;
createEntity(entity.x, entity.y, entity.vx + Math.random(), entity.vy + Math.random(), 0.0,0.0,0.0,0.0, entityTypes.METERORITE_SMALL, id=entity.ueid, iframes=1000);
}
}
function BlackHole(x,y,m,entity){
}
function drawBackground(refImage){
let w = windowWidth / refImage.width;
let h = windowHeight / refImage.height;
for (let iy = 0; iy <= h; iy++){
for (let ix = 0; ix <= w; ix++){
image(refImage, refImage.width * ix, refImage.height * iy);
}
}
}
function drawEntity(entity){
if (entity.show){
push();
imageMode(CENTER);
translate(entity.x, entity.y, 0);
if (entity.type == entityTypes.COMET){
rotate((Math.atan2(entity.vx, entity.vy) - Math.atan2(-1,0)) * 180/Math.PI);
}else{
rotate(entity.rot);
}
image(images[entity.type], 0,0);
pop();
}
}
function preload(){
images[entityTypes.METERORITE_SMALL] = loadImage("/media/Art/meteorite_small_1.png");
images[entityTypes.METERORITE_LARGE] = loadImage("/media/Art/Meteorite_Large_1_100.png");
images[entityTypes.COMET] = loadImage("/media/Art/comet.png");
//images["ship"] = loadImage("/media/Art/ship.png"); #Make Ship asset for game portion
images["background"] = loadImage("/media/Art/EmptySpace.png");
}
function setup(){
let canvas = createCanvas(windowWidth, windowHeight);
background(255);
describe("A space physics simulator");
canvas.position(0,0);
worldScale = createSlider();
//Load Entities
for(var i = 0; i <= Settings.entityCount; i+=1){
createEntity(
Math.floor(Math.random() * windowWidth), //X Location
Math.floor(Math.random() * windowHeight), //Y Location
(Math.random() * maxSpeed * 2)-maxSpeed, //X Velocity
(Math.random() * maxSpeed * 2)-maxSpeed, //Y Velocity
0.0, //X Acceleration
0.0, //Y Acceleration
0.0, //Current Rotation
(Math.random() * 2 *(Math.PI / Settings.rotationSpeed))-(Math.PI / Settings.rotationSpeed), //Rotation Velocity
getRandomType(),
id=i
);
}
}
function mouseClicked(){
console.log(mouseX, mouseY);
simulator.forEach((entity) =>{
})
console.log(worldScale.value());
}
function draw(){
//background(images["background"]);
//Draw Tiled Background
drawBackground(images["background"]);
for(var e = 1; e < simulator.length; e++){
let entity = simulator[e]
//Physics Update
if (Settings.physics){
physicsUpdate(entity)
}
//Window Wrap
if (Settings.windowWrap){
if (entity.x > windowWidth){
entity.x = 0;
}
if (entity.x < 0){
entity.x = windowWidth;
}
if (entity.y > windowHeight){
entity.y = 0;
}
if (entity.y < 0){
entity.y = windowHeight;
}
}
//Draw Entity
drawEntity(entity);
}
if (Settings.respawn){
if(Settings.emptyEntries.length > 5){
if(frameCount % 20 == 0){
createEntity(
Math.floor(Math.random() * windowWidth)+windowHeight, //X Location
Math.floor(Math.random() * windowHeight)+windowHeight, //Y Location
(Math.random() * maxSpeed * 2)-maxSpeed, //X Velocity
(Math.random() * maxSpeed * 2)-maxSpeed, //Y Velocity
0.0, //X Acceleration
0.0, //Y Acceleration
0.0, //Current Rotation
(Math.random() * 2 *(Math.PI / rotationSpeed))-(Math.PI / rotationSpeed), //Rotation Velocity
getRandomType()
);
}
}
}
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}