Masterchoc

Untitled

Dec 21st, 2017
564
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Maths      = require './core/Maths'
  2. IKinematic = require './core/IKinematic'
  3. Vec2       = require './core/Vec2'
  4. Color      = require './core/Color'
  5. Bullet     = require './bullet'
  6.  
  7. class Agent
  8.     constructor: (x = 0, y = 0, dna) ->
  9.         @acceleration    = new Vec2()
  10.         @velocity        = new Vec2 Maths.randRange(-3, 3), Maths.randRange(-3, 3)
  11.         @angle           = @velocity.getAngle() + Math.PI * 0.5
  12.         @position        = new Vec2 x, y
  13.         @radius          = 8
  14.         @maxSpeed        = 3
  15.         @maxForce        = 0.2
  16.         @health          = 1
  17.         @maxHealth       = 1
  18.         @tail            = null
  19.         @tailPhase       = 0
  20.         @tailSegments    = 16+
  21.         @tailSegLength   = 6
  22.         @team            = null
  23.         @color           = new Color 0, 0, 220, 1
  24.         @bullets         = []
  25.         @targetNutrition = null
  26.         @targetEnemy     = null
  27.         @shooting        = false
  28.         @aiming          = false
  29.         @seeking         = false
  30.  
  31.         @maxShootDistance = 200
  32.         @closestTargetEnemy = Infinity
  33.         @closestTargetNutrition = Infinity
  34.  
  35.         if dna instanceof Array
  36.             @dna = []
  37.             for i in [0 .. dna.length]
  38.                 if Math.random() < 0.1
  39.                     if i < 3
  40.                         @dna[i] = dna[i] + Maths.randRange -0.2, 0.2
  41.                     else if i == 3
  42.                         v =  dna[i] + Maths.randRange -10, 10
  43.                         rSq = @radius * @radius
  44.                         v = rSq if v < rSq
  45.                         @dna[i] = v
  46.                     else if i == 4
  47.                         min = Math.PI / 16
  48.                         max = Math.PI / 2
  49.                         v =  dna[i] + Maths.randRange min, max
  50.                         v = min if v < min
  51.                         @dna[i] = v
  52.                 else
  53.                     @dna[i] = dna[i]
  54.         else
  55.             max = 3
  56.             # 0: Attraction / repulsion to food
  57.             # 1: Attraction / repulsion to poison
  58.             # 2: Attraction / repulsion to enemy
  59.             # 3: Line of sight radius
  60.             # 4: Line of sight angle
  61.  
  62.             @dna = [
  63.                 Maths.randRange(-max, max),
  64.                 Maths.randRange(-max, max),
  65.                 Maths.randRange(-max, max),
  66.                 Maths.randRange(@radius * @radius, @radius * @radius + @radius * @radius),
  67.                 Maths.randRange(Math.PI / 16, Math.PI / 2)
  68.             ]
  69.         @
  70.  
  71.     isDead : -> @health <= 0
  72.  
  73.     reproduce: ->
  74.         if Math.random() < 0.001
  75.             agent = new Agent @position.x, @position.y, @dna
  76.             agent.team = @team
  77.             agent.color = @color
  78.             agent.createTail()
  79.             return agent
  80.         else
  81.             return null
  82.  
  83.     createTail: ->
  84.         @tail = new IKinematic @position
  85.         @tail.addNode(@tailSegLength, @color) for i in [1 .. @tailSegments]
  86.  
  87.     shoot: (target) ->
  88.         bullet = new Bullet this, @color
  89.         bullet.position.setX @position.x
  90.         bullet.position.setY @position.y
  91.         bullet.velocity.setLength Maths.randRange(4, 8)
  92.         bullet.velocity.setAngle target.position.subtract(@position).getAngle()
  93.         @bullets.push bullet
  94.  
  95.         setTimeout =>
  96.             @aiming = false
  97.         , 1100
  98.  
  99.     attack: (enemies) ->
  100.         @aim enemies
  101.  
  102.     aim: (list) ->
  103.         @targetEnemy = null
  104.         @closestTargetEnemy = Infinity
  105.  
  106.         for enemy, i in list by -1
  107.             dist = enemy.position.distance @position
  108.  
  109.             if dist < @dna[3] and dist < @closestTargetEnemy
  110.                 @closestTargetEnemy = dist
  111.                 @targetEnemy = enemy
  112.  
  113.         if @targetEnemy != null && !@aiming
  114.             if @isInSight @targetEnemy.position
  115.                 @aiming = true
  116.                 seek = @seek @targetEnemy
  117.                 seek.multiply @dna[2]
  118.                 seek.limit @maxForce
  119.                 @applyForce seek
  120.                 @shoot @targetEnemy
  121.  
  122.     eat: (list, index) ->
  123.         @targetNutrition = null
  124.         @closestTargetNutrition = Infinity
  125.  
  126.         for item, i in list by -1
  127.             dist = item.position.distance @position
  128.  
  129.             if dist < @dna[3] and dist < @closestTargetNutrition
  130.                 @closestTargetNutrition = dist
  131.                 @targetNutrition = item
  132.  
  133.                 if dist < 9
  134.                     @health += item.nutrition
  135.                     list.splice i, 1
  136.  
  137.         if @targetNutrition != null
  138.             if @isInSight @targetNutrition.position
  139.                 seek = @seek @targetNutrition, index
  140.                 seek.multiply @dna[index]
  141.                 seek.limit @maxForce
  142.                 @applyForce seek
  143.  
  144.     followFlowField: (flowField) ->
  145.         x = Math.floor @position.x / flowField.scale
  146.         y = Math.floor @position.y / flowField.scale
  147.         i = x + y * flowField.cols
  148.         force = flowField.field[i]
  149.         @applyForce force.limit(@maxForce) if typeof force != 'undefined'
  150.  
  151.     draw: (ctx) ->
  152.         if window.toggleTails
  153.             @tail.draw ctx if @tail isnt null
  154.  
  155.         ctx.save()
  156.         @drawAimLine ctx
  157.         ctx.translate @position.x, @position.y
  158.  
  159.  
  160.         @angle = @velocity.getAngle() + Math.PI * 0.5
  161.  
  162.         ctx.rotate @angle
  163.         @drawLineOfSight ctx
  164.  
  165.         @debug ctx
  166.         @drawHealthBar ctx
  167.  
  168.         @drawShape ctx
  169.  
  170.         ctx.restore()
  171.  
  172.     drawShape: (ctx) ->
  173.         ctx.beginPath()
  174.         ctx.ellipse 0, 0, @radius, @radius * 2, 0, 0, 2 * Math.PI
  175.         ctx.closePath();
  176.         gradient = ctx.createRadialGradient 0, 0, @radius * 1.5, 0, -@radius * 1.5, @radius / 3
  177.         c = Color.FromHex @color
  178.         c.r += 60
  179.         c.g += 60
  180.         c.b += 60
  181.         gradient.addColorStop 1, c.toStr()
  182.         gradient.addColorStop 0, @color
  183.         ctx.fillStyle = gradient
  184.         ctx.fill()
  185.  
  186.     drawAimLine: (ctx) ->
  187.         if @targetEnemy && window.toggleAimLines
  188.             p = @targetEnemy.position.clone()
  189.             ctx.beginPath()
  190.             ctx.moveTo @position.x, @position.y
  191.             ctx.lineTo p.x, p.y
  192.             ctx.closePath()
  193.             color = Color.FromHex @color
  194.             ctx.lineWidth = 2
  195.             ctx.strokeStyle = "rgba(#{color.r}, #{color.g}, #{color.b}, 1)"
  196.             ctx.stroke()
  197.  
  198.     isInSight: (target) ->
  199.         delta = target.subtract(@position)
  200.         angle = delta.getAngle()
  201.         baseAngle = @angle - (Math.PI * 0.5)
  202.         los1Angle = baseAngle - (@dna[4] * 0.5)
  203.         los2Angle = baseAngle + (@dna[4] * 0.5)
  204.  
  205.         if angle >= los1Angle && angle <= los2Angle
  206.             return true
  207.         else
  208.             @color = @team.color
  209.             return false
  210.  
  211.     drawLineOfSight: (ctx) ->
  212.         if window.toggleSightLines
  213.             los1 = new Vec2()
  214.             los2 = new Vec2()
  215.             baseAngle = @angle - (Math.PI * 0.5)
  216.             los1Angle = baseAngle - (@dna[4] * 0.5)
  217.             los2Angle = baseAngle + (@dna[4] * 0.5)
  218.  
  219.             ctx.save()
  220.             ctx.lineWidth = 0
  221.             ctx.rotate -@angle
  222.             gradient = ctx.createRadialGradient 0, 0, @dna[3] / 3, 0, 0, @dna[3]
  223.             c = Color.FromHex @color
  224.             c.a = 0.3
  225.             gradient.addColorStop 1, 'rgba(255,255,255,0.0)'
  226.             gradient.addColorStop 0, c.toStr()
  227.             los1.setLength @dna[3]
  228.             los2.setLength @dna[3]
  229.             los1.setAngle los1Angle
  230.             ctx.beginPath()
  231.             ctx.moveTo 0, 0
  232.             ctx.lineTo los1.x, los1.y
  233.  
  234.             ctx.arc 0, 0,  @dna[3], los1Angle, los2Angle
  235.  
  236.             los2.setAngle los2Angle
  237.             ctx.moveTo 0, 0
  238.             ctx.lineTo los2.x, los2.y
  239.             ctx.fillStyle = gradient
  240.             ctx.fill()
  241.  
  242.             ctx.restore()
  243.  
  244.     drawHealthBar: (ctx) ->
  245.         if window.toggleHealthBar
  246.             ctx.save()
  247.             ctx.rotate -@angle
  248.             ctx.rect -@radius * 4, 40, @radius * 8, 4
  249.             ctx.strokeStyle = "rgba(0,0,0,0.3)";
  250.             ctx.lineWidth = 2
  251.             ctx.stroke()
  252.             percent = @health / @maxHealth
  253.             green = new Color 0, 255, 0, 1
  254.             red = new Color 255, 0, 0, 1
  255.             ctx.fillStyle = red.blend(green, @health).toStr()
  256.             ctx.fillRect -@radius * 4, 40, (@radius * 8) * percent, 4
  257.             ctx.restore()
  258.  
  259.     debug: (ctx) ->
  260.         if window.toggleFoodAttraction is true
  261.             lineFood = new Vec2()
  262.             lineFood.setLength @dna[0] * 60
  263.             lineFood.setAngle -Math.PI * 0.5
  264.  
  265.             ctx.beginPath()
  266.             ctx.moveTo 0, 0
  267.             ctx.lineTo lineFood.x, lineFood.y
  268.             ctx.closePath()
  269.             ctx.strokeStyle = 'rgba(0, 255, 0, 1)'
  270.             ctx.lineWidth = 1
  271.             ctx.stroke()
  272.  
  273.  
  274.         if window.togglePoisonAttraction is true
  275.             linePoison = new Vec2()
  276.             linePoison.setLength @dna[1] * 60
  277.             linePoison.setAngle Math.PI * 0.5
  278.  
  279.             ctx.beginPath()
  280.             ctx.moveTo 0, 0
  281.             ctx.lineTo linePoison.x, linePoison.y
  282.             ctx.closePath()
  283.             ctx.strokeStyle = 'rgba(255, 0, 0, 1)'
  284.             ctx.lineWidth = 1
  285.             ctx.stroke()
  286.  
  287.     update: ->
  288.         if @tail isnt null
  289.             @tail.update()
  290.  
  291.         @velocity.add @acceleration
  292.         @velocity.limit @maxSpeed
  293.         @position.add @velocity
  294.         @acceleration.multiplyBy 0
  295.         @health -= 0.0015
  296.         @health = @maxHealth if @health > @maxHealth
  297.         @health = 0 if @health < 0
  298.  
  299.     applyForce: (force) ->
  300.         @acceleration.add force
  301.  
  302.     seek: (target) ->
  303.         @seeking = true
  304.         focus = target.position.subtract @position
  305.         focus.setLength @maxSpeed
  306.         focus.subtract @velocity
  307.  
  308.     boundaries: ->
  309.         dist = 10
  310.         focus = null
  311.  
  312.         if @position.x  < dist
  313.             focus = new Vec2 @maxSpeed, @velocity.y
  314.         else if @position.x + dist > window.canvasWidth - dist
  315.             focus = new Vec2 -@maxSpeed, @velocity.y
  316.  
  317.         if @position.y  < dist
  318.             focus = new Vec2 @velocity.x, @maxSpeed
  319.         else if @position.y + dist > window.canvasHeight - dist
  320.             focus = new Vec2 @velocity.x, -@maxSpeed
  321.  
  322.         if focus isnt null
  323.             focus.setLength @maxSpeed
  324.             steer = focus.subtract @velocity
  325.             steer.limit @maxForce
  326.             @applyForce steer
  327.  
  328. if typeof module != 'undefined'
  329.     module.exports = Agent
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×