title: Javascript | P5.JS Library - Snake Game (X) Is Undefined
body: <p>I am coding / following a snake game coding tutorial and seemed to have hit a point where I have found an error that the instructor hasn't encountered, and I seem to not understand the origin of the problem.</p>
  
  <p>I have even commented each line describing the function each line has to maybe help me figure out the problem but I have blanked out.</p>
  
  <p>The line with the problem is clearly pointed out.</p>
  
  <p>Full Error From Chrome Console:</p>
  
  <blockquote>
    <p>Uncaught TypeError: Cannot read property 'x' of undefined<br>
    --at Snake.show (snake:95)<br>
    --at draw (snake:37)<br>
    --at p5.redraw (p5.js:17153)<br>
    --at p5. (p5.js:12358)  </p>
  </blockquote>
  
  <p>Specific Problematic Line:</p>
  
  <blockquote>
    <p>rect(this.tail[i].x, this.tail[i].y, scl, scl);  // Draw The Tail At The End.</p>
  </blockquote>
  
  <p>When I either run into a border wall or run into myself by going the opposite direction I was initially going in with 3+ length of the tail I get this error.
  Can someone explain whats causing this error? It must be something to do with the death aspect.</p>
  
  <p>Full Code:  </p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
      &lt;head&gt;
          &lt;title&gt;Snake Game&lt;/title&gt;
          &lt;script src="http://sethjfreeman.com/resources/jquery-3.1.1.js"&gt;&lt;/script&gt;
          &lt;script src="http://sethjfreeman.com/resources/P5/p5.js"&gt;&lt;/script&gt;
          &lt;link href="http://sethjfreeman.com/projects/snake.css" rel="stylesheet" type="text/css"&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;script&gt;  &lt;!-- Uses p5.js Javascript Library --&gt;
              var s;  // Snake Character.
              var scl = 20;   // Size Of Everything.
              var food;   // Food Items. Makes Em Grow When Eatin.
  
              function setup() {
                  createCanvas($(window).width() - 10, $(window).height() - 10);  // Creates De Canvas For Everything To Be In.
                  s = new Snake();  // Creates A New Snake | Calls Snake Function To Create A Snake |.
                  frameRate(10);  // Sloooowwwssss Down The Game To Actully Be Able To Control The Snake.
                  pickLocation(); // Calls Pick Location To Pick A Location For The First Food Item To Be Placed.
              }
  
              function pickLocation() {  // A Function To Control Where The Food Goes
                  var cols = floor(width / scl);  // Creates An Imaginary Vertical Grid Every 20 Pixels. Floor Is Being Used To Prevent A Column From Being Placed At E.G: 40.6 Pixels.
                  var rows = floor(height / scl);  // Creates An Imaginary Horizontal Gird Every 20 Pixels. Floor Is Being Used To Prevent A Column From Being Placed At E.G: 40.6 Pixels.
                  food = createVector(floor(random(cols)), floor(random(rows)));  // Assigns Food To Being At The Random Location.
                  food.mult(scl);  // Makes Sure The Food Vector Is Set In The 20 Pixels Guide Lines. Not The 20.5 Pixel Guide Lines.
              }
  
              function draw() {  // Controls Everything That Is Being Drawn To The Canvas.
                  background(51);  // Sets Background To Be A Grayscale Value. 
  
                  if(s.eat(food)) {  // Checks If Food Was Eatin, If True Picks A New Location For A Food Peice.
                      pickLocation();  // Calls Pick Locatoin Function.
                  }
                  s.death();  // Calls Death Function.
                  s.update();  // Calls Update Function.
                  s.show();  // Calls Show Function.
  
                  fill(255, 0, 100);  // Sets Food's Background Color.
                  rect(food.x, food.y, scl, scl);  // Creates A New Food Item.
              }
  
              function Snake() {  // Controls Everything To Do With De Snake Character.
                  this.x = 0;  // Holds The X Pos Of Player.
                  this.y = 0;  // Holds The Y Pos Of The Player.
                  this.xspeed = 1;  // Moves Player (X) Speed.
                  this.yspeed = 0;  // Moves Player (X) Speed.
                  this.total = 0;  // Holds The Amount Of Squares On Snake.
                  this.tail = [];  // History For Where Each Part Of The Body Needs To Go.
  
                  this.dir = function(x, y) {  // Controls The Direction Of The Snake.
                      this.xspeed = x;  // Recives The Intput From keyPressed.
                      this.yspeed = y;  // Recives The Intput From keyPressed.
                  }
  
                  this.eat = function(pos) {  // Controls What Happens When A Food Item Was Eatin.
                      var d = dist(this.x, this.y, pos.x, pos.y);  // Holds The Distance Between Two Points, In This Case, Between The Snake &amp; The Food Item.
                      if(d &lt; 1) {  // If The Distance Is Less Than 1 Pixel From Food Item Add 1 To Total. 
                          this.total++;
                          return true;
                      } else {  // Else Go To Sleep.
                          return false;
                      }
                  }
  
                  this.death = function() {  // Controls When The Player Dies.
                      for(var i = 0; i &lt; this.tail.length; i++) {  // Loops Through Snake Length. Loop Used For Checking If Snake Runs Into Self.
                          var pos = this.tail[i];  // Checks Position Of Each Square Of Tail
                          var d = dist(this.x, this.y, pos.x, pos.y);  // Holds The Distance Between Two Points, In This Case, Between The Snake Head &amp; The Particular Spot On The Tail Thats Being Hit.
                          if(d &lt; 1) {  // If The Pixel Between The Distance, Restart The Player.
                              total = 0;  // Resets Total.
                              this.tail = [];  // Resets Tail.
                          }
                      }
                  }
  
                  this.update =  function() {  // Updates Everything. Simple Right?
                      if(this.total === this.tail.length) {  
                          for(var i = 0; i &lt; this.tail.length - 1; i++) {  //  Loops Through Whole Snake Besides Head.
                              this.tail[i] = this.tail[i + 1];  // Shifts Each Body Square Location By 1.
                          }
                      }
                      this.tail[this.total - 1] = createVector(this.x, this.y);
  
                      this.x = this.x + this.xspeed * scl;  // The X Cords Of Snake Changes Depending On X Speed * The Scale Of The Snake
                      this.y = this.y + this.yspeed * scl;  // The Y Cords Of Snake Changes Depending On Y Speed * The Scale Of The Snake
  
                      this.x = constrain(this.x, 0, width - scl);  // Constrains The Snake Between The Left Border And Right Border Of The Sceen
                      this.y = constrain(this.y, 0, height - scl);  // Constrains The Snake Between The Top Border And Bottom Border Of The Sceen
                  }
                  /*
                      _____  _____   ____  ____  _      ______ __  __ 
                      |  __ \|  __ \ / __ \|  _ \| |    |  ____|  \/  |
                      | |__) | |__) | |  | | |_) | |    | |__  | \  / |
                      |  ___/|  _  /| |  | |  _ &lt;| |    |  __| | |\/| |
                      | |    | | \ \| |__| | |_) | |____| |____| |  | |
                      |_|    |_|  \_\\____/|____/|______|______|_|  |_|
  
                  */
                  this.show = function() {
                      fill(255);  // Draw The Tail White.
                      for(var i = 0; i &lt; this.tail.length; i++) {  // Draw The Tail.
                          rect(this.tail[i].x, this.tail[i].y, scl, scl);  // Draw The Tail At The End.
                      }
  
                      rect(this.x, this.y, scl, scl);
                  }
              }
  
              function keyPressed() {  // Checks Which Keys Were Pressed.
                  if(keyCode === UP_ARROW) {  // If Up Arrow Was Pressed Move Snake Upwards.
                      s.dir(0, -1);  // Because Direction Starts From Left &amp; Top, -1 = Subtract From Top Pos. +1 = Add From Top Pos.
                  } else if(keyCode === DOWN_ARROW) {  // If Down Arrow Was Pressed Move Snake Downwards.
                      s.dir(0, 1);  // Because Direction Starts From Left &amp; Top, -1 = Subtract From Top Pos. +1 = Add From Top Pos.
                  } else if(keyCode === RIGHT_ARROW) {  // If Right Arrow Was Pressed Move Snake Right.
                      s.dir(1, 0);  // Because Direction Starts From Left &amp; Top, -1 = Subtract From Top Left. +1 = Add From Top Left.
                  } else if(keyCode === LEFT_ARROW) {  // If Left Arrow Was Pressed Move Snake Left.
                      s.dir(-1, 0);  // Because Direction Starts From Left &amp; Top, -1 = Subtract From Top Left. +1 = Add From Top Left.
                  }
              }
          &lt;/script&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>