initial commit

This commit is contained in:
Baipyrus 2022-05-15 17:03:59 +02:00
commit 38c8d3ecf2
5 changed files with 387 additions and 0 deletions

10
index.html Normal file
View File

@ -0,0 +1,10 @@
<html>
<head>
</head>
<body>
<script type="text/javascript" src="js/vector.js"></script>
<script type="text/javascript" src="js/rocket.js"></script>
<script type="text/javascript" src="js/sketch.js"></script>
<script type="text/javascript" src="js/canvas.js"></script>
</body>
</html>

41
js/canvas.js Normal file
View File

@ -0,0 +1,41 @@
let canv = document.createElement("canvas");
canv.width = window.innerWidth;
canv.height = window.innerHeight;
canv.style.position = "absolute";
canv.style.top = "0px";
canv.style.left = "0px";
let ctx = canv.getContext("2d");
document.body.appendChild(canv);
let frameRate = 144, frameCount = 0;
if (typeof setup == "function") {
setup();
}
if (typeof draw == "function") {
interv = setInterval(() => {
let cached_function = draw;
const x = function() {
let result = cached_function.apply(this, arguments);
frameCount = (frameCount + 1201) % 1200;
return result;
}();
return x;
}, 1000/frameRate);
}
let tempFrameRate = 0;
let tempFrameCount = 0;
let tempInterv = setInterval(function(){
console.clear();
if (frameCount < tempFrameCount) {
tempFrameCount -= 1200;
}
tempFrameRate = frameCount - tempFrameCount;
tempFrameCount = frameCount;
console.log("Framerate is about "+tempFrameRate+" FPS.");
}, 1000);

129
js/rocket.js Normal file
View File

@ -0,0 +1,129 @@
class Rocket {
constructor(tempType) {
this.position = new Vector(
Math.floor(Math.random() * canv.width),
Math.floor(Math.random() * canv.height)
);
//let randomIndex = Math.floor(Math.random()*targets.length);
//this.target = targets[randomIndex];
this.target = undefined;
this.velocity = new Vector(0, 0);
this.acceleration = new Vector(0, 0);
this.type = tempType;
}
update() {
if (frameCount % (frameRate * SWITCH_TARGETS_AFTER_X_SECONDS) == 0 && this.type == "none") {
this.target = new Vector(
Math.floor(Math.random() * canv.width),
Math.floor(Math.random() * canv.height)
);
}
switch (this.type) {
case "red":
if (targets.length >= 1) {
this.target = targets[0].position;
} else {
this.target = new Vector(0, 0);
}
break;
case "green":
if (targets.length >= 2) {
this.target = targets[1].position;
} else {
this.target = new Vector(0, 0);
}
break;
case "blue":
if (targets.length >= 3) {
this.target = targets[2].position;
} else {
this.target = new Vector(0, 0);
}
break;
}
let direction = Vector.sub(this.target, this.position);
let separation = new Vector(0, 0);
if (this.type != "none") {
direction.setMag( ACCELERATION_MAG );
let total = 0;
for (let i = 0; i < rockets.length; i++) {
let other = rockets[i];
let diff = Vector.sub(this.position, other.position);
let d = diff.mag();
if (other != this) {
if (d < PERCEPTION_RADIUS) {
diff.div(d * d);
separation.add(diff);
total++;
}
if (d < ROCKET_RADIUS * 2) {
switch (this.type) {
case "red":
if (other.type == "green") {
this.type = other.type;
} else if (other.type == "blue") {
rockets[i].type = this.type;
}
break;
case "green":
if (other.type == "blue") {
this.type = other.type;
} else if (other.type == "red") {
rockets[i].type = this.type;
}
break;
case "blue":
if (other.type == "red") {
this.type = other.type;
} else if (other.type == "green") {
rockets[i].type = this.type;
}
break;
}
}
}
}
if (total > 0) {
separation.div(total);
separation.setMag( SEPARATION_SPEED );
separation.sub(this.velocity);
separation.limit( SEPARATION_FORCE );
}
separation.mult( SEPARATION_MULTIPLY );
} else {
direction.setMag( TARGET_ACCELERATION_MAG );
}
this.acceleration.mult(0);
this.acceleration.add(direction);
this.acceleration.add(separation);
this.velocity.add( this.acceleration );
this.velocity.limit( (this.type == "none") ? TARGET_MAX_VELOCITY : MAX_VELOCITY );
this.position.add(this.velocity);
if (this.type == "none") {
if (this.position.x > canv.width) {
this.position.x = canv.width;
} else if (this.position.x < 0) {
this.position.x = 0;
}
if (this.position.y > canv.height) {
this.position.y = canv.height;
} else if (this.position.y < 0) {
this.position.y = 0;
}
}
}
show() {
ctx.fillStyle = this.type;
ctx.strokeStyle = this.type;
ctx.beginPath();
ctx.ellipse(this.position.x, this.position.y, ROCKET_RADIUS, ROCKET_RADIUS, 0, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
}
}

112
js/sketch.js Normal file
View File

@ -0,0 +1,112 @@
/*
It's probably best to have the targets be places where each of the 3 types gather in a group.
Then you should probably tend towards the other target, that they are able to beat.
Of course all that while running from the target group, that can beat them.
Lastly, all capital "constants" are to be changed to be "perfect".
They are not const variables so that every user can change them in the console.
*/
let rockets = Array(), rAmount = 90, targets = Array(), tcount = 3;
let ACCELERATION_MAG = .005;
let MAX_VELOCITY = 1;
let ROCKET_RADIUS = 10;
let PERCEPTION_RADIUS = 30;
let SEPARATION_SPEED = 2.5;
let SEPARATION_FORCE = .005;
let SEPARATION_MULTIPLY = 1.5;
let SWITCH_TARGETS_AFTER_X_SECONDS = 2;
let TARGET_MAX_VELOCITY = 0.5;
let TARGET_ACCELERATION_MAG = 0.001;
function setup() {
/*for (let x = 0; x <= canv.width; x+=canv.width / 5) {
for (let y = 0; y <= canv.height; y+=canv.height / 5) {
let t = new Vector(x, y);
targets.push(t);
}
}*/
for (let i = 0; i < tcount; i++) {
targets.push(new Rocket("none"));
}
for (let i = 0; i < rAmount / 3; i++) {
rockets.push(new Rocket("red"));
}
for (let i = 0; i < rAmount / 3; i++) {
rockets.push(new Rocket("green"));
}
for (let i = 0; i < rAmount / 3; i++) {
rockets.push(new Rocket("blue"));
}
}
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canv.width, canv.height);
ctx.fillStyle = "rgb(255, 255, 0, .1)";
ctx.strokeStyle = "rgb(255, 255, 0, .1)";
for (let i = 0; i < targets.length; i++) {
if (targets[i] != -1) {
ctx.beginPath();
ctx.ellipse(targets[i].position.x, targets[i].position.y, PERCEPTION_RADIUS, PERCEPTION_RADIUS, 0, 0, Math.PI*2);
ctx.stroke();
ctx.fill();
ctx.closePath();
}
}
let counts = Array();
for (let i = 0; i < targets.length; i++) {
counts.push(0);
if (targets[i] != -1) {
targets[i].update();
}
}
rockets.forEach(rocket => {
switch (rocket.type) {
case "red":
if (counts.length >= 1) {
counts[0]++;
}
break;
case "green":
if (counts.length >= 2) {
counts[1]++;
}
break;
case "blue":
if (counts.length >= 3) {
counts[2]++;
}
break;
}
rocket.update();
rocket.show();
});
for (let i = 0; i < counts.length; i++) {
if (counts[i] <= 0 && targets[i] != -1) {
targets[i] = -1;
tcount--;
}
}
ctx.textAlign = "center";
ctx.font = "30px Arial"
ctx.beginPath();
ctx.fillStyle = "red";
ctx.fillText("Rocks: "+((counts[0]==undefined)?0:counts[0]), canv.width/2 - 30*9, 30);
ctx.fill();
ctx.fillStyle = "green";
ctx.fillText("Papers: "+((counts[1]==undefined)?0:counts[1]), canv.width/2 - 30*3, 30);
ctx.fill();
ctx.fillStyle = "blue";
ctx.fillText("Scissors: "+((counts[2]==undefined)?0:counts[2]), canv.width/2 + 30*3, 30);
ctx.fill();
ctx.fillStyle = "yellow";
ctx.fillText("Targets: "+tcount, canv.width/2 + 30*9, 30);
ctx.fill();
ctx.closePath();
}

95
js/vector.js Normal file
View File

@ -0,0 +1,95 @@
class Vector {
constructor(x, y, z = undefined) {
this.x = x;
this.y = y;
this.z = z;
}
static add(a, b) {
let z;
if (a.z != undefined && b.z != undefined) {
z = a.z + b.z;
}
return new Vector(a.x + b.x, a.y + b.y, z);
}
add(other) {
this.x+=other.x;
this.y+=other.y;
this.z = (this.z != undefined) ? this.z+other.z : this.z;
}
static sub(a, b) {
let z;
if (a.z != undefined && b.z != undefined) {
z = a.z - b.z;
}
return new Vector(a.x - b.x, a.y - b.y, z);
}
sub(other) {
this.x-=other.x;
this.y-=other.y;
this.z = (this.z != undefined) ? this.z-other.z : this.z;
}
static mult(a, b) {
let z;
if (a.z != undefined && b.z != undefined) {
z = a.z * b.z;
}
return new Vector(a.x * b.x, a.y * b.y, z);
}
mult(x) {
this.x*=x;
this.y*=x;
this.z = (this.z != undefined) ? this.z*x : this.z;
}
static div(a, b) {
let z;
if (a.z != undefined && b.z != undefined) {
z = a.z / b.z;
}
return new Vector(a.x / b.x, a.y / b.y, z);
}
div(x) {
this.x/=x;
this.y/=x;
this.z = (this.z != undefined) ? this.z/x : this.z;
}
static fromAngle(a) {
return new Vector(Math.cos(a), Math.sin(a));
}
heading() {
return Math.atan(this.y/this.x);
}
mag() {
return Math.sqrt(Math.pow(this.x,2)+Math.pow(this.y,2));
}
normalize() {
this.div(this.mag());
}
setMag(x) {
this.normalize();
this.mult(x);
}
limit(x) {
var nx = Math.sqrt(Math.pow(x,2));
if (this.mag() > nx) {
this.setMag(nx);
}
}
copy() {
return new Vector(this.x, this.y, this.z);
}
}