Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import processing.core.PApplet;
- import processing.core.PVector;
- import java.util.ArrayList;
- public class MainApp extends PApplet {
- PVector target, cameraOffset;
- float centerToCornerDistance, farAway;
- float alignRadius, alignWeight, centralizeRadius, centralizeWeight;
- float spdLimit = 10;
- int fishCount = 100;
- Fish player;
- ArrayList<Fish> fish = new ArrayList<Fish>();
- ArrayList<Fish> fishToRemove = new ArrayList<Fish>();
- private boolean targetActive = false;
- private float t;
- private final float maxFishSize = 30;
- public static void main(String[] args) {
- PApplet.main("MainApp");
- }
- public void settings() {
- size(800, 800, P3D);
- // fullScreen(P3D);
- }
- public void setup() {
- cameraOffset = new PVector(width * .5f, height * .5f);
- player = new Fish();
- player.pos = new PVector(0, 0);
- player.spd = new PVector();
- target = new PVector(player.pos.x, player.pos.y);
- }
- public void draw() {
- t = radians(frameCount);
- centerToCornerDistance = dist(0, 0, width * .5f, height * .5f);
- farAway = centerToCornerDistance * 2;
- background(0);
- pushMatrix();
- translate(cameraOffset.x, cameraOffset.y);
- updateTarget();
- movePlayerTowardsTarget();
- moveCameraTowardsPlayer();
- drawFish();
- while (fish.size() < fishCount) {
- fish.add(new Fish());
- }
- popMatrix();
- drawSliders();
- if(frameCount > 1300 && frameCount < 1600){
- // saveFrame("capture/####.jpg");
- }
- }
- private void drawSliders() {
- spdLimit = /*slider("spd limit", 1, 100,*/ 10;
- alignRadius = /*slider("align radius", 10, 400,*/ 200;
- alignWeight = /*slider("align weight", 0, 1,*/ .5f;
- // avoidRadius = /*slider("avoid radius", 10, 200,*/ 20;
- centralizeRadius = /*slider("centralize radius", 10, 400,*/ 100;
- centralizeWeight = /*slider("centralize weight", 0, 1,*/ .5f;
- }
- private void drawFish() {
- noFill();
- for (Fish f : fish) {
- stroke(155, 155, 255, 150);
- strokeWeight(1);
- f.updateAndDraw();
- if (f.toRemove) {
- fishToRemove.add(f);
- }
- }
- stroke(255, 255);
- strokeWeight(1);
- player.updateAndDraw();
- fish.removeAll(fishToRemove);
- fishToRemove.clear();
- }
- private void updateTarget() {
- if (mousePressed) {
- target.x = mouseX - cameraOffset.x;
- target.y = mouseY - cameraOffset.y;
- targetActive = true;
- }
- if (dist(player.pos.x, player.pos.y, target.x, target.y) < 3) {
- targetActive = false;
- }
- }
- private float distanceFromPlayerToTarget() {
- return (target.x == player.pos.x && target.y == player.pos.y) ? 0 : dist(player.pos.x, player.pos.y, target.x, target.y);
- }
- private void movePlayerTowardsTarget() {
- if (!targetActive) {
- return;
- }
- player.spd.x = lerp(player.pos.x, target.x, .1f);
- player.spd.y = lerp(player.pos.y, target.y, .1f);
- player.spd.sub(player.pos);
- player.spd.limit(10);
- player.spd.mult(.9f);
- player.pos.add(player.spd);
- }
- private void moveCameraTowardsPlayer() {
- PVector playerCoordinateOnScreen = new PVector(modelX(player.pos.x, player.pos.y, player.pos.z), modelY(player.pos.x, player.pos.y, player.pos.z), 0);
- cameraOffset.x = lerp(cameraOffset.x, width * .5f - player.pos.x, .1f);
- cameraOffset.y = lerp(cameraOffset.y, height * .5f - player.pos.y, .1f);
- }
- boolean isPointInRect(float px, float py, float rx, float ry, float rw, float rh) {
- return px >= rx && px <= rx + rw && py >= ry && py <= ry + rh;
- }
- class Fish {
- PVector pos;
- PVector spd = new PVector();
- PVector acc = new PVector();
- float radius;
- boolean toRemove = false;
- PVector centralizeAvgPos = new PVector();
- PVector friendAlignAvgSpd = new PVector();
- PVector friendAvoidance = new PVector();
- PVector enemyAvoidance = new PVector();
- PVector foodAvgPos = new PVector();
- private float seekFoodWeight = 2;
- Fish beingEatenBy = null;
- Fish() {
- if (player == null) {
- pos = new PVector(width * .5f, height * .5f);
- radius = 15;
- } else {
- pos = randomPositionOffscreenInFrontOfPlayer();
- radius = random(maxFishSize);
- }
- }
- void updateAndDraw() {
- if(beingEatenBy != null){
- beingEatenBy.radius *= 1.05f;
- beingEatenBy.radius = constrain(beingEatenBy.radius, 0, maxFishSize);
- this.toRemove = true;
- return;
- }
- acc.mult(0);
- centralizeAvgPos.mult(0);
- friendAlignAvgSpd.mult(0);
- friendAvoidance.mult(0);
- enemyAvoidance.mult(0);
- foodAvgPos.mult(0);
- int alignToFriendsFlockCount = 0;
- int centralizeFriendCount = 0;
- int foodCount = 0;
- float safeDistanceFromFriend = radius*2;
- float foodRecognitionRadius = radius*6;
- float safeDistanceFromEnemy = radius*8;
- for (Fish f : fish) {
- if (this.equals(f)) {
- continue;
- }
- float d = dist(f.pos.x, f.pos.y, pos.x, pos.y);
- if (isFriend(f) && d < alignRadius) {
- friendAlignAvgSpd.add(f.spd);
- alignToFriendsFlockCount++;
- }
- if (isFriend(f) && d < safeDistanceFromFriend) {
- friendAvoidance.add(PVector.sub(pos, f.pos).normalize());
- }else if(isEnemy(f) && d < safeDistanceFromEnemy){
- enemyAvoidance.add(PVector.sub(pos, f.pos).normalize());
- }
- if (isFood(f) && d < foodRecognitionRadius){
- foodAvgPos.add(f.pos);
- foodCount++;
- if(d < radius){
- f.beingEatenBy = this;
- }
- }
- if (isFriend(f) && d < centralizeRadius) {
- centralizeAvgPos.add(f.pos);
- centralizeFriendCount++;
- }
- }
- if (centralizeFriendCount > 0) {
- centralizeAvgPos.div(centralizeFriendCount);
- }
- if (alignToFriendsFlockCount > 0) {
- friendAlignAvgSpd.div(alignToFriendsFlockCount);
- }
- acc.add(friendAvoidance);
- // acc.add(enemyAvoidance);
- // acc.add(PVector.sub(foodAvgPos, pos).normalize().mult(seekFoodWeight));
- acc.add(PVector.sub(centralizeAvgPos, pos).normalize().mult(centralizeWeight));
- acc.add(friendAlignAvgSpd.normalize().mult(alignWeight));
- spd.add(acc);
- spd.limit(spdLimit);
- spd.mult(.9f);
- pos.add(spd);
- pushMatrix();
- translate(pos.x, pos.y);
- rotate(spd.heading());
- float distanceToPlayer = dist(pos.x, pos.y, player.pos.x, player.pos.y);
- if (distanceToPlayer > farAway && isBehindPlayer(pos)) {
- this.toRemove = true;
- }
- beginShape(TRIANGLE_STRIP);
- int vertexCount = 12;
- for (float i = -vertexCount * .25f; i < vertexCount; i++) {
- boolean tail = i < 0;
- float iN = map(i, 0, vertexCount - 1, 0, 1);
- float x = map(iN, 0, 1, -radius * 2, radius);
- float y0 = radius * .5f * sin(iN * 3.f) + radius*.1f*sin(iN*2-t*25)*(tail?2:1);
- float y1 = -radius * .5f * sin(iN * 3.f) + radius*.1f*sin(iN*2-t*25)*(tail?2:1);
- vertex(x, y0);
- vertex(x, y1);
- }
- endShape();
- popMatrix();
- }
- private boolean isFood(Fish f){
- return false;
- // return f.radius < radius*.5f;
- }
- private boolean isFriend(Fish f) {
- return true;
- //abs(f.radius-radius)<=5;
- }
- private boolean isEnemy(Fish f){
- return false;
- // return f.radius - 5 > radius;
- }
- private boolean isBehindPlayer(PVector pos) {
- float angleToPlayer = atan2(player.pos.y - pos.y, player.pos.x - pos.x);
- float normalizedAngleToPlayer = normalizeAngle(angleToPlayer, PI);
- float normalizedPlayerHeading = normalizeAngle(player.spd.heading(), PI);
- float angleToPlayerVsHeading = normalizeAngle(normalizedAngleToPlayer - normalizedPlayerHeading, 0);
- return abs(angleToPlayerVsHeading) < HALF_PI;
- }
- private PVector randomPositionOffscreenInFrontOfPlayer() {
- float angle = random(player.spd.heading() - HALF_PI, player.spd.heading() + HALF_PI);
- float distance = random(centerToCornerDistance, farAway);
- return new PVector(player.pos.x + distance * cos(angle), player.pos.y + distance * sin(angle));
- }
- public float normalizeAngle(float a, float center) {
- return a - TWO_PI * floor((a + PI - center) / TWO_PI);
- }
- boolean isPointInRect(float px, float py, float rx, float ry, float rw, float rh) {
- return px >= rx && px <= rx + rw && py >= ry && py <= ry + rh;
- }
- boolean isPointInRectCenterMode(float px, float py, float rx, float ry, float rw, float rh) {
- return px >= rx - rw * .5f && px <= rx + rw * .5f && py >= ry - rh * .5f && py <= ry + rh * .5f;
- }
- class Slider {
- String name;
- float value;
- float min;
- float max;
- float defaultValue;
- int lastInteractedWith = -1;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement