Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by Tharuin

Hey!

Can somebody tell me if this is possible using impactjs (with impact++)?

http://www.david-amador.com/2010/03/xna-2d-independent-resolution-rendering/

I want to make my game fullscreen all the time, but I do not want it to stretch too much when the window is beeing resized or so.

1 decade ago by Mediamonkey

Sure, in impact.js you'll find the _boot method at line 369.
Here is where the viewport and the useragent are checked for device specific information.

In your own main file you can check the device specs and set up conditions, then call your main method with the appropriate dimensions and your preferred zoom level.

1 decade ago by Tharuin

Thank you!

How do I calculate the zoom level, so my "virtual" resolution (what my background gfx is for instance, in my case 1280x720) does appear "full" but not stretched in a random window of 1500x500 for instance?

I'm not that good in all this transformation stuff, so I don't know how to calculate all this stuff. I'll probably also have to check for the current window size?

1 decade ago by Joncom

A couple things:
- If you want the game to scale up or down on the fly, you will lose the "sharp" pixel perfect look.
- I'm not even sure how you would scale on the fly, because Impact handles all scaling once before the game loads.

Thought: Perhaps you can achieve on the fly scaling by overloading ig.Image.draw and, like you already mentioned, get into some "transformation stuff" directly with the canvas.

1 decade ago by vincentpiel

I think that indeed resolution independance would be a nice feature.

We need to distinguish world coordinates from screen coordinates, since it allows not only for resolution independance, but it allows also to have 'understandable' figures within your code.

In fact we have 3 coordinates : world coordinates, screen coordinates, and also world view coordinates === world coordinates - current view coordinates (in case you move the screen).
For instance a game where you fight in the streets will have world x coordinates ranging from 0 to 2000 ( you make your way through the 2kms of the city), a world view width of 20 ( you see 20 meters away), and screen coordinates ranging from 0 to 959 pixels on an iphone 4.

Two more examples :
- In a fighting game happening in a room, you would choose meter as unit, so you can easily understand that 2 is 'far', and 0.2 is 'near'.
The world width would be of like 5, and height of 3.
- In a strategy game like starcraft, choose also meter as unit, <10 is near and >1000 is far. The range of each weapon (expl : 200m) is easy to understand.
The world width would be 500 for instance.

As Joncon stated, the fact that the scale is no more an integer scale will cause the images to have lower quality. However 1) i didn't found this loss important and 2) the fact that you will always take all available room is more important than 1).
Because -that's when things gets complicated- you have anyway to handle 2 resolutions of image to handle hi-dpi devices.

OR... have all your graphics as vector graphics and have them drawn on the fly when you know the final resolution. For this you can use svg, or the solution i used : load .js files that describes a draw(ctx,x,y) function, that i called a drawCode.

// draw this object. uses world view coordinates as input
function draw(ctx,x,y) {
    ctx.beginPath();
    ctx.moveTo(...  );
    ctx.lineTo(... );
    ctx.strokeStyle='#F00';
    ctx.stroke();
}

I did it in a game i made (yet to be finished...) and it worked fine.
To implement it, i had to change ig.main, the scaling of the images, and i added a new kind of object that is considered as a resource, the drawCode == a text file that contains a draw(ctx,x,y) function.


So basically what i do :
- choose a fixed aspect ratio in the constants of the game.
- choose a view width (expl : 5 (meters) for a fighting game).
view height is computed out of width + aspect ratio.
- get width/height of current screen, and try to best fit the aspect ratio (portait / landscape mode) with this screen.
- compute the scale (most probably non-integer)
- all images will be scaled with this scale, so the drawImage will be unscaled.
- For non-Safari browsers, all vector graphics will be 'printed' in this scale into some canvases, so the drawImage will be unscaled.
- For Safari/iOS you will have much much better (>5X) performances with canvas draws (ctx.lineTo(), ... ) rather than with putImage, so i just keep on calling my drawing code using ctx.scale.

By doing this, almost full screens size is used whatever the resolution, and yet the game seems pretty much the same on the several devices i tested it on.

The signature of my ig.main becomes :
   ig.main( gameClass, worldWidth, aspectRatio, [loaderClass] );

(i create the canvas in code, so no need to put it in html file + recall its id in ig.main)

( 1.5 aspect ratio is a good value if you target recent mobile devices. )

1 decade ago by Chema

Playing with viewports has given me and everyone I know many a headache, and iOS has this nasty bug when rotating the device that prevents it from updating the DOM screen size, I think both in Chrome and Safari, making it impossible to adjust it correctly on the fly...

Changing the CSS style of the canvas on the other hand (as demonstrated by Jesse Freeman), works great on every modern browser I've tried. All you need is to merge the following with your own HTML:

<!DOCTYPE html>
<html>
<head>
	<title>My full screen game</title>
    <meta charset="utf-8" />

	<style type="text/css">
		html,body {
			margin: 0;
			padding: 0;
		}
		
		#canvas {
			position: absolute;
			left: 50%;
			right: 0;
			top: 50%;
			bottom: 0;
		}
	</style>

	<script type="text/javascript" src="lib/impact/impact.js"></script>
	<script type="text/javascript" src="lib/game/main.js"></script>
</head>
<body>
	
	<script type="text/javascript">
		function resizeGame() {
			var gameCanvas = document.getElementById('canvas');
			var widthToHeight = gameCanvas.width / gameCanvas.height;
			var newWidth = window.innerWidth;
			var newHeight = window.innerHeight;
			var newWidthToHeight = newWidth / newHeight;

			if (newWidthToHeight > widthToHeight) {
				newWidth = newHeight * widthToHeight;
				gameCanvas.style.height = (newHeight-8) + 'px';
				gameCanvas.style.width = (newWidth-8) + 'px';
			} else {
				newHeight = newWidth / widthToHeight;
				gameCanvas.style.width = (newWidth-8) + 'px';
				gameCanvas.style.height = (newHeight-8) + 'px';
			}
			gameCanvas.style.marginTop = (-newHeight / 2) + 'px';
			gameCanvas.style.marginLeft = (-newWidth / 2) + 'px';
		}
	</script>

	<canvas id="canvas"></canvas>
	
	<script type="text/javascript">
		window.onload = resizeGame;
		resizeGame();
		window.addEventListener('resize', resizeGame, false);
	</script>
	
</body>
</html>

Voila! It will adjust instantly to window resizing, full screen browser (kweeeel), rotating handhelds, Firebug and friends, anything! (except, ahem, Impact's debug bar).

P.S: Impact&039;s coordinates will work just the same after this; same with canvas coordinates if you want to draw directly on it (e.g. to draw over an entity find it with #canvasPosX = this.pos.x * ig.system.scale - ig.game.screen.x * ig.system.scale, etc.).

1 decade ago by collinhover

Sorry if I'm late to the discussion or if I misunderstand the question, but since you mentioned Impact++ in the OP: yes, Impact++ should be able to handle resolution independence for you. The short answer is to set the following in your "plusplus/config-user" file:

// make it fullscreen
GAME_WIDTH_PCT: 1,
GAME_HEIGHT_PCT: 1,

// Dynamic scaling based on dimensions in view
// i.e. scale the game to keep roughly 320 x 240 pixels in view
// (it won't go below 1, and scale is always an integer)
GAME_WIDTH_VIEW: 320,
GAME_HEIGHT_VIEW: 240

The not really longer answer is that Impact++ does scaling on the entity level, and your animation sheets / images are scaled the first time they're drawn, rather than the when the game first loads. I'm not entirely sure if I want to keep it that way, because scaling very large images to large scales can cause a small pause in the game, but for now the case is rare. Also, entities in Impact++ hook into a game-wide resize signal and will resize themselves whenever the screen resizes. You can also tell entities to ignore the system scale and give them a scale manually. This works really well for text and UI, as generally they should be a fixed scale for better usability / legibility.

Hope this helps! (p.s. ping me on twitter if you need help, I usually respond faster)
Page 1 of 1
« first « previous next › last »