Skip to content
Binary file modified .DS_Store
Binary file not shown.
Binary file added Examples/.DS_Store
Binary file not shown.
40 changes: 40 additions & 0 deletions StudentFolders/A1/29kingstont/side_scroller/Body.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
public abstract class Body {
protected PVector pos;

// protected PVector vel, acc;
protected float mass;

Body(PVector pos, float mass) {
this.pos = pos;

// this.vel = new PVector();
// this.acc = new PVector();
this.mass = mass;
}

public PVector getPos() {
return this.pos;
}
public abstract PVector getBottom();
public abstract PVector getTop();
public abstract PVector getCenter();
public final PVector getAppropriatePos(boolean isUpsideDown) {
return isUpsideDown ? getBottom() : getTop();
}
public float getMass() {
return this.mass;
}

public void setPos(PVector pos) {
this.pos = pos;
}
public abstract void setBottom(PVector p);
public abstract void setTop(PVector p);
public abstract void setCenter(PVector p);

public abstract void resolveAllCollisions(Entity entity, Terrain terr, ArrayList<Platform> platforms, boolean isUpsideDown);
public abstract boolean isGrounded(Terrain terr, boolean isUpsideDown);
public abstract boolean isGrounded(Terrain terr, ArrayList<Platform> platforms, boolean isUpsideDown);

public abstract boolean isWithin(float minX, float maxX);
}
56 changes: 56 additions & 0 deletions StudentFolders/A1/29kingstont/side_scroller/BoringZombie.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
public class BoringZombie extends Enemy<RectBody> {
protected Weapon weapon;

BoringZombie(PVector pos, boolean isUpsideDown) {
super(new RectBody(pos, 40, 80, 1), 0.5, 5, 1000, 100, 2, isUpsideDown);

this.weapon = new Knife(0, this.damage, 30, 30); // cooldown 0 because managed by Enemy class
}

BoringZombie(PVector pos, int movementSpeed, float damage, int cooldown, int maxHealth, int sacrificialHealth, boolean isUpsideDown) {
super(new RectBody(pos, 40, 80, 1), movementSpeed, damage, cooldown, maxHealth, sacrificialHealth, isUpsideDown);

this.weapon = new Knife(0, this.damage, 30, 30); // cooldown 0 because managed by Enemy class
}

@Override
protected void move(Meeple meeple) {
float diff = meeple.getPos().x - this.getPos().x;

if (diff > 0) {
if (abs(diff) >= 20) this.getPos().x += movementSpeed;
this.setIsFacingRight(true);
} else if (diff < 0) {
if (abs(diff) >= 20) this.getPos().x -= movementSpeed;
this.setIsFacingRight(false);
}
}

@Override
protected boolean attackConditionSatisfied(Meeple meeple) {
return !this.weapon.getTargetsInRange(this, meeple).isEmpty();
}

@Override
protected void attack(World world) {
Meeple meeple = world.getMeeple();
if (meeple == null) return;

weapon.useAction(this, meeple);
}

@Override
public void display() {
stroke(0);
strokeWeight(1);
fill(RED);

PVector pos = this.getPos();
RectBody body = this.getBody();
rect(pos.x, pos.y, body.getW(), body.getH());

this.weapon.handheldDisplay(this);

displayHp(this);
}
}
53 changes: 53 additions & 0 deletions StudentFolders/A1/29kingstont/side_scroller/Bullet.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
public class Bullet extends Entity<RectBody> {
private ArrayList<Entity> targets;
private float damage;

private int lifetime;
private int startOfLife;

Bullet(PVector pos, PVector vel, PVector acc, float damage, ArrayList<Entity> targets) {
super(new RectBody(pos, 10, 5, 0)); // 10, 5

this.damage = damage;
this.targets = targets;
this.vel = vel;
this.acc = acc;

this.startOfLife = millis();
this.lifetime = 10*1000;
}

@Override
public void update(World world) {
super.update(world);
this.attack();

if (millis()-this.startOfLife >= this.lifetime) this.die();
}

private void attack() {
for (Entity e : targets) {
if (!(e instanceof HasHealth) || e.getIsDead()) continue;
HasHealth damageable = (HasHealth) e;

if (e.getBody() instanceof RectBody) {
if (Collision.check((RectBody) e.getBody(), this.getBody()).collided) {
damageable.damage(this.damage);
this.die();
}
} else if (e.getBody() instanceof CircleBody) {
if (Collision.check((CircleBody) e.getBody(), this.getBody()).collided) {
damageable.damage(this.damage);
this.die();
}
}
}
}

@Override
public void display() {
fill(255, 0, 0);
noStroke();
rect(this.getPos().x, this.getPos().y, this.getBody().getW(), this.getBody().getH());
}
}
12 changes: 12 additions & 0 deletions StudentFolders/A1/29kingstont/side_scroller/Bush.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Bush extends Static {
Bush(PVector pos, int w, int h) {
super(pos, w, h);
}

public void display() {
fill(8, 107, 57, 255);
stroke(0);
strokeWeight(1);
ellipse(pos.x, pos.y, w, h);
}
}
76 changes: 76 additions & 0 deletions StudentFolders/A1/29kingstont/side_scroller/CircleBody.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
public class CircleBody extends Body {
float r;

CircleBody(PVector pos, float r) {
super(pos, 0);
this.r = r;
}
CircleBody(PVector pos, float r, float mass) {
super(pos, mass);
this.r = r;
}

@Override
public PVector getTop() {
return PVector.add(this.pos, new PVector(0, r));
}
@Override
public PVector getBottom() {
return PVector.sub(this.pos, new PVector(0, r));
}
@Override
public PVector getCenter() {
return this.pos;
}
public float getR() {
return this.r;
}

@Override
public void setTop(PVector p) {
this.pos = p.add(0, r);
}
@Override
public void setBottom(PVector p) {
this.pos = p.sub(0, r);
}
@Override
public void setCenter(PVector p) {
this.pos = p;
}

@Override
public void resolveAllCollisions(Entity entity, Terrain rightsideUpTerr, ArrayList<Platform> platforms, boolean isUpsideDown) {
if (isGrounded(rightsideUpTerr, platforms, isUpsideDown)) {
float bestY = rightsideUpTerr.getHeightAt(this.pos.x)-this.r;

entity.vel.y = 0;
this.pos.y = bestY;
}
}

@Override
public boolean isGrounded(Terrain rightsideUpTerr, boolean isUpsideDown) {
float terrH = rightsideUpTerr.getHeightAt(this.pos.x);
return this.pos.y+this.r >= terrH;
}

@Override
public boolean isGrounded(Terrain rightsideUpTerr, ArrayList<Platform> platforms, boolean isUpsideDown) {
float terrH = rightsideUpTerr.getHeightAt(this.pos.x);
boolean isOnFloor = this.pos.y+this.r >= terrH;
boolean isOnPlatform = false;
// for (Platform p : platforms) {
// if (p.intersects(this)) {
// isOnPlatform = true;
// break;
// }
// }
return isOnFloor || isOnPlatform;
}

@Override
public boolean isWithin(float minX, float maxX) {
return pos.x+r >= minX && pos.x-r <= maxX;
}
}
95 changes: 95 additions & 0 deletions StudentFolders/A1/29kingstont/side_scroller/Collision.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
public static class CollisionResult {
public boolean collided;
public String side;
public float penetration;

public CollisionResult(boolean collided, String side, float penetration) {
this.collided = collided;
this.side = side;
this.penetration = penetration;
}

public static CollisionResult none() {
return new CollisionResult(false, "", 0);
}
}

public static class Collision {
public static CollisionResult check(RectBody a, RectBody b) {
float overlapX = min(a.getX() + a.getW() - b.getX(), b.getX() + b.getW() - a.getX());
float overlapY = min(a.getY() + a.getH() - b.getY(), b.getY() + b.getH() - a.getY());

if (overlapX > 0 && overlapY > 0) {
if (overlapX < overlapY) {
return new CollisionResult(
true,
(a.getX() < b.getX() ? "left" : "right"),
overlapX
);
} else {
return new CollisionResult(
true,
(a.getY() < b.getY() ? "top" : "bottom"),
overlapY
);
}
}

return CollisionResult.none();
}



// ChatGPTed because this is literally never used. Idk why I don't just remove CircleBody -_-
public static CollisionResult check(CircleBody circle, RectBody rect) {
float cx = circle.getPos().x;
float cy = circle.getPos().x;
float r = circle.getR();

float rx = rect.getX();
float ry = rect.getY();
float rw = rect.getW();
float rh = rect.getH();

// 1. Find closest point on rectangle to circle center
float closestX = clamp(cx, rx, rx + rw);
float closestY = clamp(cy, ry, ry + rh);

// 2. Distance from circle to closest point
float dx = cx - closestX;
float dy = cy - closestY;

float distSq = dx * dx + dy * dy;

if (distSq > r * r) {
return CollisionResult.none(); // No collision
}

// 3. Determine penetration along X/Y
float distance = (float)Math.sqrt(distSq);
float penetration = r - distance;

// Normalize direction
float nx = dx / distance;
float ny = dy / distance;

// Choose axis of strongest push
if (Math.abs(nx) > Math.abs(ny)) {
return new CollisionResult(
true,
nx < 0 ? "left" : "right",
Math.abs(penetration * nx)
);
} else {
return new CollisionResult(
true,
ny < 0 ? "top" : "bottom",
Math.abs(penetration * ny)
);
}
}

private static float clamp(float value, float min, float max) {
return Math.max(min, Math.min(max, value));
}
}
21 changes: 21 additions & 0 deletions StudentFolders/A1/29kingstont/side_scroller/Constants.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
public static class Constants {
static final int MAX_LAYER = 4;
static final int MAX_ITEMS = 5; // must be less than 9
static int CHUNK_W; // Will be set to half of width
static final int RENDER_CHUNK_RADIUS = 0; // max # chunks from the current on-screen chunks that will be rendered
static final int LIVE_CHUNK_RADIUS = 2; // max # chunks away from the current on-screen chunks that will be updated
static final boolean MINIMIZE_GRAPHICS = false; // minimize details

static final float TRAMPOLINE_SPAWN_CHANCE = 0.25; // [0, 1]
static final int TRAMPOLINE_W = 100;
static final int TRAMPOLINE_H = 20;

static final float FLAG_SPAWN_CHANCE = 1;

static final int BLOCK_UNIT = 40;

// Debugging
static final boolean SPAWN_ENEMIES = true; // default: true
static final boolean CONSTANT_DAYTIME = false; // default: false
static final boolean ALLOW_FLYING = false; // default: false
}
13 changes: 13 additions & 0 deletions StudentFolders/A1/29kingstont/side_scroller/Dirt.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
public class Dirt extends Particle {
Dirt(PVector p, PVector vel, PVector acc) {
super(p, vel, acc, 15);
}

void display() {
stroke(0, this.lifespan);

float alpha = map(this.lifespan, 0, this.maxLifespan, 0, 255);
fill(PLATFORM_BLUE, alpha);
circle(pos.x, pos.y, 8);
}
}
Loading