Advertisement
Guest User

Untitled

a guest
Dec 29th, 2015
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.61 KB | None | 0 0
  1. ### Ben Scott # 2015-10-12 # Mania ###
  2.  
  3. 'use strict' # just like JavaScript
  4.  
  5. ### `P5.js` Main class
  6.  
  7. This is our instance of the main class in the `P5.js` library.
  8. The argument is the link between the library and this code, and
  9. the special functions we override in the class definition are
  10. callbacks for P5.js events.
  11. ###
  12. myp = new p5 (p) ->
  13.  
  14. ### Input ###
  15. mouse = [p.mouseX,p.mouseY]
  16. lastMouse = [p.pmouseX,p.pmouseY]
  17.  
  18. ### Library ###
  19. rand = p.random
  20.  
  21. ### DOM ###
  22. [container,canvas] = [null,null]
  23.  
  24. ### Assets ###
  25. [bg_img,dope_img] = [null,null]
  26.  
  27. ### Mania ###
  28. manic = false
  29. [max_v,max_f,dope_rate] = [3,0.05,60]
  30. [receptors,transmitters] = [[],[]]
  31.  
  32.  
  33. ### `Neurotransmitter`
  34.  
  35. This class represents a generic neurotransmitter, which
  36. the dopamine and amphetamine classes extend.
  37. - `@a` **real** : acceleration (m^2/ms)
  38. - `@v` **real** : velocity (m/ms)
  39. - `@m` **int** : mass (kg)
  40. - `@t` **real** : lifetime (ms)
  41. - `@pos` \<**real**,**real**\> : current position
  42. - `@tgt` \<**real**,**real**\> : target position
  43. ###
  44. class Neurotransmitter
  45.  
  46. constructor: (@pos,@tgt,@m=1,@t=1024) ->
  47. @a = p.createVector(0,0)
  48. @v = p.createVector(rand(-1,1), rand(-1,1))
  49. @tgt = p.createVector(p.width/2,p.height/2)
  50. unless (@pos?)
  51. @pos = p.createVector(
  52. p.width/2+p.random(-50,50),-10)
  53. @v.y = p.random(1,2)
  54.  
  55. run: (group) ->
  56. @flock(group)
  57. @update()
  58. @bounds()
  59. @draw()
  60.  
  61. applyForce: (list...) ->
  62. @a.add(force)/@m for force in list
  63.  
  64. flock: (group) ->
  65. @applyForce(
  66. @separate(group).mult(1.5)
  67. @align(group).mult(1)
  68. @cohesion(group).mult(1))
  69.  
  70. seek: (tgt) ->
  71. @tgt = tgt
  72. len = p5.Vector.sub(tgt,@pos)
  73. len.normalize()
  74. len.mult(max_v)
  75. dir = p5.Vector.sub(len,@v)
  76. dir.limit(0.05)
  77. return dir
  78.  
  79. bounds: ->
  80. return if (-10<@pos.x<p.width+10)
  81. unless (-10<@pos.y<p.height+10)
  82. transmitters.remove(this)
  83. delete this
  84.  
  85. update: ->
  86. @v.add(@a)
  87. @v.limit(max_v)
  88. @pos.add(@v)
  89. @a = p.createVector(0,0)
  90.  
  91. draw: ->
  92. p.push()
  93. polygon(@pos.x,@pos.y,5,6)
  94. p.pop()
  95.  
  96. ### `Dopamine`
  97.  
  98. This is a class which represents the neurotransmitter
  99. Dopamine, which is responsible for pleasure and euphoria.
  100. - `@a` **real** : acceleration (m^2/ms)
  101. - `@v` **real** : velocity (m/ms)
  102. - `@m` **int** : mass (kg)
  103. - `@t` **real** : lifetime (ms)
  104. - `@r` **int** : radius (pixel)
  105. - `@pos` \<**real**,**real**\> : current position
  106. - `@tgt` \<**real**,**real**\> : target position
  107. - `@max_v` **real** : maximum speed
  108. - `@max_f` **real** : maximum force
  109. ###
  110. class Dopamine extends Neurotransmitter
  111.  
  112. flock: (group) ->
  113. super
  114. final_steer = @seek(
  115. p.createVector(p.width/2,p.height*2))
  116. final_steer.mult(0.5)
  117. @applyForce(final_steer)
  118.  
  119. draw: ->
  120. p.push()
  121. value = p.map(value,0,255,60,120)
  122. p.fill(value,180,180)
  123. p.stroke(180)
  124. p.strokeWeight(2)
  125. if (manic && @pos.y>p.height/3)
  126. p.translate(rand(3),rand(3))
  127. p.line(@pos.x,@pos.y,@pos.x-8,@pos.y-4)
  128. p.line(@pos.x,@pos.y,@pos.x-8,@pos.y+4)
  129. p.line(@pos.x,@pos.y,@pos.x+8,@pos.y-4)
  130. p.line(@pos.x+8,@pos.y-4,@pos.x+12,@pos.y-2)
  131. polygon(@pos.x,@pos.y,5,6)
  132. p.pop()
  133.  
  134. separate: (group) ->
  135. [tgt,n] = [20,0]
  136. dir = p.createVector(0,0)
  137. for elem in group
  138. d = p5.Vector.dist(@pos,elem.pos)
  139. if (0<d<tgt)
  140. diff = p5.Vector.sub(@pos,elem.pos)
  141. diff.normalize()
  142. diff.div(d)
  143. dir.add(diff)
  144. n++
  145. dir.div(n) if (n>0)
  146. if (0<dir.mag())
  147. dir.normalize()
  148. dir.mult(max_v)
  149. dir.sub(@v)
  150. dir.limit(0.05)
  151. return dir
  152.  
  153. align: (group) ->
  154. [len,n] = [50.0,0]
  155. sum = p.createVector(0,0)
  156. for elem in group
  157. d = p5.Vector.dist(@pos,elem.pos)
  158. if (0<d<len)
  159. sum.add(elem.v)
  160. n++
  161. if (n>0)
  162. sum.div(n)
  163. sum.normalize()
  164. sum.mult(max_v)
  165. dir = p5.Vector.sub(sum,@v)
  166. dir.limit(0.05)
  167. return dir
  168. else return p.createVector(0,0)
  169.  
  170. cohesion: (group) ->
  171. [len,n] = [50,0]
  172. dir = p.createVector(0,0)
  173. for elem in group
  174. d = p5.Vector.dist(@pos,elem.pos)
  175. if (0<d<=len)
  176. dir.add(elem.pos)
  177. n++
  178. if (n>0)
  179. dir.div(n)
  180. return @seek(dir)
  181. else return p.createVector(0,0)
  182.  
  183. ### `Cocaine`
  184.  
  185. This is a class which represents Cocaine, a dopamine
  186. reuptake inhibitor (obviously this is what it's known for)
  187. - `@a` **real** : acceleration (m^2/ms)
  188. - `@v` **real** : velocity (m/ms)
  189. - `@m` **int** : mass (kg)
  190. - `@t` **real** : lifetime (ms)
  191. - `@pos` \<**real**,**real**\> : current position
  192. - `@tgt` \<**real**,**real**\> : target position
  193. - `@n_tgt` \<**real**,**real**\> : clearing behaviour
  194. ###
  195. class Cocaine extends Dopamine
  196. @n_tgt = null
  197.  
  198. constructor: ->
  199. super
  200. @t = 512+p.random(-128,128)
  201. @mass = 3
  202. @pos = p.createVector(p.mouseX,p.mouseY)
  203. @n_tgt = p.createVector(
  204. p.width/2+rand(-128,128)
  205. p.height/2+rand(-50,50))
  206.  
  207. update: ->
  208. super
  209. @t--
  210. if (@t<0)
  211. @applyForce(@seek(p.createVector(
  212. p.width*2, rand(-30,30))).mult(3))
  213.  
  214. draw: ->
  215. p.push()
  216. p.fill(255)
  217. p.stroke(200)
  218. p.line(@pos.x,@pos.y,@pos.x,@pos.y-8)
  219. p.line(@pos.x,@pos.y-8,@pos.x+2,@pos.y-12)
  220. p.line(@pos.x,@pos.y,@pos.x+8,@pos.y+4)
  221. p.line(@pos.x+8,@pos.y+4,@pos.x+12,@pos.y+6)
  222. polygon(@pos.x-4,@pos.y,5,6,30)
  223. polygon(@pos.x+4,@pos.y,5,6,30)
  224. p.pop()
  225.  
  226. flock: (group) ->
  227. @applyForce(
  228. @separate(group)
  229. @seek(@n_tgt))
  230.  
  231. separate: (group) ->
  232. [tgt,n] = [20,0]
  233. dir = p.createVector(0,0)
  234. for elem in group
  235. d = p5.Vector.dist(@pos,elem.pos)
  236. if (0<d<tgt)
  237. diff = p5.Vector.sub(elem.pos,@pos)
  238. diff.normalize()
  239. diff.div(d)
  240. dir.add(diff)
  241. n++
  242. unless (elem instanceof Cocaine)
  243. elem.applyForce(diff.normalize())
  244. else elem.applyForce(
  245. p.createVector())
  246. dir.div(n) if (n>0)
  247. if (0<dir.mag())
  248. dir.normalize()
  249. dir.mult(-1)
  250. dir.sub(@v)
  251. dir.limit(0.5)
  252. return dir
  253.  
  254. ### `Amphetamine`
  255.  
  256. The same neuron! Now with amphetamines! Amphetamines act
  257. as a releasing agent for dopamine, and are much easier
  258. to animate!
  259. - `@a` **real** : acceleration (m^2/ms)
  260. - `@v` **real** : velocity (m/ms)
  261. - `@m` **int** : mass (kg)
  262. - `@t` **real** : lifetime (ms)
  263. - `@pos` \<**real**,**real**\> : current position
  264. - `@tgt` \<**real**,**real**\> : target position
  265. - `@n_tgt` \<**real**,**real**\> : clearing behaviour
  266. ###
  267. class Amphetamine extends Dopamine
  268. @n_tgt = null
  269.  
  270. constructor: (@pos,@tgt,@m=1,@t=1024) ->
  271. super
  272. @pos = p.createVector(p.mouseX,p.mouseY)
  273. @n_tgt = p.createVector(
  274. p.width/2-128+rand(-2,2)
  275. p.height/2-100+rand(-2,2))
  276. if (p.width/3<@pos.x)
  277. @n_tgt = p.createVector(
  278. p.width/2+128+rand(-2,2)
  279. p.height/2-100+rand(-2,2))
  280.  
  281. update: ->
  282. super
  283. @t--
  284. if (@t<0)
  285. if (rand(2)>1)
  286. @applyForce(@seek(p.createVector(
  287. p.width*2, rand(-30,30))).mult(3))
  288. else @applyForce(@seek(p.createVector(
  289. p.width/2,-p.height).mult(3)))
  290.  
  291. draw: ->
  292. p.push()
  293. p.fill(255,180,180)
  294. p.stroke(180)
  295. p.strokeWeight(2)
  296. p.line(@pos.x,@pos.y,@pos.x+8,@pos.y-4)
  297. p.line(@pos.x+8,@pos.y-4,@pos.x+12,@pos.y-2)
  298. polygon(@pos.x,@pos.y,5,6)
  299. p.pop()
  300.  
  301. flock: (group) ->
  302. super
  303. @applyForce(@seek(@n_tgt))
  304.  
  305. separate: (group) ->
  306. [tgt,n] = [20,0]
  307. dir = p.createVector(0,0)
  308. for elem in group
  309. d = p5.Vector.dist(@pos,elem.pos)
  310. if (0<d<tgt)
  311. diff = p5.Vector.sub(elem.pos,@pos)
  312. diff.normalize()
  313. diff.div(d)
  314. dir.add(diff)
  315. unless (elem instanceof Cocaine)
  316. elem.applyForce(diff.normalize())
  317. n++
  318. dir.div(n) if (n>0)
  319. if (0<dir.mag())
  320. dir.normalize()
  321. dir.mult(3)
  322. dir.sub(@v)
  323. dir.limit(0.1)
  324. return dir
  325.  
  326. align: (group) -> return p.createVector(0,0)
  327.  
  328. cohesion: (group) -> return p.createVector(0,0)
  329.  
  330. ### `Events`
  331.  
  332. These functions are automatic callbacks for `P5.js` events:
  333. - `p.preload` is called once, immediately before `setup`
  334. - `p.setup` is called once, at the beginning of execution
  335. - `p.draw` is called as frequently as `p.framerate`
  336. - `p.keyPressed` is called on every key input event
  337. - `p.mousePressed` is called on mouse down
  338. - `p.windowResized` keeps window full
  339. - `p.remove` destroys everything in the sketch
  340. ###
  341. p.preload = ->
  342. bg_img = p.loadImage("/rsc/sketch/synapse.png")
  343.  
  344. p.setup = ->
  345. setupDOM()
  346. p.noStroke()
  347. p.frameRate(60)
  348.  
  349. p.draw = ->
  350. drawDOM()
  351. getInput()
  352. manic = (dope_rate<60)
  353. drawReceptors()
  354. dope_rate++ if (dope_rate<60 && p.frameCount%60==0)
  355. if (p.frameCount%dope_rate==0 && transmitters.length<100)
  356. n = if (dope_rate<55) then 20 else 5
  357. for i in [0..rand(2,n)]
  358. transmitters.push(new Dopamine())
  359. for dope in transmitters
  360. dope?.run(transmitters)
  361.  
  362. p.keyPressed = ->
  363. alt = !alt if (p.keyCode is p.ALT)
  364.  
  365. p.mouseDragged = ->
  366. mouse = [p.mouseX,p.mouseY]
  367. lastMouse = [p.pmouseX,p.pmouseY]
  368.  
  369. p.mousePressed = ->
  370. if (p.width/3<p.mouseX<2*p.width/3)
  371. if (p.height/3<p.mouseY<2*p.height/3)
  372. transmitters.unshift(new Cocaine())
  373. else transmitters.unshift(new Amphetamine())
  374. dope_rate-- if (dope_rate>30)
  375.  
  376. #p.windowResized = ->
  377. # p.resizeCanvas(p.windowWidth, p.windowHeight);
  378.  
  379. #p.remove = -> p5 = null
  380.  
  381. ### Library Functions
  382.  
  383. These functions I've included from other files. They're the
  384. sort of generic utilities that would constitute a library.
  385.  
  386. - 'Array::Remove' takes an element out of a standard array
  387. - `@e`: element to remove
  388. - `polygon` draws a regular polygon.
  389. - `@x,@y` \<**int**,**int**\> : center
  390. - `@r` **int** : radius
  391. - `@n` **int** : number of points
  392. - `@o` **real** : offset theta
  393. ###
  394. Array::remove = (e) ->
  395. @[t..t] = [] if (t=@indexOf(e))>-1
  396.  
  397. polygon = (x,y,r=1,n=3,o=0) ->
  398. theta = p.TWO_PI/n
  399. p.beginShape()
  400. for i in [0..p.TWO_PI] by theta
  401. p.vertex(
  402. x+p.cos(i+o)*r
  403. y+p.sin(i+o)*r)
  404. p.endShape(p.CLOSE)
  405.  
  406. ### DOM Functions
  407.  
  408. These functions initialize and position the DOM objects
  409. and the main canvas.
  410. - `setupDOM`: creates DOM objects & canvas
  411. - `drawDOM`: draws all DOM objects to the canvas
  412. - `getInput`: collects input data, processes it, and in
  413. the case of `p.mouseIsPressed`, it calls the mouse
  414. event callback (otherwise it single-clicks)
  415. ###
  416. setupDOM = ->
  417. canvas = p.createCanvas(756,512)
  418. canvas.parent('CoffeeSketch')
  419. canvas.class("entry")
  420. canvas.style("max-width", "100%")
  421.  
  422. drawDOM = ->
  423. p.clear()
  424. p.background(bg_img)
  425.  
  426. getInput = ->
  427. mouse = [p.mouseX,p.mouseY]
  428. lastMouse = [p.pmouseX,p.pmouseY]
  429.  
  430. ### Mania Functions
  431.  
  432. These functions draw the stars, the planets, and carry out
  433. the logic of the game / sketch.
  434. - `drawReceptors`: draws the reuptake receptors on the axon
  435. ###
  436. drawReceptors = ->
  437. p.push()
  438. p.translate(p.width/2-128,p.height/2-100)
  439. p.rotate(60)
  440. p.ellipse(0,0,30,40)
  441. p.fill(240)
  442. p.ellipse(10,0,10,30)
  443. p.ellipse(-10,0,10,30)
  444. p.pop()
  445. p.push()
  446. p.translate(p.width/2+128,p.height/2-100)
  447. p.rotate(-60)
  448. p.ellipse(0,0,30,40)
  449. p.fill(240)
  450. p.ellipse(10,0,10,30)
  451. p.ellipse(-10,0,10,30)
  452. p.pop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement