273 lines
7.8 KiB
JavaScript
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 Explode(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);
|
|
} |