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;
}
});
});