Jump to content

Resize screen in pixel art - Pixi.js


suyashmshephertz
 Share

Recommended Posts

Hey!, I have started learning Pixi.js.

 

What I am trying to do is fill the whole screen, but preserve the pixel art style and ratio.

I tried using renderer.resize() but it simply changes the viewport.

 

Suppose I have a game at 320x240 resolution, and my screen is 1366x768. So my game should zoom 3x and new resolution should be 960x720. But the new screen should use nearest neighbor scaling 

Link to comment
Share on other sites

Note that you can also set scaling on a per-texture basis. Setting the default scaling will make all new textures take that scale mode by default.

 

I think I am going to update this code so that the default scale mode can be changed at any time, and all textures (even existing ones) that do not have an explicit scale mode will use the new default.

Link to comment
Share on other sites

Note that you can also set scaling on a per-texture basis. Setting the default scaling will make all new textures take that scale mode by default.

 

I think I am going to update this code so that the default scale mode can be changed at any time, and all textures (even existing ones) that do not have an explicit scale mode will use the new default.

 

 

Hi there!

 

You could set the scaling mode of the textures?

If you add this line before loading your assets ->

 

PIXI.BaseTexture.SCALE_MODE.DEFAULT = PIXI.BaseTexture.SCALE_MODE.NEAREST;

 

it should resize correctly. thanks!

 

Hey, since I was using 1.3.0, your solution didn't worked. So, I updated to 1.4.2

Now when I run following code, my canvas re-sizes to 640, 480, but there is no zooming. But I guess this is they way it should work. Now the problem is, 'PIXI.BaseTexture.SCALE_MODE.DEFAULT = PIXI.BaseTexture.SCALE_MODE.NEAREST;' causes a flickering. Animation has some noisiness.  

		var assetsToLoad = ["sprites.json"];		var loader = new PIXI.AssetLoader(assetsToLoad);		PIXI.BaseTexture.SCALE_MODE.DEFAULT = PIXI.BaseTexture.SCALE_MODE.NEAREST;		loader.onComplete = onLoadDone;		loader.load();		var stage = new PIXI.Stage(0x34495e);		var renderer = PIXI.autoDetectRenderer(320, 240);		renderer.resize(640, 480);		document.body.appendChild(renderer.view);

If I use following code,

 

		var assetsToLoad = ["sprites.json"];		var loader = new PIXI.AssetLoader(assetsToLoad);		PIXI.BaseTexture.SCALE_MODE.DEFAULT = PIXI.BaseTexture.SCALE_MODE.NEAREST;		loader.onComplete = onLoadDone;		loader.load();		var stage = new PIXI.Stage(0x34495e);		var renderer = PIXI.autoDetectRenderer(320, 240);		renderer.view.style.width = '640px';		renderer.view.style.height = '480px';		document.body.appendChild(renderer.view);

the game zooms at 2x. But still the animation is not pixel sharp. It is blurry and has the same flickering and nosiness and since its zoomed at 2x, it looks more ugly.

Here is the screenshot 

oBpgGBx.png

Link to comment
Share on other sites

Because at that point pixi isn't scaling the scene, your browser is. What you want to do is use a DisplayObjectContainer for all your stage items, and add that container to the stage. Then scale that object container:

PIXI.BaseTexture.SCALE_MODE.DEFAULT = PIXI.BaseTexture.SCALE_MODE.NEAREST;var assetsToLoad = ["sprites.json"];var loader = new PIXI.AssetLoader(assetsToLoad);loader.onComplete = onLoadDone;loader.load();var stage = new PIXI.Stage(0x34495e);var renderer = PIXI.autoDetectRenderer(640, 480);document.body.appendChild(renderer.view);var container = new PIXI.DisplayObjectContainer();container.scale.x = container.scale.y = 2;stage.addChild(container);//.. add all children to container, not the stage

That way pixi will be scaling your objects, not the browser so it will interpolate the way we tell it to.

Link to comment
Share on other sites

Because at that point pixi isn't scaling the scene, your browser is. What you want to do is use a DisplayObjectContainer for all your stage items, and add that container to the stage. Then scale that object container:

PIXI.BaseTexture.SCALE_MODE.DEFAULT = PIXI.BaseTexture.SCALE_MODE.NEAREST;var assetsToLoad = ["sprites.json"];var loader = new PIXI.AssetLoader(assetsToLoad);loader.onComplete = onLoadDone;loader.load();var stage = new PIXI.Stage(0x34495e);var renderer = PIXI.autoDetectRenderer(640, 480);document.body.appendChild(renderer.view);var container = new PIXI.DisplayObjectContainer();container.scale.x = container.scale.y = 2;stage.addChild(container);//.. add all children to container, not the stage

That way pixi will be scaling your objects, not the browser so it will interpolate the way we tell it to.

Got it. Thanks  :) 

It is now working the way I wanted 

Link to comment
Share on other sites

var currentWindowWidth = 0;

var stage = new PIXI.Stage(0x66FF99,true);

var renderer = new PIXI.autoDetectRenderer(800,400, document.getElementById("maincanvas"));

//My game's screen aspect ration is 2:1

renderer.view.style.width = window.innerWidth + "px";

currentWindowWidth = window.innerWidth; //Save the current width that we just set the view at

renderer.view.style.height = Math.floor( (window.innerWidth*.5) ) + "px";

renderer.view.style.display = "block"

document.body.appendChild(renderer.view);

function resize(){

if(window.innerWidth != currentWindowWidth){

renderer.view.style.width = window.innerWidth + "px";

renderer.view.style.height = Math.floor( (window.innerWidth*.5) ) + "px";

currentWindowWidth = window.innerWidth;

}

}

requestAnimFrame( animate );

function animate() {

requestAnimFrame( animate );

resize(); //calls resize above this is what my comment is about below

mainLoop();

renderer.render(stage);

}

I think I am running into the same thing as you were suyashmshephertz. Trying to fill the full screen, but keep the aspect ratio and right now only using bitmaps.  

 

Basically I am super new at this so the above may be a really bad cludge and that is what I am wondering.  I initially set the view to the window width and then height to 1/2 with window width. (My game aspect is 2:1)

 

In the animate loop I call resize which checks to see if the window height ever changes and if so it resizes the view in real-time. (and that I guess changes my objects as they all have their own aspects set)   Right now it seems to work pretty good.  On mobile phone it seems to work as an auto rotate as well, because as soon as you rotate the screen it resizes perfect. So works so far. 

 

My questions are is this a proper way to do this?  Is this Pixi doing the scaling as you are talking about above or the browser?  For now it doesn't seem to affect performance, but as the games gets more complex is there a better way to resize the view in realtime as the user resizes the browser window, but keep the correct aspect ratio of the game? 

 

Apologize in advance if I am  not quite using the right terms etc. Thanks for any insight. 
Link to comment
Share on other sites

var currentWindowWidth = 0;var stage = new PIXI.Stage(0x66FF99,true);var renderer = new PIXI.autoDetectRenderer(800,400, document.getElementById("maincanvas"));//My game's screen aspect ration is 2:1 renderer.view.style.width = window.innerWidth + "px";  currentWindowWidth = window.innerWidth; //Save the current width that we just set the view at renderer.view.style.height = Math.floor( (window.innerWidth*.5) ) + "px";renderer.view.style.display = "block"document.body.appendChild(renderer.view);function resize(){     if(window.innerWidth != currentWindowWidth){        renderer.view.style.width = window.innerWidth + "px";	renderer.view.style.height = Math.floor( (window.innerWidth*.5) ) + "px";        currentWindowWidth = window.innerWidth;     }}requestAnimFrame( animate );function animate() {   requestAnimFrame( animate );     resize(); //calls resize above this is what my comment is about below     mainLoop();               renderer.render(stage);}
I think I am running into the same thing as you were suyashmshephertz. Trying to fill the full screen, but keep the aspect ratio and right now only using bitmaps.  
 
Basically I am super new at this so the above may be a really bad cludge and that is what I am wondering.  I initially set the view to the window width and then height to 1/2 with window width. (My game aspect is 2:1)
 
In the animate loop I call resize which checks to see if the window height ever changes and if so it resizes the view in real-time. (and that I guess changes my objects as they all have their own aspects set)   Right now it seems to work pretty good.  On mobile phone it seems to work as an auto rotate as well, because as soon as you rotate the screen it resizes perfect. So works so far. 
 
My questions are is this a proper way to do this?  Is this Pixi doing the scaling as you are talking about above or the browser?  For now it doesn't seem to affect performance, but as the games gets more complex is there a better way to resize the view in realtime as the user resizes the browser window, but keep the correct aspect ratio of the game? 
 
Apologize in advance if I am  not quite using the right terms etc. Thanks for any insight. 

 

 

When you use 'renderer.view.style.width', it's the browser that does the scaling not pixi.js. Also, checking for window re-size in loop is a bad practice. Instead use onresize event of window.

 

Correct me if I am wrong.

Link to comment
Share on other sites

When you use 'renderer.view.style.width', it's the browser that does the scaling not pixi.js. Also, checking for window re-size in loop is a bad practice. Instead use onresize event of window.

 

Correct me if I am wrong.

 

 

 

Ok thank you!!  Figured out onresize event. Thank you!  This is what I have now...

Added to the body tag in this case: <body onresize="resize()">~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~        var currentWindowWidth = 0;    	var currentWindowHeight = 0;	var stage = new PIXI.Stage(0x000000,true);	var renderer = new PIXI.autoDetectRenderer(800,400);	resize();  //figured I'd initialize size by calling function below as well	renderer.view.style.display = "block"	document.body.appendChild(renderer.view);	function resize(){             currentWindowWidth = window.innerWidth;   //set new currents	     currentWindowHeight = window.innerHeight; //set new currents	     if(Math.floor( (currentWindowWidth*.5) ) > currentWindowHeight){                  renderer.view.style.height = currentWindowHeight + "px";		  renderer.view.style.width =  Math.floor( currentWindowHeight*.5 ) + "px";             }             else{	          renderer.view.style.width = window.innerWidth + "px"; 	          renderer.view.style.height = Math.floor( (currentWindowWidth*.5) ) + "px";             }	}        requestAnimFrame( animate );	function animate() {	     requestAnimFrame( animate );             mainLoop(); 	     renderer.render(stage);	}

Found and played around with the renderer.resize(w,h); but that doesn't do what I am looking for I think. (Found some other thread regarding this as well)

 

Is there a more native version to resize and keep the elements scaled/full screen?  

 

I added the if/else statement so that it basically keeps scroll bars away. So if the width is like 1600 and height is 300 it switches how it calculates versus if the width is 600 and height 1000, so as the user is dragging the window around no scroll bars show up. 

Link to comment
Share on other sites

  • 2 months later...

Hello,

I'm planning on making pixel based games with PIXI.js and I wanted to have the screen scaled as described in the first post. I used a DisplayObjectContainer that I scaled 3 times, it's working great, but when I move my sprite, it can be rendered between pixels, so the movement is fluid, but what I want is the sprite to be displayed on round coordinates.

Of course I can round the coordinates by myself, but it wouldn't work for transformations like rotation, I really want my game to keep a pixel look...

Thanks for your help! :)

Link to comment
Share on other sites

  • 3 weeks later...

I imagine other people looking to do pixel art with Pixi will find this forum thread when trying to figure out how to do nearest neighbor scaling without anti-aliasing.

 

Note that the way you do it has changed!  The line to change the scaling looks like this now:

PIXI.scaleModes.DEFAULT = PIXI.scaleModes.NEAREST;
Link to comment
Share on other sites

  • 5 weeks later...

 

I imagine other people looking to do pixel art with Pixi will find this forum thread when trying to figure out how to do nearest neighbor scaling without anti-aliasing.

 

Note that the way you do it has changed!  The line to change the scaling looks like this now:

PIXI.scaleModes.DEFAULT = PIXI.scaleModes.NEAREST;

 

Thanks for pointing that out, I was starting to get "restless"... lol

Link to comment
Share on other sites

  • 2 weeks later...

 

I imagine other people looking to do pixel art with Pixi will find this forum thread when trying to figure out how to do nearest neighbor scaling without anti-aliasing.

 

Note that the way you do it has changed!  The line to change the scaling looks like this now:

PIXI.scaleModes.DEFAULT = PIXI.scaleModes.NEAREST;

This also isn't true anymore.  Now you simply do this:

    var renderer = PIXI.autoDetectRenderer(400, 300);    renderer.resize(800, 600);

to increase its size. 

Link to comment
Share on other sites

resize spoils  :(

scale.x, scale.y - suitable.
 

game.container.scale.x = game.viewport.scale.x = game.scale.main;
rendererObjects = PIXI.autoDetectRenderer(game.width * game.scale.main, game.height * game.scale.main, layoutObjects);

how much effect on FPS?


1920*900

 

Link to comment
Share on other sites

Actually what I said is wrong.  But it is true that

PIXI.scaleModes.DEFAULT = PIXI.scaleModes.NEAREST;

no longer works.  I'd like to know what it's been replaced with.

 

It should still work fine, if not please open a bug on github with example code that shows it not working.

Link to comment
Share on other sites

  • 2 years later...
  • 3 years later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...