Tilemap Collision in and working :) Needs testing against Groups now.

This commit is contained in:
Richard Davey 2013-09-12 15:39:52 +01:00
parent d211cf669c
commit 92e86494e3
21 changed files with 6084 additions and 3247 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

2
build/phaser-min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
<?php
// All JS files in build order.
// Much easier for debugging
// All JS files in build order. Much easier for debugging
// <xscript src="../src/pixi/extras/Spine.js"></script> <xscript src="../src/pixi/display/MovieClip.js"></script>
?>
<script src="../src/Intro.js"></script>
<script src="../src/pixi/Pixi.js"></script>
@ -13,12 +13,12 @@
<script src="../src/pixi/display/DisplayObject.js"></script>
<script src="../src/pixi/display/DisplayObjectContainer.js"></script>
<script src="../src/pixi/display/Sprite.js"></script>
<script src="../src/pixi/display/MovieClip.js"></script>
<script src="../src/pixi/display/Stage.js"></script>
<script src="../src/pixi/extras/CustomRenderable.js"></script>
<script src="../src/pixi/extras/Strip.js"></script>
<script src="../src/pixi/extras/Rope.js"></script>
<script src="../src/pixi/extras/Spine.js"></script>
<script src="../src/pixi/extras/TilingSprite.js"></script>
<script src="../src/pixi/filters/FilterBlock.js"></script>
<script src="../src/pixi/filters/MaskFilter.js"></script>

92
examples/mapcollide.php Normal file
View file

@ -0,0 +1,92 @@
<!DOCTYPE HTML>
<html>
<head>
<title>phaser.js - a new beginning</title>
<?php
require('js.php');
?>
</head>
<body>
<script type="text/javascript">
(function () {
// var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update, render: render });
var game = new Phaser.Game(800, 600, Phaser.CANVAS, '', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.tilemap('mario', 'assets/maps/mario1.png', 'assets/maps/mario1.json', null, Phaser.Tilemap.JSON);
game.load.image('player', 'assets/sprites/phaser-dude.png');
}
var map;
var p;
function create() {
game.stage.backgroundColor = '#787878';
map = game.add.tilemap(0, 0, 'mario');
// floor
map.setCollisionRange(80, 97, true, true, true, true);
// pipes
// map.setCollisionRange(31, 32, true, true, true, true);
// map.setCollisionRange(37, 38, true, true, true, true);
// map.setCollisionRange(39, 40, true, true, true, true);
// map.setCollisionRange(45, 46, true, true, true, true);
// map.setCollisionRange(73, 74, true, true, true, true);
// one-ways
map.setCollisionRange(15, 17, true, true, false, true);
p = game.add.sprite(0, 0, 'player');
// p.body.velocity.y = 150;
// p.body.gravity.y = 10;
// p.body.bounce.y = 0.5;
}
function update() {
map.collide(p);
p.body.velocity.x = 0;
p.body.acceleration.y = 250;
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
p.body.velocity.x = -150;
// game.camera.x -= 8;
}
else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
p.body.velocity.x = 150;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
{
if (p.body.touching.down)
{
p.body.velocity.y = -200;
}
}
}
function render() {
game.debug.renderSpriteCorners(p);
game.debug.renderSpriteCollision(p, 32, 320);
}
})();
</script>
</body>
</html>

48
examples/mariocombo.php Normal file
View file

@ -0,0 +1,48 @@
<!DOCTYPE HTML>
<html>
<head>
<title>phaser.js - Super Mario Combo</title>
<script src="phaser-min.js"></script>
<style type="text/css">
body: {
margin: 0;
}
</style>
</head>
<body>
<script type="text/javascript">
(function () {
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.tilemap('nes', 'gfx/mario1.png', 'gfx/mario1.json', null, Phaser.Tilemap.JSON);
game.load.tilemap('snes', 'gfx/smb_tiles.png', 'gfx/smb_level1.json', null, Phaser.Tilemap.JSON);
}
function create() {
game.stage.backgroundColor = '#5c94fc';
game.add.tilemap(0, 0, 'nes');
game.add.tilemap(0, 168, 'snes');
game.add.tween(game.camera).to( { x: 5120-800 }, 30000, Phaser.Easing.Linear.None, true, 0, 1000, true);
game.input.onDown.add(goFull, this);
}
function goFull() {
game.stage.scale.startFullScreen();
}
})();
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8" />
<title>phaser.js - Super Mario Combo</title>
<script src="phaser-min.js"></script>
<style type="text/css">
body {
margin: 0;
font-family: sans-serif;
}
p {
padding: 16px;
margin: 0px;
}
</style>
</head>
<body>
<div id="game"></div>
<script type="text/javascript">
(function () {
var game = new Phaser.Game(800, 600, Phaser.AUTO, 'game', { preload: preload, create: create });
function preload() {
game.load.image('phaser', 'assets/phaser.png');
game.load.tilemap('nes', 'assets/mario1.png', 'assets/mario1.json', null, Phaser.Tilemap.JSON);
game.load.tilemap('snes', 'assets/smb_tiles.png', 'assets/smb_level1.json', null, Phaser.Tilemap.JSON);
}
function create() {
game.stage.backgroundColor = '#5c94fc';
game.add.tilemap(0, 0, 'nes');
game.add.tilemap(0, 168, 'snes');
var logo = game.add.sprite(688, 8, 'phaser');
logo.scrollFactor.setTo(0, 0);
game.add.tween(game.camera).to( { x: 4320 }, 30000, Phaser.Easing.Linear.None, true, 0, 1000, true);
game.input.onDown.add(goFull, this);
}
function goFull() {
game.stage.scale.startFullScreen();
}
})();
</script>
<p>Potential game idea here? :)</p>
<p>Click game to full-screen (if supported)</p>
<p>Created with <a href="https://github.com/photonstorm/phaser">Phaser 1.0</a> by <a href="https://twitter.com/photonstorm">@photonstorm</a></p>
</body>
</html>

View file

@ -0,0 +1,45 @@
<!DOCTYPE HTML>
<html>
<head>
<title>phaser.js - Super Mario Combo</title>
<?php
require('js.php');
?>
</head>
<body>
<script type="text/javascript">
(function () {
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.tilemap('nes', 'assets/maps/mario1.png', 'assets/maps/mario1.json', null, Phaser.Tilemap.JSON);
game.load.tilemap('snes', 'assets/maps/smb_tiles.png', 'assets/maps/smb_level1.json', null, Phaser.Tilemap.JSON);
}
function create() {
game.stage.backgroundColor = '#5c94fc';
game.add.tilemap(0, 0, 'nes');
game.add.tilemap(0, 168, 'snes');
game.add.tween(game.camera).to( { x: 5120-800 }, 30000, Phaser.Easing.Linear.None, true, 0, 1000, true);
game.input.onDown.add(goFull, this);
}
function goFull() {
game.stage.scale.startFullScreen();
}
})();
</script>
</body>
</html>

View file

@ -110,7 +110,7 @@ Phaser.GameObjectFactory.prototype = {
tilemap: function (x, y, key, resizeWorld, tileWidth, tileHeight) {
return this.world.group.add(new Phaser.Tilemap(this.game, key, resizeWorld, tileWidth, tileHeight));
return this.world.group.add(new Phaser.Tilemap(this.game, key, x, y, resizeWorld, tileWidth, tileHeight));
},

View file

@ -440,7 +440,8 @@ Phaser.Math = {
for (var i = 1, max = 0, len = arguments.length; i < len; i++)
{
if (arguments[max] < arguments[i]) {
if (arguments[max] < arguments[i])
{
max = i;
}
}
@ -459,7 +460,8 @@ Phaser.Math = {
for (var i =1 , min = 0, len = arguments.length; i < len; i++)
{
if (arguments[i] < arguments[min]){
if (arguments[i] < arguments[min])
{
min = i;
}
}

View file

@ -424,6 +424,204 @@ Phaser.Physics.Arcade.prototype = {
}
},
/**
* The core Collision separation function used by Collision.overlap.
* @param object1 The first GameObject to separate
* @param object2 The second GameObject to separate
* @returns {boolean} Returns true if the objects were separated, otherwise false.
*/
separateTile: function (object, x, y, width, height, mass, collideLeft, collideRight, collideUp, collideDown, separateX, separateY) {
// Yes, the Y first
var separatedY = this.separateTileY(object.body, x, y, width, height, mass, collideUp, collideDown, separateY);
var separatedX = this.separateTileX(object.body, x, y, width, height, mass, collideLeft, collideRight, separateX);
if (separatedX || separatedY)
{
object.body.postUpdate();
return true;
}
return false;
},
/**
* Separates the two objects on their x axis
* @param object The GameObject to separate
* @param tile The Tile to separate
* @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
*/
separateTileX: function (object, x, y, width, height, mass, collideLeft, collideRight, separate) {
// Can't separate two immovable objects (tiles are always immovable)
if (object.immovable)
{
return false;
}
// First, get the object delta
this._overlap = 0;
// console.log('separatedX', x, y, object.deltaX());
if (object.deltaX() != 0)
{
this._obj1Bounds.setTo(object.x, object.y, object.width, object.height);
if ((this._obj1Bounds.right > x) && (this._obj1Bounds.x < x + width) && (this._obj1Bounds.bottom > y) && (this._obj1Bounds.y < y + height))
{
// The hulls overlap, let's process it
this._maxOverlap = object.deltaAbsX() + this.OVERLAP_BIAS;
// TODO - We need to check if we're already inside of the tile, i.e. jumping through an n-way tile
// in which case we didn't ought to separate because it'll look like tunneling
if (object.deltaX() < 0)
{
// Going left ...
this._overlap = object.x - width - x;
if (object.allowCollision.left && collideLeft && this._overlap < this._maxOverlap)
{
object.touching.left = true;
// console.log('left', this._overlap);
}
else
{
this._overlap = 0;
}
}
else
{
// Going right ...
this._overlap = object.right - x;
if (object.allowCollision.right && collideRight && this._overlap < this._maxOverlap)
{
object.touching.right = true;
// console.log('right', this._overlap);
}
else
{
this._overlap = 0;
}
}
}
}
// Then adjust their positions and velocities accordingly (if there was any overlap)
if (this._overlap != 0)
{
if (separate)
{
object.x = object.x - this._overlap;
if (object.bounce.x == 0)
{
object.velocity.x = 0;
}
else
{
object.velocity.x = -object.velocity.x * object.bounce.x;
}
}
return true;
}
else
{
return false;
}
},
/**
* Separates the two objects on their x axis
* @param object The GameObject to separate
* @param tile The Tile to separate
* @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
*/
separateTileY: function (object, x, y, width, height, mass, collideUp, collideDown, separate) {
// Can't separate two immovable objects (tiles are always immovable)
if (object.immovable)
{
return false;
}
// First, get the object delta
this._overlap = 0;
if (object.deltaY() != 0)
{
this._obj1Bounds.setTo(object.x, object.y, object.width, object.height);
if ((this._obj1Bounds.right > x) && (this._obj1Bounds.x < x + width) && (this._obj1Bounds.bottom > y) && (this._obj1Bounds.y < y + height))
{
// The hulls overlap, let's process it
// Not currently used, may need it so keep for now
this._maxOverlap = object.deltaAbsY() + this.OVERLAP_BIAS;
// TODO - We need to check if we're already inside of the tile, i.e. jumping through an n-way tile
// in which case we didn't ought to separate because it'll look like tunneling
if (object.deltaY() > 0)
{
// Going down ...
this._overlap = object.bottom - y;
if (object.allowCollision.down && collideDown && this._overlap < this._maxOverlap)
{
object.touching.down = true;
}
else
{
this._overlap = 0;
}
}
else
{
// Going up ...
this._overlap = object.y - height - y;
if (object.allowCollision.up && collideUp && this._overlap < this._maxOverlap)
{
object.touching.up = true;
}
else
{
this._overlap = 0;
}
}
}
}
// Then adjust their positions and velocities accordingly (if there was any overlap)
if (this._overlap != 0)
{
if (separate)
{
object.y = object.y - this._overlap;
if (object.bounce.y == 0)
{
object.velocity.y = 0;
}
else
{
object.velocity.y = -object.velocity.y * object.bounce.y;
}
}
return true;
}
else
{
return false;
}
},
/**
* Given the angle and speed calculate the velocity and return it as a Point
*

View file

@ -122,6 +122,19 @@ Phaser.Physics.Arcade.Body.prototype = {
},
postUpdate: function () {
this.sprite.x = this.x;
this.sprite.y = this.y;
if (this.allowRotation)
{
this.sprite.angle = this.rotation;
}
},
/*
postUpdate: function () {
// this.sprite.x = this.x - this.offset.x + (this.sprite.anchor.x * this.width);
@ -136,6 +149,7 @@ Phaser.Physics.Arcade.Body.prototype = {
}
},
*/
checkWorldBounds: function () {

View file

@ -17,7 +17,7 @@
* @param tileWidth {number} Width of tiles in this map (used for CSV maps).
* @param tileHeight {number} Height of tiles in this map (used for CSV maps).
*/
Phaser.Tilemap = function (game, key, resizeWorld, tileWidth, tileHeight) {
Phaser.Tilemap = function (game, key, x, y, resizeWorld, tileWidth, tileHeight) {
if (typeof resizeWorld === "undefined") { resizeWorld = true; }
if (typeof tileWidth === "undefined") { tileWidth = 0; }
@ -47,8 +47,9 @@ Phaser.Tilemap = function (game, key, resizeWorld, tileWidth, tileHeight) {
var map = this.game.cache.getTilemap(key);
// this._container = new PIXI.DisplayObjectContainer();
PIXI.DisplayObjectContainer.call(this);
this.position.x = x;
this.position.y = y;
this.renderer = new Phaser.TilemapRenderer(this.game);
@ -208,16 +209,16 @@ Phaser.Tilemap.prototype.setCollisionCallback = function (context, callback) {
* @param separateX {bool} Enable seprate at x-axis.
* @param separateY {bool} Enable seprate at y-axis.
*/
Phaser.Tilemap.prototype.setCollisionRange = function (start, end, collision, resetCollisions, separateX, separateY) {
Phaser.Tilemap.prototype.setCollisionRange = function (start, end, left, right, up, down, resetCollisions, separateX, separateY) {
if (typeof collision === "undefined") { collision = Phaser.Types.ANY; }
if (typeof resetCollisions === "undefined") { resetCollisions = false; }
if (typeof separateX === "undefined") { separateX = true; }
if (typeof separateY === "undefined") { separateY = true; }
for (var i = start; i < end; i++)
{
this.tiles[i].setCollision(collision, resetCollisions, separateX, separateY);
//setCollision: function (left, right, up, down, reset, separateX, separateY) {
this.tiles[i].setCollision(left, right, up, down, resetCollisions, separateX, separateY);
}
};
@ -343,13 +344,13 @@ Phaser.Tilemap.prototype.collide = function (objectOrGroup, callback, context) {
}
// Group?
if (objectOrGroup.isGroup == false)
if (objectOrGroup instanceof Phaser.Group)
{
this.collideGameObject(objectOrGroup);
// objectOrGroup.forEachAlive(this, this.collideGameObject, true);
}
else
{
objectOrGroup.forEachAlive(this, this.collideGameObject, true);
this.collideGameObject(objectOrGroup);
}
};
@ -361,7 +362,7 @@ Phaser.Tilemap.prototype.collide = function (objectOrGroup, callback, context) {
*/
Phaser.Tilemap.prototype.collideGameObject = function (object) {
if (object.body.type == Phaser.Types.BODY_DYNAMIC && object.exists == true && object.body.allowCollisions != Phaser.Types.NONE)
if (object.exists && object.body.allowCollision.none == false)
{
this._tempCollisionData = this.collisionLayer.getTileOverlaps(object);

View file

@ -306,31 +306,30 @@ Phaser.TilemapLayer.prototype = {
getTileOverlaps: function (object) {
// If the object is outside of the world coordinates then abort the check (tilemap has to exist within world bounds)
if (object.body.bounds.x < 0 || object.body.bounds.x > this.widthInPixels || object.body.bounds.y < 0 || object.body.bounds.bottom > this.heightInPixels)
if (object.body.x < 0 || object.body.x > this.widthInPixels || object.body.y < 0 || object.body.bottom > this.heightInPixels)
{
return;
}
// What tiles do we need to check against?
this._tempTileX = this.game.math.snapToFloor(object.body.bounds.x, this.tileWidth) / this.tileWidth;
this._tempTileY = this.game.math.snapToFloor(object.body.bounds.y, this.tileHeight) / this.tileHeight;
this._tempTileW = (this.game.math.snapToCeil(object.body.bounds.width, this.tileWidth) + this.tileWidth) / this.tileWidth;
this._tempTileH = (this.game.math.snapToCeil(object.body.bounds.height, this.tileHeight) + this.tileHeight) / this.tileHeight;
this._tempTileX = this.game.math.snapToFloor(object.body.x, this.tileWidth) / this.tileWidth;
this._tempTileY = this.game.math.snapToFloor(object.body.y, this.tileHeight) / this.tileHeight;
this._tempTileW = (this.game.math.snapToCeil(object.body.width, this.tileWidth) + this.tileWidth) / this.tileWidth;
this._tempTileH = (this.game.math.snapToCeil(object.body.height, this.tileHeight) + this.tileHeight) / this.tileHeight;
// Loop through the tiles we've got and check overlaps accordingly (the results are stored in this._tempTileBlock)
this._tempBlockResults = [];
this.getTempBlock(this._tempTileX, this._tempTileY, this._tempTileW, this._tempTileH, true);
/*
for (var r = 0; r < this._tempTileBlock.length; r++)
{
if (this.game.world.physics.separateTile(object, this._tempTileBlock[r].x * this.tileWidth, this._tempTileBlock[r].y * this.tileHeight, this.tileWidth, this.tileHeight, this._tempTileBlock[r].tile.mass, this._tempTileBlock[r].tile.collideLeft, this._tempTileBlock[r].tile.collideRight, this._tempTileBlock[r].tile.collideUp, this._tempTileBlock[r].tile.collideDown, this._tempTileBlock[r].tile.separateX, this._tempTileBlock[r].tile.separateY) == true)
{
this._tempBlockResults.push({ x: this._tempTileBlock[r].x, y: this._tempTileBlock[r].y, tile: this._tempTileBlock[r].tile });
// separateTile: function (object, x, y, width, height, mass, collideLeft, collideRight, collideUp, collideDown, separateX, separateY)
if (this.game.physics.separateTile(object, this._tempTileBlock[r].x * this.tileWidth, this._tempTileBlock[r].y * this.tileHeight, this.tileWidth, this.tileHeight, this._tempTileBlock[r].tile.mass, this._tempTileBlock[r].tile.collideLeft, this._tempTileBlock[r].tile.collideRight, this._tempTileBlock[r].tile.collideUp, this._tempTileBlock[r].tile.collideDown, this._tempTileBlock[r].tile.separateX, this._tempTileBlock[r].tile.separateY))
{
this._tempBlockResults.push({ x: this._tempTileBlock[r].x, y: this._tempTileBlock[r].y, tile: this._tempTileBlock[r].tile });
}
}
}
*/
return this._tempBlockResults;
@ -377,7 +376,7 @@ Phaser.TilemapLayer.prototype = {
if (collisionOnly)
{
// We only want to consider the tile for checking if you can actually collide with it
if (this.mapData[ty] && this.mapData[ty][tx] && this.parent.tiles[this.mapData[ty][tx]].allowCollisions != Phaser.Types.NONE)
if (this.mapData[ty] && this.mapData[ty][tx] && this.parent.tiles[this.mapData[ty][tx]].collideNone == false)
{
this._tempTileBlock.push({
x: tx,

View file

@ -162,6 +162,8 @@ Phaser.Time = function (game) {
this.game.onPause.add(this.gamePaused, this);
this.game.onResume.add(this.gameResumed, this);
this._justResumed = false;
};
Phaser.Time.prototype = {
@ -212,6 +214,18 @@ Phaser.Time.prototype = {
this.pausedTime = this.now - this._pauseStarted;
}
if (this._justResumed)
{
console.log('Time just resumed');
console.log('now', this.now);
console.log('timeToCall', this.timeToCall);
console.log('elapsed', this.elapsed);
console.log('lastTime', this.lastTime);
console.log('physicsElapsed', this.physicsElapsed);
this._justResumed = false;
}
},
/**
@ -221,6 +235,12 @@ Phaser.Time.prototype = {
*/
gamePaused: function () {
this._pauseStarted = this.now;
console.log('Time paused');
console.log('now', this.now);
console.log('timeToCall', this.timeToCall);
console.log('elapsed', this.elapsed);
console.log('lastTime', this.lastTime);
console.log('physicsElapsed', this.physicsElapsed);
},
/**
@ -235,6 +255,8 @@ Phaser.Time.prototype = {
this.physicsElapsed = 0;
this.pauseDuration = this.pausedTime;
this._justResumed = true;
},
/**

View file

@ -312,6 +312,22 @@ Phaser.Utils.Debug.prototype = {
},
renderSpriteCollision: function (sprite, x, y, color) {
color = color || 'rgb(255,255,255)';
this.start(x, y, color);
this.line('Sprite Collision: (' + sprite.width + ' x ' + sprite.height + ')');
this.line('left: ' + sprite.body.touching.left);
this.line('right: ' + sprite.body.touching.right);
this.line('up: ' + sprite.body.touching.up);
this.line('down: ' + sprite.body.touching.down);
this.line('velocity.x: ' + sprite.body.velocity.x);
this.line('velocity.y: ' + sprite.body.velocity.y);
this.stop();
},
/**
* Render debug information about the Input object.
* @param x {number} X position of the debug info to be rendered.