Advertisement
Guest User

Untitled

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