From ea3802a556fff45433743ee32d3b2496c421eebd Mon Sep 17 00:00:00 2001 From: photonstorm Date: Thu, 5 Dec 2013 18:12:16 +0000 Subject: [PATCH] Lots of new tilemap code in here. If your game relies on tilemaps then please don't update to this commit unless you want to help debugging! --- examples/assets/maps/newtest.json | 76 ++++++++++++++++ examples/assets/maps/newtest.tmx | 27 ++++++ examples/tilemaps/sci fly.js | 3 +- examples/wip/tilemap.js | 118 ++++++++++++++++++++++++ src/physics/arcade/ArcadePhysics.js | 119 ++++++++++++++++++++++-- src/physics/arcade/Body.js | 57 +++++++++++- src/tilemap/Tile.js | 41 ++++++--- src/tilemap/Tilemap.js | 136 ++++++++++++++++++++++++++++ src/tilemap/TilemapLayer.js | 134 +++++++++++++++++++++------ src/tilemap/TilemapParser.js | 64 ++++++++++++- src/utils/Debug.js | 50 ++++++++-- 11 files changed, 762 insertions(+), 63 deletions(-) create mode 100644 examples/assets/maps/newtest.json create mode 100644 examples/assets/maps/newtest.tmx create mode 100644 examples/wip/tilemap.js diff --git a/examples/assets/maps/newtest.json b/examples/assets/maps/newtest.json new file mode 100644 index 00000000..824ff849 --- /dev/null +++ b/examples/assets/maps/newtest.json @@ -0,0 +1,76 @@ +{ "height":18, + "layers":[ + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":18, + "name":"Tile Layer 1", + "opacity":1, + "properties": + { + "bob":"eat's cheese" + }, + "type":"tilelayer", + "visible":true, + "width":50, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":18, + "name":"Tile Layer 2", + "opacity":1, + "type":"tilelayer", + "visible":false, + "width":50, + "x":0, + "y":0 + }], + "orientation":"orthogonal", + "properties": + { + + }, + "tileheight":32, + "tilesets":[ + { + "firstgid":1, + "image":"ground_1x1.png", + "imageheight":32, + "imagewidth":800, + "margin":0, + "name":"ground_1x1", + "properties": + { + + }, + "spacing":0, + "tileheight":32, + "tileproperties": + { + "1": + { + "bounce":"1" + } + }, + "tilewidth":32 + }, + { + "firstgid":26, + "image":"walls_1x2.png", + "imageheight":64, + "imagewidth":256, + "margin":0, + "name":"walls_1x2", + "properties": + { + + }, + "spacing":0, + "tileheight":64, + "tilewidth":32 + }], + "tilewidth":32, + "version":1, + "width":50 +} \ No newline at end of file diff --git a/examples/assets/maps/newtest.tmx b/examples/assets/maps/newtest.tmx new file mode 100644 index 00000000..472bfe21 --- /dev/null +++ b/examples/assets/maps/newtest.tmx @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + AQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAA + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + + diff --git a/examples/tilemaps/sci fly.js b/examples/tilemaps/sci fly.js index c0e15f28..cf6c92d5 100644 --- a/examples/tilemaps/sci fly.js +++ b/examples/tilemaps/sci fly.js @@ -52,7 +52,7 @@ function create() { sprite = game.add.sprite(450, 80, 'phaser'); sprite.anchor.setTo(0.5, 0.5); - // sprite.angle = 45; + sprite.angle = 5; game.camera.follow(sprite); // game.camera.deadzone = new Phaser.Rectangle(160, 160, layer.renderWidth-320, layer.renderHeight-320); @@ -113,6 +113,7 @@ function update() { function render() { game.debug.renderSpriteBounds(sprite); + // game.debug.renderSpriteInfo(sprite, 32, 32); // game.debug.renderSpriteCoords(sprite, 32, 32); diff --git a/examples/wip/tilemap.js b/examples/wip/tilemap.js new file mode 100644 index 00000000..7de691ee --- /dev/null +++ b/examples/wip/tilemap.js @@ -0,0 +1,118 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.tilemap('map', 'assets/maps/newtest.json', null, Phaser.Tilemap.TILED_JSON); + game.load.tileset('tiles', 'assets/maps/ground_1x1.png', 32, 32); + // game.load.image('phaser', 'assets/sprites/phaser-ship.png'); + game.load.image('phaser', 'assets/sprites/mushroom2.png'); + +} + +var cursors; +var map; +var layer; +var sprite; + +function create() { + + game.stage.backgroundColor = '#5c94fc'; + + map = game.add.tilemap('map'); + + map.setCollisionByIndex(1); + + // Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, tilemap, layer) { + + layer = game.add.tilemapLayer(0, 0, 800, 600, null, map, 0); + + // tileset = game.add.tileset('tilesNes'); + // layer = game.add.tilemapLayer(0, 0, map.layers[0].width*tilesetNes.tileWidth, 600, tileset, map, 0); + + // disable this and you can place anywhere, but will almost certainly screw collision + // layer.fixedToCamera=false; + + // this screws something up - not quite sure what, but needs investigating! + // layer.resizeWorld(); + + sprite = game.add.sprite(120, 510, 'phaser'); + sprite.anchor.setTo(0.5, 0.5); + // sprite.angle = 5; + + // game.camera.follow(sprite); + + cursors = game.input.keyboard.createCursorKeys(); + + game.input.onDown.add(dump, this); + + +} + +function dump() { + + console.log(sprite.bounds); + console.log(sprite.body.hull); + console.log('wy', sprite.world.y); + +} + +function update() { + + /* + if (cursors.left.isDown) + { + layer.scrollX -= 4; + } + else if (cursors.right.isDown) + { + layer.scrollX += 4; + } + + if (cursors.up.isDown) + { + layer.scrollY -= 4; + } + else if (cursors.down.isDown) + { + layer.scrollY += 4; + } + */ + + game.physics.collide(sprite, layer); + + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + + if (cursors.up.isDown) + { + sprite.body.velocity.y = -150; + } + else if (cursors.down.isDown) + { + sprite.body.velocity.y = 150; + } + + if (cursors.left.isDown) + { + sprite.body.velocity.x = -150; + sprite.scale.x = -1; + } + else if (cursors.right.isDown) + { + sprite.body.velocity.x = 150; + sprite.scale.x = 1; + } + + +} + +function render() { + + game.debug.renderSpriteBody(sprite); + // game.debug.renderSpriteBounds(sprite); + + game.debug.renderText(sprite.x, 32, 32); + game.debug.renderText(sprite.y, 32, 64); + +} \ No newline at end of file diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index 570b3b2e..ad3b1057 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -610,11 +610,6 @@ Phaser.Physics.Arcade.prototype = { return; } - if (group.length === 0) - { - return; - } - if (group._container.first._iNext) { var currentNode = group._container.first._iNext; @@ -995,7 +990,7 @@ Phaser.Physics.Arcade.prototype = { * @param {Phaser.Tile} tile - The tile to collide against. * @returns {boolean} Returns true if the bodies were separated, otherwise false. */ - separateTile: function (body, tile) { + XseparateTile: function (body, tile) { this._result = (this.separateTileX(body, tile, true) || this.separateTileY(body, tile, true)); @@ -1003,6 +998,110 @@ Phaser.Physics.Arcade.prototype = { }, + separateTile: function (body, tile) { + + // Can't separate two immovable objects (tiles are always immovable) + if (body.immovable || Phaser.Rectangle.intersects(body, tile) === false) + { + return false; + } + + var overlapX = 0; + var overlapY = 0; + + console.log('x', tile.x, 'y', tile.y, 'r', tile.right, 'b', tile.bottom); + console.log('x', body.x, 'y', body.y, 'r', body.right, 'b', body.bottom); + console.log(Phaser.Rectangle.intersects(body, tile)); + + if (body.deltaX() < 0 && body.allowCollision.left && tile.tile.faceRight) + { + // LEFT + if (tile.right - body.x < Math.ceil(body.deltaAbsX())) + { + overlapX = tile.right - body.x; + + body.touching.left = true; + body.touching.none = false; + } + } + else if (body.deltaX() > 0 && body.allowCollision.right && tile.tile.faceLeft) + { + // RIGHT + if (body.right - tile.x < Math.ceil(body.deltaAbsX())) + { + overlapX = tile.x - body.right; + + body.touching.right = true; + body.touching.none = false; + } + } + + if (body.deltaY() < 0 && body.allowCollision.up && tile.tile.faceBottom) + { + // UP + if (tile.bottom - body.y < Math.ceil(body.deltaAbsY())) + { + overlapY = tile.bottom - body.y; + + body.touching.up = true; + body.touching.none = false; + } + } + else if (body.deltaY() > 0 && body.allowCollision.down && tile.tile.faceTop) + { + // DOWN + if (body.bottom - tile.y < Math.ceil(body.deltaAbsY())) + { + overlapY = tile.y - body.bottom; + + body.touching.down = true; + body.touching.none = false; + } + } + + // Separate in a single sweep + + if (overlapX === 0 && overlapY === 0) + { + return false; + } + + if (overlapX !== 0) + { + // body.overlapX = overlapX; + body.x += overlapX; + body.preX = body.x; + + if (body.bounce.x === 0) + { + body.velocity.x = 0; + } + else + { + body.velocity.x = -body.velocity.x * body.bounce.x; + } + } + + if (overlapY !== 0) + { + // body.overlapY = overlapY; + body.y += overlapY; + body.preY = body.y; + + if (body.bounce.y === 0) + { + body.velocity.y = 0; + } + else + { + body.velocity.y = -body.velocity.y * body.bounce.y; + } + } + + return true; + + }, + /** * The core separation function to separate a physics body and a tile on the x axis. * @method Phaser.Physics.Arcade#separateTileX @@ -1059,6 +1158,8 @@ Phaser.Physics.Arcade.prototype = { { if (separate) { + // console.log('dx1', body.x); + if (body.deltaX() < 0) { body.x = body.x + this._overlap; @@ -1068,6 +1169,8 @@ Phaser.Physics.Arcade.prototype = { body.x = body.x - this._overlap; } + // console.log('dx2', body.x, this._overlap); + if (body.bounce.x === 0) { body.velocity.x = 0; @@ -1077,7 +1180,7 @@ Phaser.Physics.Arcade.prototype = { body.velocity.x = -body.velocity.x * body.bounce.x; } - body.updateHulls(); + body.updateHulls(false); } return true; @@ -1163,7 +1266,7 @@ Phaser.Physics.Arcade.prototype = { body.velocity.y = -body.velocity.y * body.bounce.y; } - body.updateHulls(); + body.updateHulls(false); } return true; diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index f1441d5e..ac217b70 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -286,6 +286,8 @@ Phaser.Physics.Arcade.Body = function (sprite) { */ this.overlapY = 0; + this.hull = new Phaser.Rectangle(); + /** * @property {Phaser.Rectangle} hullX - The dynamically calculated hull used during collision. */ @@ -368,6 +370,9 @@ Phaser.Physics.Arcade.Body.prototype = { this.y = this.preY; this.rotation = this.preRotation; + this.overlapX = 0; + this.overlapY = 0; + if (this.moves) { this.game.physics.updateMotion(this); @@ -377,7 +382,11 @@ Phaser.Physics.Arcade.Body.prototype = { this.checkWorldBounds(); } - this.updateHulls(); + this.hull.setTo(this.preX, this.preY, this.width, this.height); + + // this.hullX.setTo(this.x, this.preY, this.width, this.height); + // this.hullY.setTo(this.preX, this.y, this.width, this.height); + this.updateHulls(true); } if (this.skipQuadTree === false && this.allowCollision.none === false && this.sprite.visible && this.sprite.alive) @@ -415,8 +424,37 @@ Phaser.Physics.Arcade.Body.prototype = { this.facing = Phaser.DOWN; } + /* + if (this.overlapX !== 0) + { + this.sprite.x += this.overlapX; + } + else + { + if (this.deltaX() !== 0) + { + this.sprite.x += this.deltaX(); + } + } + + if (this.overlapY !== 0) + { + this.sprite.y += this.overlapY; + } + else + { + if (this.deltaY() !== 0) + { + this.sprite.y += this.deltaY(); + } + } + */ + if (this.deltaX() !== 0 || this.deltaY() !== 0) { + // console.log('dx', this.deltaX()); + // console.log('dy', this.deltaY()); + this.sprite.x += this.deltaX(); this.sprite.y += this.deltaY(); this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight); @@ -435,10 +473,21 @@ Phaser.Physics.Arcade.Body.prototype = { * @method Phaser.Physics.Arcade#updateHulls * @protected */ - updateHulls: function () { + updateHulls: function (separation) { - this.hullX.setTo(this.x, this.preY, this.width, this.height); - this.hullY.setTo(this.preX, this.y, this.width, this.height); + // this.hull.setTo(this.x, this.y, this.width, this.height); + + // if (separation) + // { + // this.hullX.setTo(this.x, this.preY, this.width, this.height); + // this.hullY.setTo(this.preX, this.y, this.width, this.height); + // } + // else + // { + // if this has separated then the preX/Y values are no longer valid + // this.hullX.setTo(this.x, this.y, this.width, this.height); + // this.hullY.setTo(this.x, this.y, this.width, this.height); + // } }, diff --git a/src/tilemap/Tile.js b/src/tilemap/Tile.js index 1c21c6f4..96e0bb9f 100644 --- a/src/tilemap/Tile.js +++ b/src/tilemap/Tile.js @@ -17,18 +17,29 @@ * @param {number} width - Width of the tile. * @param {number} height - Height of the tile. */ -Phaser.Tile = function (tileset, index, x, y, width, height) { +// Phaser.Tile = function (tileset, index, x, y, width, height) { +Phaser.Tile = function (index, x, y, width, height) { /** * @property {Phaser.Tileset} tileset - The tileset this tile belongs to. */ - this.tileset = tileset; + // this.tileset = tileset; /** * @property {number} index - The index of this tile within the tileset. */ this.index = index; + /** + * @property {number} x - The x map coordinate of this tile. + */ + this.x = x; + + /** + * @property {number} y - The y map coordinate of this tile. + */ + this.y = y; + /** * @property {number} width - The width of the tile in pixels. */ @@ -40,14 +51,9 @@ Phaser.Tile = function (tileset, index, x, y, width, height) { this.height = height; /** - * @property {number} x - The top-left corner of the tile within the tileset. + * @property {number} alpha - The alpha value at which this tile is drawn to the canvas. */ - this.x = x; - - /** - * @property {number} y - The top-left corner of the tile within the tileset. - */ - this.y = y; + this.alpha = 1; // Any extra meta data info we need here @@ -55,7 +61,18 @@ Phaser.Tile = function (tileset, index, x, y, width, height) { * @property {number} mass - The virtual mass of the tile. * @default */ - this.mass = 1.0; + // this.mass = 1.0; + + + // Keep track of our interesting faces + this.faceTop = false; + this.faceBottom = false; + this.faceLeft = false; + this.faceRight = false; + + this.collides = false; + + /** * @property {boolean} collideNone - Indicating this Tile doesn't collide at all. @@ -91,13 +108,13 @@ Phaser.Tile = function (tileset, index, x, y, width, height) { * @property {boolean} separateX - Enable separation at x-axis. * @default */ - this.separateX = true; + // this.separateX = true; /** * @property {boolean} separateY - Enable separation at y-axis. * @default */ - this.separateY = true; + // this.separateY = true; /** * @property {boolean} collisionCallback - Tilemap collision callback. diff --git a/src/tilemap/Tilemap.js b/src/tilemap/Tilemap.js index 87dda754..58dcbbb4 100644 --- a/src/tilemap/Tilemap.js +++ b/src/tilemap/Tilemap.js @@ -123,6 +123,140 @@ Phaser.Tilemap.prototype = { }, + /** + * Sets collision values on a tile in the set. + * + * @method Phaser.Tileset#setCollision + * @param {number} index - The index of the tile within the set. + * @param {boolean} left - Should the tile collide on the left? + * @param {boolean} right - Should the tile collide on the right? + * @param {boolean} up - Should the tile collide on the top? + * @param {boolean} down - Should the tile collide on the bottom? + */ + + // Sets all tiles matching the given index to collide on the given faces + // Recalculates the collision map + setCollisionByIndex: function (index, layer) { + + if (typeof layer === "undefined") { layer = this.currentLayer; } + + for (var y = 0; y < this.layers[layer].height ; y++) + { + for (var x = 0; x < this.layers[layer].width; x++) + { + var tile = this.layers[layer].data[y][x]; + + if (tile && tile.index === index) + { + tile.collides = true; + tile.faceTop = true; + tile.faceBottom = true; + tile.faceLeft = true; + tile.faceRight = true; + } + } + } + + // Now re-calculate interesting faces + this.calculateFaces(layer); + + }, + + calculateFaces: function (layer) { + + var above = null; + var below = null; + var left = null; + var right = null; + +console.log(this.layers[layer].width, 'x', this.layers[layer].height); + + for (var y = 0; y < this.layers[layer].height ; y++) + { + for (var x = 0; x < this.layers[layer].width; x++) + { + var tile = this.layers[layer].data[y][x]; + + if (tile) + { + above = this.getTileAbove(layer, x, y); + below = this.getTileBelow(layer, x, y); + left = this.getTileLeft(layer, x, y); + right = this.getTileRight(layer, x, y); + + if (above && above.collides) + { + // There is a tile above this one that also collides, so the top of this tile is no longer interesting + tile.faceTop = false; + } + + if (below && below.collides) + { + // There is a tile below this one that also collides, so the bottom of this tile is no longer interesting + tile.faceBottom = false; + } + + if (left && left.collides) + { + // There is a tile left this one that also collides, so the left of this tile is no longer interesting + tile.faceLeft = false; + } + + if (right && right.collides) + { + // There is a tile right this one that also collides, so the right of this tile is no longer interesting + tile.faceRight = false; + } + } + } + } + + }, + + getTileAbove: function (layer, x, y) { + + if (y > 0) + { + return this.layers[layer].data[y - 1][x]; + } + + return null; + + }, + + getTileBelow: function (layer, x, y) { + + if (y < this.layers[layer].height - 1) + { + return this.layers[layer].data[y + 1][x]; + } + + return null; + + }, + + getTileLeft: function (layer, x, y) { + + if (x > 0) + { + return this.layers[layer].data[y][x - 1]; + } + + return null; + + }, + + getTileRight: function (layer, x, y) { + + if (x < this.layers[layer].width - 1) + { + return this.layers[layer].data[y][x + 1]; + } + + return null; + + }, + /** * Internal function that calculates the tile indexes for the map data. * @@ -130,6 +264,7 @@ Phaser.Tilemap.prototype = { */ calculateIndexes: function () { + /* for (var layer = 0; layer < this.layers.length; layer++) { this.layers[layer].indexes = []; @@ -147,6 +282,7 @@ Phaser.Tilemap.prototype = { } } } + */ }, diff --git a/src/tilemap/TilemapLayer.js b/src/tilemap/TilemapLayer.js index e546cb10..1b21bb5b 100644 --- a/src/tilemap/TilemapLayer.js +++ b/src/tilemap/TilemapLayer.js @@ -286,8 +286,9 @@ Phaser.TilemapLayer.prototype.constructor = Phaser.TilemapLayer; */ Phaser.TilemapLayer.prototype.postUpdate = function () { - Phaser.Sprite.prototype.postUpdate.call( this ); + Phaser.Sprite.prototype.postUpdate.call(this); + // Stops you being able to scroll the camera if it's not following a sprite this.scrollX = this.game.camera.x * this.scrollFactorX; this.scrollY = this.game.camera.y * this.scrollFactorY; @@ -357,6 +358,8 @@ Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) { { this.tilemap = tilemap; this.layer = this.tilemap.layers[layer]; + this.tileWidth = this.layer.tileWidth; + this.tileHeight = this.layer.tileHeight; this.index = layer; this.updateMax(); this.tilemap.layers[layer].dirty = true; @@ -507,7 +510,7 @@ Phaser.TilemapLayer.prototype.getTileXY = function (x, y, point) { * @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels) * @param {number} width - The width of the area to copy (given in tiles, not pixels) * @param {number} height - The height of the area to copy (given in tiles, not pixels) -* @param {boolean} collides - If true only return tiles that collide on one or more faces. +* @param {boolean} [collides=false] - If true only return tiles that collide on one or more faces. * @return {array} Array with tiles informations (each contains x, y, and the tile). */ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides) { @@ -533,8 +536,8 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides } // adjust the x,y coordinates for scrollFactor - x = this._fixX( x ); - y = this._fixY( y ); + x = this._fixX(x); + y = this._fixY(y); if (width > this.widthInPixels) { @@ -546,6 +549,9 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides height = this.heightInPixels; } + this.context.fillStyle = 'rgba(255,0,255,0.5)'; + // this.context.fillRect(x, y, width, height); + var tileWidth = this.tileWidth * this.scale.x; var tileHeight = this.tileHeight * this.scale.y; @@ -555,19 +561,19 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides this._tw = (this.game.math.snapToCeil(width, tileWidth) + tileWidth) / tileWidth; this._th = (this.game.math.snapToCeil(height, tileHeight) + tileHeight) / tileHeight; + this.context.fillRect(this._tx * tileWidth, this._ty * tileHeight, this._tw * tileWidth, this._th * tileHeight); + // This should apply the layer x/y here - - // this._results.length = 0; - this._results = []; - - // pretty sure we don't use this any more? - // this._results.push( { x: x, y: y, width: width, height: height, tx: this._tx, ty: this._ty, tw: this._tw, th: this._th }); + this._results.length = 0; var _index = 0; var _tile = null; var sx = 0; var sy = 0; + this.context.fillStyle = 'rgba(255,0,0,0.5)'; + this.context.strokeStyle = 'rgba(0,0,0,1)'; + for (var wy = this._ty; wy < this._ty + this._th; wy++) { for (var wx = this._tx; wx < this._tx + this._tw; wx++) @@ -575,19 +581,42 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides if (this.layer.data[wy] && this.layer.data[wy][wx]) { // Could combine - _index = this.layer.data[wy][wx] - 1; - _tile = this.tileset.getTile(_index); + // _index = this.layer.data[wy][wx] - 1; + // _tile = this.tileset.getTile(_index); + _tile = this.layer.data[wy][wx]; - sx = _tile.width * this.scale.x; - sy = _tile.height * this.scale.y; - - if (collides === false || (collides && _tile.collideNone === false)) + if (_tile) { - // convert tile coordinates back to camera space for return - var _wx = this._unfixX( wx*sx ) / tileWidth; - var _wy = this._unfixY( wy*sy ) / tileHeight; - this._results.push({ x: _wx * sx, right: (_wx * sx) + sx, y: _wy * sy, bottom: (_wy * sy) + sy, width: sx, height: sy, tx: _wx, ty: _wy, tile: _tile }); + + // sx = _tile.width * this.scale.x; + // sy = _tile.height * this.scale.y; + sx = this.tileWidth * this.scale.x; + sy = this.tileHeight * this.scale.y; + + if (collides === false || (collides && _tile.collides)) + { + this.context.fillRect(_tile.x * this.tileWidth, _tile.y * this.tileHeight, this.tileWidth, this.tileHeight); + this.context.strokeRect(_tile.x * this.tileWidth, _tile.y * this.tileHeight, this.tileWidth, this.tileHeight); + + // convert tile coordinates back to camera space for return + var _wx = this._unfixX(wx * sx) / this.tileWidth; + var _wy = this._unfixY(wy * sy) / this.tileHeight; + + this._results.push({ + x: _wx * sx, + y: _wy * sy, + width: sx, + height: sy, + right: (_wx * sx) + sx, + bottom: (_wy * sy) + sy, + tx: _wx, + ty: _wy, + tile: _tile + }); + } + } + } } } @@ -633,34 +662,82 @@ Phaser.TilemapLayer.prototype.updateMax = function () { */ Phaser.TilemapLayer.prototype.render = function () { - if (this.tilemap && this.tilemap.layers[this.index].dirty ) + if (this.tilemap && this.tilemap.layers[this.index].dirty) { this.dirty = true; } if (!this.dirty || !this.tileset || !this.tilemap || !this.visible) { - return; + // return; } this._prevX = this._dx; this._prevY = this._dy; + // console.log('render', this._x); + this._dx = -(this._x - (this._startX * this.tileWidth)); this._dy = -(this._y - (this._startY * this.tileHeight)); + // this._dx = Math.floor(this._dx); + // this._dy = Math.floor(this._dy); + this._tx = this._dx; this._ty = this._dy; - this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); + // this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); + // this.context.fillStyle = '#000000'; + // this.context.fillRect(0, 0, this.canvas.width, this.canvas.height); - for (var y = this._startY; y < this._startY + this._maxY; y++) + this.context.strokeStyle = '#00ff00'; + + for (var y = this._startY, lenY = this._startY + this._maxY; y < lenY; y++) { this._column = this.layer.data[y]; - for (var x = this._startX; x < this._startX + this._maxX; x++) + for (var x = this._startX, lenX = this._startX + this._maxX; x < lenX; x++) { + var tile = this._column[x]; + + if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight)) + { + this._tx = Math.floor(this._tx); + + this.context.beginPath(); + + if (tile.faceTop) + { + this.context.moveTo(this._tx, this._ty); + this.context.lineTo(this._tx + this.tileWidth, this._ty); + } + + if (tile.faceBottom) + { + this.context.moveTo(this._tx, this._ty + this.tileHeight); + this.context.lineTo(this._tx + this.tileWidth, this._ty + this.tileHeight); + } + + if (tile.faceLeft) + { + this.context.moveTo(this._tx, this._ty); + this.context.lineTo(this._tx, this._ty + this.tileHeight); + } + + if (tile.faceRight) + { + this.context.moveTo(this._tx + this.tileWidth, this._ty); + this.context.lineTo(this._tx + this.tileWidth, this._ty + this.tileHeight); + } + + this.context.stroke(); + + // this.context.fillRect(this._tx, this._ty, this.tileWidth, this.tileHeight); + // this.context.strokeRect(this._tx, this._ty, this.tileWidth, this.tileHeight); + } + // only -1 on TILED maps, not CSV + /* var tile = this.tileset.tiles[this._column[x]-1]; if (tile) @@ -677,6 +754,7 @@ Phaser.TilemapLayer.prototype.render = function () { this.tileHeight ); } + */ this._tx += this.tileWidth; @@ -684,17 +762,18 @@ Phaser.TilemapLayer.prototype.render = function () { this._tx = this._dx; this._ty += this.tileHeight; + } // Only needed if running in WebGL, otherwise this array will never get cleared down I don't think! - if (this.game.renderType == Phaser.WEBGL) + if (this.game.renderType === Phaser.WEBGL) { PIXI.texturesToUpdate.push(this.baseTexture); } this.dirty = false; - if( this.tilemap.layers[this.index].dirty ) + if (this.tilemap.layers[this.index].dirty) { this.tilemap.layers[this.index].dirty = false; } @@ -764,6 +843,7 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollX", { this._x = this.widthInPixels - this.renderWidth; } + this._startX = this.game.math.floor(this._x / this.tileWidth); if (this._startX < 0) diff --git a/src/tilemap/TilemapParser.js b/src/tilemap/TilemapParser.js index 0278c21a..9714a1bf 100644 --- a/src/tilemap/TilemapParser.js +++ b/src/tilemap/TilemapParser.js @@ -140,6 +140,8 @@ Phaser.TilemapParser = { } } + // Build collision map + return [{ name: 'csv', width: width, height: height, alpha: 1, visible: true, indexes: [], tileMargin: 0, tileSpacing: 0, data: output }]; }, @@ -147,11 +149,19 @@ Phaser.TilemapParser = { /** * Parses a Tiled JSON file into valid map data. * @method Phaser.TilemapParser.parseJSON - * @param {object} json- The Tiled JSON data. + * @param {object} json - The Tiled JSON data. * @return {object} Generated map data. */ parseTiledJSON: function (json) { + // Let's work out which tilesets are in here + var tilesets = []; + + for (var i = 0; i < json.tilesets.length; i++) + { + tilesets.push(json.tilesets[i].firstgid); + } + var layers = []; for (var i = 0; i < json.layers.length; i++) @@ -168,29 +178,69 @@ Phaser.TilemapParser = { var layer = { name: json.layers[i].name, + x: json.layers[i].x, + y: json.layers[i].y, width: json.layers[i].width, height: json.layers[i].height, alpha: json.layers[i].opacity, visible: json.layers[i].visible, + properties: {}, + tileWidth: json.tilewidth, + tileHeight: json.tileheight, + indexes: [], - tileMargin: json.tilesets[0].margin, - tileSpacing: json.tilesets[0].spacing + // tileset specific + // tileMargin: json.tilesets[0].margin, + // tileSpacing: json.tilesets[0].spacing }; + if (json.layers[i].properties) + { + layer.properties = json.layers[i].properties; + } + + var x = 0; + var row = []; var output = []; - var c = 0; - var row; + + // Loop through the data field in the JSON. + + // This is an array containing the tile indexes, one after the other. 0 = no tile, everything else = the tile index (starting at 1) + // If the map contains multiple tilesets then the indexes are relative to that which the set starts from + // Need to set which tileset in the cache = which tileset in the JSON, if you do this manually it means you can use the same map data but a new tileset. for (var t = 0; t < json.layers[i].data.length; t++) { + // index, x, y, width, height + if (json.layers[i].data[t] > 0) + { + row.push(new Phaser.Tile(json.layers[i].data[t], x, output.length, json.tilewidth, json.tileheight)); + } + else + { + row.push(null); + } + + x++; + + if (x === json.layers[i].width) + { + output.push(row); + x = 0; + row = []; + } + + + /* if (c === 0) { row = []; } row.push(json.layers[i].data[t]); + c++; if (c == json.layers[i].width) @@ -198,9 +248,13 @@ Phaser.TilemapParser = { output.push(row); c = 0; } + */ } layer.data = output; + + // Build collision map + // console.log(output); layers.push(layer); diff --git a/src/utils/Debug.js b/src/utils/Debug.js index 48184bcc..edcaefe8 100644 --- a/src/utils/Debug.js +++ b/src/utils/Debug.js @@ -627,7 +627,7 @@ Phaser.Utils.Debug.prototype = { */ renderSpriteBody: function (sprite, color) { - if (this.context == null) + if (this.context == null || sprite.body.touching.none === true) { return; } @@ -636,8 +636,37 @@ Phaser.Utils.Debug.prototype = { this.start(0, 0, color); - this.context.fillStyle = color; - this.context.fillRect(sprite.body.screenX, sprite.body.screenY, sprite.body.width, sprite.body.height); + // this.context.fillStyle = color; + // this.context.fillRect(sprite.body.screenX, sprite.body.screenY, sprite.body.width, sprite.body.height); + + this.context.beginPath(); + this.context.strokeStyle = '#000000'; + + if (sprite.body.touching.up) + { + this.context.moveTo(sprite.body.x, sprite.body.y); + this.context.lineTo(sprite.body.x + sprite.body.width, sprite.body.y); + } + + if (sprite.body.touching.down) + { + this.context.moveTo(sprite.body.x, sprite.body.y + sprite.body.height); + this.context.lineTo(sprite.body.x + sprite.body.width, sprite.body.y + sprite.body.height); + } + + if (sprite.body.touching.left) + { + this.context.moveTo(sprite.body.x, sprite.body.y); + this.context.lineTo(sprite.body.x, sprite.body.y + sprite.body.height); + } + + if (sprite.body.touching.right) + { + this.context.moveTo(sprite.body.x + sprite.body.width, sprite.body.y); + this.context.lineTo(sprite.body.x + sprite.body.width, sprite.body.y + sprite.body.height); + } + + this.context.stroke(); this.stop(); @@ -670,9 +699,18 @@ Phaser.Utils.Debug.prototype = { } else { - this.context.strokeStyle = color; - this.context.strokeRect(sprite.bounds.x, sprite.bounds.y, sprite.bounds.width, sprite.bounds.height); - this.context.stroke(); + // this.context.strokeStyle = color; + // this.context.strokeRect(sprite.bounds.x, sprite.bounds.y, sprite.bounds.width, sprite.bounds.height); + // this.context.strokeRect(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height); + // this.context.strokeRect(sprite.body.hull.x, sprite.body.hull.y, sprite.body.hull.width, sprite.body.hull.height); + // this.context.stroke(); + + // this.context.strokeStyle = '#ff0000'; + // this.context.strokeRect(sprite.body.hullX.x, sprite.body.hullX.y, sprite.body.hullX.width, sprite.body.hullX.height); + // this.context.stroke(); + // this.context.strokeStyle = '#00ff00'; + // this.context.strokeRect(sprite.body.hullY.x, sprite.body.hullY.y, sprite.body.hullY.width, sprite.body.hullY.height); + // this.context.stroke(); } this.stop();