initial commit

This commit is contained in:
Baipyrus 2022-05-15 17:01:06 +02:00
commit bdb4bff01a
5 changed files with 288 additions and 0 deletions

43
InputEvent.pde Normal file
View File

@ -0,0 +1,43 @@
void userMovement(char k, float hfo) {
// Move User 'basePosition'
float finalAngle = hfo;
switch (k) {
case 'a':
finalAngle -= HALF_PI;
break;
case 'd':
finalAngle += HALF_PI;
break;
case 's':
finalAngle += PI;
}
PVector t = PVector.fromAngle(finalAngle);
t.setMag(USER_ACCELERATION_MAGNITUDE);
userVelocity.add(t);
userVelocity.limit(USER_TERMINAL_VELOCITY);
}
void mousePressed() {
// Move Wall Endpoints
if (mouseButton == LEFT) {
for (int i = 0; i < walls.size(); i++) {
Wall w = walls.get(i);
final float d1 = PVector.dist(w.start, mouse);
if (d1 <= PROJECTILE_RADIUS) {
dragIndex = i;
break;
}
final float d2 = PVector.dist(w.end, mouse);
if (d2 <= PROJECTILE_RADIUS) {
dragIndex = i;
dragType = true;
break;
}
}
}
}
void mouseReleased() {
dragIndex = -1;
dragType = false;
}

80
Logic.pde Normal file
View File

@ -0,0 +1,80 @@
PVector intersect(PVector A, PVector B, PVector C, PVector D) {
// This returns the Intersection Point between lines AB and CD
// ONLY IF said point lies within the two segmented lines.
final float dx1 = B.x - A.x;
final float dx2 = D.x - C.x;
if ((dx1 == 0) || (dx2 == 0)) {
return null;
}
final float M1 = (B.y-A.y)/dx1;
final float M2 = (D.y-C.y)/dx2;
final float dm = M1 - M2;
if (dm == 0) {
return null;
}
final float B1 = A.y - M1 * A.x;
final float B2 = C.y - M2 * C.x;
if (M1 == M2 && B1 == B2) {
return null;
}
final float tx = (B2-B1)/dm;
final PVector common = new PVector(tx, M2 * tx + B2);
final PVector midpointA = B.copy();
midpointA.sub(A).div(2).add(A);
if (PVector.dist(midpointA, common) > PVector.dist(A, B) / 2) {
return null;
}
PVector midpointB = D.copy();
midpointB.sub(C).div(2).add(C);
if (PVector.dist(midpointB, common) > PVector.dist(C, D) / 2) {
return null;
}
return common;
}
boolean reflect(Projectile p, Wall w) {
// Position -> Next : A -> B
// Wall.start -> Wall.end : C -> D
PVector A = p.position.copy();
PVector B = p.next.copy();
final PVector C = w.start.copy();
final PVector D = w.end.copy();
final PVector I = intersect(A, B, C, D);
if (I != null && C.y - D.y != 0) {
// Calculating the Mathematical Function for the line CD
final double m_2 = (C.y - D.y) / (C.x - D.x); // -0???
final double b_2 = C.y - m_2 * C.x; // 100???
// Calculating the Mathematical Function for the line BE
final double m_0 = (-1) / m_2; // INFINITY???
final double b_0 = B.y - m_0 * B.x; // -INFINITY???
if (m_0 - m_2 != 0) {
// Calculating the Midpoint between B and soon-to-be E
// This would also work using scalar projection:
// https://www.youtube.com/watch?v=DHPfoqiE4yQ
final double mx = (b_2 - b_0) / (m_0 - m_2);
final PVector M = new PVector((float)mx, (float)(m_0 * mx + b_0));
// Calculating E, which is reflecting Point B across line CD
PVector E = PVector.sub(PVector.mult(M, 2), B);
// Calculate E, such that Lines AI and IE are of the same length
E.sub(I).setMag(PVector.dist(I, A)).add(I);
p.next = E.copy();
PVector newVelocity = PVector.sub(E, I);
newVelocity.setMag(p.velocity.mag());
p.velocity = newVelocity.copy();
return true;
}
}
return false;
}

28
Projectile.pde Normal file
View File

@ -0,0 +1,28 @@
class Projectile {
PVector position, next, velocity;
Projectile(PVector pos, PVector vel) {
position = pos.copy();
velocity = vel.copy();
}
void move() {
next = PVector.add(position, velocity);
// Check if projectile is offscreen
if (next.x < -PROJECTILE_RADIUS || next.x > width+PROJECTILE_RADIUS || next.y < -PROJECTILE_RADIUS || next.y > height+PROJECTILE_RADIUS)
projectiles.remove(this);
// Check for reflection across 'Walls'
for (int i = 0; i < walls.size(); i++)
reflect(this, walls.get(i));
position = next.copy();
}
void show() {
stroke(255);
fill(255);
ellipse(position.x, position.y, PROJECTILE_RADIUS*2, PROJECTILE_RADIUS*2);
}
}

16
Wall.pde Normal file
View File

@ -0,0 +1,16 @@
class Wall {
PVector start, end;
Wall(PVector s, PVector e) {
start = s.copy();
end = e.copy();
}
void show() {
stroke(255);
fill(255);
line(start.x, start.y, end.x, end.y);
ellipse(start.x, start.y, PROJECTILE_RADIUS*2, PROJECTILE_RADIUS*2);
ellipse(end.x, end.y, PROJECTILE_RADIUS*2, PROJECTILE_RADIUS*2);
}
}

121
reflectingProjectiles.pde Normal file
View File

@ -0,0 +1,121 @@
final int SHOOTING_COOLDOWN = 2;
final float PROJECTILE_RADIUS = 10;
final float VELOCITY_MAGNITUDE = 2;
final float HEADING_LINE_LENGTH = 50;
final float USER_TERMINAL_VELOCITY = 6;
final float USER_DECELERATION_MAGNITUDE = 0.1;
final float USER_ACCELERATION_MAGNITUDE = 0.25;
ArrayList<Projectile> projectiles = new ArrayList<Projectile>();
ArrayList<Wall> walls = new ArrayList<Wall>();
PVector mouse;
int dragIndex = -1;
boolean dragType = false;
PVector userPosition, userVelocity;
void setup() {
fullScreen();
mouse = new PVector(width, height/2);
userPosition = new PVector(width/2, height/2);
userVelocity = new PVector(0, 0);
walls.add(new Wall(
new PVector(width/2, 0),
new PVector(width, height/2)
));
walls.add(new Wall(
new PVector(width, height/2),
new PVector(width/2, height)
));
walls.add(new Wall(
new PVector(width/2, height),
new PVector(0, height/2)
));
walls.add(new Wall(
new PVector(0, height/2),
new PVector(width/2, 0)
));
}
void draw() {
background(0);
for (Wall w : walls)
w.show();
for (int i = projectiles.size()-1; i >= 0; i--) {
Projectile p = projectiles.get(i);
p.show();
p.move();
}
mouse = new PVector(mouseX, mouseY);
stroke(255,0,0);
fill(255,0,0);
ellipse(userPosition.x, userPosition.y, PROJECTILE_RADIUS*2, PROJECTILE_RADIUS*2);
// Handle 'mouseDrag' when pressing LMB
if (dragIndex != -1) {
Wall w = walls.get(dragIndex);
if (dragType)
w.end = mouse.copy();
else
w.start = mouse.copy();
}
// Handle 'shooting' when pressing RMB
if (mousePressed && mouseButton == RIGHT && frameCount % SHOOTING_COOLDOWN == 0 && !mouse.equals(userPosition)) {
PVector baseVelocity = PVector.sub(mouse, userPosition);
baseVelocity.setMag(VELOCITY_MAGNITUDE);
baseVelocity.add(userVelocity);
projectiles.add(new Projectile(
userPosition,
baseVelocity
));
}
// Display user heading
PVector userHeading = PVector.sub(mouse, userPosition);
userHeading.setMag(HEADING_LINE_LENGTH);
PVector temp = PVector.add(userPosition, userHeading);
float headingFromOrigin = userHeading.heading();
PVector arrowLeft = PVector.fromAngle(headingFromOrigin-(4*PI)/5);
PVector arrowRight = PVector.fromAngle(headingFromOrigin+(4*PI)/5);
arrowLeft.setMag(HEADING_LINE_LENGTH / 3);
arrowRight.setMag(HEADING_LINE_LENGTH / 3);
arrowLeft.add(temp);
arrowRight.add(temp);
if (!mouse.equals(userPosition)) {
stroke(255);
noFill();
line(userPosition.x, userPosition.y, temp.x, temp.y);
line(temp.x, temp.y, arrowLeft.x, arrowLeft.y);
line(temp.x, temp.y, arrowRight.x, arrowRight.y);
}
// Handle user movement
float decel = userVelocity.mag()-USER_DECELERATION_MAGNITUDE;
if (decel < 0)
decel = 0;
userVelocity.setMag(decel);
PVector nPos = PVector.add(userPosition, userVelocity);
boolean xZero = nPos.x < 0;
if (xZero || nPos.x > width) {
nPos.x = (xZero) ? 0 : width;
userVelocity.x = 0;
}
boolean yZero = nPos.y < 0;
if (yZero || nPos.y > height) {
nPos.y = (yZero) ? 0 : height;
userVelocity.y = 0;
}
userPosition = nPos.copy();
if (keyPressed) {
userMovement(key, headingFromOrigin);
}
}