I just started my first JavaScript game project, and I am not sure what is the best way to load assets (images and sounds) in JS. The problem is I am using inheritance, so there is a problem with loading asset when needed ( example: Paddle extends Entity ):
Paddle:
function Paddle( layer )
{
Entity.call(this, layer);
}
Paddle.prototype.SetAnimations = function()
{
this.image.onload = // INITIALIZE this.sprite using this.image
this.image.src = "js/assets/paddle/blue/paddle_blue_idle.png";
};
Entity:
function Entity(layer)
{
this.SetAnimations();
layer.add( this.sprite );
}
So the problem here is, when I am using Paddle constructor, the first thing is to call Entity ( parents ) constructor. Then Entity constructor use Paddle.prototype.SetAnimations to set image source and after load, with KineticJS i am creating Sprite using this loaded Image. But before this happens, Entity tries to add this.sprite to the layer ( and the sprite isnt already initialised ).
My question is, what is the best way in JS to load assets ( before every scene/at whole game startup OR #runtime using maybe event listeners?? ). Any help would be appreciated.
That depends on the size of your game / your assets. I personally load my assets before the game / at a loading screen. I use PxLoader for loading assets. I then store the images / assets in a big array in my game and access them when I need them.
Related
I'm currently in the process of writing a point and click adventure game using TypeScript and Electron (outside of work FWIW). Now that I have the basic structure with some user input and graphics routines up and running, I've turned my attention to optimising what I have so I can leave it in the background and move on to the next stage in the process.
Right now I merely create a new Image() object with its "src" attribute set to my desired PNG, and hold the resulting HTMLImageElement in memory. I then draw the element to the canvas using drawImage on every frame.
Throwing PNGs to the canvas every frame feels wrong and inneficient. What would be the best way to hold image data in memory to draw it to the Canvas as efficiently as possible?
Right now, TS classes that implement my IDrawable interface look like this.
private Sprite: HTMLImageElement;
public GetImage()
{
return this.Sprite;
}
public LoadImage(src: string)
{
var image = new Image();
image.src = src;
this.Sprite = image;
}
I'm working with Phaser and I'm using the module pattern, creating a module that has a prototype of Object.create(Phaser.Sprite.prototype) and creating an instance of that in the main module.
The problem is the sprite seems to be created in the main module in the create function but the image of the sprite is not loading and I can't find the problem or set the image.
Thanks so much!!
In Player.js:
// doenst work at all with game.load... on top
//game.load.spritesheet('playersheet', 'resources/data/foo.png', 64, 64);
Player = function(game, x, y){
game.load.spritesheet('playersheet', 'resources/data/foo.png', 64, 64);
Phaser.Sprite.call(this, game, x, y, 'playersheet');
this.anAttribute = 'whatever'; this.anotherAttribute = 20;};
Player.prototype = Object.create(Phaser.Sprite.prototype);
Player.prototype.constructor = Player;
throws:
Phaser.Loader - script[Player]: error loading asset from URL resources/js/Player.js
and
Phaser.Cache.getImage: Key "playersheet" not found in Cache.
main:
in preload
game.load.script('Player', 'resources/js/Player.js');
in create
testPlayer = new Player(game,77,77);
The usual way of preloading assets is by calling the loader inside the preload() method of a Phaser.State (just like you do with Player.js). The state manager will only move past preload() after all load calls are executed and all the needed resources are fetched. Yes, it might be inconvenient if you have a lot of assets that you don't want to load at once, but the other way would be to check yourself if the spritesheet has loaded, which might introduce lag in the creation of the Player (plus it seems that there isn't a way to check for individual assets, only for the whole queue).
If you still want to load it manually, that's a way to do it (haven't tested it):
game.load.spritesheet('playersheet', 'resources/data/foo.png', 64, 64);
game.load.start();
game.load.onLoadComplete.add(function() {
// do the rest of the stuff here
}, this);
... but this way it becomes messy if you need another callback in there, plus it only works if the player spritesheet is the only thing to load at that point.
As for why it doesn't find Player.js, you need to supply a path relative to main.js, so if they're in the same directory, go with just the filename.
With Phaser I am working on a game. This game rewards the player with an item that is not capable of being preloaded. After an Ajax call I was hoping to load the image and then display it in the phaser animation. Is there anyway to do this?
Flow: Game is playing
Game Completes and Ajax Call is made.
Ajax responds with which image to use.
Phaser loads image and displays what they won.
You can use Phaser's loader to load an image at anytime by invoking
game.load.image('referenceName', 'assets/pics/file.jpg');
then you can set an event like the ones at
http://phaser.io/examples/v2/loader/load-events
game.load.onLoadComplete.add(aFunctionToCall, this);
But most importantly don't forget to actually tell the loader to start after you've set everything up.
game.load.start();
Lazzy loading in Phaser 3 can be done by using the Phaser.Loader.LoaderPlugin(scene)
lazzyLoading:function(){
var name = 'card-back';
// texture needs to be loaded to create a placeholder card
const card = this.add.image(WIDTH/2, HEIGHT/2, name);
let loader = new Phaser.Loader.LoaderPlugin(this);
// ask the LoaderPlugin to load the texture
loader.image(name, 'assets/images/demon-large1.png');
loader.once(Phaser.Loader.Events.COMPLETE, () => {
// texture loaded so use instead of the placeholder
card.setTexture(name)
});
loader.start();
}
This might be a obvious question but I haven't seen it addressed anywhere, but I'm trying to figure out why my web export of my Processing sketch is not retrieving saved images? I'm thinking I should package the image with the other files, but just dropping the image in the same folder doesn't seem to work. I also know that I am exporting it correctly because when I export sketches without saved images (just shapes or text created within the program), it works just fine.
Does anyone have any experience with this? If this helps at all, the code is below (it's really very simple). Thank you!
draw.pde
void setup () {
size(1280,800);
background(255,255,255);
}
void draw() {
PImage img;
img = loadImage("drake.png");
image(img, mouseX, mouseY);
}
Processing's JavaScript mode uses asynchronous loading of images. That means that the image is loaded in the background, and it isn't loaded by the time you try to draw it.
A quick fix (which you should use anyway, even in Java mode) is to not load your images in the draw() function: you'll be reloading the same file 60 times per second! Instead, load it once at the start of the sketch.
Also, if you're using Processing.js, then you need the preload at the top.
/* #pjs preload="drake.png"; */
PImage img;
void setup () {
size(1280,800);
img = loadImage("drake.png");
background(255,255,255);
}
void draw() {
image(img, mouseX, mouseY);
}
More info in the Processing.js reference here.
using Processing.js, I would like to know if what I'm trying to do is even possible. I've looked on Pomax's tutorials, Processing.js the quick start of JS developers page, PJS the Google group, here, and I can't seem to find an answer to the question, "Can you have multiple canvases, such that they all use the same processing sketch (in my example below, engine.pde) each canvas passing variables to the sketch with the result being processing opens different images in each canvas, but edits them the same way.
So to sum up, I would like to use only 1 processing sketch, with many canvases, with each canvas telling the processing sketch a different name, and having a corresponding background image open in the sketch in each canvas.
<!DOCTYPE html><html><head><meta charset="utf-8">
<script src="../../../processingjs/processing.js"></script>
<script>
// Tell sketch what counts as JavaScript per Processing on the Web tutorial
var bound = false;
function bindJavascript(instance) { // Can I pass 'instance' like this?
var pjs = Processing.getInstanceById(instance);
if(pjs!=null) {
pjs.bindJavascript(this);
bound = true; }
if(!bound) setTimeout(bindJavascript, 250); }
bindJavascript('B104');
bindJavascript('B105');
function drawSomeImages(instance) {
// This is where I am trying to tell processing that each canvas has a number, and the number is assigned to a corresponding image.
var pjs = Processing.getInstanceById(instance);
var imageName = document.getElementById(instance);
pjs.setup(instance);
}
drawSomeImages('B104');
drawSomeImages('B105');
// Where is the Mouse?
function showXYCoordinates(x, y) { ... this is working ... }
// Send images back to server
function postAjax(canvasID) { ... AJAX Stuff is working ...}
</script>
</head>
<body>
<canvas id="B104" data-processing-sources="engine.pde" onmouseout="postAjax('B104')"></canvas>
<canvas id="B105" data-processing-sources="engine.pde" onmouseout="postAjax('B105')"></canvas>
</body>
</html>
And on the processing side:
/* #pjs preload=... this is all working ; */
// Tell Processing about JavaScript, straight from the tutorial...
interface JavaScript {
void showXYCoordinates(int x, int y);
}
void bindJavascript(JavaScript js) {
javascript = js;
}
JavaScript javascript;
// Declare Variables
PImage img;
... some other variables related to the functionality ...
void setup(String instance) {
size(300,300);
img = loadImage("data/"+instance+".png");
//img = loadImage("data/B104.png"); Example of what it should open if canvas 104 using engine.pde
background(img);
smooth();
}
void draw() { ... this is fine ... }
void mouseMoved(){ ... just calls draw and checks if mouse is in canvas, fine... }
if(javascript!=null){
javascript.showXYCoordinates(mouseX, mouseY);
}}
Just add a million canvas elements to your page all with the same data-processing-sources attribute, so they all load the same file. Processing.js will build as many sketches as you ask for, it doesn't care that the sketch files are the same for each one =)
(Note that what you described, one sketch instance rendering onto multiple canvases, giving each a different image, is not how sketches work. A sketch is tied to a canvas as its drawing surface. However, you can make a million "slave" sketches whose sole responsibility is to draw images when so instructed from JavaScript, and making the master sketch tell JavaScript to tell slave sketches to draw. Note that this is very, very silly. Just make JavaScript set the image, you don't need Processing if you're just showing images really)