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.
Related
ive ventured into the world of PIXI and JS, new programming language for me, liking the way it is right now but i have an issue.
I am a bit confused with the TextureCache and the loader. If you look at part of my code i try to add 3 different images to the screen. Ive been following the 'Get Started section' of the pixi website. I wanted to add their cat image, which i have, the tileset image (all of it)* and then a tile of the tileset image.
The issue is, i create 3 new sprite instances and the tileset image shows the area ive set for the tile(rocket) when i want it to show the whole tileset. Ive loaded in the tileset iin the cahce and the loader.
Why does tile show the cropped image and not the whole image?
Am i using the cache correctly to just store images?
Am i using the resources method properly to locate the image FROM the cache or the loader?
Is there any point of the cache?
my thoughts**
when you use the rectangle method, it destroys the original image and the cropped version is now tileset1 (the name of my image)?
<html>
<body>
<script src="pixi.js"></script>
<script>
//Aliases
let Application = PIXI.Application,
loader = PIXI.loader,
resources = PIXI.loader.resources,
Sprite = PIXI.Sprite,
Rectangle = PIXI.Rectangle,
TextureCache = PIXI.utils.TextureCache;
let app = new PIXI.Application({
width: 1000,
height: 600,
antialias: true,
transparent: false,
resolution: 1
}
);
//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);
TextureCache["tileset1.png","images/3.png"];
//load an image and run the `setup` function when it's done
loader.add(["images/3.png","tileset1.png"]).load(setup);
//This `setup` function will run when the image has loaded
function setup() {
let texture = TextureCache["tileset1.png"];
let rectangle = new Rectangle(96,64,32,32);
texture.frame = rectangle;
//Create the cat sprite, use a texture from the loader
let card = new Sprite(resources["images/3.png"].texture);
let tile = new Sprite(resources["tileset1.png"].texture);
let rocket = new Sprite(texture);
card.scale.set(0.06,0.06);
tile.x=400;
tile.y=400;
rocket.x=100;
rocket.y=100;
//Add the cat to the stage
app.stage.addChild(card);
app.stage.addChild(tile);
app.stage.addChild(rocket);
app.renderer.render(app.stage);
}
</script>
</body>
</html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.2.4/pixi.js"></script>
Is there any point of the cache? - this question seems to be most important from your questions :)
Searching around about "pixi.js" and "TextureCache" gives following answers for example:
https://github.com/pixijs/pixi.js/issues/4053
MySecret commented on May 23, 2017:
the docs has no specs about PIXI.utils.TextureCache
...
englercj commented on May 26, 2017
This is intentional, it is not meant as a public-facing API. It is an internal cache used by some texture creation methods.
https://www.html5gamedevs.com/topic/17788-loader-and-texturecache-tutorial-anywhere/
xerver - Pixi.js Moderator:
Here is the loader: https://github.com/englercj/resource-loader
The code is really well documented, and there are examples on the readme. The pixi examples also use the loader a few times: http://pixijs.github.io/examples/
The TextureCache is an internal mechanism, there is rarely any reason you should even know it exists.
https://www.html5gamedevs.com/topic/25575-pixiloaderresources-or-texturecache/
xerver - Pixi.js Moderator:
Dont do this:
let e = PIXI.utils.TextureCache[player.img];
Instead use the resources the loader loaded for you:
let e = PIXI.loader.resources[player.img].texture;
...
TLDR: Usually TextureCache shouldnt be used directly :)
See also:
this explanation: https://www.html5gamedevs.com/topic/9255-pixijs-caching/?tab=comments#comment-55233
http://pixijs.download/release/docs/PIXI.BaseTexture.html#.addToCache
^ example of usage: https://jsfiddle.net/themoonrat/br35x20j/
I need some help understanding what the best practice is for creating a PIXI.extras.AnimatedSprite from spritesheet(s). I am currently loading 3 medium-sized spritesheets for 1 animation, created by TexturePacker, I collect all the frames and then play. However the first time playing the animation is very unsmooth, and almost jumps immediately to the end, from then on it plays really smooth. I have read a bit and I can see 2 possible causes. 1) The lag might be caused by the time taken to upload the textures to the GPU. There is a PIXI plugin called prepare renderer.plugins.prepare.upload which should enable me to upload them before playing and possibly smoothen out the initial loop. 2) Having an AnimatedSprite build from more than one texture/image is not ideal and could be the cause.
Question 1: Should I use the PIXI Prepare plugin, will this help, and if so how do I actually use it. Documentation for it is incredibly limited.
Question 2: Is having frames across multiple textures a bad idea, could it be the cause & why?
A summarised example of what I am doing:
function loadSpriteSheet(callback){
let loader = new PIXI.loaders.Loader()
loader.add('http://mysite.fake/sprite1.json')
loader.add('http://mysite.fake/sprite2.json')
loader.add('http://mysite.fake/sprite3.json')
loader.once('complete', callback)
loader.load()
}
loadSpriteSheet(function(resource){
// helper function to get all the frames from multiple textures
let frameArray = getFrameFromResource(resource)
let animSprite = new PIXI.extras.AnimatedSprite(frameArray)
stage.addChild(animSprite)
animSprite.play()
})
Question 1
So I have found a solution, possibly not the solution but it works well for me. The prepare plugin was the right solution but never worked. WebGL needs the entire texture(s) uploaded not the frames. The way textures are uploaded to the GPU is via renderer.bindTexture(texture). When the PIXI loader receives a sprite atlas url e.g. my_sprites.json it automatically downloads the image file and names it as mysprites.json_image in the loaders resources. So you need to grab that, make a texture and upload it to the GPU. So here is the updated code:
let loader = new PIXI.loaders.Loader()
loader.add('http://mysite.fake/sprite1.json')
loader.add('http://mysite.fake/sprite2.json')
loader.add('http://mysite.fake/sprite3.json')
loader.once('complete', callback)
loader.load()
function uploadToGPU(resourceName){
resourceName = resourceName + '_image'
let texture = new PIXI.Texture.fromImage(resourceName)
this.renderer.bindTexture(texture)
}
loadSpriteSheet(function(resource){
uploadToGPU('http://mysite.fake/sprite1.json')
uploadToGPU('http://mysite.fake/sprite2.json')
uploadToGPU('http://mysite.fake/sprite3.json')
// helper function to get all the frames from multiple textures
let frameArray = getFrameFromResource(resource)
let animSprite = new PIXI.extras.AnimatedSprite(frameArray)
this.stage.addChild(animSprite)
animSprite.play()
})
Question 2
I never really discovered and answer but the solution to Question 1 has made my animations perfectly smooth so in my case, I see no performance issues.
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.
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.
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)