I have the following code in the index.html page of my site, which when the page loads, draws a number of images to the HTML5 canvas:
window.onload = function(){
var sources = {};
sources[0] = document.getElementById("building").src,
sources[1] = document.getElementById("chair").src,
sources[2] = document.getElementById("drink").src,
sources[3] = document.getElementById("food").src,
sources[4] = document.getElementById("fridge").src,
sources[5] = document.getElementById("land").src,
sources[6] = document.getElementById("money").src,
sources[7] = document.getElementById("oven").src,
sources[8] = document.getElementById("table").src,
sources[9] = document.getElementById("van").src,
sources[10] = document.getElementById("burger").src,
sources[11] = document.getElementById("chips").src,
sources[12] = document.getElementById("drink").src,
sources[13] = document.getElementById("franchiseFee").src,
sources[14] = document.getElementById("wages").src,
sources[15] = document.getElementById("admin").src,
sources[16] = document.getElementById("cleaners").src,
sources[17] = document.getElementById("electricity").src,
sources[18] = document.getElementById("insurance").src,
sources[19] = document.getElementById("manager").src,
sources[20] = document.getElementById("rates").src,
sources[21] = document.getElementById("training").src,
sources[22] = document.getElementById("water").src,
sources[23] = document.getElementById("burger").src,
sources[24] = document.getElementById("chips").src,
sources[25] = document.getElementById("drink").src,
sources[26] = document.getElementById("creditors").src,
sources[27] = document.getElementById("electricity").src,
sources[28] = document.getElementById("food").src,
sources[29] = document.getElementById("hirePurchase").src,
sources[30] = document.getElementById("loan").src,
sources[31] = document.getElementById("overdraft").src,
sources[32] = document.getElementById("payeTax").src,
sources[33] = document.getElementById("tax").src
loadImages(sources, drawImage);
};
Sources is the array that I'm using to hold the images in JavaScript so that they can be drawn to the canvas once they've been loaded from a hidden section in my HTML.
This function currently works exactly as it's intended- it has a call to the loadImages function, which loads the images from a hidden section in the HTML into the JavaScript array, and calls the drawImage function on each of the images in the array.
But I also have another function that I want to be called with the window.onload:
The function I want to add to window.onload is this:
function drawGameElements(){
/* Draw a line for the 'score bar'. */
context.moveTo(0, 25);
context.lineTo(1000, 25);
context.stroke();
/* Draw current level/ total levels on the left, and current score on the right. */
context.font = "11pt Calibri"; /* Text font & size */
context.strokeStyle = "black"; /* Font colour */
context.strokeText(currentLevel + "/" + totalLevels, 10, 15);
context.strokeText(currentScore, 950, 15);
}
I tried adding a call to the function just below the loadImages(sources, drawImage); line in window.onload = function(){};
So that I now have:
window.onload = function(){
...
loadImages(sources, drawImage);
drawGameElements();
};
Although this partially works, in that it draws the line across the top of the canvas for the 'score bar' and writes "1/3" for the levels on the left hand side of the canvas just above the line, for some reason it doesn't draw the current score on the right hand side.
Also, as soon as I click on one of the images that's been drawn to the canvas, to drag and drop it around the canvas, the 'score bar' then disappears from the canvas completely.
Does anyone know why this is? How can I get the score bar to remain visible throughout the duration of the game, no matter what else happens on the canvas? Also, how can I get the currentScore variable to be displayed?
I would instead use a callback inside of loadImages to call drawGameElements. That way drawGameElements only runs after loadImages is finished. It sounds like you've created a race condition with your two functions.
If I where you, I would create the score bar outside of the canvas. Set its position to absolute and let it hover above the canvas at the desired location. That way you can just access it as HTML elements and do not need to worry about redrawing.
The major advantage of using HTML elements for these displays is that you don't need to redraw them, for example after moving the images around on the canvas. You also don't have to worry about how to refresh the values (on a canvas, just painting new values over the old ones will not be enough). This way you can just store the values in HTML elements and go wild on the canvas, knowing the score will always stay on top.
Related
I have been practicing using sprites for a game I am going to make and have watched and read a few tutorials, I thought I was close to getting my sprite to appear so I could finally start my game but while practicing I cant get it to work, I have dont 2 seperate tutorials where I can get the sprite and the background to appear by themselfs but cannot get them to work together, I have been using EaselJS too. some of the sprite animation code has been copied from tutorials too.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>sprite prac<title>
<!-- EaselJS library -->
<script src="lib/easel.js"></script>
<script>
// Initialize on start up so game runs smoothly
function init() {
canvas = document.getElementById("canvas");
stage = new Stage(canvas);
bg = new Image();
bg.src = "img/grassbg.jpg";
bg.onload = setBG;
stage.addChild(background);
imgMonsterARun = new Image();
imgMonsterARun.onload = handleImageLoad;
imgMonsterARun.onerror = handleImageError;
imgMonsterARun.src = "img/MonsterARun.png";
stage.update();
}
function handleImageLoad(e) {
startGame();
}
// Simple function for setting up the background
function setBG(event){
var bgrnd = new Bitmap(bg);
stage.addChild(bgrnd);
stage.update();
}
function startGame() {
// create a new stage and point it at our canvas:
stage = new createjs.Stage(canvas);
// grab canvas width and height for later calculations:
screen_width = canvas.width;
screen_height = canvas.height;
// create spritesheet and assign the associated data.
var spriteSheet = new createjs.SpriteSheet({
// image to use
images: [imgMonsterARun],
// width, height & registration point of each sprite
frames: {width: 64, height: 64, regX: 32, regY: 32},
animations: {
walk: [0, 9, "walk"]
}
});
// create a BitmapAnimation instance to display and play back the sprite sheet:
bmpAnimation = new createjs.BitmapAnimation(spriteSheet);
// start playing the first sequence:
bmpAnimation.gotoAndPlay("walk"); //animate
// set up a shadow. Note that shadows are ridiculously expensive. You could display hundreds
// of animated rats if you disabled the shadow.
bmpAnimation.shadow = new createjs.Shadow("#454", 0, 5, 4);
bmpAnimation.name = "monster1";
bmpAnimation.direction = 90;
bmpAnimation.vX = 4;
bmpAnimation.x = 16;
bmpAnimation.y = 32;
// have each monster start at a specific frame
bmpAnimation.currentFrame = 0;
stage.addChild(bmpAnimation);
// we want to do some work before we update the canvas,
// otherwise we could use Ticker.addListener(stage);
createjs.Ticker.addListener(window);
createjs.Ticker.useRAF = true;
createjs.Ticker.setFPS(60);
}
//called if there is an error loading the image (usually due to a 404)
function handleImageError(e) {
console.log("Error Loading Image : " + e.target.src);
}
function tick() {
// Hit testing the screen width, otherwise our sprite would disappear
if (bmpAnimation.x >= screen_width - 16) {
// We've reached the right side of our screen
// We need to walk left now to go back to our initial position
bmpAnimation.direction = -90;
}
if (bmpAnimation.x < 16) {
// We've reached the left side of our screen
// We need to walk right now
bmpAnimation.direction = 90;
}
// Moving the sprite based on the direction & the speed
if (bmpAnimation.direction == 90) {
bmpAnimation.x += bmpAnimation.vX;
}
else {
bmpAnimation.x -= bmpAnimation.vX;
}
// update the stage:
stage.update();
}
</script>
</head>
<body onload="init();">
<canvas id="canvas" width="500" height="500" style="border: thin black solid;" ></canvas>
</body>
</html>
There are a few places where you are using some really old APIs, which may or may not be supported depending on your version of EaselJS. Where did you get the easel.js script you reference?
Assuming you have a version of EaselJS that matches the APIs you are using, there are a few issues:
You add background to the stage. There is no background, so you are probably getting an error when you add it. You already add bgrnd in the setBackground method, which should be fine. If you get an error here, then this could be your main issue.
You don't need to update the stage any time you add something, just when you want the stage to "refresh". In your code, you update after setting the background, and again immediately at the end of your init(). These will fire one after the other.
Are you getting errors in your console? That would be a good place to start debugging. I would also recommend posting code if you can to show an actual demo if you continue to have issues, which will help identify what is happening.
If you have a newer version of EaselJS:
BitmapAnimation is now Sprite, and doesn't support direction. To flip Sprites, use scaleX=-1
Ticker no longer uses addListener. Instead it uses the EventDispatcher. createjs.Ticker.addEventListener("tick", tickFunction);
You can get new versions of the CreateJS libraries at http://code.createjs.com, and you can get updated examples and code on the website and GitHub.
I am working on a html 5 javascript game. It has a heavily textured background. I am looking at having one 3d background item and swapping it out on the fly. So in this instance we see a room with a closed door - then when a js event is fired - the image is swapped out to show an open door.
I am trying to create the function and although I can swap the image - I am unable to stop it from jumping.
so a new image path comes in - I null and remove the old backdrop and replace it with the new. I have read about adding it to the texture cache - not sure how to do that? Its my first time using pixijs
GroundPlane.prototype.resetBackdrop = function (imagePath) {
if(this.backdrop) {
this.backdrop.alpha = 0;
this.removeChild(this.backdrop);
this.backdrop = null;
this.backdrop = PIXI.Sprite.fromImage(imagePath);
this.backdrop.anchor.x = .5;
this.backdrop.anchor.y = .5;/*
this.backdrop.scale.x = 1.2;
this.backdrop.scale.y = 1.2;*/
this.addChildAt(this.backdrop, 0);
this.backdrop.alpha = 1;
}
};
The reason for the "jump" is that the image being swapped in takes some time to load before it can be displayed on the screen.
To prevent this, you can load the image into the TextureCache ahead of time, so when you swap images, there won't be any delay.
//set the initial backdrop image
this.backdrop = PIXI.Sprite.fromImage("Image1.png");
this.backdrop.anchor.x = 0.5;
this.backdrop.anchor.y = 0.5;
this.backdrop.scale.x = 1.2;
this.backdrop.scale.y = 1.2;
//this will store the second image into the texture cache
PIXI.Texture.fromImage("Image2.png");
//if you need to keep track of when the image has finished loading,
//use a new PIXI.ImageLoader() instead.
GroundPlane.prototype.resetBackdrop = function (imagePath)
{
//Update the image Texture
this.backdrop.setTexture(PIXI.Texture.fromFrame(imagePath));
};
I have JavaScript code in my site.
The code is using 2 identical photos-same size, same resolution - only different colors.
First photo is black and white photo - this is what the canvas presents.
Second photo is the same only with the original colors.
I have a button that triggers JS code - which generally removes a pixel from the black and white -and paints color pixel on the canvas. At first I used Math.random for the pixel locations.
And than I decided to use it by order. No matter where it starts or begging.. as long it will go
in this order (x,y)..(x+1,y).. until maximum x.. and than (x,y+1).. until maximum x.. and so on until all the black and white photo "transformed" into the colorful photo..
for some reason I just cant make it happen.. i tried a lot of techniques..
here is demo for global understanding:
demo is working sorry - they deactivated my free host :\ hope you still understand..
here is the original code- i just changed the last function : **removeDrawRandomPixel** ..it's just playing the function there and it should be fixed..
///////////////////////global variables///////////////////
var gray_url="bwcat.jpg"; //black and white image URI
var regular_url="cat.jpg"; //regular image URI
var n=100; //number of pixels changed per click
/////////////////////////////////////
document.addEventListener("DOMContentLoaded", function(){
var c=new EditableCanvas(document.getElementById('cnvs'));
grayScaleImage=new Image();
grayScaleImage.src=gray_url;
grayScaleImage.onload=function()
{
c.drawImage(this);
}
regularImage=new Image();
regularImage.src=regular_url;
regularImage.onload=function()
{
var p=getPixelArray(this);
btn.onclick=function(){
for(var i=1;i<=n&&p.length>0;i++){
removeDrawRandomPixel(p,c);
}
}
}
},false);
//create a Pixel object
function ImagePixel(x,y,r,g,b,a)
{
this.x=x;
this.y=y;
this.r=r;
this.g=g;
this.b=b;
this.a=a;
}
//object that allows custom methods
function EditableCanvas(canvas)
{
this.canvas=canvas;
this.context=canvas.getContext('2d');
this.width=canvas.width;
this.height=canvas.height;
this.pixelImage=this.context.createImageData(1,1);
//draw an entire picture and adjust the canvas for it
this.drawImage=function(image)
{
this.width=image.width;
this.height=image.height;
this.canvas.height=image.height;
this.canvas.width=image.width;
this.context.drawImage(image,0,0);
}
//draw a single pixel, ImagePixel pixel
this.drawPixel=function(pixel)
{
this.pixelImage.data[0]=pixel.r;
this.pixelImage.data[1]=pixel.g;
this.pixelImage.data[2]=pixel.b;
this.pixelImage.data[3]=pixel.a;
this.context.putImageData(this.pixelImage,pixel.x,pixel.y);//,pixel.x,pixel.y);
}
}
//the function returns an ordered array of Pixel pixels of the image at `src`.
function getPixelArray(img)
{
var pixelArray=[];
var cnvs=document.createElement('canvas');
cnvs.width=img.width;
cnvs.height=img.width;
var context=cnvs.getContext('2d');
context.drawImage(img,0,0);
var originalData = context.getImageData(0,0,img.width,img.height).data;
for(var i=0,pixelId=0,px;i<originalData.length;i+=4)
{
px=new ImagePixel(pixelId%img.width,Math.floor(pixelId/img.width),originalData[i],originalData[i+1],originalData[i+2],originalData[i+3]);
pixelArray.push(px);
pixelId++;
}
return pixelArray;
}
//the function remove a random pixel from pixelArray and draws it on editableCnvs
function removeDrawRandomPixel(pixelArray,editableCnvs)
{
var place=Math.floor(Math.random()*pixelArray.length);
var px=pixelArray.splice(place,1)[0];
editableCnvs.drawPixel(px);
}
html :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>canvas rules</title>
<script src="pixel.js"></script>
</head>
<body>
<canvas id="cnvs">
oh goddmamit no support
</canvas>
<button id="btn">click to convert</button>
</body>
</html>
I tried playing the last function.. because i know the answer is in the function,how to choose the pixels..
This is untested however this is what I would change the removeDrawRandomPixel function to. You are grabbing a random point in the array currently and passing it, so it could be starting on the blue component of one pixel and ending on the g component of another pixel.
//the function remove a random pixel from pixelArray and draws it on editableCnvs
function removeDrawRandomPixel(pixelArray,editableCnvs)
{
// width and height need to be the width and height of the canvas.
var width = canvas.width,
height = canvas.height,
x = Math.floor(Math.random()*width),
y = Math.floo(Math.random()*height);
var px = (y * width + x) * 4;
editableCnvs.drawPixel(px);
}
I am trying to make a program that will make video game maps. It worked perfectly fine before, but I added a variable, pixelWideAndTall, to automatically set the width and height of the canvas, and now it will only load the images in the top left corner. I just want to know why that is happening and how to fix it. If you need to see it, you'll have to copy and paste the code into whichever text editor you use. I would post a picture, but my reputation isn't high enough.
Thanks!
<html>
<head>
<title></title>
<script>
window.onload = function () {
var canvas = document.getElementById('paper');
var c = canvas.getContext('2d');
var posX=0; //All of my variables
var posY=0;
var pixelWideAndTall = prompt('How wide and tall do you want each picture to be? Make sure it\'s a number, please!');
while(isNaN(pixelWideAndTall)){
pixelWideAndTall = prompt('Alright, put in a number this time.');
}
var map = [
[0,0,1,0,0], //Map
[0,0,1,0,0],
[1,1,1,1,1],
[0,0,1,0,0],
[0,0,1,0,0]];
canvas.height = map.length * pixelWideAndTall;
canvas.width = map[0].length * pixelWideAndTall;
//Now for the pictures!
var grass = new Image();
grass.src='https://fbcdn-sphotos-g-a.akamaihd.net/hphotos-ak-ash3/v/t1.0-9/10252096_483877768405708_6915128458002047622_n.jpg?oh=0dd45ac8392b31dd89da67f2b74e0eef&oe=53ABDB2A&__gda__=1404253465_7ee03498efb21d7759862a3268769775';
var sand = new Image();
sand.src='https://scontent-b-sea.xx.fbcdn.net/hphotos-prn2/t1.0-9/10169458_483877771739041_423139715070437533_n.jpg';
var logA = new Image();
logA.src='https://fbcdn-sphotos-b-a.akamaihd.net/hphotos-ak-frc1/t1.0-9/10014648_483877575072394_6204441713213423736_n.jpg';
var logB = new Image();
logB.src='https://scontent-a-sea.xx.fbcdn.net/hphotos-frc1/t1.0-9/10247323_483877578405727_3664131849980667819_n.jpg';
for(var i=0;i<map.length;i++){
for(var j=0;j<map[i].length;j++){
switch(map[i][j]){
case 0:
c.drawImage(grass,posX,posY,pixelWideAndTall,pixelWideAndTall);
break;
case 1:
c.drawImage(sand,posX,posY,pixelWideAndTall,pixelWideAndTall);
/*Loops through every spot of the array. Based on what's
in that particular index, it draws a certain picture. */
break;
case 2:
c.drawImage(logA,posX,posY,pixelWideAndTall,pixelWideAndTall);
break;
case 3:
c.drawImage(logB,posX,posY,pixelWideAndTall,pixelWideAndTall);
break;
default:
alert('You must have put in an input that isn\'t supported yet. Please fix!');
break;
}
posX+=pixelWideAndTall;
}
posX=0;
posY+=pixelWideAndTall;
}
}
</script>
<style>
#paper{
border:3px solid black;
}
p{
font-size:6px;
}
</style>
</head>
<body> <!-- Just in case... -->
<canvas id='paper' height = 0 width = 0>Your browser does not support the HTML5 Canvas element. Either try a different browser, or just give it up.</canvas>
<p>You <strong><em>may</em></strong> need to refresh a few times for the image to load. Thank you!</p>
</body>
</html>
It's because the pixelWideAndTall variable is a string when returned from prompt.
It get converted to number when multiply is used which is why it works with this line:
canvas.height = map.length * pixelWideAndTall;
but not when adding - so what is happening is that the value is concatenated as a string instead at the plus operator with the posX etc. in the loop.
To fix simply force it to a number right away:
var pixelWideAndTall = prompt('...');
while(isNaN(pixelWideAndTall)){
pixelWideAndTall = prompt('Alright, put in a number this time.');
}
pixelWideAndTall *= 1; // this will force it to a number
optionally:
pixelWideAndTall = parseInt(pixelWideAndTall, 10);
Fiddle here
PS: You should really consider implementing an image loader for the images.
I'm trying to create a rectangle and a pointtext element, where the rectangle will be the
text element's container.
Without text element, everything works fine. When text element inserted, rectangle is pushed away. Well, rectangle is displayed at the correct position, but the points where it receives the events are pushed away.
Please see http://jsbin.com/abejim/1
Rectangle's visibility should increase when hovered. Hovering does not affect, but when mouse moved to 580,280 and around , it's visibility increases.
Any suggestions?
That jsbin seems to be working fine for me in Firefox. The rectangle is displayed in the correct location and hovering over the rectangle makes it highlight. Possibly the paper.js code has updated since you asked the question.
It looks like you asked the same question on the paper.js mailing list. For future reference here, the response was:
pointtext takes relative coordinates and you r trying to give absolute coordinates.
try this one:
var size = new paper.Size(125, 75); //SM size to paper size
var rectangle = new paper.Rectangle({ x: 0, y: 0 }, size); //(top_left, bottom_right)
var cornerSize = new paper.Size(10, 10); //rounding of edges
var shape = new paper.Path.RoundRectangle(rectangle, cornerSize);
shape.strokeWidth = 3;
shape.strokeColor = '#525252';
shape.fillColor = '#FFFFFF';
shape.name = 'shape';
var stateNameTxt = new paper.PointText(10, 65);
stateNameTxt.content = state_name;
stateNameTxt.name = 'stateNameTxt';
var state = new paper.Group(); //create group
state.name = state_name;
state.opacity = 0.8;
state.addChild(shape); //add shape to grpup
state.addChild(stateNameTxt); //add pointtext to group