1 decade ago by CaptainFrech
I am tinkering around with Map Rotation - I would love to rotate the screen (camera)
any tips how i can do this?
any tips how i can do this?
This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact
039;s concept of a camera is hard-coded into the system, meaning entities and maps rely on #ig.game.screen
being a simple x/y
. If you want to enhance the camera capabilities, you'd need to edit most of Impact's core drawing, tiling, and culling methods.RotatableGame
instead of ig.Game
.039;s screen and context sizes so that things like #ig.game.screen += 1
still work.ig.module( 'plugins.rotatablegame' ) .requires( 'impact.game' ) .defines(function(){ ig.RotatableGame = ig.Game.extend({ screenRotation: { centerOffset: { x: 0, y: 0 }, angle: 0 }, draw: function() { // figure out which side of the canvas is the largest var maxDimension = Math.max(ig.system.width, ig.system.height); // and then find the hypotenuse, as it is impossible for the context, // at any angle, to be larger than this length var diagonalLen = maxDimension * Math.SQRT2; // save the original: // system.{width/height} width/height of the logical drawing surface // system.real{Width/Height}: width/height of the actual drawing surface in pixels // screen.{x/y}: upper left position of the "camera" var systemWidth = ig.system.width; var systemHeight = ig.system.height; var systemRealWidth = ig.system.realWidth; var systemRealHeight = ig.system.realHeight; var screenX = ig.game.screen.x; var screenY = ig.game.screen.y; // temporarily tell impact to use screen and system that are big // enough to cover any rotations of the original size ig.system.width = diagonalLen; ig.system.height = diagonalLen; ig.system.realWidth = ig.system.scale * diagonalLen; ig.system.realHeight = ig.system.scale * diagonalLen; // using the original values... var halfRealWidth = systemRealWidth / 2; var halfRealHeight = systemRealHeight / 2; // these are the offsets required to move the context to compensate for // increasing the drawing area (difference between the original real // context size and increased context size, divided by 2) var diffHalfRealWidth = ig.system.realWidth/2 - halfRealWidth; var diffHalfRealHeight = ig.system.realHeight/2 - halfRealHeight; var rotationOffsetX = halfRealWidth + this.screenRotation.centerOffset.x; var rotationOffsetY = halfRealHeight + this.screenRotation.centerOffset.y; // rotate the context itself using original center as point of rotation ig.system.context.translate( rotationOffsetX, rotationOffsetY ); ig.system.context.rotate(this.screenRotation.angle); ig.system.context.translate( -rotationOffsetX, -rotationOffsetY ); // translate the context to ensure that drawing that occurs outside // is actually captured ig.system.context.translate( -diffHalfRealWidth, -diffHalfRealHeight ); // move the screen to compensate for drawing at a translated offset // this is not "undone" because the screen is just reset to the old // position at the end of the step ig.game.screen.x -= diffHalfRealWidth / ig.system.scale; ig.game.screen.y -= diffHalfRealHeight / ig.system.scale; // do all the typical impact stuff, draw maps, entities, etc. this.parent(); // put the context back in alignment with the natural system size ig.system.context.translate( diffHalfRealWidth, diffHalfRealHeight ); // undo the rotation from earlier ig.system.context.translate( rotationOffsetX, rotationOffsetY ); ig.system.context.rotate(-this.screenRotation.angle); ig.system.context.translate( -rotationOffsetX, -rotationOffsetY ); // undo all the width/height/screen changes ig.system.width = systemWidth; ig.system.height = systemHeight; ig.system.realWidth = systemRealWidth; ig.system.realHeight = systemRealHeight; ig.game.screen.x = screenX; ig.game.screen.y = screenY; } }); });