-1

I've got this issue with the canvas not being written to the browser, I'm following a w3schools tutorial to build a basic game.

I'm wondering why the body-block isn't growing given the placement of the canvas in the style tag. The javascript is an external file, the dimensions of the canvas tag are specified there.

There should be the thread for the CSS calls and a thread for the HTML/Javascript calls, where and why is this code not defining a block for my canvas?

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
 <body>
   <style>
     canvas {
       border:1px solid #d3d3d3;
       background-color: #f1f1f1;
   }
   </style>
  <script type="text/javascript" src="/Users/cgoodwin/game/g.js">
   window.onload = start;
  </script>
 </body>
</html>

The above is the HTML document

Below is the JS

    function start(){

      gameArea.start();

      }

var gameArea={

 canvas:document.createElement("canvas"),

 start:function(){
  this.canvas.width=480;
  this.canvas.height=270;
  this.context=this.canvas.getContext("2d");
  document.body.insertBefore(this.canvas, document.body.childNodes[0]);
  this.interval=setInterval(update,20);
  },
    clear:function(){
     this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
    }
}

var gamePiece;
function start(){
 gameArea.start();
 gamePiece=new component(30,30,"red",10,120);
}

 function component(width,height,color,x,y){
  this.width=width;
  this.height=height;
  this.x=x;
  this.y=y;
   this.update=function(){
    ctx=gameArea.context;
    ctx.fillStyle=color;
    ctx.fillRect(this.x,this.y,this.width,this.height);
 }
}

function updateGameArea(){
 gameArea.clear();
 gamePiece.x += 1;
 gamePiece.update();
}

I added a "Watch Expression" with the developer tools on the gamePiece and it's saying it isn't defined. Likely, that's my issue, but why isn't it being defined? It could be that the game updating triggers it to be undefined in any given instance, adding a watch might not work when evaluating something that is being cleared and changed every 20 milliseconds.

  • Also, why is the "this" necessary in the component function? That's what w3 schools had. Is it that it otherwise would've maintained the global definition of width/height/etc, maybe not the global definitions but the definitions of those variables from previous functions? And so the "this" just ensures that the variables are set to the context of that function at runtime? – Tyler Curtis Jowers Jun 05 '18 at 06:34
  • it must be: `window.onload = start`. Watch out for the lowercase `onload`. Don't call the function usign the `()` notation, just pass the function object, other it will be called right away… – philipp Jun 05 '18 at 06:36
  • @philipp Appreciate it, what is the difference, so you said it won't be called right away? Still hasn't painted the canvas to the browser. – Tyler Curtis Jowers Jun 05 '18 at 06:51
  • `var x = start()` calls the function and assigns the result to `x`, while `var x = start` assigns the function itself to `x`, then you can `var y = x()`. With `window.onload = …` you ask the browser to call the given **function** when loaded. That is really pretty basic JS… – philipp Jun 05 '18 at 07:00
  • @philipp So would you say that `var x = start()` stores the address of the function `start()` whereas `var x = start` just puts a string as the value at the location in memory where `x` is? So the latter case is just shortcutting the verbosity and the former case is establishing a "pointer" to the function call returning? – Tyler Curtis Jowers Jun 05 '18 at 08:09
  • NO! Please read my comment above again. This has nothing to do with strings, it is either about a reference to a function object, or the return value of an executed function. Functions are 1st class members in Javascript. – philipp Jun 05 '18 at 08:26
  • On your question about the component function, this function is an [object constructor](https://www.w3schools.com/js/js_object_constructors.asp). `new component(...)` creates a new instance of the object with `this` referring to that instance. See https://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – Stuart Jun 05 '18 at 08:38
  • @Stuart so is `this` a global variable, or a global object storing all local variables, hence, a global variable reference object... I guess? @philipp Is it that `var x = start` dereferences the address and stores N many bytes in a section of memory to store the block code of the function with the preprocessor? If so then I see that it is not simply a verbosity shortcut, otherwise, if the block of code isn't being stored by the preprocessor and is instead being resolved at runtime then I would definitely say that it is just a semantic shortcut and overall somewhat unnecessary. – Tyler Curtis Jowers Jun 05 '18 at 08:54
  • `this` is a keyword that takes different values within a function depending on how the function is invoked. See e.g. https://stackoverflow.com/a/134149/567595 – Stuart Jun 05 '18 at 10:22

1 Answers1

1

why is this code not defining a block for my canvas?

Because you don't have a canvas.

A <script> element can load JavaScript in one of two ways.

  1. Via a src attribute
  2. Via JS placed between the start and end tags

This is your code:

<script type="text/javascript" src="/Users/cgoodwin/game/g.js">
   window.onload = start;
</script>

Since the script is loaded via the src attribute, window.onload = start is ignored.

Since you never call start, the <canvas> element is never added to the DOM.

Move your second script so it is either:

  1. part of the g.js
  2. in a <script> element of its own
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335