Skip to content

Instantly share code, notes, and snippets.

@kirbysayshi
Created July 29, 2013 04:25
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kirbysayshi/6102134 to your computer and use it in GitHub Desktop.
Save kirbysayshi/6102134 to your computer and use it in GitHub Desktop.
rotatablegame.js: Rotate the camera in an impactjs game! Underscores in filenames indicate directories.
ig.module(
'game.entities.square'
)
.requires(
'impact.entity'
)
.defines(function(){
EntitySquare = ig.Entity.extend({
size: { x: 8, y: 8 },
draw: function() {
ig.system.context.fillStyle = 'rgba(255, 0, 0, 0.6)';
ig.system.context.fillRect(
ig.system.getDrawPos(this.pos.x - ig.game.screen.x),
ig.system.getDrawPos(this.pos.y - ig.game.screen.y),
ig.system.getDrawPos(this.size.x),
ig.system.getDrawPos(this.size.y)
);
}
});
});
ig.module( 'game.levels.rotation-demo' )
.requires( 'impact.image','game.entities.square' )
.defines(function(){
LevelRotationDemo=/*JSON[*/{"entities":[{"type":"EntitySquare","x":0,"y":0},{"type":"EntitySquare","x":0,"y":232},{"type":"EntitySquare","x":312,"y":0},{"type":"EntitySquare","x":312,"y":232},{"type":"EntitySquare","x":32,"y":204},{"type":"EntitySquare","x":280,"y":24},{"type":"EntitySquare","x":156,"y":116}],"layer":[]}/*]JSON*/;
});
ig.module(
'game.rotation-example'
)
.requires(
'plugins.rotatablegame',
'game.levels.rotation-demo'
)
.defines(function(){
GameRotationExample = ig.RotatableGame.extend({
init: function() {
ig.input.bind( ig.KEY.ESC, 'halt' );
ig.input.bind( ig.KEY.SHIFT, 'shift' );
ig.input.bind( ig.KEY.LEFT_ARROW, 'screen_left' );
ig.input.bind( ig.KEY.RIGHT_ARROW, 'screen_right' );
ig.input.bind( ig.KEY.UP_ARROW, 'screen_up' );
ig.input.bind( ig.KEY.DOWN_ARROW, 'screen_down' );
this.loadLevel( LevelRotationDemo );
},
update: function() {
// Stop rendering when esc is pressed to save developer battery :)
if(ig.input.pressed('halt')){
ig.system.stopRunLoop.call(ig.system);
ig.log('HALT IN THE NAME OF SCIENCE!');
}
var rotationVel = 0.01;
// rotate camera if shift is held down with arrows
if( ig.input.state('shift') && ig.input.state('screen_left') ){
this.screenRotation.angle -= rotationVel;
} else if( ig.input.state('shift') && ig.input.state('screen_right') ){
this.screenRotation.angle += rotationVel;
}
var screenVel = 1;
// move the camera around via arrow keys!
if( !ig.input.state('shift') ){
if( ig.input.state('screen_left') ) {
this.screen.x -= screenVel;
} else if( ig.input.state('screen_right') ) {
this.screen.x += screenVel;
}
if( ig.input.state('screen_up') ) {
this.screen.y -= screenVel;
} else if( ig.input.state('screen_down') ) {
this.screen.y += screenVel;
}
}
// Update all entities and backgroundMaps
this.parent();
}
});
// Start the Game with 60fps, a resolution of 320x240, scaled
// up by a factor of 2
ig.main( '#canvas', GameRotationExample, 60, 320, 240, 2 );
});
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;
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment