ersatzben

TOMBOLA SEQUENCER FOR JSUI v2

Oct 25th, 2024
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.42 KB | None | 0 0
  1. autowatch = 1;
  2. outlets = 3;
  3. mgraphics.init();
  4. mgraphics.relative_coords = 1;
  5. mgraphics.autofill = 0;
  6.  
  7. var window_width = box.rect[2] - box.rect[0];
  8. var window_height = box.rect[3] - box.rect[1];
  9.  
  10. var config = {
  11. sides: 8,
  12. numBalls: 12,
  13. gravity: 0.4,
  14. spinspeed: -0.4,
  15. cooldownTime: 300,
  16. damping: 0.05,
  17. ballSize: 0.01,
  18. shapeSize: 0.9
  19. };
  20.  
  21. var rotationAngle = 0;
  22. var refreshRate = 60;
  23.  
  24. var balls = [];
  25. var edgeHitTimes = [];
  26. for (var i = 0; i < config.sides; i++) {
  27. edgeHitTimes.push(0);
  28. }
  29. var vertices = [];
  30.  
  31. // New: Collision report cooldown
  32. var collisionCooldowns = {};
  33.  
  34. function createBall() {
  35. var r = Math.random() * 0.3;
  36. var angle = Math.random() * 2 * Math.PI;
  37. return {
  38. position: [r * Math.cos(angle), r * Math.sin(angle)],
  39. velocity: [Math.random() * 0.006 - 0.003, Math.random() * 0.006 - 0.003],
  40. radius: config.ballSize,
  41. color: [Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, 1]
  42. };
  43. }
  44.  
  45. for (var i = 0; i < config.numBalls; i++) {
  46. balls.push(createBall());
  47. }
  48.  
  49. var rotateTask = new Task(updateScene, this);
  50. rotateTask.interval = 1000 / refreshRate;
  51. rotateTask.repeat();
  52.  
  53. function paint() {
  54. with (mgraphics) {
  55. set_source_rgba(0.2, 0.2, 0.2, 1);
  56. paint();
  57. drawShapeOutline();
  58. drawBalls();
  59. }
  60. }
  61.  
  62. function hslToRgb(h, s, l) {
  63. var r, g, b;
  64.  
  65. if (s == 0) {
  66. r = g = b = l;
  67. } else {
  68. function hue2rgb(p, q, t) {
  69. if (t < 0) t += 1;
  70. if (t > 1) t -= 1;
  71. if (t < 1/6) return p + (q - p) * 6 * t;
  72. if (t < 1/2) return q;
  73. if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
  74. return p;
  75. }
  76.  
  77. var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
  78. var p = 2 * l - q;
  79. r = hue2rgb(p, q, h + 1/3);
  80. g = hue2rgb(p, q, h);
  81. b = hue2rgb(p, q, h - 1/3);
  82. }
  83.  
  84. return [r, g, b];
  85. }
  86.  
  87. function drawShapeOutline() {
  88. var angleStep = (2 * Math.PI) / config.sides;
  89. var radius = config.shapeSize;
  90. var cosA = Math.cos(rotationAngle);
  91. var sinA = Math.sin(rotationAngle);
  92.  
  93. vertices = [];
  94. for (var i = 0; i < config.sides; i++) {
  95. var angle = i * angleStep;
  96. var x = radius * Math.cos(angle);
  97. var y = radius * Math.sin(angle);
  98. vertices.push([x * cosA - y * sinA, x * sinA + y * cosA]);
  99. }
  100.  
  101. for (var i = 0; i < config.sides; i++) {
  102. var p1 = vertices[i];
  103. var p2 = vertices[(i + 1) % config.sides];
  104.  
  105. if (!p1 || !p2) {
  106. post("Error: Undefined vertex at index " + i + "\n");
  107. continue;
  108. }
  109.  
  110. var timeSinceHit = Date.now() - edgeHitTimes[i];
  111. var hitIntensity = Math.max(0, 1 - timeSinceHit / 500);
  112.  
  113. // Calculate flash color using HSL
  114. var hue = i / config.sides;
  115. var flashColor = hslToRgb(0.75-hue*0.75, 0.8, 0.6);
  116.  
  117. // Interpolate between grey (0.8) and flash color based on hit intensity
  118. var r = 0.8 * (1 - hitIntensity) + flashColor[0] * hitIntensity;
  119. var g = 0.8 * (1 - hitIntensity) + flashColor[1] * hitIntensity;
  120. var b = 0.8 * (1 - hitIntensity) + flashColor[2] * hitIntensity;
  121.  
  122. mgraphics.set_source_rgba(r, g, b, 1);
  123.  
  124. var lineWidth = 0.005 + 0.05 * hitIntensity;
  125. mgraphics.set_line_width(lineWidth);
  126.  
  127. mgraphics.move_to(p1[0], p1[1]);
  128. mgraphics.line_to(p2[0], p2[1]);
  129. mgraphics.stroke();
  130. }
  131. }
  132.  
  133. function drawBalls() {
  134. for (var i = 0; i < balls.length; i++) {
  135. var ball = balls[i];
  136. mgraphics.set_source_rgba(ball.color[0], ball.color[1], ball.color[2], ball.color[3]);
  137. mgraphics.ellipse(ball.position[0] - ball.radius, ball.position[1] - ball.radius, ball.radius * 2, ball.radius * 2);
  138. mgraphics.fill();
  139. }
  140. }
  141.  
  142. function updateScene() {
  143. rotationAngle = (rotationAngle + (-0.2 * Math.PI * config.spinspeed) / refreshRate) % (2 * Math.PI);
  144.  
  145. for (var i = 0; i < balls.length; i++) {
  146. var ball = balls[i];
  147. ball.velocity[1] += config.gravity * -0.0001;
  148. ball.position[0] += ball.velocity[0];
  149. ball.position[1] += ball.velocity[1];
  150.  
  151. checkEdgeCollisions(ball, i);
  152.  
  153. if (Math.abs(ball.position[0]) > 1 || Math.abs(ball.position[1]) > 1) {
  154. ball.position = [0, 0];
  155. ball.velocity = [Math.random() * 0.006 - 0.003, Math.random() * 0.006 - 0.003];
  156. // post("Ball " + i + " escaped - resetting to center\n");
  157. }
  158. }
  159.  
  160. mgraphics.redraw();
  161. }
  162.  
  163. function checkEdgeCollisions(ball, ballIndex) {
  164. if (vertices.length !== config.sides) {
  165. // post("Error: Mismatch between config.sides and vertices.length\n");
  166. return;
  167. }
  168.  
  169. for (var i = 0; i < config.sides; i++) {
  170. var p1 = vertices[i];
  171. var p2 = vertices[(i + 1) % config.sides];
  172.  
  173. if (!p1 || !p2) {
  174. post("Error: Undefined vertex at index " + i + " or " + ((i + 1) % config.sides) + "\n");
  175. continue;
  176. }
  177.  
  178. var edge = [p2[0] - p1[0], p2[1] - p1[1]];
  179. var edgeLength = Math.sqrt(edge[0] * edge[0] + edge[1] * edge[1]);
  180. var edgeUnit = [edge[0] / edgeLength, edge[1] / edgeLength];
  181. var normal = [-edgeUnit[1], edgeUnit[0]];
  182.  
  183. var relativePosition = [ball.position[0] - p1[0], ball.position[1] - p1[1]];
  184. var distanceToEdge = Math.abs(relativePosition[0] * normal[0] + relativePosition[1] * normal[1]);
  185.  
  186. if (distanceToEdge < ball.radius) {
  187. var dotProduct = relativePosition[0] * edgeUnit[0] + relativePosition[1] * edgeUnit[1];
  188. if (dotProduct >= 0 && dotProduct <= edgeLength) {
  189. edgeHitTimes[i] = Date.now();
  190.  
  191. // Check cooldown before reporting collision
  192. var cooldownKey = ballIndex + "-" + i;
  193. var currentTime = Date.now();
  194. if (!collisionCooldowns[cooldownKey] || currentTime - collisionCooldowns[cooldownKey] > config.cooldownTime) {
  195. // post("Ball " + ballIndex + " hit edge between vertices " + i + " and " + ((i + 1) % config.sides) + "\n");
  196. outlet(0, ballIndex);
  197. outlet(1, i);
  198. outlet(2, ball.position[0]);
  199. collisionCooldowns[cooldownKey] = currentTime;
  200. }
  201.  
  202. var velocityDotNormal = ball.velocity[0] * normal[0] + ball.velocity[1] * normal[1];
  203. ball.velocity[0] -= 2 * velocityDotNormal * normal[0];
  204. ball.velocity[1] -= 2 * velocityDotNormal * normal[1];
  205.  
  206. var penetrationDepth = ball.radius - distanceToEdge;
  207. ball.position[0] += normal[0] * penetrationDepth;
  208. ball.position[1] += normal[1] * penetrationDepth;
  209.  
  210. if (Math.random() < 0.025) {
  211. var boostFactor = 1.1 + Math.random() * 0.2;
  212. ball.velocity[0] *= boostFactor;
  213. ball.velocity[1] *= boostFactor;
  214. } else {
  215. ball.velocity[0] *= (1 - 0.2*config.damping);
  216. ball.velocity[1] *= (1 - 0.2*config.damping);
  217. }
  218. }
  219. }
  220. }
  221. }
  222.  
  223. function anything() {
  224. var a = arrayfromargs(messagename, arguments);
  225.  
  226. if (a.length < 2) {
  227. post("Error: Not enough arguments for parameter adjustment\n");
  228. return;
  229. }
  230.  
  231. var param = a[0];
  232. var value = parseFloat(a[1]);
  233.  
  234. // Helper function to check if a number is an integer
  235. function isInteger(n) {
  236. return Math.floor(n) === n;
  237. }
  238.  
  239. switch(param) {
  240. case "sides":
  241. if (isInteger(value) && value >= 3) {
  242. config.sides = value;
  243. // Reset edge hit times array for new number of sides
  244. edgeHitTimes = [];
  245. for (var i = 0; i < config.sides; i++) {
  246. edgeHitTimes.push(0);
  247. }
  248. } else {
  249. post("Error: sides must be an integer >= 3\n");
  250. }
  251. break;
  252.  
  253. case "numBalls":
  254. if (isInteger(value) && value > 0) {
  255. config.numBalls = value;
  256. // Adjust number of balls
  257. while (balls.length > value) {
  258. balls.pop();
  259. }
  260. while (balls.length < value) {
  261. balls.push(createBall());
  262. }
  263. } else {
  264. post("Error: numBalls must be a positive integer\n");
  265. }
  266. break;
  267.  
  268. case "gravity":
  269. config.gravity = value;
  270. break;
  271.  
  272. case "ballSize":
  273. config.ballSize = value/100;
  274. bang();
  275. break;
  276.  
  277. case "shapeSize":
  278. config.shapeSize = value;
  279. break;
  280.  
  281. case "spinspeed":
  282. config.spinspeed = value;
  283. break;
  284.  
  285. case "cooldownTime":
  286. config.cooldownTime = value;
  287. break;
  288.  
  289. case "damping":
  290. config.damping = value;
  291. break;
  292.  
  293. case "getconfig":
  294. post("Current configuration:\n");
  295. post("sides: " + config.sides + "\n");
  296. post("numBalls: " + config.numBalls + "\n");
  297. post("gravity: " + config.gravity + "\n");
  298. post("spinspeed: " + config.spinspeed + "\n");
  299. post("cooldownTime: " + config.cooldownTime + "\n");
  300. post("damping: " + config.damping + "\n");
  301. break;
  302.  
  303. default:
  304. post("Unknown parameter: " + param + "\n");
  305. post("Available parameters: sides, numBalls, gravity, spinspeed, getconfig\n");
  306. break;
  307. }
  308.  
  309. // Redraw the scene after any parameter change
  310. mgraphics.redraw();
  311. }
  312.  
  313. function bang() {
  314. balls = [];
  315.  
  316. for (var i = 0; i < config.numBalls; i++) {
  317. balls.push(createBall());
  318. }
  319.  
  320. collisionCooldowns = {};
  321.  
  322. edgeHitTimes = [];
  323. for (var i = 0; i < config.sides; i++) {
  324. edgeHitTimes.push(0);
  325. }
  326.  
  327. mgraphics.redraw();
  328. }
  329.  
  330. function forcesize(w,h) {
  331. if (w != h) {
  332. w = h;
  333. box.size(w,h);
  334. }
  335. }
  336. forcesize.local = 1;
  337.  
  338. function onresize(w,h) {
  339. forcesize(w,h);
  340. window_width = box.rect[2] - box.rect[0];
  341. window_height = box.rect[3] - box.rect[1];
  342. mgraphics.redraw();
  343. }
  344. onresize.local = 1;
Advertisement
Add Comment
Please, Sign In to add comment