initial commit
This commit is contained in:
commit
bdb4bff01a
43
InputEvent.pde
Normal file
43
InputEvent.pde
Normal 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
80
Logic.pde
Normal 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
28
Projectile.pde
Normal 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
16
Wall.pde
Normal 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
121
reflectingProjectiles.pde
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user