xxxxxxxxxx
550
let debug = true; // enables rendering of debug lines
let DTcount = 0;
let timescale;
function deepCopy(array) {
return JSON.parse(JSON.stringify(array));
}
let joints = []; // [0 = name, 1 = rotation, 2 = X, 3 = Y]
function jointOffset(name, X, Y) {
let joint;
for (let i = 0; i < joints.length; i++) {
if (joints[i][0] == name) {
joint = joints[i];
}
}
if (joint == null) return;
let Jr = joint[1];
let Jx = joint[2];
let Jy = joint[3];
let x = cos(Jr) * Y + cos(Jr + 90) * X + Jx;
let y = sin(Jr) * Y + sin(Jr + 90) * X + Jy;
return [x, y];
}
function createJoint(name, R, X, Y) {
joints[joints.length] = [name, R, X, Y];
}
function setJoint(name, R, X, Y) {
for (let i = 0; i < joints.length; i++) {
if (joints[i][0] == name) {
joints[i] = [name, R, X, Y];
}
}
}
function linkJoint(name, linkName, R, L) {
let joint;
for (let i = 0; i < joints.length; i++) {
if (joints[i][0] == name) {
joint = i;
}
}
if (joint == null) {
print("no joint");
return;
}
let link;
for (let i = 0; i < joints.length; i++) {
if (joints[i][0] == linkName) {
link = i;
}
}
if (link == null) {
print("no link");
return;
}
let r = joints[link][1] + R;
let x = cos(r) * L + joints[link][2];
let y = sin(r) * L + joints[link][3];
joints[joint] = [name, r, x, y];
if (debug) {
line(joints[link][2], joints[link][3], joints[joint][2], joints[joint][3]);
}
}
function pointsLine(POINT1, POINT2) {
line(POINT1[0], POINT1[1], POINT2[0], POINT2[1]);
}
function pointsTriangle(POINT1,POINT2,POINT3){
triangle(POINT1[0], POINT1[1], POINT2[0], POINT2[1], POINT3[0], POINT3[1])
}
// might be a bit weird due to the order of the diagonals not being specified
function pointsRectangle(POINT1,POINT2,POINT3,POINT4){
pointsLine(POINT1,POINT2)
pointsLine(POINT2,POINT3)
pointsLine(POINT3,POINT4)
pointsLine(POINT4,POINT1)
noStroke()
pointsTriangle(POINT1,POINT2,POINT3)
pointsTriangle(POINT1,POINT4,POINT3)
stroke(STROKE)
}
function triangleArea(x1,y1,x2,y2,x3,y3){
x1 = round(x1,3)
y1 = round(y1,3)
x2 = round(x2,3)
y2 = round(y2,3)
x3 = round(x3,3)
y3 = round(y3,3)
return (1/2)*abs(x1*(y2 - y3) + x2*(y3 - y1) + x3*(y1 - y2))
}
function checkTrianglePoint(x1,y1,x2,y2,x3,y3,px,py){
let area = triangleArea(x1,y1,x2,y2,x3,y3)
px = round(px,3)
py = round(py,3)
if(area + 0.01 >= triangleArea(px,py,x2,y2,x3,y3)+triangleArea(x1,y1,px,py,x3,y3)+triangleArea(x1,y1,x2,y2,px,py)){
return true
} else {
return false
}
}
var cameraPos = [0,0]
var canDock = false;
var docked = false;
var shipJoint;
var playerShip;
var asteroid;
var station;
var dockingPort;
var speed = 5;
var turn = 5;
function createStation(lightCol){
station = new Sprite(random(1500, 3000),random(-2000,2000),1000,1000)
station.diameter = 1500
station.collider = "static"
station.color = color(10,10,15,255)
station.stroke = color(200)
station.spinSpeed = 10 // custom value, determines the visual rotation speed of the station and the orbit speed of docking ports
station.lightColor = lightCol
dockingPort1 = new Sprite(station.x + station.diameter/2,station.y,200,200)
dockingPort1.collider = "kinematic"
dockingPort1.color = color(10,10,15)
dockingPort1.stroke = color(200)
dockingPort1.station = "station"
dockingPort2 = new Sprite(station.x - station.diameter/2,station.y,200,200)
dockingPort2.collider = "kinematic"
dockingPort2.color = color(10,10,15)
dockingPort2.stroke = color(200)
dockingPort2.station = "station"
dockingPort3 = new Sprite(station.x,station.y - station.diameter/2,200,200)
dockingPort3.collider = "kinematic"
dockingPort3.color = color(10,10,15)
dockingPort3.stroke = color(200)
dockingPort3.station = "station"
dockingPort4 = new Sprite(station.x,station.y + station.diameter/2,200,200)
dockingPort4.collider = "kinematic"
dockingPort4.color = color(10,10,15)
dockingPort4.stroke = color(200)
dockingPort4.station = "station"
}
function updateStation(){
let x = dockingPort1.x - station.x
let y = dockingPort1.y - station.y
let angle = atan(y/x)
if(x > 0) angle = angle + 180
angle += 90
dockingPort1.direction = angle
dockingPort1.speed = (station.spinSpeed/360) * PI * (station.diameter/60)
dockingPort1.rotation = angle
setJoint("dockingPort1",angle,dockingPort1.x,dockingPort1.y)
// prevents the docking port from drifting off into space due to imprecision
if(dist(station.x,station.y,dockingPort1.x,dockingPort1.y) > (station.diameter/2) + 0.5){
dockingPort1.x = station.x + cos(angle+90)*(station.diameter/2);
dockingPort1.y = station.y + sin(angle+90)*(station.diameter/2);
}
let p1 = jointOffset("dockingPort1",100,100)
let p2 = jointOffset("dockingPort1",100,-100)
let p3 = jointOffset("dockingPort1",300,100)
let p4 = jointOffset("dockingPort1",300,-100)
if(checkTrianglePoint(p1[0],p1[1],p4[0],p4[1],p2[0],p2[1],playerShip.x,playerShip.y) ||
checkTrianglePoint(p1[0],p1[1],p4[0],p4[1],p3[0],p3[1],playerShip.x,playerShip.y) ) {
canDock = true;
if(kb.pressed("e") && !docked){
docked = true;
shipJoint = new GlueJoint(playerShip, dockingPort1)
shipJoint.visible = false;
} else if(kb.pressed("e") && docked) {
shipJoint.remove()
docked = false;
}
}
angle += 90
dockingPort3.direction = angle
dockingPort3.speed = (station.spinSpeed/360) * PI * (station.diameter/60)
dockingPort3.rotation = angle
setJoint("dockingPort3",angle,dockingPort3.x,dockingPort3.y)
// prevents the docking port from drifting off into space due to imprecision
if(dist(station.x,station.y,dockingPort3.x,dockingPort3.y) > (station.diameter/2) + 0.5){
dockingPort3.x = station.x + cos(angle+90)*(station.diameter/2);
dockingPort3.y = station.y + sin(angle+90)*(station.diameter/2);
}
p1 = jointOffset("dockingPort3",100,100)
p2 = jointOffset("dockingPort3",100,-100)
p3 = jointOffset("dockingPort3",300,100)
p4 = jointOffset("dockingPort3",300,-100)
if(checkTrianglePoint(p1[0],p1[1],p4[0],p4[1],p2[0],p2[1],playerShip.x,playerShip.y) ||
checkTrianglePoint(p1[0],p1[1],p4[0],p4[1],p3[0],p3[1],playerShip.x,playerShip.y) ) {
canDock = true;
if(kb.pressed("e") && !docked){
docked = true;
shipJoint = new GlueJoint(playerShip, dockingPort3)
shipJoint.visible = false;
} else if(kb.pressed("e") && docked) {
shipJoint.remove()
docked = false;
}
}
angle += 90
dockingPort2.direction = angle
dockingPort2.speed = (station.spinSpeed/360) * PI * (station.diameter/60)
dockingPort2.rotation = angle
setJoint("dockingPort2",angle,dockingPort2.x,dockingPort2.y)
// prevents the docking port from drifting off into space due to imprecision
if(dist(station.x,station.y,dockingPort2.x,dockingPort2.y) > (station.diameter/2) + 0.5){
dockingPort2.x = station.x + cos(angle+90)*(station.diameter/2);
dockingPort2.y = station.y + sin(angle+90)*(station.diameter/2);
}
p1 = jointOffset("dockingPort2",100,100)
p2 = jointOffset("dockingPort2",100,-100)
p3 = jointOffset("dockingPort2",300,100)
p4 = jointOffset("dockingPort2",300,-100)
if(checkTrianglePoint(p1[0],p1[1],p4[0],p4[1],p2[0],p2[1],playerShip.x,playerShip.y) ||
checkTrianglePoint(p1[0],p1[1],p4[0],p4[1],p3[0],p3[1],playerShip.x,playerShip.y) ) {
canDock = true;
if(kb.pressed("e") && !docked){
docked = true;
shipJoint = new GlueJoint(playerShip, dockingPort2)
shipJoint.visible = false;
} else if(kb.pressed("e") && docked) {
shipJoint.remove()
docked = false;
}
}
angle += 90
dockingPort4.direction = angle
dockingPort4.speed = (station.spinSpeed/360) * PI * (station.diameter/60)
dockingPort4.rotation = angle
setJoint("dockingPort4",angle,dockingPort4.x,dockingPort4.y)
// prevents the docking port from drifting off into space due to imprecision
if(dist(station.x,station.y,dockingPort4.x,dockingPort4.y) > (station.diameter/2) + 0.5){
dockingPort4.x = station.x + cos(angle+90)*(station.diameter/2);
dockingPort4.y = station.y + sin(angle+90)*(station.diameter/2);
}
p1 = jointOffset("dockingPort4",100,100)
p2 = jointOffset("dockingPort4",100,-100)
p3 = jointOffset("dockingPort4",300,100)
p4 = jointOffset("dockingPort4",300,-100)
if(checkTrianglePoint(p1[0],p1[1],p4[0],p4[1],p2[0],p2[1],playerShip.x,playerShip.y) ||
checkTrianglePoint(p1[0],p1[1],p4[0],p4[1],p3[0],p3[1],playerShip.x,playerShip.y) ) {
canDock = true;
if(kb.pressed("e") && !docked){
docked = true;
shipJoint = new GlueJoint(playerShip, dockingPort4)
shipJoint.visible = false;
} else if(kb.pressed("e") && docked) {
shipJoint.remove()
docked = false;
}
}
if(checkTrianglePoint(200,50,250,120,400,0,playerShip.x,playerShip.y)){
testTriangle.stroke = color(0,255,0)
} else {
testTriangle.stroke = color(255,0,0)
}
setJoint("station",angle,0,0)
// custom draw code for the station
station.draw = () => {
noFill()
stroke(station.stroke)
strokeWeight(2)
pointsRectangle(
jointOffset("station",-station.diameter/20,0),
jointOffset("station",station.diameter/20,0),
jointOffset("station",station.diameter/20,(station.diameter/2)-(station.diameter/20)),
jointOffset("station",-station.diameter/20,(station.diameter/2)-(station.diameter/20))
)
pointsRectangle(
jointOffset("station",-station.diameter/20,0),
jointOffset("station",station.diameter/20,0),
jointOffset("station",station.diameter/20,-(station.diameter/2)+(station.diameter/20)),
jointOffset("station",-station.diameter/20,-(station.diameter/2)+(station.diameter/20))
)
pointsRectangle(
jointOffset("station",0,-station.diameter/20),
jointOffset("station",0,station.diameter/20),
jointOffset("station",(station.diameter/2)-(station.diameter/20),station.diameter/20),
jointOffset("station",(station.diameter/2)-(station.diameter/20),-station.diameter/20)
)
pointsRectangle(
jointOffset("station",0,-station.diameter/20),
jointOffset("station",0,station.diameter/20),
jointOffset("station",-(station.diameter/2)+(station.diameter/20),station.diameter/20),
jointOffset("station",-(station.diameter/2)+(station.diameter/20),-station.diameter/20)
)
strokeWeight(1)
noFill()
stroke(station.color)
strokeWeight(station.diameter/6)
circle(0,0,station.diameter-(station.diameter/6))
fill(station.color)
noStroke()
circle(0,0,station.diameter/3)
stroke(station.stroke)
strokeWeight(1)
noFill()
stroke(station.stroke)
circle(0,0,station.diameter-(station.diameter/3))
noFill()
stroke(station.stroke)
circle(0,0,station.diameter)
circle(0,0,station.diameter/3)
fill(station.color)
noStroke()
pointsRectangle(
jointOffset("station",-station.diameter/20,0),
jointOffset("station",station.diameter/20,0),
jointOffset("station",station.diameter/20,(station.diameter/2)-(station.diameter/20)),
jointOffset("station",-station.diameter/20,(station.diameter/2)-(station.diameter/20))
)
noStroke()
pointsRectangle(
jointOffset("station",-station.diameter/20,0),
jointOffset("station",station.diameter/20,0),
jointOffset("station",station.diameter/20,-(station.diameter/2)+(station.diameter/20)),
jointOffset("station",-station.diameter/20,-(station.diameter/2)+(station.diameter/20))
)
noStroke()
pointsRectangle(
jointOffset("station",0,-station.diameter/20),
jointOffset("station",0,station.diameter/20),
jointOffset("station",(station.diameter/2)-(station.diameter/20),station.diameter/20),
jointOffset("station",(station.diameter/2)-(station.diameter/20),-station.diameter/20)
)
noStroke()
pointsRectangle(
jointOffset("station",0,-station.diameter/20),
jointOffset("station",0,station.diameter/20),
jointOffset("station",-(station.diameter/2)+(station.diameter/20),station.diameter/20),
jointOffset("station",-(station.diameter/2)+(station.diameter/20),-station.diameter/20)
)
let angle;
for (let i = 0; i < joints.length; i++) {
if (joints[i][0] == "station") {
angle = joints[i][1];
}
}
let arcGapIn = 50
let arcGapOut = 35
let arcRadIn = station.diameter/4
let arcRadOut = station.diameter-(station.diameter/20)
stroke(station.lightColor)
noFill()
strokeWeight(20)
strokeCap(PROJECT)
arc(0,0,arcRadIn,arcRadIn, angle + 0 + (arcGapIn/2), angle + 0 + 90 - (arcGapIn/2))
arc(0,0,arcRadIn,arcRadIn, angle + 90 + (arcGapIn/2), angle + 90 + 90 - (arcGapIn/2))
arc(0,0,arcRadIn,arcRadIn, angle + 180 + (arcGapIn/2), angle + 180 + 90 - (arcGapIn/2))
arc(0,0,arcRadIn,arcRadIn, angle + 270 + (arcGapIn/2), angle + 270 + 90 - (arcGapIn/2))
strokeWeight(25)
arc(0,0,arcRadOut,arcRadOut, angle + 0 + (arcGapOut/2), angle + 0 + 90 - (arcGapOut/2))
arc(0,0,arcRadOut,arcRadOut, angle + 90 + (arcGapOut/2), angle + 90 + 90 - (arcGapOut/2))
arc(0,0,arcRadOut,arcRadOut, angle + 180 + (arcGapOut/2), angle + 180 + 90 - (arcGapOut/2))
arc(0,0,arcRadOut,arcRadOut, angle + 270 + (arcGapOut/2), angle + 270 + 90 - (arcGapOut/2))
}
}
function setup() {
createCanvas(700, 700);
camera.zoom = 0.5
playerShip = new Sprite(0,0,80,60);
playerShip.mass = 0.7
playerShip.rotationDrag = 0.5
playerShip.drag = 0.5
playerShip.color = color(10,10,15)
playerShip.stroke = color(0,0,255)
playerShip.strokeWeight = 3
playerShip.maxIntegrity = 100;
playerShip.integrity = 100;
function resetPlayer(){
playerShip.x = 0
playerShip.y = 0
playerShip.rotationSpeed = 0
playerShip.speed = 0
}
createStation(color(0,0,255));
}
createJoint("dockingPort1",0,0,0)
createJoint("dockingPort2",0,0,0)
createJoint("dockingPort3",0,0,0)
createJoint("dockingPort4",0,0,0)
createJoint("station",0,2000,1000)
function draw() {
background(10,10,15);
DTcount += round(deltaTime/1000,3)
DTcount = round(DTcount,3)
noFill()
stroke(255)
rect(100,100,500,500)
fill(255)
noStroke()
textSize(15)
textAlign(LEFT,TOP)
text("background",120,120)
// smooth-ish camera follow
camera.x = playerShip.x - (playerShip.vel.x/abs(playerShip.vel.x))*(sqrt(abs(playerShip.vel.x))*3)
camera.y = playerShip.y - (playerShip.vel.y/abs(playerShip.vel.y))*(sqrt(abs(playerShip.vel.y))*3)
playerShip.bearing = playerShip.rotation - 90;
if(kb.pressing("up")) playerShip.applyForce(speed)
if(kb.pressing("down")) playerShip.applyForce(-speed/2)
if(kb.pressing("right")) playerShip.applyTorque(turn)
if(kb.pressing("left")) playerShip.applyTorque(-turn)
if(kb.pressing("up")&&kb.pressing("left")&&kb.pressing("right")){
playerShip.drag = 0.2
playerShip.rotationDrag = 0.2
} else {
playerShip.drag = 0.5
playerShip.rotationDrag = 0.5
}
playerShip.draw = () => {
fill(200,100,0)
noStroke()
if(kb.pressing("up") && !docked){
triangle(20,30,-20,30,0,sin(DTcount*360*8)*10+38)
}
if(kb.pressing("left") && !docked){
triangle(25,28,40,5,cos(40)*(sin(DTcount*360*8)*20)+33,sin(40)*(sin(DTcount*360*8)*20)+17)
}
if(kb.pressing("right") && !docked){
triangle(-25,28,-40,5,cos(140)*(sin(DTcount*360*8)*20)-33,sin(140)*(sin(DTcount*360*8)*20)+17)
}
stroke(0,50,240)
strokeWeight(3)
fill(10,10,15)
triangle(0,5,20,30,-20,30)
triangle(-5,5,-25,28,-40,5)
triangle(5,5,25,28,40,5)
noStroke()
triangle(0,0,20,-30,-20,-30)
triangle(0,0,40,0,20,-30)
triangle(0,0,-40,0,-20,-30)
stroke(0,50,240)
line(-40,0,40,0)
line(40,0,20,-30)
line(20,-30,-20,-30)
line(-40,0,-20,-30)
}
updateStation()
camera.on()
allSprites.draw()
camera.off()
// arrow pointing to station
x = playerShip.x - station.x
y = playerShip.y - station.y
angle = atan(y/x)
if(x > 0) angle = angle + 180
noFill()
stroke(200)
triangle(350 + cos(angle+5)*50,350 + sin(angle+5)*50,350 + cos(angle-5)*50,350 + sin(angle-5)*50,350 + cos(angle)*75,350 + sin(angle)*75)
if(docked){
textAlign(CENTER,CENTER)
textSize(20)
fill(color(255,255,255,100))
noStroke()
text("press e to undock",350,350)
} else if(canDock){
textAlign(CENTER,CENTER)
textSize(20)
fill(color(255,255,255,100))
noStroke()
text("press e to dock",350,350)
}
canDock = false;
}