Updated impact engine lib from 1.20 to 1.22

This commit is contained in:
Ruben Müller 2013-04-03 21:02:06 +02:00
parent 91b8222037
commit 85e2f3a1ba
20 changed files with 215 additions and 96 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
design/design-layout.psd
.DS_Store

View file

@ -50,7 +50,7 @@ ig.Animation = ig.Class.extend({
rewind: function() {
this.timer.reset();
this.timer.set();
this.loopCount = 0;
this.tile = this.sequence[0];
return this;

View file

@ -48,6 +48,10 @@ ig.BackgroundMap = ig.Map.extend({
var totalWidth = this.width * this.tilesize * ig.system.scale,
totalHeight = this.height * this.tilesize * ig.system.scale;
// If this layer is smaller than the chunkSize, adjust the chunkSize
// accordingly, so we don't have as much overdraw
this.chunkSize = Math.min( Math.max(totalWidth, totalHeight), this.chunkSize );
var chunkCols = Math.ceil(totalWidth / this.chunkSize),
chunkRows = Math.ceil(totalHeight / this.chunkSize);
@ -133,8 +137,11 @@ ig.BackgroundMap = ig.Map.extend({
if( this.repeat ) {
dx %= this.width * this.tilesize * ig.system.scale;
dy %= this.height * this.tilesize * ig.system.scale;
var w = this.width * this.tilesize * ig.system.scale;
dx = (dx%w + w) % w;
var h = this.height * this.tilesize * ig.system.scale;
dy = (dy%h + h) % h;
}
var minChunkX = Math.max( Math.floor(dx / this.chunkSize), 0 ),
@ -168,18 +175,18 @@ ig.BackgroundMap = ig.Map.extend({
ig.system.context.strokeRect( x, y, this.chunkSize, this.chunkSize );
}
// If we repeat in X and this chunks width wasn't the full chunk size
// If we repeat in X and this chunk's width wasn't the full chunk size
// and the screen is not already filled, we need to draw anohter chunk
// AND nudge it to be flush with the last chunk
if( this.repeat && chunk.width < this.chunkSize && x + chunk.width < ig.system.realWidth ) {
nudgeX = this.chunkSize - chunk.width;
if( this.repeat && chunk.width < this.chunkSize && x + chunk.width < ig.system.realWidth ) {
nudgeX += this.chunkSize - chunk.width;
maxChunkX++;
}
}
// Same as above, but for Y
if( this.repeat && chunk.height < this.chunkSize && y + chunk.height < ig.system.realHeight ) {
nudgeY = this.chunkSize - chunk.height;
if( this.repeat && chunk.height < this.chunkSize && y + chunk.height < ig.system.realHeight ) {
nudgeY += this.chunkSize - chunk.height;
maxChunkY++;
}
}
@ -209,9 +216,7 @@ ig.BackgroundMap = ig.Map.extend({
// Repeat Y?
if( tileY >= this.height || tileY < 0 ) {
if( !this.repeat ) { continue; }
tileY = tileY > 0
? tileY % this.height
: ((tileY+1) % this.height) + this.height - 1;
tileY = (tileY%this.height + this.height) % this.height;
}
for( var mapX = -1, pxX = pxMinX; pxX < pxMaxX; mapX++, pxX += this.tilesize ) {
@ -220,9 +225,7 @@ ig.BackgroundMap = ig.Map.extend({
// Repeat X?
if( tileX >= this.width || tileX < 0 ) {
if( !this.repeat ) { continue; }
tileX = tileX > 0
? tileX % this.width
: ((tileX+1) % this.width) + this.width - 1;
tileX = (tileX%this.width + this.width) % this.width;
}
// Draw!

View file

@ -39,7 +39,7 @@ ig.Debug = ig.Class.extend({
var style = ig.$new('link');
style.rel = 'stylesheet';
style.type = 'text/css';
style.href = 'lib/impact/debug/debug.css';
style.href = ig.prefix + 'lib/impact/debug/debug.css';
ig.$('body')[0].appendChild( style );
// Create the Debug Container

View file

@ -121,21 +121,16 @@ ig.Font = ig.Image.extend({
this.widthMap = [];
this.indices = [];
var canvas = ig.$new('canvas');
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext('2d');
ctx.drawImage( image, 0, 0 );
var px = ctx.getImageData(0, image.height-1, image.width, 1);
var px = ig.getImagePixels( image, 0, image.height-1, image.width, 1 );
var currentChar = 0;
var currentWidth = 0;
for( var x = 0; x < image.width; x++ ) {
var index = x * 4 + 3; // alpha component of this pixel
if( px.data[index] != 0 ) {
if( px.data[index] > 127 ) {
currentWidth++;
}
else if( px.data[index] == 0 && currentWidth ) {
else if( px.data[index] < 128 && currentWidth ) {
this.widthMap.push( currentWidth );
this.indices.push( x-currentWidth );
currentChar++;

View file

@ -86,16 +86,11 @@ ig.Image = ig.Class.extend({
// and copied into another offscreen canvas with the new size.
// The scaled offscreen canvas becomes the image (data) of this object.
var origPixels = ig.getImagePixels( this.data, 0, 0, this.width, this.height );
var widthScaled = this.width * scale;
var heightScaled = this.height * scale;
var orig = ig.$new('canvas');
orig.width = this.width;
orig.height = this.height;
var origCtx = orig.getContext('2d');
origCtx.drawImage( this.data, 0, 0, this.width, this.height, 0, 0, this.width, this.height );
var origPixels = origCtx.getImageData(0, 0, this.width, this.height);
var scaled = ig.$new('canvas');
scaled.width = widthScaled;
scaled.height = heightScaled;

View file

@ -1,6 +1,6 @@
// -----------------------------------------------------------------------------
// Impact Game Engine 1.20
// Impact Game Engine 1.22
// http://impactjs.com/
// -----------------------------------------------------------------------------
@ -56,14 +56,26 @@ Array.prototype.random = function() {
return this[ Math.floor(Math.random() * this.length) ];
};
Function.prototype.bind = Function.prototype.bind || function(bind) {
var self = this;
return function(){
var args = Array.prototype.slice.call(arguments);
return self.apply(bind || null, args);
};
};
Function.prototype.bind = Function.prototype.bind || function (oThis) {
if( typeof this !== "function" ) {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(
(this instanceof fNOP && oThis ? this : oThis),
aArgs.concat(Array.prototype.slice.call(arguments))
);
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
// -----------------------------------------------------------------------------
@ -72,7 +84,7 @@ Function.prototype.bind = Function.prototype.bind || function(bind) {
window.ig = {
game: null,
debug: null,
version: '1.20',
version: '1.22',
global: window,
modules: {},
resources: [],
@ -164,6 +176,55 @@ window.ig = {
return values;
},
// Ah, yes. I love vendor prefixes. So much fun!
setVendorAttribute: function( el, attr, val ) {
var uc = attr.charAt(0).toUpperCase() + attr.substr(1);
el[attr] = el['ms'+uc] = el['moz'+uc] = el['webkit'+uc] = el['o'+uc] = val;
},
getVendorAttribute: function( el, attr ) {
var uc = attr.charAt(0).toUpperCase() + attr.substr(1);
return el[attr] || el['ms'+uc] || el['moz'+uc] || el['webkit'+uc] || el['o'+uc];
},
normalizeVendorAttribute: function( el, attr ) {
var prefixedVal = ig.getVendorAttribute( el, attr );
if( !el[attr] && prefixedVal ) {
el[attr] = prefixedVal;
}
},
// This function normalizes getImageData to extract the real, actual
// pixels from an image. The naive method recently failed on retina
// devices with a backgingStoreRatio != 1
getImagePixels: function( image, x, y, width, height ) {
var canvas = ig.$new('canvas');
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext('2d');
// Try to draw pixels as accurately as possible
ig.System.SCALE.CRISP(canvas, ctx);
var ratio = ig.getVendorAttribute( ctx, 'backingStorePixelRatio' ) || 1;
ig.normalizeVendorAttribute( ctx, 'getImageDataHD' );
var realWidth = image.width / ratio,
realHeight = image.height / ratio;
canvas.width = Math.ceil( realWidth );
canvas.height = Math.ceil( realHeight );
ctx.drawImage( image, 0, 0, realWidth, realHeight );
return (ratio === 1)
? ctx.getImageData( x, y, width, height )
: ctx.getImageDataHD( x, y, width, height );
},
module: function( name ) {
if( ig._current ) {
@ -324,8 +385,10 @@ window.ig = {
ig.ua.iPhone4 = (ig.ua.iPhone && ig.ua.pixelRatio == 2);
ig.ua.iPad = /iPad/i.test(navigator.userAgent);
ig.ua.android = /android/i.test(navigator.userAgent);
ig.ua.winPhone = /Windows Phone/i.test(navigator.userAgent);
ig.ua.iOS = ig.ua.iPhone || ig.ua.iPad;
ig.ua.mobile = ig.ua.iOS || ig.ua.android;
ig.ua.mobile = ig.ua.iOS || ig.ua.android || ig.ua.winPhone;
ig.ua.touchDevice = (('ontouchstart' in window) || (window.navigator.msMaxTouchPoints));
},
@ -355,13 +418,8 @@ window.ig = {
// Provide ig.setAnimation and ig.clearAnimation as a compatible way to use
// requestAnimationFrame if available or setInterval otherwise
// Find vendor prefix, if any
var vendors = ['ms', 'moz', 'webkit', 'o'];
for( var i = 0; i < vendors.length && !window.requestAnimationFrame; i++ ) {
window.requestAnimationFrame = window[vendors[i]+'RequestAnimationFrame'];
}
// Use requestAnimationFrame if available
ig.normalizeVendorAttribute( window, 'requestAnimationFrame' );
if( window.requestAnimationFrame ) {
var next = 1,
anims = {};
@ -481,13 +539,19 @@ window.ig.Class.extend = function(prop) {
}
Class.prototype = prototype;
Class.constructor = Class;
Class.prototype.constructor = Class;
Class.extend = window.ig.Class.extend;
Class.inject = inject;
return Class;
};
// Merge the ImpactMixin - if present - into the 'ig' namespace. This gives other
// code the chance to modify 'ig' before it's doing any work.
if( window.ImpactMixin ) {
ig.merge(ig, window.ImpactMixin);
}
})(window);

View file

@ -125,9 +125,18 @@ ig.Input = ig.Class.extend({
ig.system.canvas.addEventListener('mouseup', this.keyup.bind(this), false );
ig.system.canvas.addEventListener('mousemove', this.mousemove.bind(this), false );
ig.system.canvas.addEventListener('touchstart', this.keydown.bind(this), false );
ig.system.canvas.addEventListener('touchend', this.keyup.bind(this), false );
ig.system.canvas.addEventListener('touchmove', this.mousemove.bind(this), false );
if( ig.ua.touchDevice ) {
// Standard
ig.system.canvas.addEventListener('touchstart', this.keydown.bind(this), false );
ig.system.canvas.addEventListener('touchend', this.keyup.bind(this), false );
ig.system.canvas.addEventListener('touchmove', this.mousemove.bind(this), false );
// MS
ig.system.canvas.addEventListener('MSPointerDown', this.keydown.bind(this), false );
ig.system.canvas.addEventListener('MSPointerUp', this.keyup.bind(this), false );
ig.system.canvas.addEventListener('MSPointerMove', this.mousemove.bind(this), false );
ig.system.canvas.style.msTouchAction = 'none';
}
},
@ -160,22 +169,17 @@ ig.Input = ig.Class.extend({
mousemove: function( event ) {
var el = ig.system.canvas;
var internalWidth = parseInt(ig.system.canvas.offsetWidth) || ig.system.realWidth;
var scale = ig.system.scale * (internalWidth / ig.system.realWidth);
var pos = {left: 0, top: 0};
while( el != null ) {
pos.left += el.offsetLeft;
pos.top += el.offsetTop;
el = el.offsetParent;
}
var tx = event.pageX;
var ty = event.pageY;
if( event.touches ) {
tx = event.touches[0].clientX;
ty = event.touches[0].clientY;
if( ig.system.canvas.getBoundingClientRect ) {
pos = ig.system.canvas.getBoundingClientRect();
}
this.mouse.x = (tx - pos.left) / ig.system.scale;
this.mouse.y = (ty - pos.top) / ig.system.scale;
var ev = event.touches ? event.touches[0] : event;
this.mouse.x = (ev.clientX - pos.left) / scale;
this.mouse.y = (ev.clientY - pos.top) / scale;
},
@ -188,7 +192,8 @@ ig.Input = ig.Class.extend({
keydown: function( event ) {
if( event.target.type == 'text' ) { return; }
var tag = event.target.tagName;
if( tag == 'INPUT' || tag == 'TEXTAREA' ) { return; }
var code = event.type == 'keydown'
? event.keyCode
@ -212,7 +217,8 @@ ig.Input = ig.Class.extend({
keyup: function( event ) {
if( event.target.type == 'text' ) { return; }
var tag = event.target.tagName;
if( tag == 'INPUT' || tag == 'TEXTAREA' ) { return; }
var code = event.type == 'keyup'
? event.keyCode
@ -243,13 +249,10 @@ ig.Input = ig.Class.extend({
var element = ig.$( selector );
var that = this;
element.addEventListener('touchstart', function(ev) {
that.touchStart( ev, action );
}, false);
element.addEventListener('touchend', function(ev) {
that.touchEnd( ev, action );
}, false);
element.addEventListener('touchstart', function(ev) {that.touchStart( ev, action );}, false);
element.addEventListener('touchend', function(ev) {that.touchEnd( ev, action );}, false);
element.addEventListener('MSPointerDown', function(ev) {that.touchStart( ev, action );}, false);
element.addEventListener('MSPointerUp', function(ev) {that.touchEnd( ev, action );}, false);
},

View file

@ -9,6 +9,12 @@ ig.SoundManager = ig.Class.extend({
format: null,
init: function() {
// Quick sanity check if the Browser supports the Audio tag
if( !ig.Sound.enabled || !window.Audio ) {
ig.Sound.enabled = false;
return;
}
// Probe sound formats and determine the file extension to load
var probe = new Audio();
for( var i = 0; i < ig.Sound.use.length; i++ ) {

View file

@ -34,6 +34,13 @@ ig.System = ig.Class.extend({
this.context = this.canvas.getContext('2d');
this.getDrawPos = ig.System.drawMode;
// Automatically switch to crisp scaling when using a scale
// other than 1
if( this.scale != 1 ) {
ig.System.scaleMode = ig.System.SCALE.CRISP;
}
ig.System.scaleMode( this.canvas, this.context );
},
@ -108,7 +115,7 @@ ig.System = ig.Class.extend({
},
getDrawPos: null, // Set through constructor
getDrawPos: null // Set through constructor
});
ig.System.DRAW = {
@ -118,4 +125,21 @@ ig.System.DRAW = {
};
ig.System.drawMode = ig.System.DRAW.SMOOTH;
ig.System.SCALE = {
CRISP: function( canvas, context ) {
ig.setVendorAttribute( context, 'imageSmoothingEnabled', false );
canvas.style.imageRendering = '-moz-crisp-edges';
canvas.style.imageRendering = '-o-crisp-edges';
canvas.style.imageRendering = '-webkit-optimize-contrast';
canvas.style.imageRendering = 'crisp-edges';
canvas.style.msInterpolationMode = 'nearest-neighbor'; // No effect on Canvas :/
},
SMOOTH: function( canvas, context ) {
ig.setVendorAttribute( context, 'imageSmoothingEnabled', true );
canvas.style.imageRendering = '';
canvas.style.msInterpolationMode = '';
}
};
ig.System.scaleMode = ig.System.SCALE.SMOOTH;
});

View file

@ -58,7 +58,7 @@ ig.Timer = ig.Class.extend({
});
ig.Timer._last = 0;
ig.Timer.time = 0;
ig.Timer.time = Number.MIN_VALUE;
ig.Timer.timeScale = 1;
ig.Timer.maxStep = 0.05;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -44,8 +44,8 @@ wm.config = {
'view': {
'zoom': 1,
'zoomMax': 1,
'zoomMin': 1,
'zoomMax': 4,
'zoomMin': 0.125,
'grid': false
},

View file

@ -147,17 +147,33 @@ wm.EditEntities = ig.Class.extend({
selectEntityAt: function( x, y ) {
this.selector.pos = { x: x, y: y };
// Find all possible selections
var possibleSelections = [];
for( var i = 0; i < this.entities.length; i++ ) {
var ent = this.entities[i];
if( ent.touches(this.selector) ) {
this.selector.offset = {x: (x - ent.pos.x + ent.offset.x), y: (y - ent.pos.y + ent.offset.y)};
this.selectEntity( ent );
this.wasSelectedOnScaleBorder = this.isOnScaleBorder( ent, this.selector );
return ent;
if( this.entities[i].touches(this.selector) ) {
possibleSelections.push( this.entities[i] );
}
}
this.selectEntity( null );
return false;
// Nothing found? Early out.
if( !possibleSelections.length ) {
this.selectEntity( null );
return false;
}
// Find the 'next' selection
var selectedIndex = possibleSelections.indexOf(this.selectedEntity);
var nextSelection = (selectedIndex + 1) % possibleSelections.length;
var ent = possibleSelections[nextSelection];
// Select it!
this.selector.offset = {
x: (x - ent.pos.x + ent.offset.x),
y: (y - ent.pos.y + ent.offset.y)
};
this.selectEntity( ent );
this.wasSelectedOnScaleBorder = this.isOnScaleBorder( ent, this.selector );
return ent;
},

View file

@ -35,7 +35,9 @@ var req = $.ajax({
var moduleNames = [];
var modules = {};
for( var i = 0; i < files.length; i++ ) {
var name = files[i].replace(/^lib\/|\.js$/g,'').replace(/\//g, '.');
var name = files[i]
.replace(new RegExp("^"+ig.lib+"|\\.js$", "g"), '')
.replace(/\//g, '.');
moduleNames.push( name );
modules[name] = files[i];
}

View file

@ -15,7 +15,8 @@ wm.EventedInput = ig.Input.extend({
keydown: function( event ) {
if( event.target.type == 'text' ) { return; }
var tag = event.target.tagName;
if( tag == 'INPUT' || tag == 'TEXTAREA' ) { return; }
var code = event.type == 'keydown'
? event.keyCode
@ -35,7 +36,9 @@ wm.EventedInput = ig.Input.extend({
keyup: function( event ) {
if( event.target.type == 'text' ) { return; }
var tag = event.target.tagName;
if( tag == 'INPUT' || tag == 'TEXTAREA' ) { return; }
var code = event.type == 'keyup'
? event.keyCode
: (event.button == 2 ? ig.KEY.MOUSE2 : ig.KEY.MOUSE1);

View file

@ -114,6 +114,11 @@ wm.Weltmeister = ig.Class.extend({
$('input#toggleSidebar').toggleClass('active');
});
// Always unfocus current input field when clicking the canvas
$('#canvas').mousedown(function(){
$('input:focus').blur();
});
this.undo = new wm.Undo( wm.config.undoLevels );

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 484 B

View file

@ -8,14 +8,16 @@ SET GAME=lib/game/main.js
SET OUTPUT_FILE=game.min.js
:: Change CWD to Impact's base dir and bake!
:: Change CWD to Impact's base dir
cd ../
php tools/bake.php %IMPACT_LIBRARY% %GAME% %OUTPUT_FILE%
:: Bake!
php tools/bake.php %IMPACT_LIBRARY% %GAME% %OUTPUT_FILE%
:: If you dont have the php.exe in your PATH uncomment the
:: following line and point it to your php.exe
::c:/php/php.exe bake.php %IMPACT_LIBRARY% %GAME% %OUTPUT_FILE%
::c:/php/php.exe tools/bake.php %IMPACT_LIBRARY% %GAME% %OUTPUT_FILE%
pause