initial commit
This commit is contained in:
commit
38c8d3ecf2
10
index.html
Normal file
10
index.html
Normal 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
41
js/canvas.js
Normal 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
129
js/rocket.js
Normal 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
112
js/sketch.js
Normal 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
95
js/vector.js
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user