Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.15 KB | None | 0 0
  1. import processing.core.PApplet;
  2. import processing.core.PVector;
  3. import java.util.ArrayList;
  4.  
  5. PVector target, cameraOffset;
  6. float centerToCornerDistance, farAway;
  7. float alignRadius, alignWeight, centralizeRadius, centralizeWeight;
  8. float spdLimit = 10;
  9. int fishCount = 50;
  10. Fish player;
  11. ArrayList<Fish> fish = new ArrayList<Fish>();
  12. ArrayList<Fish> fishToRemove = new ArrayList<Fish>();
  13. private boolean targetActive = false;
  14. private float t;
  15. private final float maxFishSize = 30;
  16.  
  17.  
  18. public void settings() {
  19. fullScreen(P3D);
  20. orientation(PORTRAIT);
  21. }
  22.  
  23. public void setup() {
  24. cameraOffset = new PVector(width * .5f, height * .5f);
  25. player = new Fish();
  26. player.pos = new PVector(0, 0);
  27. player.spd = new PVector();
  28. target = new PVector(player.pos.x, player.pos.y);
  29. }
  30.  
  31. public void draw() {
  32. t = radians(frameCount);
  33. centerToCornerDistance = dist(0, 0, width * .5f, height * .5f);
  34. farAway = centerToCornerDistance * 2;
  35. background(0);
  36. pushMatrix();
  37. translate(cameraOffset.x, cameraOffset.y);
  38. updateTarget();
  39. movePlayerTowardsTarget();
  40. moveCameraTowardsPlayer();
  41. drawFish();
  42. while (fish.size() < fishCount) {
  43. fish.add(new Fish());
  44. }
  45. popMatrix();
  46. drawSliders();
  47.  
  48. if (frameCount > 1300 && frameCount < 1600) {
  49. // saveFrame("capture/####.jpg");
  50. }
  51. }
  52.  
  53. private void drawSliders() {
  54. spdLimit = /*slider("spd limit", 1, 100,*/ 10;
  55. alignRadius = /*slider("align radius", 10, 400,*/ 200;
  56. alignWeight = /*slider("align weight", 0, 1,*/ .5f;
  57. // avoidRadius = /*slider("avoid radius", 10, 200,*/ 20;
  58. centralizeRadius = /*slider("centralize radius", 10, 400,*/ 100;
  59. centralizeWeight = /*slider("centralize weight", 0, 1,*/ .5f;
  60. }
  61.  
  62. private void drawFish() {
  63. noFill();
  64. for (Fish f : fish) {
  65. stroke(155, 155, 255, 150);
  66. strokeWeight(1);
  67. f.updateAndDraw();
  68. if (f.toRemove) {
  69. fishToRemove.add(f);
  70. }
  71. }
  72. stroke(255, 255);
  73. strokeWeight(1);
  74. player.updateAndDraw();
  75. fish.removeAll(fishToRemove);
  76. fishToRemove.clear();
  77. }
  78.  
  79. private void updateTarget() {
  80. if (mousePressed) {
  81. target.x = mouseX - cameraOffset.x;
  82. target.y = mouseY - cameraOffset.y;
  83. targetActive = true;
  84. }
  85. if (dist(player.pos.x, player.pos.y, target.x, target.y) < 3) {
  86. targetActive = false;
  87. }
  88. }
  89.  
  90. private float distanceFromPlayerToTarget() {
  91. return (target.x == player.pos.x && target.y == player.pos.y) ? 0 : dist(player.pos.x, player.pos.y, target.x, target.y);
  92. }
  93.  
  94. private void movePlayerTowardsTarget() {
  95. if (!targetActive) {
  96. return;
  97. }
  98. player.spd.x = lerp(player.pos.x, target.x, .1f);
  99. player.spd.y = lerp(player.pos.y, target.y, .1f);
  100. player.spd.sub(player.pos);
  101. player.spd.limit(10);
  102. player.spd.mult(.9f);
  103. player.pos.add(player.spd);
  104. }
  105.  
  106. private void moveCameraTowardsPlayer() {
  107. 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);
  108. cameraOffset.x = lerp(cameraOffset.x, width * .5f - player.pos.x, .1f);
  109. cameraOffset.y = lerp(cameraOffset.y, height * .5f - player.pos.y, .1f);
  110. }
  111.  
  112. boolean isPointInRect(float px, float py, float rx, float ry, float rw, float rh) {
  113. return px >= rx && px <= rx + rw && py >= ry && py <= ry + rh;
  114. }
  115.  
  116. class Fish {
  117. PVector pos;
  118. PVector spd = new PVector();
  119. PVector acc = new PVector();
  120. float radius;
  121. boolean toRemove = false;
  122. PVector centralizeAvgPos = new PVector();
  123. PVector friendAlignAvgSpd = new PVector();
  124. PVector friendAvoidance = new PVector();
  125. PVector enemyAvoidance = new PVector();
  126. PVector foodAvgPos = new PVector();
  127.  
  128.  
  129. private float seekFoodWeight = 2;
  130.  
  131. Fish beingEatenBy = null;
  132.  
  133.  
  134. Fish() {
  135. if (player == null) {
  136. pos = new PVector(width * .5f, height * .5f);
  137. radius = 15;
  138. } else {
  139. pos = randomPositionOffscreenInFrontOfPlayer();
  140. radius = random(maxFishSize);
  141. }
  142. }
  143.  
  144. void updateAndDraw() {
  145. if (beingEatenBy != null) {
  146. beingEatenBy.radius *= 1.05f;
  147. beingEatenBy.radius = constrain(beingEatenBy.radius, 0, maxFishSize);
  148. this.toRemove = true;
  149. return;
  150. }
  151.  
  152. acc.mult(0);
  153. centralizeAvgPos.mult(0);
  154. friendAlignAvgSpd.mult(0);
  155. friendAvoidance.mult(0);
  156. enemyAvoidance.mult(0);
  157. foodAvgPos.mult(0);
  158. int alignToFriendsFlockCount = 0;
  159. int centralizeFriendCount = 0;
  160. int foodCount = 0;
  161.  
  162. float safeDistanceFromFriend = radius*2;
  163. float foodRecognitionRadius = radius*6;
  164. float safeDistanceFromEnemy = radius*8;
  165.  
  166. for (Fish f : fish) {
  167. if (this.equals(f)) {
  168. continue;
  169. }
  170. float d = dist(f.pos.x, f.pos.y, pos.x, pos.y);
  171. if (isFriend(f) && d < alignRadius) {
  172. friendAlignAvgSpd.add(f.spd);
  173. alignToFriendsFlockCount++;
  174. }
  175. if (isFriend(f) && d < safeDistanceFromFriend) {
  176. friendAvoidance.add(PVector.sub(pos, f.pos).normalize());
  177. } else if (isEnemy(f) && d < safeDistanceFromEnemy) {
  178. enemyAvoidance.add(PVector.sub(pos, f.pos).normalize());
  179. }
  180. if (isFood(f) && d < foodRecognitionRadius) {
  181. foodAvgPos.add(f.pos);
  182. foodCount++;
  183. if (d < radius) {
  184. f.beingEatenBy = this;
  185. }
  186. }
  187. if (isFriend(f) && d < centralizeRadius) {
  188. centralizeAvgPos.add(f.pos);
  189. centralizeFriendCount++;
  190. }
  191. }
  192. if (centralizeFriendCount > 0) {
  193. centralizeAvgPos.div(centralizeFriendCount);
  194. }
  195. if (alignToFriendsFlockCount > 0) {
  196. friendAlignAvgSpd.div(alignToFriendsFlockCount);
  197. }
  198.  
  199. acc.add(friendAvoidance);
  200. // acc.add(enemyAvoidance);
  201. // acc.add(PVector.sub(foodAvgPos, pos).normalize().mult(seekFoodWeight));
  202. acc.add(PVector.sub(centralizeAvgPos, pos).normalize().mult(centralizeWeight));
  203. acc.add(friendAlignAvgSpd.normalize().mult(alignWeight));
  204.  
  205. spd.add(acc);
  206. spd.limit(spdLimit);
  207. spd.mult(.9f);
  208. pos.add(spd);
  209.  
  210. pushMatrix();
  211. translate(pos.x, pos.y);
  212. rotate(spd.heading());
  213. float distanceToPlayer = dist(pos.x, pos.y, player.pos.x, player.pos.y);
  214. if (distanceToPlayer > farAway && isBehindPlayer(pos)) {
  215. this.toRemove = true;
  216. }
  217.  
  218. beginShape(TRIANGLE_STRIP);
  219. int vertexCount = 12;
  220. for (float i = -vertexCount * .25f; i < vertexCount; i++) {
  221. boolean tail = i < 0;
  222. float iN = map(i, 0, vertexCount - 1, 0, 1);
  223. float x = map(iN, 0, 1, -radius * 2, radius);
  224. float y0 = radius * .5f * sin(iN * 3.f) + radius*.1f*sin(iN*2-t*25)*(tail?2:1);
  225. float y1 = -radius * .5f * sin(iN * 3.f) + radius*.1f*sin(iN*2-t*25)*(tail?2:1);
  226. vertex(x, y0);
  227. vertex(x, y1);
  228. }
  229. endShape();
  230. popMatrix();
  231. }
  232.  
  233. private boolean isFood(Fish f) {
  234. return false;
  235. // return f.radius < radius*.5f;
  236. }
  237.  
  238. private boolean isFriend(Fish f) {
  239. return true;
  240. //abs(f.radius-radius)<=5;
  241. }
  242.  
  243. private boolean isEnemy(Fish f) {
  244. return false;
  245. // return f.radius - 5 > radius;
  246. }
  247.  
  248. private boolean isBehindPlayer(PVector pos) {
  249. float angleToPlayer = atan2(player.pos.y - pos.y, player.pos.x - pos.x);
  250. float normalizedAngleToPlayer = normalizeAngle(angleToPlayer, PI);
  251. float normalizedPlayerHeading = normalizeAngle(player.spd.heading(), PI);
  252. float angleToPlayerVsHeading = normalizeAngle(normalizedAngleToPlayer - normalizedPlayerHeading, 0);
  253. return abs(angleToPlayerVsHeading) < HALF_PI;
  254. }
  255.  
  256. private PVector randomPositionOffscreenInFrontOfPlayer() {
  257. float angle = random(player.spd.heading() - HALF_PI, player.spd.heading() + HALF_PI);
  258. float distance = random(centerToCornerDistance, farAway);
  259. return new PVector(player.pos.x + distance * cos(angle), player.pos.y + distance * sin(angle));
  260. }
  261.  
  262. public float normalizeAngle(float a, float center) {
  263. return a - TWO_PI * floor((a + PI - center) / TWO_PI);
  264. }
  265.  
  266. boolean isPointInRect(float px, float py, float rx, float ry, float rw, float rh) {
  267. return px >= rx && px <= rx + rw && py >= ry && py <= ry + rh;
  268. }
  269.  
  270. boolean isPointInRectCenterMode(float px, float py, float rx, float ry, float rw, float rh) {
  271. return px >= rx - rw * .5f && px <= rx + rw * .5f && py >= ry - rh * .5f && py <= ry + rh * .5f;
  272. }
  273.  
  274. class Slider {
  275. String name;
  276. float value;
  277. float min;
  278. float max;
  279. float defaultValue;
  280. int lastInteractedWith = -1;
  281. }
  282. }
  283.  
  284. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement