From 822a2df2890c42999ebef9b8640dd0758512c3f8 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Fri, 6 Sep 2013 15:00:05 +0100 Subject: [PATCH] Lots of work on Group and also resolved the issue of the core game loop structure not being quite right. --- Phaser.sublime-workspace | 863 ++++++++++++++++++---------- examples/group1.php | 58 ++ examples/js.php | 1 + src/core/Game.js | 30 +- src/core/Group.js | 347 +++++++++-- src/core/World.js | 4 +- src/gameobjects/Sprite.js | 2 +- src/physics/arcade/ArcadePhysics.js | 5 +- src/physics/arcade/Body.js | 37 +- 9 files changed, 1003 insertions(+), 344 deletions(-) create mode 100644 examples/group1.php diff --git a/Phaser.sublime-workspace b/Phaser.sublime-workspace index 91dce77e..a0f19d89 100644 --- a/Phaser.sublime-workspace +++ b/Phaser.sublime-workspace @@ -3,6 +3,10 @@ { "selected_items": [ + [ + "add", + "addChild" + ], [ "refre", "refreshRate" @@ -510,45 +514,58 @@ [ "va", "vars" - ], - [ - "con", - "consts" ] ] }, "buffers": [ { - "file": "examples/consoleBanner2.php", + "file": "src/core/World.js", "settings": { - "buffer_size": 2371, + "buffer_size": 5207, "line_ending": "Windows" } }, { - "file": "/D/wamp/www/consoledemo/index.html", + "file": "src/physics/arcade/Body.js", "settings": { - "buffer_size": 8399, + "buffer_size": 5758, "line_ending": "Windows" } }, { - "file": "/D/wamp/www/consoledemo/src/codef_scrolltext.js", + "file": "src/core/Group.js", "settings": { - "buffer_size": 8518, - "line_ending": "Unix" + "buffer_size": 4677, + "line_ending": "Windows", + "name": "Phaser.Group = function () {" } }, { - "file": "/D/wamp/www/consoledemo/src/codef_core.js", + "file": "TS Source/core/Group.ts", "settings": { - "buffer_size": 26037, - "line_ending": "Unix" + "buffer_size": 33895, + "line_ending": "Windows" + } + }, + { + "file": "TS Source/core/Group.js", + "settings": + { + "buffer_size": 31469, + "line_ending": "Windows" + } + }, + { + "file": "src/gameobjects/GameObjectFactory.js", + "settings": + { + "buffer_size": 2568, + "line_ending": "Windows" } } ], @@ -580,6 +597,11 @@ }, "file_history": [ + "/D/wamp/www/phaser/src/system/Canvas.js", + "/D/wamp/www/consoledemo/index.html", + "/D/wamp/www/phaser/examples/consoleBanner2.php", + "/D/wamp/www/consoledemo/src/codef_core.js", + "/D/wamp/www/consoledemo/src/codef_scrolltext.js", "/D/wamp/www/consoledemo/src/codef_tween.js", "/D/wamp/www/consoledemo/src/codef_3d.js", "/D/wamp/www/consoledemo/src/codef_starfield.js", @@ -702,12 +724,7 @@ "/D/wamp/www/phaser/src/system/Device.js", "/D/wamp/www/phaser/TS Source/system/Device.js", "/D/wamp/www/phaser/src/core/State.js", - "/D/wamp/www/bbc-wolfblood/game.js", - "/D/wamp/www/phaser/TS Source/gameobjects/GameObjectFactory.js", - "/D/wamp/www/phaser/TS Source/tweens/Tween.ts", - "/D/wamp/www/phaser/TS Source/tweens/TweenManager.ts", - "/D/wamp/www/phaser/src/tween/TweenManager.js", - "/C/Users/rich/Desktop/game.js" + "/D/wamp/www/bbc-wolfblood/game.js" ], "find": { @@ -970,282 +987,23 @@ "groups": [ { - "selected": 1, + "selected": 2, "sheets": [ { "buffer": 0, - "file": "examples/consoleBanner2.php", + "file": "src/core/World.js", "settings": { - "buffer_size": 2371, + "buffer_size": 5207, "regions": { }, "selection": [ [ - 524, - 536 - ] - ], - "settings": - { - "codeintel": true, - "codeintel_config": - { - "JavaScript": - { - "codeintel_max_recursive_dir_depth": 2, - "codeintel_scan_files_in_project": false, - "javascriptExtraPaths": - [ - ] - }, - "PHP": - { - "codeintel_max_recursive_dir_depth": 5, - "codeintel_scan_files_in_project": false, - "phpExtraPaths": - [ - ] - }, - "Python": - { - "env": - { - } - } - }, - "codeintel_enabled_languages": - [ - "JavaScript", - "Mason", - "XBL", - "XUL", - "RHTML", - "SCSS", - "Python", - "HTML", - "Ruby", - "Python3", - "XML", - "Sass", - "XSLT", - "Django", - "HTML5", - "Perl", - "CSS", - "Twig", - "Less", - "Smarty", - "Node.js", - "Tcl", - "TemplateToolkit", - "PHP" - ], - "codeintel_live": true, - "codeintel_live_enabled_languages": - [ - "JavaScript", - "Mason", - "XBL", - "XUL", - "RHTML", - "SCSS", - "Python", - "HTML", - "Ruby", - "Python3", - "XML", - "Sass", - "XSLT", - "Django", - "HTML5", - "Perl", - "CSS", - "Twig", - "Less", - "Smarty", - "Node.js", - "Tcl", - "TemplateToolkit", - "PHP" - ], - "codeintel_max_recursive_dir_depth": 10, - "codeintel_scan_exclude_dir": - { - "JavaScript": - [ - "/build/", - "/min/" - ] - }, - "codeintel_scan_files_in_project": true, - "codeintel_selected_catalogs": - [ - "PyWin32", - "jQuery", - "Rails" - ], - "codeintel_snippets": true, - "codeintel_syntax_map": - { - "Python Django": "Python" - }, - "sublime_auto_complete": true, - "syntax": "Packages/PHP/PHP.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 144.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 1, - "file": "/D/wamp/www/consoledemo/index.html", - "settings": - { - "buffer_size": 8399, - "regions": - { - }, - "selection": - [ - [ - 6153, - 6153 - ] - ], - "settings": - { - "codeintel": true, - "codeintel_config": - { - "JavaScript": - { - "codeintel_max_recursive_dir_depth": 2, - "codeintel_scan_files_in_project": false, - "javascriptExtraPaths": - [ - ] - }, - "PHP": - { - "codeintel_max_recursive_dir_depth": 5, - "codeintel_scan_files_in_project": false, - "phpExtraPaths": - [ - ] - }, - "Python": - { - "env": - { - } - } - }, - "codeintel_enabled_languages": - [ - "JavaScript", - "Mason", - "XBL", - "XUL", - "RHTML", - "SCSS", - "Python", - "HTML", - "Ruby", - "Python3", - "XML", - "Sass", - "XSLT", - "Django", - "HTML5", - "Perl", - "CSS", - "Twig", - "Less", - "Smarty", - "Node.js", - "Tcl", - "TemplateToolkit", - "PHP" - ], - "codeintel_live": true, - "codeintel_live_enabled_languages": - [ - "JavaScript", - "Mason", - "XBL", - "XUL", - "RHTML", - "SCSS", - "Python", - "HTML", - "Ruby", - "Python3", - "XML", - "Sass", - "XSLT", - "Django", - "HTML5", - "Perl", - "CSS", - "Twig", - "Less", - "Smarty", - "Node.js", - "Tcl", - "TemplateToolkit", - "PHP" - ], - "codeintel_max_recursive_dir_depth": 10, - "codeintel_scan_exclude_dir": - { - "JavaScript": - [ - "/build/", - "/min/" - ] - }, - "codeintel_scan_files_in_project": true, - "codeintel_selected_catalogs": - [ - "PyWin32", - "jQuery", - "Rails" - ], - "codeintel_snippets": true, - "codeintel_syntax_map": - { - "Python Django": "Python" - }, - "sublime_auto_complete": true, - "syntax": "Packages/HTML/HTML.tmLanguage", - "translate_tabs_to_spaces": false - }, - "translation.x": 0.0, - "translation.y": 2092.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 2, - "file": "/D/wamp/www/consoledemo/src/codef_scrolltext.js", - "settings": - { - "buffer_size": 8518, - "regions": - { - }, - "selection": - [ - [ - 1956, - 1956 + 2283, + 2858 ] ], "settings": @@ -1357,25 +1115,25 @@ "translate_tabs_to_spaces": false }, "translation.x": 0.0, - "translation.y": 701.0, + "translation.y": 1930.0, "zoom_level": 1.0 }, "type": "text" }, { - "buffer": 3, - "file": "/D/wamp/www/consoledemo/src/codef_core.js", + "buffer": 1, + "file": "src/physics/arcade/Body.js", "settings": { - "buffer_size": 26037, + "buffer_size": 5758, "regions": { }, "selection": [ [ - 3147, - 3147 + 0, + 0 ] ], "settings": @@ -1486,7 +1244,530 @@ "syntax": "Packages/JavaScript/JavaScript.tmLanguage" }, "translation.x": 0.0, - "translation.y": 972.0, + "translation.y": 1270.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 2, + "file": "src/core/Group.js", + "settings": + { + "buffer_size": 4677, + "regions": + { + }, + "selection": + [ + [ + 3819, + 3819 + ] + ], + "settings": + { + "auto_name": "Phaser.Group = function () {", + "codeintel": true, + "codeintel_config": + { + "JavaScript": + { + "codeintel_max_recursive_dir_depth": 2, + "codeintel_scan_files_in_project": false, + "javascriptExtraPaths": + [ + ] + }, + "PHP": + { + "codeintel_max_recursive_dir_depth": 5, + "codeintel_scan_files_in_project": false, + "phpExtraPaths": + [ + ] + }, + "Python": + { + "env": + { + } + } + }, + "codeintel_enabled_languages": + [ + "JavaScript", + "Mason", + "XBL", + "XUL", + "RHTML", + "SCSS", + "Python", + "HTML", + "Ruby", + "Python3", + "XML", + "Sass", + "XSLT", + "Django", + "HTML5", + "Perl", + "CSS", + "Twig", + "Less", + "Smarty", + "Node.js", + "Tcl", + "TemplateToolkit", + "PHP" + ], + "codeintel_live": true, + "codeintel_live_enabled_languages": + [ + "JavaScript", + "Mason", + "XBL", + "XUL", + "RHTML", + "SCSS", + "Python", + "HTML", + "Ruby", + "Python3", + "XML", + "Sass", + "XSLT", + "Django", + "HTML5", + "Perl", + "CSS", + "Twig", + "Less", + "Smarty", + "Node.js", + "Tcl", + "TemplateToolkit", + "PHP" + ], + "codeintel_max_recursive_dir_depth": 10, + "codeintel_scan_exclude_dir": + { + "JavaScript": + [ + "/build/", + "/min/" + ] + }, + "codeintel_scan_files_in_project": true, + "codeintel_selected_catalogs": + [ + "PyWin32", + "jQuery", + "Rails" + ], + "codeintel_snippets": true, + "codeintel_syntax_map": + { + "Python Django": "Python" + }, + "sublime_auto_complete": true, + "syntax": "Packages/JavaScript/JavaScript.tmLanguage" + }, + "translation.x": 0.0, + "translation.y": 2738.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 3, + "file": "TS Source/core/Group.ts", + "settings": + { + "buffer_size": 33895, + "regions": + { + }, + "selection": + [ + [ + 0, + 0 + ] + ], + "settings": + { + "codeintel": true, + "codeintel_config": + { + "JavaScript": + { + "codeintel_max_recursive_dir_depth": 2, + "codeintel_scan_files_in_project": false, + "javascriptExtraPaths": + [ + ] + }, + "PHP": + { + "codeintel_max_recursive_dir_depth": 5, + "codeintel_scan_files_in_project": false, + "phpExtraPaths": + [ + ] + }, + "Python": + { + "env": + { + } + } + }, + "codeintel_enabled_languages": + [ + "JavaScript", + "Mason", + "XBL", + "XUL", + "RHTML", + "SCSS", + "Python", + "HTML", + "Ruby", + "Python3", + "XML", + "Sass", + "XSLT", + "Django", + "HTML5", + "Perl", + "CSS", + "Twig", + "Less", + "Smarty", + "Node.js", + "Tcl", + "TemplateToolkit", + "PHP" + ], + "codeintel_live": true, + "codeintel_live_enabled_languages": + [ + "JavaScript", + "Mason", + "XBL", + "XUL", + "RHTML", + "SCSS", + "Python", + "HTML", + "Ruby", + "Python3", + "XML", + "Sass", + "XSLT", + "Django", + "HTML5", + "Perl", + "CSS", + "Twig", + "Less", + "Smarty", + "Node.js", + "Tcl", + "TemplateToolkit", + "PHP" + ], + "codeintel_max_recursive_dir_depth": 10, + "codeintel_scan_exclude_dir": + { + "JavaScript": + [ + "/build/", + "/min/" + ] + }, + "codeintel_scan_files_in_project": true, + "codeintel_selected_catalogs": + [ + "PyWin32", + "jQuery", + "Rails" + ], + "codeintel_snippets": true, + "codeintel_syntax_map": + { + "Python Django": "Python" + }, + "sublime_auto_complete": true, + "syntax": "Packages/Text/Plain text.tmLanguage", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 0.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 4, + "file": "TS Source/core/Group.js", + "settings": + { + "buffer_size": 31469, + "regions": + { + }, + "selection": + [ + [ + 1372, + 1372 + ] + ], + "settings": + { + "codeintel": true, + "codeintel_config": + { + "JavaScript": + { + "codeintel_max_recursive_dir_depth": 2, + "codeintel_scan_files_in_project": false, + "javascriptExtraPaths": + [ + ] + }, + "PHP": + { + "codeintel_max_recursive_dir_depth": 5, + "codeintel_scan_files_in_project": false, + "phpExtraPaths": + [ + ] + }, + "Python": + { + "env": + { + } + } + }, + "codeintel_enabled_languages": + [ + "JavaScript", + "Mason", + "XBL", + "XUL", + "RHTML", + "SCSS", + "Python", + "HTML", + "Ruby", + "Python3", + "XML", + "Sass", + "XSLT", + "Django", + "HTML5", + "Perl", + "CSS", + "Twig", + "Less", + "Smarty", + "Node.js", + "Tcl", + "TemplateToolkit", + "PHP" + ], + "codeintel_live": true, + "codeintel_live_enabled_languages": + [ + "JavaScript", + "Mason", + "XBL", + "XUL", + "RHTML", + "SCSS", + "Python", + "HTML", + "Ruby", + "Python3", + "XML", + "Sass", + "XSLT", + "Django", + "HTML5", + "Perl", + "CSS", + "Twig", + "Less", + "Smarty", + "Node.js", + "Tcl", + "TemplateToolkit", + "PHP" + ], + "codeintel_max_recursive_dir_depth": 10, + "codeintel_scan_exclude_dir": + { + "JavaScript": + [ + "/build/", + "/min/" + ] + }, + "codeintel_scan_files_in_project": true, + "codeintel_selected_catalogs": + [ + "PyWin32", + "jQuery", + "Rails" + ], + "codeintel_snippets": true, + "codeintel_syntax_map": + { + "Python Django": "Python" + }, + "sublime_auto_complete": true, + "syntax": "Packages/JavaScript/JavaScript.tmLanguage", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 272.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 5, + "file": "src/gameobjects/GameObjectFactory.js", + "settings": + { + "buffer_size": 2568, + "regions": + { + }, + "selection": + [ + [ + 765, + 749 + ] + ], + "settings": + { + "codeintel": true, + "codeintel_config": + { + "JavaScript": + { + "codeintel_max_recursive_dir_depth": 2, + "codeintel_scan_files_in_project": false, + "javascriptExtraPaths": + [ + ] + }, + "PHP": + { + "codeintel_max_recursive_dir_depth": 5, + "codeintel_scan_files_in_project": false, + "phpExtraPaths": + [ + ] + }, + "Python": + { + "env": + { + } + } + }, + "codeintel_enabled_languages": + [ + "JavaScript", + "Mason", + "XBL", + "XUL", + "RHTML", + "SCSS", + "Python", + "HTML", + "Ruby", + "Python3", + "XML", + "Sass", + "XSLT", + "Django", + "HTML5", + "Perl", + "CSS", + "Twig", + "Less", + "Smarty", + "Node.js", + "Tcl", + "TemplateToolkit", + "PHP" + ], + "codeintel_live": true, + "codeintel_live_enabled_languages": + [ + "JavaScript", + "Mason", + "XBL", + "XUL", + "RHTML", + "SCSS", + "Python", + "HTML", + "Ruby", + "Python3", + "XML", + "Sass", + "XSLT", + "Django", + "HTML5", + "Perl", + "CSS", + "Twig", + "Less", + "Smarty", + "Node.js", + "Tcl", + "TemplateToolkit", + "PHP" + ], + "codeintel_max_recursive_dir_depth": 10, + "codeintel_scan_exclude_dir": + { + "JavaScript": + [ + "/build/", + "/min/" + ] + }, + "codeintel_scan_files_in_project": true, + "codeintel_selected_catalogs": + [ + "PyWin32", + "jQuery", + "Rails" + ], + "codeintel_snippets": true, + "codeintel_syntax_map": + { + "Python Django": "Python" + }, + "sublime_auto_complete": true, + "syntax": "Packages/JavaScript/JavaScript.tmLanguage", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 0.0, "zoom_level": 1.0 }, "type": "text" diff --git a/examples/group1.php b/examples/group1.php new file mode 100644 index 00000000..49acff28 --- /dev/null +++ b/examples/group1.php @@ -0,0 +1,58 @@ + + + + phaser.js - a new beginning + + + + + + + + \ No newline at end of file diff --git a/examples/js.php b/examples/js.php index 279877a8..208d8425 100644 --- a/examples/js.php +++ b/examples/js.php @@ -50,6 +50,7 @@ + diff --git a/src/core/Game.js b/src/core/Game.js index 079abf84..ffd728b7 100644 --- a/src/core/Game.js +++ b/src/core/Game.js @@ -375,23 +375,27 @@ Phaser.Game.prototype = { this.time.update(time); - this.plugins.preUpdate(); - this.physics.preUpdate(); + if (!this.paused) + { + this.plugins.preUpdate(); + // this.world.preUpdate(); + this.physics.preUpdate(); - this.input.update(); - this.tweens.update(); - this.sound.update(); - this.world.update(); - this.state.update(); - this.plugins.update(); + this.input.update(); + this.tweens.update(); + this.sound.update(); + this.world.update(); + this.state.update(); + this.plugins.update(); - this.renderer.render(this.world._stage); - this.state.render(); + this.renderer.render(this.world._stage); + this.state.render(); - this.world.postUpdate(); - this.physics.postUpdate(); + // this.world.postUpdate(); + // this.physics.postUpdate(); - this.plugins.postRender(); + this.plugins.postRender(); + } }, diff --git a/src/core/Group.js b/src/core/Group.js index 020c692e..b605b0e4 100644 --- a/src/core/Group.js +++ b/src/core/Group.js @@ -53,6 +53,7 @@ Phaser.Group.prototype = { createSprite: function (x, y, key, frame) { var child = new Phaser.Sprite(this.game, x, y, key, frame); + child.group = this; this._container.addChild(child); return child; @@ -60,13 +61,102 @@ Phaser.Group.prototype = { swap: function (child1, child2) { - return this.game.world.swapChildren(child1, child2); + if (child1 === child2 || !child1.parent || !child2.parent) + { + console.warn('You cannot swap a child with itself or swap un-parented children'); + return false; + } + // Cache the values + var child1Prev = child1._iPrev; + var child1Next = child1._iNext; + var child2Prev = child2._iPrev; + var child2Next = child2._iNext; + + var endNode = this._container.last._iNext; + var currentNode = this._container.first; + + do + { + if (currentNode !== child1 && currentNode !== child2) + { + if (currentNode.first === child1) + { + currentNode.first = child2; + } + else if (currentNode.first === child2) + { + currentNode.first = child1; + } + + if (currentNode.last === child1) + { + currentNode.last = child2; + } + else if (currentNode.last === child2) + { + currentNode.last = child1; + } + } + + currentNode = currentNode._iNext; + } + while (currentNode != endNode) + + if (child1._iNext == child2) + { + // This is a downward (A to B) neighbour swap + child1._iNext = child2Next; + child1._iPrev = child2; + child2._iNext = child1; + child2._iPrev = child1Prev; + + if (child1Prev) { child1Prev._iNext = child2; } + if (child2Next) { child2Next._iPrev = child1; } + + return true; + } + else if (child2._iNext == child1) + { + // This is an upward (B to A) neighbour swap + child1._iNext = child2; + child1._iPrev = child2Prev; + child2._iNext = child1Next; + child2._iPrev = child1; + + if (child2Prev) { child2Prev._iNext = child1; } + if (child1Next) { child2Next._iPrev = child2; } + + return true; + } + else + { + // Children are far apart + child1._iNext = child2Next; + child1._iPrev = child2Prev; + child2._iNext = child1Next; + child2._iPrev = child1Prev; + + if (child1Prev) { child1Prev._iNext = child2; } + if (child1Next) { child1Next._iPrev = child2; } + if (child2Prev) { child2Prev._iNext = child1; } + if (child2Next) { child2Next._iPrev = child1; } + + return true; + } + + return false; + }, bringToTop: function (child) { - // ?! + if (!child === this._container.last) + { + this.swap(child, this._container.last); + } + + return child; }, @@ -118,7 +208,104 @@ Phaser.Group.prototype = { */ }, - setAll: function () { + // key is an ARRAY of values. + setProperty: function (child, key, value, operation) { + + operation = operation || 0; + + // As ugly as this approach looks, and although it's limited to a depth of only 4, it's extremely fast. + // Much faster than a for loop or object iteration. There are no checks, so if the key isn't valid then it'll fail + // but as you are likely to call this from inner loops that have to perform well, I'll take that trade off. + + // 0 = Equals + // 1 = Add + // 2 = Subtract + // 3 = Multiply + // 4 = Divide + + if (key.length == 1) + { + if (operation == 0) { child[key[0]] = value; } + else if (operation == 1) { child[key[0]] += value; } + else if (operation == 2) { child[key[0]] -= value; } + else if (operation == 3) { child[key[0]] *= value; } + else if (operation == 4) { child[key[0]] /= value; } + } + else if (key.length == 2) + { + if (operation == 0) { child[key[0]][key[1]] = value; } + else if (operation == 1) { child[key[0]][key[1]] += value; } + else if (operation == 2) { child[key[0]][key[1]] -= value; } + else if (operation == 3) { child[key[0]][key[1]] *= value; } + else if (operation == 4) { child[key[0]][key[1]] /= value; } + } + else if (key.length == 3) + { + if (operation == 0) { child[key[0]][key[1]][key[2]] = value; } + else if (operation == 1) { child[key[0]][key[1]][key[2]] += value; } + else if (operation == 2) { child[key[0]][key[1]][key[2]] -= value; } + else if (operation == 3) { child[key[0]][key[1]][key[2]] *= value; } + else if (operation == 4) { child[key[0]][key[1]][key[2]] /= value; } + } + else if (key.length == 4) + { + if (operation == 0) { child[key[0]][key[1]][key[2]][key[3]] = value; } + else if (operation == 1) { child[key[0]][key[1]][key[2]][key[3]] += value; } + else if (operation == 2) { child[key[0]][key[1]][key[2]][key[3]] -= value; } + else if (operation == 3) { child[key[0]][key[1]][key[2]][key[3]] *= value; } + else if (operation == 4) { child[key[0]][key[1]][key[2]][key[3]] /= value; } + } + else + { + // TODO - Deep property scane + } + + }, + + setAll: function (key, value, checkAlive, checkVisible, operation) { + + key = key.split('.'); + checkAlive = checkAlive || false; + checkVisible = checkVisible || false; + operation = operation || 0; + + var currentNode = this._container.first._iNext; + + do + { + if ((checkAlive == false || (checkAlive && currentNode.alive)) && (checkVisible == false || (checkVisible && currentNode.visible))) + { + this.setProperty(currentNode, key, value, operation); + } + + currentNode = currentNode._iNext; + } + while (currentNode != this._container.last._iNext) + + }, + + addAll: function (key, value, checkAlive, checkVisible) { + + this.setAll(key, value, checkAlive, checkVisible, 1); + + }, + + subAll: function (key, value, checkAlive, checkVisible) { + + this.setAll(key, value, checkAlive, checkVisible, 2); + + }, + + multiplyAll: function (key, value, checkAlive, checkVisible) { + + this.setAll(key, value, checkAlive, checkVisible, 3); + + }, + + divideAll: function (key, value, checkAlive, checkVisible) { + + this.setAll(key, value, checkAlive, checkVisible, 4); + }, callAll: function () { @@ -133,10 +320,15 @@ Phaser.Group.prototype = { forEachDead: function () { }, + /** + * Call this function to retrieve the first object with alive == true in the group. + * This is handy for checking if everything's wiped out, or choosing a squad leader, etc. + * + * @return {Any} The first alive child, or null if none found. + */ getFirstAlive: function () { - var endNode = this._container.last._iNext; - var currentNode = this._container.first; + var currentNode = this._container.first._iNext; do { @@ -147,51 +339,46 @@ Phaser.Group.prototype = { currentNode = currentNode._iNext; } - while (currentNode != endNode) + while (currentNode != this._container.last._iNext) + + return null; }, + /** + * Call this function to retrieve the first object with alive == false in the group. + * This is handy for checking if everything's wiped out, or choosing a squad leader, etc. + * + * @return {Any} The first dead child, or null if none found. + */ getFirstDead: function () { - var endNode = this._container.last._iNext; - var currentNode = this._container.first; + var currentNode = this._container.first._iNext; do { - if (currentNode.alive == false) + if (!currentNode.alive) { return currentNode; } currentNode = currentNode._iNext; } - while (currentNode != endNode) + while (currentNode != this._container.last._iNext) + + return null; }, - count: function (alive, visible) { - - var endNode = this._container.last._iNext; - var currentNode = this._container.first; - - do - { - if (currentNode.alive) - { - return currentNode; - } - - currentNode = currentNode._iNext; - } - while (currentNode != endNode) - - } - + /** + * Call this function to find out how many members of the group are alive. + * + * @return {number} The number of children flagged as alive. Returns -1 if Group is empty. + */ countLiving: function () { - var total = 0; - var endNode = this._container.last._iNext; - var currentNode = this._container.first; + var total = -1; + var currentNode = this._container.first._iNext; do { @@ -202,16 +389,52 @@ Phaser.Group.prototype = { currentNode = currentNode._iNext; } - while (currentNode != endNode); + while (currentNode != this._container.last._iNext); return total; }, + /** + * Call this function to find out how many members of the group are dead. + * + * @return {number} The number of children flagged as dead. Returns -1 if Group is empty. + */ countDead: function () { + + var total = -1; + var currentNode = this._container.first._iNext; + + do + { + if (!currentNode.alive) + { + total++; + } + + currentNode = currentNode._iNext; + } + while (currentNode != this._container.last._iNext); + + return total; + }, - getRandom: function () { + /** + * Returns a member at random from the group. + * + * @param {number} startIndex Optional offset off the front of the array. Default value is 0, or the beginning of the array. + * @param {number} length Optional restriction on the number of values you want to randomly select from. + * + * @return {Any} A random child of this Group. + */ + getRandom: function (startIndex, length) { + + startIndex = startIndex || 0; + length = length || this._container.children.length; + + return this.game.math.getRandom(this._container.children, startIndex, length); + }, remove: function (child) { @@ -222,7 +445,63 @@ Phaser.Group.prototype = { }; -Object.defineProperty(Phaser.World.prototype, "visible", { +Object.defineProperty(Phaser.Group.prototype, "x", { + + get: function () { + return this._container.position.x; + }, + + set: function (value) { + this._container.position.x = value; + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Group.prototype, "y", { + + get: function () { + return this._container.position.y; + }, + + set: function (value) { + this._container.position.y = value; + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Group.prototype, "angle", { + + get: function() { + return Phaser.Math.radToDeg(this._container.rotation); + }, + + set: function(value) { + this._container.rotation = Phaser.Math.degToRad(value); + } + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Group.prototype, "rotation", { + + get: function () { + return this._container.rotation; + }, + + set: function (value) { + this._container.rotation = value; + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Group.prototype, "visible", { get: function () { return this._container.visible; diff --git a/src/core/World.js b/src/core/World.js index e7c460e6..3c0bfb75 100644 --- a/src/core/World.js +++ b/src/core/World.js @@ -3,9 +3,10 @@ Phaser.World = function (game) { this.game = game; this._stage = new PIXI.Stage(0x000000); + this._stage.name = '_stage_root'; this._container = new PIXI.DisplayObjectContainer(); - this._container.name = '_stage_root'; + // this._container.name = '_stage_root'; this._stage.addChild(this._container); @@ -52,6 +53,7 @@ Phaser.World.prototype = { this.camera.update(); + // TODO - sort this out, the nodes are wrong var displayObject = this._stage; var testObject = displayObject.last._iNext; diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js index 72884303..495e15ce 100644 --- a/src/gameobjects/Sprite.js +++ b/src/gameobjects/Sprite.js @@ -140,7 +140,7 @@ Phaser.Sprite.prototype = Object.create(PIXI.Sprite.prototype); Phaser.Sprite.prototype.constructor = Phaser.Sprite; /** - * Automatically called by the game loop. + * Automatically called by World.update */ Phaser.Sprite.prototype.update = function() { diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index 082823b9..2fd46433 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -22,7 +22,7 @@ Phaser.Physics.Arcade = function (game) { this.OVERLAP_BIAS = 4; this.TILE_OVERLAP = false; - this.quadTree = null; + this.quadTree = new Phaser.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); this.quadTreeID = 0; // avoid gc spikes by caching these values for re-use @@ -124,6 +124,9 @@ Phaser.Physics.Arcade.prototype = { preUpdate: function () { + // Clear the tree + this.quadTree.clear(); + // Create our tree which all of the Physics bodies will add themselves to this.quadTreeID = 0; this.quadTree = new Phaser.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index fd68870c..c26802ed 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -49,7 +49,7 @@ Phaser.Physics.Arcade.Body = function (sprite) { this.immovable = false; this.moves = true; this.rotation = 0; - this.allowRotation = false; + this.allowRotation = true; this.allowGravity = true; this.collideWorldBounds = false; @@ -95,6 +95,10 @@ Phaser.Physics.Arcade.Body.prototype = { this.lastX = this.x; this.lastY = this.y; + this.x = this.sprite.x; + this.y = this.sprite.y; + this.rotation = this.sprite.angle; + if (this.moves) { this.game.physics.updateMotion(this); @@ -103,6 +107,11 @@ Phaser.Physics.Arcade.Body.prototype = { this.bounds.x = this.x; this.bounds.y = this.y; + if (this.collideWorldBounds) + { + this.checkWorldBounds(); + } + if (this.allowCollision.none == false && this.sprite.visible && this.sprite.alive) { this.quadTreeIDs = []; @@ -110,6 +119,15 @@ Phaser.Physics.Arcade.Body.prototype = { this.game.physics.quadTree.insert(this); } + // Adjust the sprite based on all of the above, so the x/y coords will be correct going into the State update + this.sprite.x = this.x - this.offset.x + (this.sprite.anchor.x * this.width); + this.sprite.y = this.y - this.offset.y + (this.sprite.anchor.y * this.height); + + if (this.allowRotation) + { + this.sprite.angle = this.rotation; + } + }, checkWorldBounds: function () { @@ -144,18 +162,31 @@ Phaser.Physics.Arcade.Body.prototype = { postUpdate: function () { + /* + // The State update may (almost certainly?) will had + if (this.collideWorldBounds) { + // Adjust sprite directly? this.checkWorldBounds(); } - this.sprite.x = this.x - this.offset.x + (this.sprite.anchor.x * this.width); - this.sprite.y = this.y - this.offset.y + (this.sprite.anchor.y * this.height); + console.log('pre pu', this.x, this.y); + + // if (this.moves) + // { + this.sprite.x = this.x - this.offset.x + (this.sprite.anchor.x * this.width); + this.sprite.y = this.y - this.offset.y + (this.sprite.anchor.y * this.height); + // } + + console.log('post pu', this.sprite.x, this.sprite.y); if (this.allowRotation) { this.sprite.angle = this.rotation; } + */ + },