Having trouble finding sprite on canvas of html5 game - javascript

I am new at learning coding and game development. I have attempted to make a HTML5 simple game based off my online instructor's. Looking though my html coding, I believe it is exactly how my instructor did it. Problem is that I cannot seem to find my sprite.
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Tico's Flight</title>
<script type="text/javascript" src="simpleGame.js"></script>
<script type="text/javascript">
var scene;
var bird;
function init() {
scene = new Scene();
bird = new Sprite(scene, "birdgame.png", 50, 50);
bird.setAngle(270);
bird.setSpeed(0);
scene.start();
}
function update() {
scene.clear();
if (keyDown[K_UP]) {
bird.setSpeedBy(1);
}
if (keyDown[K_DOWN]) {
bird.changeSpeedBy(-1);
}
if (keyDown[K_LEFT]) {
bird.changeAngleBy(-5);
}
if (keyDown[K_RIGHT]) {
bird.changeAngleBy(5);
}
bird.update();
}
</script>
</head>
<body onload="init()">
<center>
<h1>Fly Tico!</h1>
</body>
</html>

I figured it out! Something simple, as I am learning it usually is: I typed "keyDown" instead of "keysDown". Got my bird visible and flying around.

Related

How to use p5.js sound in instance mode

I'm trying to make a website with multiple p5 canvases on the same page, so after a lot of research, I came to the conclusion that the most adequate way to do that is by using instance mode on p5.
I spent the whole day trying to understand the instance mode, i even found a converter online that converts it for me, but I'm trying to do it all by my self using it just to check errors. The problem is that i can't find a way to use sound in my sketch using instance mode. the code i have is a lot more complex, but even trying just the basic it still does not work.
var s = function(p) {
let song;
p.preload = function() {
p.song = load('thunder.mp3')
}
p.setup = function() {
p.createCanvas(720, 200);
p.background(255, 0, 0);
p.song.loop();
};
};
var myp5 = new p5(s, 'c1');
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
<style> body {padding: 0;
margin: 0;
}
<meta charset="UTF-8">
</style>
</head>
<body>
<div id="c1"></div> <br>
<div id="c2"></div>
</body>
</html>
you can test it here: https://editor.p5js.org/jgsantos.dsn/sketches/rUWb6Nurt
This code works great in the global mode:
let song;
function preload() {
song = loadSound('thunder.mp3');
}
function setup() {
createCanvas(720, 200);
background(255,0,0);
song.loop();
}
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
You can test it here https://editor.p5js.org/jgsantos.dsn/sketches/_lQcDqOsp
It shows this error: "Uncaught ReferenceError: load is not defined (: line 9)"
What am I'm doing wrong?
Thanks in advance!
Please try to post the exact code you're running. Your question contains different code than the link you posted in the comments.
But taking a step back, here's how I would think about instance mode and libraries:
Instance mode means that the variables and functions that belong to a sketch are now referenced via a variable, in your case the p variable.
But variables and functions that belong to a library are still referenced directly, i.e. in "global mode".
In other words, you don't want to reference the load() (or is it loadSound()?) function using instance mode. You should still reference that function directly, since it's coming from a library instead of from a specific sketch.

Defining Position in Phaser

I'm making a very basic game in Javascript using the Phaser Directory. I have made games with Phaser many times before but this time I have come across an issue that is new to me and I've never had before. I've looked it up online and no one seems to have had this problem. In phaser it is telling me my "x" is not defined when I refer to x as a position. How would I go about defining x as a position or what error am I facing? I and currently using VS Code on mac with a Chrome browser and newest version of Phaser.
Thanks for the Help,
Murdoc
var game = new Phaser.Game(640, 360, Phaser.Auto);
var car1;
var GameState = {
preload: function(){
game.load.image("thecar1", "../assets/car_1.png");
//game.load.image("thecar2", "../assets/car_2.png");
//game.load.image("backgroundImg", "../assets/thebackground.png");
},
create: function(){
var car1 = game.add.sprite(200, 270, "thecar1");
//var car2 = game.add.sprite(200, 270, "thecar2");
/*game.input.keyboard.addKey(Phaser.Keyboard.W)
.onDown.add(car1Up);*/
game.input.keyboard.addKey(Phaser.Keyboard.A)
.onDown.add(car1Left);
/*game.input.keyboard.addKey(Phaser.Keyboard.S)
.onDown.add(car1Down);
game.input.keyboard.addKey(Phaser.Keyboard.D)
.onDown.add(car1Right);*/
},
update: function(){
}
};
function car1Left() {
car1.x = car1.x + 10;
}
game.state.add('GameState', GameState);
game.state.start('GameState');
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pixel Soccer</title>
<script src="phaser.js"></script>
<script src="main.js"></script>
<style>
body {
background: white;
margin: 0;
padding: 0;
}
body canvas {
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body>
</body>
</html>
You're declaring the same variable twice. You're dealing with what's called "variable shadowing". When you do var car1 = game.add.sprite(200, 270, "thecar1"); in the create() function, the scope changes to function-only and the variable with the sprite you assign to it is only available in the scope of that function. The error basically comes to tell you that var car1 that you declared outside of the function scope is undefined (which it is). Try doing just car1 = game.add.sprite(200, 270, "thecar1"); inside create() and it should be fine.

What's the proper way to destroy instance of Phaser.Game?

In the trivial case of creating and then destroying an instance of Phaser.Game there appears to be a memory leak. Below is a complete working example: click the button to create an instance, click again to destroy it. Repeatedly clicking the button causes memory usage to grow without bound. Is there something I'm missing about the phaser lifecycle that I should be doing instead?
I'm posting this as a code snippet rather than a jsfiddle because you need to look a a memory profiler or something like that to see the problem and so jsfiddle just complicates the matter.
<!doctype html>
<html>
<head>
<meta charset="UTF-8"/>
<title>test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser-ce/2.8.1/phaser.js">
</script>
</head>
<body>
<button id="button">Click</button>
<div id="canvas"></div>
<script>
window.onload = function() {
var d, n, game;
d = document.getElementById('button');
n = document.getElementById('canvas');
function preload() {
}
function create() {
}
function update() {
}
function handler() {
if(game) {
game.destroy();
game = null;
} else {
game = new Phaser.Game(800, 600, Phaser.AUTO, n, {
preload: preload,
create: create,
update: update
});
}
}
d.onclick = handler;
};
</script>
</body>
</html>
Answering (at least partially) my own question, the problem is in Phaser.CanvasPool. Whenever a new Phaser instance is created a new canvas is created and added to the pool. Destroying the instance dows not remove the canvas from the pool or mark it as available for re-use.
You can kinda-sorta hack this into working by doing something crude like setting Phaser.CanvasPool.pool = [] after calling game.destroy(), but that won't work if you have multiple phaser instances going.
If anyone knows what the correct workflow is supposed to be I'd love to know---Phaser.CanvasPool is one of phaser's points of contact with PIXI and all of those appear to be poorly documented.
EDIT: Found the source of the memory leak. It's Phaser.Utils.Debug.boot(), which adds a new canvas to the pool every time it's called, which by default is every time a phaser instance is created and booted.
The problem affects only WebGL-rendered canvases when enableDebug is enabled (which is the default).
For completeness, here's an edited version of the code above which disables debugging and therefore does not exhibit the memory leak:
<!doctype html>
<html>
<head>
<meta charset="UTF-8"/>
<title>test</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/phaser-ce/2.8.1/phaser.js"></script>
</head>
<body>
<button id="button">Click</button>
<div id="canvas"></div>
<script>
window.onload = function() {
var d, n, game;
d = document.getElementById('button');
n = document.getElementById('canvas');
function preload() {
}
function create() {
}
function update() {
}
function handler() {
if(game) {
game.destroy();
game = null;
} else {
game = new Phaser.Game({
width: 800,
height: 600,
renderer: Phaser.AUTO,
parent: n,
enableDebug: false,
state: {
preload: preload,
create: create,
update: update
},
});
}
}
d.onclick = handler;
};
</script>
</body>
</html>

PIXI.js render not working

I'm following this tutorial (http://www.yeahbutisitflash.com/?p=5226), using Chrome, and can't figure out why this isn't working. Here is my console output:
init() successfully called.
pixi.dev.js:224 Pixi.js v2.2.7 - webGL http://www.pixijs.com/ ♥♥♥
index2.html:26 PIXI.WebGLRenderer
index2.html:28 render complete.
And here is my code:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Endless Runner Game Demo</title>
</head>
<body onload="init();">
<div align="center">
<canvas id="game-canvas" width="512" height="384"></canvas>
</div>
<script src="js/pixi.js-master/bin/pixi.dev.js"></script>
<script>
function init() {
console.log("init() successfully called.");
stage = new PIXI.Stage(0x66FF99);
renderer = PIXI.autoDetectRenderer(
512,
384,
document.getElementById("game-canvas")
);
console.log(renderer);
renderer.render(stage);
console.log("render complete.");
}
</script>
</body>
</html>
Yet, it displays nothing. The tutorial says I should see the background color set on the stage at this point.
Thanks.
The third argument of PIXI.autoDetectRenderer should be an Object, not an element. You should set the Object property "view" to be your canvas element.
var renderer = PIXI.autoDetectRenderer( 512, 384, {
view: document.getElementById("game-canvas")
});
Also note that you may need to run a local server in order to view it in Chrome.

Internet Explorer 8 Messing Up My Bulletgraphs

I've created HTML and JavaScript files to display bulletgraphs, using the 'canvas' HTML5 tag. I've tried it in Chrome and it works nicely and changes width along with the size of the browser. I have to have this working in IE8, too, so I've used Excanvas, which is working in all except one way: when I resize the browser I get remnants of the valueIndicator. This only happens on IE8.
I've tried looking round for information on redrawing the canvas but I don't think this is the issue. Can anyone see where I'm going wrong, please?
EDIT
I'm keeping the complete code at the bottom, however, following advice I've cut my code down somewhat.
In IE8 it looks like this:
In Chrome it looks like this:
When I refresh the IE8 page it looks OK again.
Cut-down Bulletgraph.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bulletgraph</title>
<!--[if IE]><script src="excanvas.js"></script><![endif]-->
</head>
<body>
<canvas id="graph1"></canvas>
<script src="Scripts.js"></script>
<script>
drawGraphs();
window.onresize=function() { drawGraphs() };
function drawGraphs() {
drawBulletGraph(getScreenWidth(),300,1000,350,"graph1");
}
</script>
</body>
</html>
Complete code:
Cut-down Scripts.js:
function drawBulletGraph (cwidth, left, right, loValue, id) {
var canvas=document.getElementById(id);
var cheight=30;
var multiplier=cwidth/(right-left);
canvas.width=cwidth;
canvas.height=cheight;
var valueIndicator=canvas.getContext("2d");
valueIndicator.lineWidth="1";
valueIndicator.moveTo((loValue-left)*multiplier,0);
valueIndicator.lineTo((loValue-left)*multiplier,cheight);
valueIndicator.fill();
valueIndicator.stroke();
}
function getScreenWidth () {
return (window.innerWidth || document.documentElement.clientWidth)/7;
}
Bulletgraph.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bulletgraph</title>
<!--[if IE]><script src="excanvas.js"></script><![endif]-->
</head>
<body>
<canvas id="graph1"></canvas><br>
<canvas id="graph2"></canvas>
<script src="Scripts.js"></script>
<script>
drawGraphs();
window.onresize=function() { drawGraphs() };
function drawGraphs() {
drawBulletGraph(bgWidth(getScreenWidth()),300,400,450,600,700,1000,800,350,850,"graph1");
drawBulletGraph(bgWidth(getScreenWidth()),250,450,500,650,700,1200,600,350,850,"graph2");
}
</script>
</body>
</html>
Scripts.js:
function drawBulletGraph (cwidth, left, loRed, loAmber, hiAmber, hiRed, right, value, loValue, hiValue, id) {
var canvas=document.getElementById(id);
var cheight=16;
var colour="#008000";
if (value <= loRed || value >= hiRed)
{
colour="#FF0000";
}
else if (value <= loAmber || value >= hiAmber)
{
colour="#FFA500";
}
var multiplier=cwidth/(right-left);
canvas.width=cwidth;
canvas.height=cheight;
var red=canvas.getContext("2d");
red.fillStyle="#F4C3C6";
red.fillRect(0,0,cwidth,cheight);
var amber=canvas.getContext("2d");
amber.fillStyle="#F4F6C6";
amber.fillRect((loRed-left)*multiplier,0,(hiRed-loRed)*multiplier,cheight);
var green=canvas.getContext("2d");
green.fillStyle="#CCE5CC";
green.fillRect((loAmber-left)*multiplier,0,(hiAmber-loAmber)*multiplier,cheight);
var valueIndicator=canvas.getContext("2d");
valueIndicator.fillStyle=colour;
valueIndicator.strokeStyle=colour;
valueIndicator.lineWidth="2";
valueIndicator.moveTo((loValue-left)*multiplier,0);
valueIndicator.lineTo((loValue-left)*multiplier,cheight);
valueIndicator.moveTo((loValue-left)*multiplier,cheight/2);
valueIndicator.lineTo((hiValue-left)*multiplier,cheight/2);
valueIndicator.moveTo((hiValue-left)*multiplier,0);
valueIndicator.lineTo((hiValue-left)*multiplier,cheight);
valueIndicator.moveTo(((value-left)*multiplier)-(cheight/2),cheight/2);
valueIndicator.stroke();
valueIndicator.lineWidth="1";
valueIndicator.lineTo((value-left)*multiplier,cheight);
valueIndicator.lineTo(((value-left)*multiplier)+(cheight/2),cheight/2);
valueIndicator.lineTo((value-left)*multiplier,0);
valueIndicator.lineTo(((value-left)*multiplier)-(cheight/2),cheight/2);
valueIndicator.fill();
valueIndicator.stroke();
}
function getScreenWidth () {
return window.innerWidth || document.documentElement.clientWidth;
}
function bgWidth (screenWidth) {
var graphWidth=screenWidth/7;
if (graphWidth<70) {graphWidth=70;}
if (graphWidth>260) {graphWidth=260;}
return graphWidth;
}
I've managed to get a solution. It feels like a bit of a hack but it does the trick. Basically it involves drawing a white line round the canvas and filling it each time it's drawn again. The following code goes between the var valueIndicator=canvas.getContext("2d"); and the valueIndicator.lineWidth="1"; lines:
valueIndicator.fillStyle="#FFFFFF";
valueIndicator.strokeStyle="#FFFFFF";
valueIndicator.moveTo(0,0);
valueIndicator.beginPath();
valueIndicator.lineTo(0,cheight);
valueIndicator.lineTo(cwidth,cheight);
valueIndicator.lineTo(cwidth,0);
valueIndicator.closePath();
valueIndicator.fill();
valueIndicator.stroke();
valueIndicator.strokeStyle="#000000";
I've tried it in the full code and it works. If anyone has a more elegant solution, and I'm sure there must be many, I would still love to see them.

Categories

Resources