Guest User

Untitled

a guest
Feb 25th, 2018
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.50 KB | None | 0 0
  1. #!/usr/bin/env node
  2.  
  3. const MIN_DROP_LENGTH = 12;
  4. const MAX_DROP_LENGTH = 25;
  5.  
  6. const CHAR_MIN_RANGE = 0x21;
  7. const CHAR_MAX_RANGE = 0x7E;
  8.  
  9. const DROP_MIN_SPEED = 80;
  10. const DROP_MAX_SPEED = 20;
  11. const DROP_SPAWN_INTERVAL = 40;
  12.  
  13. const colors = [46, 40, 34, 28, 22, 16].map(index => `\x1b[38;5;${index}m`);
  14. const terminal = {
  15. clear: () => write('\033[2J'),
  16. hide: () => write('\x1b[?25l'),
  17. moveTo: (x, y) => write(`\x1b[${y + 1};${x + 1}H`)
  18. }
  19.  
  20. function write(data) {
  21. process.stdout.write(data);
  22. }
  23.  
  24. function random(min, max) {
  25. return min + Math.floor((max - min) * Math.random());
  26. }
  27.  
  28. class Drop {
  29. constructor() {
  30. this.length = random(Math.min(MIN_DROP_LENGTH, process.stdout.rows), Math.min(MAX_DROP_LENGTH, process.stdout.rows));
  31. this.speed = random(DROP_MAX_SPEED, DROP_MIN_SPEED);
  32. this.chars = new Array(process.stdout.rows).fill(0).map(() => String.fromCharCode(random(CHAR_MIN_RANGE, CHAR_MAX_RANGE)));
  33. this.head = new Head();
  34. }
  35.  
  36. update() {
  37. this.draw();
  38. this.head.slide();
  39.  
  40. if(this.head.y - this.length === process.stdout.rows) {
  41. this.clean();
  42. }
  43. }
  44.  
  45. draw() {
  46. for(let y = Math.max(0, this.head.y - process.stdout.rows); y < Math.min(this.length, this.length + (this.head.y - this.length)); y++) {
  47. terminal.moveTo(this.head.x, this.head.y - y - 1);
  48. write(colors[Math.floor(y * colors.length / this.length)]);
  49. write(this.chars[this.head.y - y - 1]);
  50. }
  51. if(this.head.y - this.length >= 0) {
  52. terminal.moveTo(this.head.x, this.head.y - this.length);
  53. write(' ');
  54. }
  55. }
  56.  
  57. clean() {
  58. removeDrop(this);
  59. }
  60. }
  61.  
  62. class Head {
  63. constructor() {
  64. this.x = random(0, process.stdout.columns);
  65. this.y = 0;
  66. }
  67.  
  68. slide() {
  69. this.y += 1;
  70. }
  71. }
  72.  
  73. terminal.clear();
  74. terminal.hide();
  75.  
  76. const drops = [];
  77. const speedIntervals = [];
  78.  
  79. function addDrop() {
  80. const drop = new Drop();
  81.  
  82. if(!drops[drop.speed]) drops[drop.speed] = [];
  83. drops[drop.speed].push(drop);
  84.  
  85. if(!speedIntervals[drop.speed]) {
  86. speedIntervals[drop.speed] = setInterval(() => {
  87. drops[drop.speed].forEach(drop => drop.update());
  88. }, drop.speed);
  89. }
  90. }
  91.  
  92. function removeDrop(drop) {
  93. drops[drop.speed].splice(drops[drop.speed].indexOf(drop), 1);
  94. if(!drops[drop.speed].length) {
  95. clearInterval(speedIntervals[drop.speed]);
  96. speedIntervals[drop.speed] = null;
  97. }
  98. }
  99.  
  100. setInterval(addDrop, DROP_SPAWN_INTERVAL);
Add Comment
Please, Sign In to add comment