ItsYaBoiWesley Posted June 30, 2018 Share Posted June 30, 2018 Hi! I'm an experienced programmer with C++, but just getting started with JavaScript. I'm making a simple 2D game to get started. I'm using the CreateJS library to do my image/spritesheet manipulation. Right now, I'm trying to create a Sprite class, which will set up a spritesheet in the constructor, and draw the sprite with coordinates in the draw() function. (a member of my Sprite class) Anyways, I'm doing some debugging now. My program stops in the constructor of my Sprite class, and I can't figure out why. To anyone with CreateJS experience, what is wrong with my constructor function?!?!?! Thanks! class Sprite { constructor(src, frameWidth, frameHeight) { window.alert("DEBUG constructor. " + src + ", " + frameWidth + ", " + frameHeight); //Gets here this.spriteSheet = new createjs.SpriteSheet({ images: [queue.getResult(src)], frames: {width: frameWidth, height: frameHeight}, animations: { ani: [0,4] } }); window.alert("DEBUG end constructor"); //Never gets here } draw(x, y) { animation = new createjs.Sprite(this.spriteSheet, "ani"); animation.regX = 99; animation.regY = 58; animation.x = enemyXPos; animation.y = enemyYPos; animation.gotoAndPlay("ani"); stage.addChildAt(animation,1); } } Quote Link to comment Share on other sites More sharing options...
b10b Posted June 30, 2018 Share Posted June 30, 2018 What does your dev-console tell you (F12)? There are elements outside of the code shared that may be causing ''new createjs.SpriteSheet' to not return (e.g. queue), or perhaps the createjs functions may not be loaded etc. @ItsYaBoiWesley feel free to share more (e.g. link to online demo). Quote Link to comment Share on other sites More sharing options...
ItsYaBoiWesley Posted June 30, 2018 Author Share Posted June 30, 2018 1 hour ago, b10b said: What does your dev-console tell you (F12)? There are elements outside of the code shared that may be causing ''new createjs.SpriteSheet' to not return (e.g. queue), or perhaps the createjs functions may not be loaded etc. @ItsYaBoiWesley feel free to share more (e.g. link to online demo). Hi, I'm using "Atom" code editor for my code. I don't think there's a dev console. Where can I find an IDE that does have such a thing? I tried Visual Studio Code, but can't get it to work on 2 computers! Without a dev-console, is there any way to find the desired information? I simply run my application with google chrome. Quote Link to comment Share on other sites More sharing options...
b10b Posted June 30, 2018 Share Posted June 30, 2018 13 minutes ago, ItsYaBoiWesley said: I don't think there's a dev console Sorry I wasn't clear, the dev-console is in the browser (e.g. Chrome). IDE's like Atom aren't able to help too much with debugging for vanilla JS. With your experience you may prefer to adopt Haxe or Typescript (to transpile your JS from a typed language) and gain a few more compile-time and IDE benefits Quote Link to comment Share on other sites More sharing options...
ItsYaBoiWesley Posted June 30, 2018 Author Share Posted June 30, 2018 Ah I see. I just checked out the console, thank you so much! This will be very helpful going forward! After correcting a series of other errors, here is the remaining error. (Which, again, runs in the constructor) Uncaught TypeError: Cannot read property 'getContext' of undefined at a.b.initialize (createjs-2013.12.12.min.js:12) at new a (createjs-2013.12.12.min.js:12) at new Sprite (init.js:24) at init (init.js:79) at onload (index.html:9) I searched up this error, and it seems to have something to do with the way my program is structured. Again, I'm a total newbie to JS, so the way a JS program is structured is still alien to me. The code you saw in my original post is in "init.js". Here is "index.html", my HTML file. <!DOCTYPE html> <html> <head> <title>Cat & Mouse EYESIGHT DEMO</title> <link href="normalize.css" type="text/css" rel="stylesheet" /> <script language="javascript" type="text/javascript" src="http://code.createjs.com/createjs-2013.12.12.min.js" ></script> <script language="javascript" type="text/javascript" src="init.js" ></script> </head> <body onload="init();"> <canvas id="demoCanvas" width="1000" height="1000"></canvas> </body> </html> Quote Link to comment Share on other sites More sharing options...
b10b Posted July 1, 2018 Share Posted July 1, 2018 @ItsYaBoiWesley I am unsure if you've done this, but CreateJS needs to 'know' about your canvas ('demoCanvas'). So typically a 'new createjs.Stage()' is created, with the root canvas injected into the constructor. Then additional displayObjects are attached to that Stage (as you're doing with your line 'stage.addChildAt(animation,1);'). Without this step Stage is not bound to a canvas, and so cannot 'getContext' - a term relating to the interface methods that sit atop a canvas that allow us to draw and transform (CreateJS uses this alot). The getting started example shows this step: https://createjs.com/getting-started Quote Link to comment Share on other sites More sharing options...
ItsYaBoiWesley Posted July 1, 2018 Author Share Posted July 1, 2018 This might be helpful. Here's what I'm doing in my JS initialization. (My HTML is unchanged) window.alert("initialized"); var canvas = document.getElementById('demoCanvas'); context = canvas.getContext('2d'); context.canvas.width = 1000; context.canvas.height = 1000; stage = new createjs.Stage("demoCanvas"); //QUEUE: queue = new createjs.LoadQueue(false); queue.installPlugin(createjs.Sound); queue.on("complete", queueLoaded, this); createjs.Sound.alternateExtensions = ["ogg"]; window.alert("createJS did stuff"); queue.loadManifest([ {id: 'backgroundImage', src: 'assets/background.png'}, {id: 'mouse', src: 'assets/mouse.png'}, ]); queue.load(); window.alert("manifest loaded"); These variables are defined globally var stage; var queue; var context; Quote Link to comment Share on other sites More sharing options...
b10b Posted July 2, 2018 Share Posted July 2, 2018 @ItsYaBoiWesley hey, I suspect the issue is because your init.js is being run as soon as it loads (which is slightly ahead of body instantiating the canvas element, hence no getContext). Given that you are calling 'init()' in the body.onLoad I suspect you intended to have all of init.js wrapped in a function? So add: function init() { ... existing init.js code here } Then you'll encounter the issue 'queueLoaded is not defined' ... so add a function in for that and continue ... Don't give up, getting any new project bootstrapped for that first build is always a challenge - often looking back later to see it was obvious Quote Link to comment Share on other sites More sharing options...
ItsYaBoiWesley Posted July 2, 2018 Author Share Posted July 2, 2018 Thanks for all the help. I don't have my entire init.js file wrapped in a function. Rather, Init() is the function I want to run first in the program. I've made some changes, (to no avail) but here is my new index.html (I've removed that part in the onload) <!DOCTYPE html> <html> <head> <title>Cat & Mouse EYESIGHT DEMO</title> <link href="normalize.css" type="text/css" rel="stylesheet" /> <script language="javascript" type="text/javascript" src="http://code.createjs.com/createjs-2013.12.12.min.js" ></script> <script language="javascript" type="text/javascript" src="init.js" ></script> </head> <body> <canvas id="demoCanvas" width="1000" height="1000"></canvas> </body> </html> Here is what I want the program to run FIRST (in Init.js) In init.js, there are other functions and classes. But here is the function I want to run first. window.onload = function() { window.alert("initialized"); canvas = document.getElementById('demoCanvas'); context = canvas.getContext('2d'); context.canvas.width = WIDTH; context.canvas.height = HEIGHT; stage = new createjs.Stage("demoCanvas"); //QUEUE: queue = new createjs.LoadQueue(false); queue.installPlugin(createjs.Sound); queue.on("complete", queueLoaded, this); createjs.Sound.alternateExtensions = ["ogg"]; window.alert("createJS did stuff"); queue.loadManifest([ {id: 'backgroundImage', src: 'assets/background.png'}, {id: 'mouse', src: 'assets/mouse.png'}, ]); queue.load(); window.alert("manifest loaded"); AND SO ON... }); Notice I'm doing window.onload, so I assume this function should load once everything is finished loading. If not, how do I make this function run once everything is finished loading? Yes, I agree. Getting the first bootup is always the hard part. When I first learned C++, that was the case. From that point on, it was smooth sailing. (Well, not really. But you get the point. ?) Quote Link to comment Share on other sites More sharing options...
b10b Posted July 2, 2018 Share Posted July 2, 2018 @ItsYaBoiWesley I think you're almost there - and that code (with the exception of the missing globals (WIDTH, HEIGHT, queueLoaded) and the extraneous ');' at the end of the file - runs ok for me. To answer your question of 39 minutes ago, ItsYaBoiWesley said: how do I make this function run once everything is finished loading? There are various ways, each with pros and cons. window.onload (or the equivalent body.onload) can vary from browser to browser, some waiting for all assets to load, some not. I would suggest neither are what you want longer-term. Best to launch your game when you need, and separate concerns from the DOM. So the game should be a function in itself (like the init() method of the createjs example). You can, optionally, call it directly and immediately on first load by adding the parenthesis on the end: game = function() { ... }(); Loading the js directly in the body (after any body dependencies have been established) is an easy way to manage load order: <body> <canvas id="gameCanvas"></canvas> <script src="http://code.createjs.com/createjs-2013.12.12.min.js"/> <script src="game.js"/> </body> I often do things this way - obvious, simple and effective. Only if I need conditional loads will I do anything more complex. Quote Link to comment Share on other sites More sharing options...
ItsYaBoiWesley Posted July 2, 2018 Author Share Posted July 2, 2018 Ok, I put all of my code in init.js into an init() function, which contains the classes and also the workflow in the original (small) init function. Now, how do I call that function from HTML? (Making sure everything was initialized) The function is init() in init.js <!DOCTYPE html> <html> <head> <title>Cat & Mouse EYESIGHT DEMO</title> </head> <body> <link href="normalize.css" type="text/css" rel="stylesheet" /> <canvas id="demoCanvas" width="1000" height="1000"></canvas> <script language="javascript" type="text/javascript" src="http://code.createjs.com/createjs-2013.12.12.min.js" ></script> <script src="init.js"></script> </body> </html> Quote Link to comment Share on other sites More sharing options...
b10b Posted July 2, 2018 Share Posted July 2, 2018 Add the parenthesis on the end of the init function declaration. Or have another script tag that calls the init function. Or use body.onload to call init. I'd go with the first option. Quote Link to comment Share on other sites More sharing options...
ItsYaBoiWesley Posted July 2, 2018 Author Share Posted July 2, 2018 Ok. Same error. Here are both of my files in full. HTML: <!DOCTYPE html> <html> <head> <title>Cat & Mouse EYESIGHT DEMO</title> </head> <body> <link href="normalize.css" type="text/css" rel="stylesheet" /> <canvas id="demoCanvas" width="1000" height="1000"></canvas> <script language="javascript" type="text/javascript" src="http://code.createjs.com/createjs-2013.12.12.min.js" ></script> <script src="init.js"></script> </body> </html> INIT.JS: init = function() { var stage; var queue; var context; var canvas; var WIDTH = 1024; var HEIGHT = 768; class Circle { constructor() { //window.alert("constructor"); this.circ = new createjs.Shape(); //window.alert("E constructor"); } draw(x, y, s) { //window.alert("drawing"); this.circ.graphics.beginFill("DeepSkyBlue").drawCircle(0, 0, s); this.circ.x = x; this.circ.y = y; stage.addChild(this.circ); } } class Sprite { constructor(src, frameWidth, frameHeight) { window.alert("DEBUG constructor. " + src + ", " + frameWidth + ", " + frameHeight); // Create bat spritesheet this.spriteSheet = new createjs.SpriteSheet({ "images": [queue.getResult(src)], "frames": {"width": frameWidth, "height": frameHeight}, "animations": { "flap": [0,4] } }); window.alert("DEBUG econstrucor"); } draw(x, y) { var animation = new createjs.Sprite(this.spriteSheet, "ani"); animation.regX = 99; animation.regY = 58; animation.x = enemyXPos; animation.y = enemyYPos; animation.gotoAndPlay("ani"); stage.addChildAt(animation,1); } } function queueLoaded(event) { // Add background image var backgroundImage = new createjs.Bitmap(queue.getResult("backgroundImage")) stage.addChild(backgroundImage); } window.alert("initialized"); canvas = document.getElementById('demoCanvas'); context = canvas.getContext('2d'); context.canvas.width = WIDTH; context.canvas.height = HEIGHT; stage = new createjs.Stage("demoCanvas"); //QUEUE: queue = new createjs.LoadQueue(false); queue.installPlugin(createjs.Sound); queue.on("complete", queueLoaded, this); createjs.Sound.alternateExtensions = ["ogg"]; window.alert("createJS did stuff"); queue.loadManifest([ {id: 'backgroundImage', src: 'assets/background.png'}, {id: 'mouse', src: 'assets/mouse.png'}, ]); queue.load(); window.alert("manifest loaded"); var objX = 100; var objY = 100; var Spi = new Sprite('mouse', 198, 148); window.alert("rdy"); document.addEventListener('keydown', function(event) { if(event.keyCode == 37) { objX -= 10; } if(event.keyCode == 38) { objY -= 10; } else if(event.keyCode == 39) { objX += 10; } else if(event.keyCode == 40) { objY += 10; } Spi.draw(objX, objY); stage.update(); }); window.alert("done"); }() As you can see, everything is in the function like you said. ? Quote Link to comment Share on other sites More sharing options...
b10b Posted July 2, 2018 Share Posted July 2, 2018 @ItsYaBoiWesley so close. Welcome to async. Your code after queue.load() is executing immediately, it's not waiting for the queue to complete loading. Instead it should be called in (or by) the queueLoaded function (which is called when load is completed). Moving it there, (and fixing the name of 'x','y' params) shows a spritesheet animating on keypress. Quote Link to comment Share on other sites More sharing options...
ItsYaBoiWesley Posted July 2, 2018 Author Share Posted July 2, 2018 Great! That issue has been solved. I also found those variables I needed to rename, thanks! New problem. When I hit a key, these errors appear repeatedly as I hold down or press the key. Still no sprite. My thoughts are that it has to do with the Sprite.draw() function. Uncaught RangeError: Maximum call stack size exceeded at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) at a.b._normalizeFrame (createjs-2013.12.12.min.js:13) Thank you SO MUCH for all of this help! It's so great that you're so willing to be helpful! Quote Link to comment Share on other sites More sharing options...
b10b Posted July 2, 2018 Share Posted July 2, 2018 @ItsYaBoiWesley you're welcome. I don't get that error, but I'm also not using your mouse.png or background.png (or the normalize.css) - so perhaps the issue is related to them or the Spritesheet's relationship to them? You may also want to use a more recent version of CreateJS - e.g. https://code.createjs.com/createjs-2015.11.26.min.js Quote Link to comment Share on other sites More sharing options...
ItsYaBoiWesley Posted July 2, 2018 Author Share Posted July 2, 2018 Oh my god! Updating the version worked! Thank you so much, the sprite is now moving happily across the screen. However, the sprite is not animated. It remains of frame 0 as it moves. (And yes, I fixed those names to be consistent in the class) I'm gonna keep working on figuring out why the sprite doesn't animate, it's probably just some dumb bug. But any insight you could give might help. b10b 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.