My index.html file seems to include all of the necessary JS files, and then defines their state. This is what I've seen people do online and it works fine for them.
<html>
<head>
<meta charset = "UTF-8"/>
<title>Test</title>
<script src = "phaser.js"></script>
<script src = "Boot.js"></script>
<script src = "Preload.js"></script>
<script src = "MainMenu.js>"></script>
</head>
<body>
<script type="text/javascript">
window.onload = function(){
var game = new Phaser.Game(800,600,Phaser.AUTO,'');
game.state.add('Boot',Game.Boot);
game.state.add('Preload',Game.Preload);
game.state.add('MainMenu',Game.MainMenu);
game.state.start('Boot');
}
</script>
</body>
</html>
My problem is that while this code successfully changes state from Boot.js to Preload.js, it claims that there is "No state found with the key: MainMenu". I'm super confused, and I'm using Phaser version 2.6.1
For the sake of your weary eyes, I've included the Boot.js file, the Preload.js and the MainMenu.js file in one concatenated Pastebin here: http://pastebin.com/sJYTsCdY .
Sorry if I've made any etiquette mistakes, this is my first time posting to StackOverflow. Any help would be appreciated, thanks!!
Try changing Game.MainMenu to Game.MainMenu.prototype at row 76 in the pastebin.
What I supposе is happening is Phaser tries to add MainMenu as a new state and when it tries to instantiate it, it fails because there is no function to act as constructor (that it needs when using new and that's what Phaser uses internally when adding a state). You define Game.MainMenu = function() { } which acts as a constructor at first, but then you override it (you assign something else to the same Game.MainMenu) and it happens that Phaser can no longer create an instance of MainMenu.
Related
Kind of embarrassing, since I worked as a React developer for over a year. But the system was set up when I came in, and when I created new components I just followed the syntax for the existing components and everything worked. But trying to do even simple React stuff on my home system has been really challenging. I'm not sure the problem is in my syntax, but maybe in my javascript environment.
Here is a simple thing that works:
react-test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>react-test-2</title>
<script type="text/javascript" src="../jquery-1.3.2.min.js"></script>
<script src="https://unpkg.com/react#18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#18/umd/react-dom.development.js" crossorigin></script>
<script src="React_Components/AAA.js"></script>
<script>
$(document).ready(function() {
const domContainer = document.querySelector('#react-container');
const root = ReactDOM.createRoot(domContainer);
root.render(React.createElement(AAA));
});
</script>
</head>
<body>
<div id="react-container"></div>
</body>
</html>
AAA.jsx
function AAA(){
return (<div>AAA</div>);
}
The .jsx files are in React_Components_JSX, which is watched by the Babel preprocessor, which makes analogous .js files in React_Components. When I navigate to the html page, it renders the expected "AAA" on the page.
Now I'm just trying to nest another component inside the AAA component. So I update the file AAA.jsx and create a file BBB.jsx, something like the following (although I have tried various syntaxes hoping to make this work). I am expecting to see a webpage that renders "AAABBB".
AAA.jsx
import BBB from '../React_Components_JSX/BBB.jsx';
function AAA(){
return (<div>AAA<BBB/></div>);
}
BBB.jsx
export default function BBB(){
return (<div>BBB</div>);
}
The main error I am getting is "Cannot use import statement outside a module". Which I know explains the problem, but I don't really understand what that means on a fundamental level, as far as how I have to set my application up.
I have 2 files the first one is an HTML file the other one is a javascript file. What I was trying to do was define a variable on the javascript file and access it on the Html side. Is it possible? A rough code is attached below but it doesn't work I get favColor is not defined error. thanks in advance.
JS Side
const favColor = "red"
Html side
<script src="pathtojsfile"></script>
<p id="insertHere"></p>
<script>
document.getElementById("insertHere").innerHTML = favColor
</script>
It is widely considered bad practice to work with global variables. To avoid it, you can make use of ECMAScript Modules, introduced back in 2015 with ES6/ES2015.
This allows your first Javascript, let's name it colors.module.js to export the variable:
export const favColor = 'red';
Then, in your script that needs to access this variable, you import it:
import { favColor } from '/path/to/js/modules/colors.module.js';
For that to work, you need your importing script to have type=module attribute, and the import must be done on top of your Javascript. The script you import from does not need to be included in the page.
Here's some helpful links to get you started with modules:
ES Modules Deep Dive
Javascript Modules on MDN
Flavio Copes' take on ES Modules
I've set up a tiny github repo demonstrating this very basic usage of an ES module.
If modules are not an option, e.g. because you must support IE 11, or your build stack doesn't support modules, here's an alternative pattern that works with a single namespace object you attach to the global object window:
// colors.module.js
window.projectNamespace = window.projectNamespace || {};
projectNamespace.colors = window.projectNamespace.colors || {};
projectNamespace.colors.favColor = 'red';
and in your page you access it from that name space:
document.getElementById("insertHere").innerHTML = window.projectNamespace.colors.favColor;
This way you have a single location to put all your globally accessible variables.
As the code is written in your example it should work fine. Just like my example here:
<script>
const favColor = "red";
</script>
<p id="insertHere"></p>
<script>
document.getElementById("insertHere").innerHTML = favColor;
</script>
But there can be a number of issues if the code is not like this. But the JavaScript code could just go in the same file. Try to separate the html from the JS like this (the code in the script element could be moved to it's own file):
<html>
<head>
<script>
const favColor = "red";
document.addEventListener('DOMContentLoaded', e => {
document.getElementById("insertHere").innerHTML = favColor;
});
</script>
</head>
<body>
<p id="insertHere"></p>
</body>
</html>
Here I'm also adding the eventlistener for DOMContentLoaded, so that I'm sure that the document is loded into the DOM.
Where your variable is declared is not the problem per se, but rather the loading order of scripts.
If you want to make sure external scripts are loaded before you execute yours, you can use the load event of window object. It will wait until all resources on your page are loaded though (images, css, etc.)...
const myvar = "Hey I'm loaded";
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<script>
//console.log(myvar); //<- fails
window.addEventListener('load', e => {
document.querySelector('#insertHere').innerHTML = myvar;
});
</script>
</head>
<body>
<p id="insertHere"></p>
</body>
</html>
Or you can put all your code in js files, and they will be invoked in the order they are declared.
Edit
Given objections and more questions popping in the comments, I'll add this. The best and cleanest way to achieve this remains to put your code in a .js file of its own and put all your <script> tags inside <head>, with yours last, as it relies on others to run.
Then you can either add the attribute defer to your <script> or have everything wrapped in an event handler for DOMContentLoaded so that it gets run after the DOM is fully loaded.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<script src='other1.js'></script> <!-- let's say this one declares myvar -->
<script src='other2.js'></script>
<script src='other3.js'></script>
<script src='myscript.js'></script>
</head>
<body>
<p id="insertHere"></p>
</body>
</html>
myscript.js
window.addEventListener('DOMContentLoaded', e => {
document.querySelector('#insertHere').innerHTML = myvar;
});
So I have a switch statement inside my Processing file which changes a variable named 'zooText'. zooText is declared in a JavaScript file named text.js. However, when for some reason, Processing is unable to access, or change, the variable.
The expected behavior would for zooText to change to whatever it is set to in the switch statement. However, the <p> only says "undefined".
Here is the switch statement:
switch(sceneNum){
case 1:
zooText = "Welcome to the office. This is where we organize all our files. Important files include our certification by the AZA (Association of Zoos & Aquariums), and other"
+ " important documents which certify we keep our animals healthy and happy";
break;
case 2:
zooText = "This is the education area. Here we teach children about the importance of conservation, and protecting our planet. According to some people,"
+ "we're really influential!";
break;
case 3:
zooText = "Scene 3";
break;
case 4:
display = "This is the Aquatic Area. Although most of these animals have natural roaming areas of hundreds of miles, we like to keep them in small enclosures";
break;
And here is the relevant JavaScript:
var zooText;
function changeText(){
document.getElementById("demo").innerHTML = zooText;
}
setTimeout(changeText, 100);
And finally, the relevant HTML:
<head>
<title>Zoo Ethics</title>
<link rel='stylesheet' href='style.css' type='text/css'>
<script src="processing.js" width="1000" height="800"></script>
<script src='text.js'></script>
</head>
<body style="background-color:#e0eaf9">
<h1>Explore the Zoo!</h1>
<p id="demo"></p>
<canvas id="sketch" data-processing-sources="zoos.pde"></canvas>
<script src='text.js'></script>
I've been struggling with this for hours. I've kind of narrowed down the problem to maybe the sketch not being loaded before the JavaScript, or something of a similar manner.
Try importing the text.js file first and then the processing.js
<script src='text.js'></script>
<script src="processing.js" width="1000" height="800"></script>
I was able to find a workaround by simply including pure JavaScript in the .pde file. I created a variable named zooText, completely deleted the text.js file, and then simply made the .pde file update the <p> in the draw() function.
This truly depends on how you call your scripting. If it is just base code inside Processing.js then it will run the moment it is loaded, even before the DOM and all other scripts are loaded. One option is to reverse the order they are loaded as stated. However this can (for various reasons such as server lag) still potentially produce the same issue. If this is how it's run then you might look into placing the base/original command inside an init() function. Then have event run on document ready:
Inside processing.js:
function init(){
//call processing.js functions/commands here
}
//remaining processing.js function definitions here
if (document.readyState !== 'loading') {
init()
} else {
// the document hasn't finished loading/parsing yet so let's add an event handler
document.addEventListener('DOMContentLoaded', init)
}
Doing it this way will help ensure all scripting is loaded before running. If you have/user jQuery the last part can be simplified with something like $(document).ready(function(){init()});
<head>
<title>Zoo Ethics</title>
<link rel='stylesheet' href='style.css' type='text/css'>
<script src='text.js'></script> <---I MOVED ABOVE PROCESS.JS
<script src="processing.js" width="1000" height="800"></script>
</head>
<body style="background-color:#e0eaf9">
<h1>Explore the Zoo!</h1>
<p id="demo"></p>
<canvas id="sketch" data-processing-sources="zoos.pde"></canvas>
<script src='text.js'></script> <---THIS SEEMS LIKE A DUPLICATE
I'm making a game in JS using P5, and I came upon a problem.
In my html file I have references to .js files:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.3/p5.min.js"></script>
<script src="main.js"></script>
<script src="isKeyPressed.js"></script>
<script src="blocks.js"></script>
<script src="player.js"></script>
</head>
<body>
</body>
</html>
I have one .js file defining the function isKeyPressed():
function isKeyPressed(keyQuery) {
var did = false;
for(var i = 0; i < keysPressed; i++) {
if(keysPressed[i] === keyQuery) {
did = true;
}
}
return did;
}
I reference this in another object inside player.js:
player.motion = function() {
if(isKeyPressed('w')) {
this.velocity.add(0,-5);
}
if(isKeyPressed('s')) {
this.velocity.add(0,5);
}
if(isKeyPressed('a')) {
this.velocity.add(-5,0);
}
if(isKeyPressed('d')) {
this.velocity.add(5,0);
}
}
But when I try to call player.motion, I get the error:
Uncaught TypeError: isKeyPressed is not a function
Does anyone know why this is occurring?
For the record, I don't think the accepted answer is correct. Specifically, I don't think the accepted answer really changes anything from what you were originally doing. My guess is that you had another problem in your code (like a syntax error) that was causing this error, and you fixed that in the process of implementing the suggested solution. So while it might look like the solution fixed your problem, really it was something else.
I'm providing this alternative answer so you don't think you have to define your JavaScript in your html directly, as that is definitely not the case.
I tried testing out your setup by creating a smaller example consisting of three files:
index.html
<!DOCTYPE html>
<html>
<head>
<script src="one.js"></script>
<script src="two.js"></script>
</head>
<body onload="printObj()">
</body>
</html>
one.js
function printOne(){
console.log("one");
}
two.js
var obj = {};
obj.printTwo = function(){
console.log("two");
printOne();
}
function printObj(){
obj.printTwo();
}
This is pretty much exactly what your setup is, and it works fine. You absolutely do not need to put your JavaScript in your html. As long as the JavaScript files are correctly loaded in the proper order, then you can use functions and variables from one file in another file.
There are two main things that could cause your problem:
Are your files correctly loaded?
Are there any syntax errors you haven't noticed? (This is my guess as to what caused your original problem.) Check the JavaScript console, and try running some test code to actually run the functions you're trying to call.
Did you get all the file names correct?
Are you behind a firewall, or are there other network problems that might cause a problem with loading?
Are your files loaded in the proper order?
For file two.js to access code defined in one.js, you have to make sure one.js is loaded before two.js. It looks like you've done this correctly, but are you sure the JavaScript is where you think it is?
In other words, are you sure it was in player.js and not in main.js?
You might want to get rid of this ambiguity by placing related JavaScript in the same file. It doesn't make a ton of sense to have one file define a keysPressed array and then another file use that array to define an isKeyPressed() function. Just put them in the same file, and make sure that file is loaded before other files that use it.
The accepted answer doesn't change anything with regard to when stuff is loaded. Unless you had a syntax error, or the player.motion() function was actually in the main.js file, or you had a network loading problem, your code should have worked. So one of those things must be your actual problem. You do not have to define your JavaScript in your html for it to work.
I recommend not making a file name have capitals. So change it from
<script src="isKeyPressed.js"></script>
to
<script src="iskeypressed.js"></script>
also change the file name too.
You could try something like this
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.3/p5.min.js"></script>
<script src="main.js"></script>
<script src="isKeyPressed.js"></script>
<script src="blocks.js"></script>
<script src="player.js"></script>
<script>
player.motion = function() {
if(isKeyPressed('w')) {
this.velocity.add(0,-5);
}
if(isKeyPressed('s')) {
this.velocity.add(0,5);
}
if(isKeyPressed('a')) {
this.velocity.add(-5,0);
}
if(isKeyPressed('d')) {
this.velocity.add(5,0);
}
}
</script>
</head>
<body>
</body>
</html>
This is importing all functions from the isKeyPressed.js file and therefore you are able to reference it in the <script> tag. You were not able to use isKeyPressed.js's functions in player.js because you cannot reference it.
I have various JS libraries in my web application, which are loaded before my main JS file (main.js). One of these libraries is jshashtable, but when I try to create a new Hashtable object in main.js, Google Chrome and Firefox throw a ReferenceError, complaining that the variable does not exist.
Here is the <head> of the application:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="/static/jquery-1.4.4.min.js"></script>
<script type="text/javacsript" src="/static/jshashtable-2.1.js"></script>
<script type="text/javascript" src="/static/main.js"></script>
Here is the problem line in main.js:
posts = new Hashtable();
This line is inside a function called init which is called when the page has finished loading (using the jquery $(document).ready() function).
Any reason why Hashtable is not global? Google maps and jquery objects work with no such problem. The source of jshashtable can be seen on Google code.
Updated answer: The problem is that you've got a typo in the script tag:
<script type="text/javacsript" src="/static/jshashtable-2.1.js"></script>
<!-- ^^---- here (the letters are transposed) -->
I couldn't understand why you would be running into a problem and decided to actually copy-and-paste your script tags and replicate the structure exactly on my machine. And things stopped working and my world tilted 3° counter-clockwise until I finally stared at them long enough to see it.
Provided that the jshashtable code really is at /static/jshashtable-2.1.js and your server is serving it up correctly (double-check on Chrome's resources tab in the dev tools), I can't see any reason for that. Your scripts are in the right order, and jshashtable's docs show using a global Hashtable (and the code link you gave clearly shows it creating one).
Edit: I've just replicated that same structure (same scripts, same order, using jQuery(document).ready(function() { ... });) on my own server, and am not having that problem. I can create a Hashtable and use its functions.
My HTML:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type='text/javascript' src='jquery-1.4.4.js'></script>
<script type='text/javascript' src='jshashtable-2.1.js'></script>
<script type='text/javascript' src='main.js'></script>
</head>
<body>
</body>
</html>
My main.js:
jQuery(document).ready(function() {
try {
var ht = new Hashtable();
display("typeof ht = " + typeof ht);
display("ht.size() = " + ht.size());
}
catch (e) {
display("Exception: " + e);
}
function display(msg)
{
$("<p>").html(msg).appendTo(document.body);
}
});
Only difference is I'm not using a /static prefix, and I'm absolutely certain that makes no difference.