diff --git a/Phaser.sublime-workspace b/Phaser.sublime-workspace index f0b37b13..837faaa9 100644 --- a/Phaser.sublime-workspace +++ b/Phaser.sublime-workspace @@ -3,6 +3,102 @@ { "selected_items": [ + [ + "re", + "releaseMummy" + ], + [ + "child", + "children" + ], + [ + "for", + "for for (…) {…}" + ], + [ + "curr", + "currentFrame" + ], + [ + "fra", + "frameHeight" + ], + [ + "g", + "game (variable)" + ], + [ + "Te", + "TextureCache" + ], + [ + "Base", + "BaseTextureCache" + ], + [ + "inn", + "innerHeight (variable)" + ], + [ + "get", + "getOffset" + ], + [ + "at", + "antialias" + ], + [ + "we", + "webGL" + ], + [ + "can", + "canvas" + ], + [ + "REN", + "RENDERER_CANVAS" + ], + [ + "AU", + "RENDERER_AUTO" + ], + [ + "visi", + "visibilityChange" + ], + [ + "onlo", + "onLoadRenderCallback (variable)" + ], + [ + "onPr", + "onPreRenderCallback" + ], + [ + "onl", + "onLoadUpdateCallback" + ], + [ + "onp", + "onPausedCallback (variable)" + ], + [ + "onload", + "onLoadUpdateCallback (variable)" + ], + [ + "star", + "states (variable)" + ], + [ + "st", + "states (variable)" + ], + [ + "State", + "StateManager" + ], [ "remem", "rememberMe" @@ -19,14 +115,6 @@ "onpause", "onPausedCallback" ], - [ - "onload", - "onLoadUpdateCallback" - ], - [ - "onp", - "onPreloadCallback (variable)" - ], [ "upda", "updateSetTimeout" @@ -223,10 +311,6 @@ "jukeb", "jukeboxPP" ], - [ - "star", - "startPause" - ], [ "Beak", "BeakerGameStartGameHook" @@ -255,10 +339,6 @@ "let", "letter1" ], - [ - "g", - "getLetterData" - ], [ "sc", "scanIt" @@ -351,10 +431,6 @@ "flo", "floatOff" ], - [ - "st", - "startY" - ], [ "pip", "piplin1" @@ -438,92 +514,65 @@ [ "pi", "piplin2" - ], - [ - "game", - "gameButton2" - ], - [ - "pl", - "playGame" - ], - [ - "mouse", - "mouseEnabled" - ], - [ - "first", - "first_time_online" - ], - [ - "use", - "useWebAudio" - ], - [ - "web", - "webAudioSupported" - ], - [ - "pop", - "poppedTotal" - ], - [ - "fn", - "function" - ], - [ - "bubb", - "bubbleSize" - ], - [ - "bub", - "bubbleMaxY" - ], - [ - "sele", - "selectGame" - ], - [ - "gameb", - "gameButton1" - ], - [ - "selec", - "selectScreen" - ], - [ - "pla", - "playButton" - ], - [ - "titl", - "titleScreen" - ], - [ - "tit", - "titleScreen" - ], - [ - "dr", - "drawGridLines" - ], - [ - "init", - "initGame" - ], - [ - "die", - "diveSpeed" ] ] }, "buffers": [ { - "file": "src/Game.js", + "file": "src/core/Game.js", "settings": { - "buffer_size": 15461, + "buffer_size": 8628, + "line_ending": "Windows" + } + }, + { + "file": "examples/sprite3.php", + "settings": + { + "buffer_size": 1406, + "line_ending": "Windows" + } + }, + { + "file": "src/gameobjects/Sprite.js", + "settings": + { + "buffer_size": 3926, + "line_ending": "Windows", + "name": "Phaser.Sprite = function () {" + } + }, + { + "file": "src/core/World.js", + "settings": + { + "buffer_size": 2705, + "line_ending": "Windows" + } + }, + { + "file": "src/pixi/textures/RenderTexture.js", + "settings": + { + "buffer_size": 6640, + "line_ending": "Windows" + } + }, + { + "file": "/D/wamp/www/pixi.js/examples/example 11 - RenderTexture/index.html", + "settings": + { + "buffer_size": 2951, + "line_ending": "Windows" + } + }, + { + "file": "src/pixi/primitives/Graphics.js", + "settings": + { + "buffer_size": 6432, "line_ending": "Windows" } } @@ -556,31 +605,89 @@ }, "file_history": [ - "/D/wamp/www/phaser/examples/flow.php", - "/D/wamp/www/phaser/examples/flow3.php", + "/D/wamp/www/phaser/src/pixi/display/Sprite.js", + "/D/wamp/www/phaser/src/pixi/display/DisplayObject.js", + "/D/wamp/www/pixi.js/examples/example 11 - RenderTexture/index.html", + "/D/wamp/www/pixi.js/examples/example 10 - Text/index.html", + "/D/wamp/www/phaser/examples/assets/fonts/desyrel.json", + "/D/wamp/www/phaser/src/core/StateManager.js", + "/D/wamp/www/phaser/src/math/Math.js", + "/D/wamp/www/phaser/src/math/RandomDataGenerator.js", + "/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/phaser/examples/flow2.php", - "/D/wamp/www/phaser/TS Tests/tilemaps/csv tilemap.js", + "/D/wamp/www/bbc-wolfblood/game.js", + "/D/wamp/www/phaser/examples/js.php", + "/D/wamp/www/phaser/TS Source/gameobjects/GameObjectFactory.js", + "/D/wamp/www/phaser/src/gameobjects/GameObjectFactory.js", + "/D/wamp/www/phaser/src/tween/Tween.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", + "/D/wamp/www/phaser/TS Source/gameobjects/GameObjectFactory.ts", + "/C/Users/rich/Desktop/game.js", + "/D/wamp/www/phaser/src/animation/AnimationManager.js", + "/D/wamp/www/phaser/src/animation/Animation.js", + "/D/wamp/www/phaser/TS Source/gameobjects/Sprite.ts", + "/D/wamp/www/phaser/TS Source/animation/Animation.js", + "/D/wamp/www/phaser/TS Source/animation/AnimationManager.js", + "/D/wamp/www/phaser/src/pixi/renderers/canvas/CanvasRenderer.js", + "/D/wamp/www/phaser/src/animation/Parser.js", + "/D/wamp/www/phaser/src/loader/Cache.js", + "/D/wamp/www/phaser/TS Source/gameobjects/Sprite.js", + "/D/wamp/www/phaser/src/loader/Loader.js", "/D/wamp/www/phaser/src/system/RequestAnimationFrame.js", + "/D/wamp/www/phaser/src/pixi/textures/Texture.js", + "/D/wamp/www/phaser/src/pixi/textures/BaseTexture.js", + "/D/wamp/www/phaser/src/pixi/display/MovieClip.js", + "/D/wamp/www/phaser/src/pixi/loaders/ImageLoader.js", + "/D/wamp/www/phaser/src/animation/FrameData.js", + "/D/wamp/www/phaser/src/animation/Frame.js", + "/D/wamp/www/phaser/src/pixi/loaders/SpriteSheetLoader.js", + "/D/wamp/www/phaser/examples/assets/sprites/running_bot.json", + "/D/wamp/www/pixi.js/examples/example 2 - SpriteSheet/index.html", + "/D/wamp/www/pixi.js/examples/example 3 - MovieClip/index.html", + "/D/wamp/www/pixi.js/examples/example 3 - MovieClip/SpriteSheet.json", + "/D/wamp/www/phaser/src/core/World.js", + "/D/wamp/www/phaser/examples/assets/sprites/pixi_monsters.json", + "/D/wamp/www/phaser/examples/assets/sprites/invaderpig.json", + "/D/wamp/www/pixi.js/examples/example 2 - SpriteSheet/SpriteSheet.json", + "/D/wamp/www/phaser/src/core/Stage.js", + "/D/wamp/www/phaser/TS Source/World.js", + "/D/wamp/www/phaser/src/Game.js", + "/D/wamp/www/phaser/src/Stage.js", + "/D/wamp/www/phaser/src/pixi/display/Stage.js", + "/D/wamp/www/phaser/src/pixi/display/DisplayObjectContainer.js", + "/D/wamp/www/phaser/examples/pixi 1.html", + "/D/wamp/www/phaser/src/system/Canvas.js", + "/D/wamp/www/phaser/src/Phaser.js", + "/D/wamp/www/phaser/TS Source/Stage.js", + "/D/wamp/www/phaser/examples/rect1.php", + "/D/wamp/www/phaser/src/geom/Point.js", + "/D/wamp/www/phaser/src/geom/Rectangle.js", + "/D/wamp/www/phaser/src/pixi/utils/Detector.js", + "/D/wamp/www/phaser/TS Source/Stage.ts", + "/D/wamp/www/phaser/examples/flow.php", + "/D/wamp/www/phaser/examples/flow6.php", + "/D/wamp/www/phaser/TS Source/utils/CanvasUtils.js", + "/D/wamp/www/phaser/examples/flow2.php", + "/D/wamp/www/phaser/examples/flow3.php", + "/D/wamp/www/phaser/examples/flow4.php", + "/D/wamp/www/phaser/TS Source/cameras/Camera.js", + "/D/wamp/www/phaser/examples/test.php", + "/D/wamp/www/phaser/TS Tests/tilemaps/csv tilemap.js", "/D/wamp/www/phaser/TS Source/system/RequestAnimationFrame.js", "/D/wamp/www/phaser/TS Source/Game.js", "/D/wamp/www/phaser/TS Source/State.js", - "/D/wamp/www/phaser/examples/js.php", - "/D/wamp/www/phaser/src/Phaser.js", "/D/wamp/www/phaser/TS Tests/audio/audio sprites 1.ts", "/D/wamp/www/phaser/examples/loader 2.html", - "/D/wamp/www/phaser/src/tween/TweenManager.js", "/D/wamp/www/phaser/src/core/Plugin.js", "/D/wamp/www/phaser/src/core/PluginManager.js", "/D/wamp/www/index.php", - "/D/wamp/www/phaser/src/loader/Loader.js", "/D/wamp/www/phaser/TS Source/core/Plugin.js", "/D/wamp/www/phaser/TS Source/core/PluginManager.js", "/D/wamp/www/phaser/TS Source/Game.ts", - "/D/wamp/www/phaser/examples/pixi 1.html", "/D/wamp/www/pixi.js/examples/example 1 - Basics/index.html", - "/D/wamp/www/phaser/src/pixi/textures/Texture.js", - "/D/wamp/www/phaser/src/pixi/textures/BaseTexture.js", "/D/wamp/www/phaser/examples/loader.html", "/D/wamp/www/phaser/examples/math sincos.html", "/D/wamp/www/phaser/examples/raf.html", @@ -589,13 +696,9 @@ "/D/wamp/www/phaser/TS Source/system/RequestAnimationFrame.ts", "/D/wamp/www/phaser/todo/Tween.js", "/D/wamp/www/phaser/TS Source/tweens/TweenManager.js", - "/D/wamp/www/phaser/src/geom/Rectangle.js", "/D/wamp/www/phaser/TS Source/utils/RectangleUtils.js", "/D/wamp/www/phaser/TS Source/geom/Rectangle.js", - "/D/wamp/www/phaser/src/system/Device.js", - "/D/wamp/www/phaser/src/math/Math.js", "/D/wamp/www/phaser/examples/point.html", - "/D/wamp/www/phaser/src/geom/Point.js", "/D/wamp/www/phaser/src/geom/Circle.js", "/D/wamp/www/phaser/TS Source/utils/PointUtils.js", "/D/wamp/www/phaser/TS Source/geom/Point.js", @@ -608,82 +711,28 @@ "/D/wamp/www/phaser/src/net/Net.js", "/D/wamp/www/phaser/examples/net.html", "/D/wamp/www/phaser/TS Source/net/Net.js", - "/D/wamp/www/phaser/src/animation/Parser.js", - "/D/wamp/www/phaser/src/loader/Cache.js", "/D/wamp/www/phaser/examples/loader audio.html", "/D/wamp/www/phaser/examples/loader spritesheet.html", "/D/wamp/www/phaser/examples/loader atlas xml.html", "/D/wamp/www/phaser/examples/loader atlas json.html", "/D/wamp/www/phaser/examples/assets/sprites/shoebot.xml", - "/D/wamp/www/phaser/src/animation/Frame.js", "/D/wamp/www/phaser/TS Source/loader/AnimationLoader.js", "/D/wamp/www/phaser/TS Source/loader/AnimationLoader.ts", - "/D/wamp/www/phaser/src/animation/Animation.js", "/D/wamp/www/phaser/src/loader/AnimationLoader.js", - "/D/wamp/www/phaser/src/animation/FrameData.js", "/D/wamp/www/phaser/TS Source/animation/FrameData.ts", "/D/wamp/www/phaser/TS Source/animation/FrameData.js", "/D/wamp/www/phaser/TS Source/animation/Frame.ts", "/D/wamp/www/phaser/TS Source/animation/Frame.js", - "/D/wamp/www/bbc-wolfblood/game.js", "/D/wamp/www/phaser/TS Source/loader/Loader.js", "/D/wamp/www/phaser/TS Source/loader/Cache.js", "/D/wamp/www/phaser/TS Source/loader/Cache.ts", "/D/wamp/www/phaser/TS Source/loader/Loader.ts", - "/D/wamp/www/phaser/src/math/RandomDataGenerator.js", "/D/wamp/www/phaser/src/core/SignalBinding.js", "/D/wamp/www/phaser/src/core/Signal.js", "/D/wamp/www/phaser/examples/signals.html", "/D/wamp/www/phaser/examples/rnd.html", "/D/wamp/www/phaser/TS Source/core/Signal.js", - "/D/wamp/www/js-signals/src/Signal.js", - "/D/wamp/www/js-signals/src/wrapper.js", - "/D/wamp/www/awasenghi/lib/Core.js", - "/D/wamp/www/phaser/TS Source/math/RandomDataGenerator.js", - "/D/wamp/www/Nonsense/Nonsense.js", - "/D/wamp/www/numtums/pop/bake.php", - "/D/wamp/www/phaser/src/pixi/Pixi.js", - "/D/wamp/www/phaser/TS Source/Phaser.ts", - "/D/wamp/www/bbc-wolfblood/tsc.txt", - "/D/wamp/www/bbc-wolfblood/load.php", - "/D/wamp/www/phaser/build/phaser-debug.js", - "/D/wamp/www/bbc-wolfblood/embed.js", - "/D/wamp/www/phaser/README.md", - "/D/wamp/www/bbc-wolfblood/mobile.php", - "/D/wamp/www/bbc-wolfblood/load-desktop.php", - "/D/wamp/www/bbc-wolfblood/Wolfblood/Wolfblood.csproj", - "/D/wamp/www/phaser/Phaser/defToXML.php", - "/D/wamp/www/bbc-wolfblood/Phaser/Phaser.csproj", - "/D/wamp/www/bbc-wolfblood/mobile-wolfblood-min.js", - "/D/wamp/www/elmo/README.md", - "/C/Users/rich/AppData/Local/Temp/dtemp-6fdf6c055229125-20.dop/mobile-wolfblood-min.js", - "/C/Users/rich/AppData/Local/Temp/dtemp-6fafca055212843-20.dop/wolfblood-min.js", - "/C/Users/rich/Desktop/embed.js", - "/D/wamp/www/bbc-wolfblood/embed (1).js", - "/C/Users/rich/Desktop/Q3.qif", - "/C/Users/rich/Downloads/Sheet 52.qif", - "/C/Users/rich/Downloads/Sheet 49-51.qif", - "/C/Users/rich/Downloads/Sheet 48.qif", - "/C/Users/rich/Downloads/Sheets 45-47.qif", - "/C/Users/rich/Downloads/Sheet 44.qif", - "/C/Users/rich/Downloads/Sheet 40 (May).qif", - "/D/wamp/www/bbc-wolfblood/Wolfblood/sha1.js", - "/D/webroot/phaser.io/index.html", - "/D/wamp/www/phaser/Phaser/Stage.js", - "/D/wamp/www/phaser/Tests/physics/temp2.ts", - "/D/wamp/www/phaser/Tests/physics/aabb vs aabb 1.js", - "/D/wamp/www/phaser/Tests/physics/aabb 1.js", - "/D/wamp/www/Proton/example/helloworld/emitter/emitter.html", - "/D/wamp/www/Proton/src/emitter/Emitter.js", - "/D/wamp/www/Proton/src/initialize/InitializeUtil.js", - "/D/wamp/www/Proton/src/initialize/Position.js", - "/D/wamp/www/Proton/src/render/BaseRender.js", - "/D/wamp/www/Proton/src/render/Renderer.js", - "/D/wamp/www/Proton/src/render/CanvasRender.js", - "/D/wamp/www/Proton/src/zone/Zone.js", - "/D/wamp/www/Proton/src/zone/PointZone.js", - "/D/wamp/www/Proton/src/plus/ease.js", - "/D/wamp/www/Proton/src/behaviour/RandomDrift.js" + "/D/wamp/www/js-signals/src/Signal.js" ], "find": { @@ -691,9 +740,10 @@ }, "find_in_files": { - "height": 0.0, + "height": 90.0, "where_history": [ + "D:\\wamp\\www\\phaser\\TS Source", "D:\\wamp\\www\\phaser\\src\\pixi", "D:\\wamp\\www\\phaser\\Tests\\tilemap", "D:\\wamp\\www\\phaser\\Tests\\sprites", @@ -716,6 +766,43 @@ "case_sensitive": false, "find_history": [ + "webg", + "loadComplete", + "loadFrameData", + "this.parent", + "Animation.prototype.", + "AnimationManager.prototype", + "});", + "AnimationManager.prototype.", + "Sprite.", + "x", + "game.math.rnd", + "name", + "frames[key].", + "cacheKey + key", + "new", + "BaseTextureCache", + "PIXI.TextureCache =", + "format", + "[i]", + "i", + "World.prototype", + "= function", + "width", + "\n ", + "y", + "webgl", + "renderDisplayObject", + "CanvasUtils.", + "boot", + "addState", + "this._pendingState", + "game", + "this", + "this.current", + "this.state", + "Phaser.GAMES[this.id].boot(parent, width, height)", + "this.boot", "game", "State.prototype.", "preload", @@ -806,44 +893,7 @@ ".src", "line", "onAlpha", - "bunny", - "bunnies", - "bunny", - "write", - "step", - "shapes", - "].", - "hapes", - "verts", - "transform", - "position", - "Manager", - "position", - "solveVelocityConstraints", - "false", - "position", - "p", - "ju", - "\n ", - "position", - "staticBody", - "stepCount", - "stats =", - "frameRateHz", - "collision", - "ready", - "runFrame", - " Manager.write('findContactSolver. Length: ' + this.contactSolvers.length);\nfindContact", - "postSolve", - "gravity", - "runFrame", - "onClickedPlayer", - "step", - "Manager", - "solveVelocity", - "velocitySolver", - "initSolve", - "step" + "bunny" ], "highlight": true, "in_selection": false, @@ -851,6 +901,8 @@ "regex": false, "replace_history": [ + "this._parent", + "this.state", "elapsed", "queueSize", "{boolean}", @@ -892,23 +944,543 @@ "groups": [ { - "selected": 0, + "selected": 5, "sheets": [ { "buffer": 0, - "file": "src/Game.js", + "file": "src/core/Game.js", "settings": { - "buffer_size": 15461, + "buffer_size": 8628, "regions": { }, "selection": [ [ - 12999, - 12999 + 7268, + 7268 + ] + ], + "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" + }, + "translation.x": 0.0, + "translation.y": 5134.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 1, + "file": "examples/sprite3.php", + "settings": + { + "buffer_size": 1406, + "regions": + { + }, + "selection": + [ + [ + 328, + 328 + ] + ], + "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", + "translate_tabs_to_spaces": false + }, + "translation.x": 0.0, + "translation.y": 246.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 2, + "file": "src/gameobjects/Sprite.js", + "settings": + { + "buffer_size": 3926, + "regions": + { + }, + "selection": + [ + [ + 2813, + 2813 + ] + ], + "settings": + { + "auto_name": "Phaser.Sprite = 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", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 3201.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 3, + "file": "src/core/World.js", + "settings": + { + "buffer_size": 2705, + "regions": + { + }, + "selection": + [ + [ + 820, + 820 + ] + ], + "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" + }, + "translation.x": 0.0, + "translation.y": 66.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 4, + "file": "src/pixi/textures/RenderTexture.js", + "settings": + { + "buffer_size": 6640, + "regions": + { + }, + "selection": + [ + [ + 6640, + 6640 ] ], "settings": @@ -1020,7 +1592,266 @@ "translate_tabs_to_spaces": false }, "translation.x": 0.0, - "translation.y": 8910.0, + "translation.y": 0.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 5, + "file": "/D/wamp/www/pixi.js/examples/example 11 - RenderTexture/index.html", + "settings": + { + "buffer_size": 2951, + "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/HTML/HTML.tmLanguage", + "translate_tabs_to_spaces": false + }, + "translation.x": 0.0, + "translation.y": 0.0, + "zoom_level": 1.0 + }, + "type": "text" + }, + { + "buffer": 6, + "file": "src/pixi/primitives/Graphics.js", + "settings": + { + "buffer_size": 6432, + "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/JavaScript/JavaScript.tmLanguage" + }, + "translation.x": 0.0, + "translation.y": 3693.0, "zoom_level": 1.0 }, "type": "text" diff --git a/examples/assets/fonts/desyrel.png b/examples/assets/fonts/desyrel.png new file mode 100644 index 00000000..c3559e1c Binary files /dev/null and b/examples/assets/fonts/desyrel.png differ diff --git a/examples/assets/fonts/desyrel.xml b/examples/assets/fonts/desyrel.xml new file mode 100644 index 00000000..54fcdbba --- /dev/null +++ b/examples/assets/fonts/desyrel.xml @@ -0,0 +1,1922 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/fonts/textDemoBG.jpg b/examples/assets/fonts/textDemoBG.jpg new file mode 100644 index 00000000..5955e59f Binary files /dev/null and b/examples/assets/fonts/textDemoBG.jpg differ diff --git a/examples/camera1.php b/examples/camera1.php new file mode 100644 index 00000000..6c4e7753 --- /dev/null +++ b/examples/camera1.php @@ -0,0 +1,37 @@ + + + + phaser.js - a new beginning + + + + + + + + \ No newline at end of file diff --git a/examples/input1.php b/examples/input1.php new file mode 100644 index 00000000..b27fa722 --- /dev/null +++ b/examples/input1.php @@ -0,0 +1,41 @@ + + + + phaser.js - a new beginning + + + + + + + + \ No newline at end of file diff --git a/examples/js.php b/examples/js.php index a5703add..aeeecab4 100644 --- a/examples/js.php +++ b/examples/js.php @@ -42,6 +42,7 @@ + @@ -51,25 +52,42 @@ + + + + + + + + + + + + + + + + + diff --git a/src/core/Camera.js b/src/core/Camera.js new file mode 100644 index 00000000..9f8134c3 --- /dev/null +++ b/src/core/Camera.js @@ -0,0 +1,258 @@ +/** +* Phaser - Camera +* +* A Camera is your view into the game world. It has a position and size and renders only those objects within its field of view. +* The game automatically creates a single Stage sized camera on boot. Move the camera around the world with Phaser.Camera.x/y +*/ + +Phaser.Camera = function (game, id, x, y, width, height) { + + this.game = game; + this.world = game.world; + this.id = 0; // reserved for future multiple camera set-ups + + // The view into the world we wish to render (by default the game dimensions) + // The x/y values are in world coordinates, not screen coordinates, the width/height is how many pixels to render + // Objects outside of this view are not rendered (unless set to ignore the Camera, i.e. UI?) + this.view = new Phaser.Rectangle(x, y, width, height); + +}; + +// Consts +Phaser.Camera.FOLLOW_LOCKON = 0; +Phaser.Camera.FOLLOW_PLATFORMER = 1; +Phaser.Camera.FOLLOW_TOPDOWN = 2; +Phaser.Camera.FOLLOW_TOPDOWN_TIGHT = 3; + +Phaser.Camera.prototype = { + + game: null, + world: null, + + id: 0, + + /** + * Camera view. + * @type {Rectangle} + */ + view: null, + + /** + * Sprite moving inside this Rectangle will not cause camera moving. + * @type {Rectangle} + */ + deadzone: null, + + /** + * Whether this camera is visible or not. (default is true) + * @type {bool} + */ + visible: true, + + /** + * If the camera is tracking a Sprite, this is a reference to it, otherwise null + * @type {Sprite} + */ + target: null, + + /** + * Tells this camera which sprite to follow. + * @param target {Sprite} The object you want the camera to track. Set to null to not follow anything. + * @param [style] {number} Leverage one of the existing "deadzone" presets. If you use a custom deadzone, ignore this parameter and manually specify the deadzone after calling follow(). + */ + follow: function (target, style) { + + if (typeof style === "undefined") { style = Phaser.Camera.FOLLOW_LOCKON; } + + this.target = target; + + var helper; + + switch (style) { + + case Phaser.Types.CAMERA_FOLLOW_PLATFORMER: + var w = this.width / 8; + var h = this.height / 3; + this.deadzone = new Phaser.Rectangle((this.width - w) / 2, (this.height - h) / 2 - h * 0.25, w, h); + break; + + case Phaser.Types.CAMERA_FOLLOW_TOPDOWN: + helper = Math.max(this.width, this.height) / 4; + this.deadzone = new Phaser.Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper); + break; + + case Phaser.Types.CAMERA_FOLLOW_TOPDOWN_TIGHT: + helper = Math.max(this.width, this.height) / 8; + this.deadzone = new Phaser.Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper); + break; + + case Phaser.Types.CAMERA_FOLLOW_LOCKON: + default: + this.deadzone = null; + break; + } + + }, + + /** + * Move the camera focus to this location instantly. + * @param x {number} X position. + * @param y {number} Y position. + */ + focusOnXY: function (x, y) { + + x += (x > 0) ? 0.0000001 : -0.0000001; + y += (y > 0) ? 0.0000001 : -0.0000001; + + this.view.x = Math.round(x - this.view.halfWidth); + this.view.y = Math.round(y - this.view.halfHeight); + + }, + + /** + * Update focusing and scrolling. + */ + update: function () { + + // this.plugins.preUpdate(); + + if (this.target !== null) + { + if (this.deadzone == null) + { + this.focusOnXY(this.target.x, this.target.y); + } + else + { + var edge; + var targetX = this.target.x + ((this.target.x > 0) ? 0.0000001 : -0.0000001); + var targetY = this.target.y + ((this.target.y > 0) ? 0.0000001 : -0.0000001); + + edge = targetX - this.deadzone.x; + + if (this.view.x > edge) + { + this.view.x = edge; + } + + edge = targetX + this.target.width - this.deadzone.x - this.deadzone.width; + + if (this.view.x < edge) + { + this.view.x = edge; + } + + edge = targetY - this.deadzone.y; + + if (this.view.y > edge) + { + this.view.y = edge; + } + + edge = targetY + this.target.height - this.deadzone.y - this.deadzone.height; + + if (this.view.y < edge) + { + this.view.y = edge; + } + } + } + + // Make sure we didn't go outside the cameras worldBounds + if (this.view.x < this.world.bounds.left) + { + this.view.x = this.world.bounds.left; + } + + if (this.view.x > this.world.bounds.right - this.width) + { + this.view.x = (this.world.bounds.right - this.width) + 1; + } + + if (this.view.y < this.world.bounds.top) + { + this.view.y = this.world.bounds.top; + } + + if (this.view.y > this.world.bounds.bottom - this.height) + { + this.view.y = (this.world.bounds.bottom - this.height) + 1; + } + + this.view.floor(); + + // this.plugins.update(); + + }, + + setPosition: function (x, y) { + + this.view.x = x; + this.view.y = y; + + }, + + setSize: function (width, height) { + + this.view.width = width; + this.view.height = height; + + } + +}; + +Object.defineProperty(Phaser.Camera.prototype, "x", { + + get: function () { + return this.view.x; + }, + + set: function (value) { + this.view.x = value; + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Camera.prototype, "y", { + + get: function () { + return this.view.y; + }, + + set: function (value) { + this.view.y = value; + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Camera.prototype, "width", { + + get: function () { + return this.view.width; + }, + + set: function (value) { + this.view.width = value; + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Camera.prototype, "height", { + + get: function () { + return this.view.height; + }, + + set: function (value) { + this.view.height = value; + }, + + enumerable: true, + configurable: true +}); diff --git a/src/core/Game.js b/src/core/Game.js index 092c6ac3..3f3bcab9 100644 --- a/src/core/Game.js +++ b/src/core/Game.js @@ -161,7 +161,7 @@ Phaser.Game.prototype = { /** * Reference to the input manager - * @type {Phaser.InputManager} + * @type {Phaser.Input} */ input: null, @@ -270,7 +270,7 @@ Phaser.Game.prototype = { this.load = new Phaser.Loader(this); this.time = new Phaser.Time(this); this.tweens = new Phaser.TweenManager(this); - // this.input = new Phaser.InputManager(this); + this.input = new Phaser.Input(this); // this.sound = new Phaser.SoundManager(this); // this.physics = new Phaser.Physics.PhysicsManager(this); this.plugins = new Phaser.PluginManager(this, this); @@ -278,9 +278,10 @@ Phaser.Game.prototype = { this.load.onLoadComplete.add(this.loadComplete, this); + this.world.boot(); this.state.boot(); // this.stage.boot(); - // this.input.boot(); + this.input.boot(); if (this.renderType == Phaser.CANVAS) { @@ -347,8 +348,8 @@ Phaser.Game.prototype = { this.plugins.preUpdate(); + this.input.update(); this.tweens.update(); - // this.input.update(); // this.stage.update(); // this.sound.update(); // this.physics.update(); diff --git a/src/core/Stage.js b/src/core/Stage.js index 5a27f08e..372186ba 100644 --- a/src/core/Stage.js +++ b/src/core/Stage.js @@ -12,10 +12,13 @@ Phaser.Stage = function (game) { this.game = game; + this.canvas = game.renderer.view; // Get the offset values (for input and other things) this.offset = new Phaser.Point; - Phaser.Canvas.getOffset(this.game.renderer.view, this.offset); + + Phaser.Canvas.getOffset(this.canvas, this.offset); + this.bounds = new Phaser.Rectangle(this.offset.x, this.offset.y, this.game.width, this.game.height); var _this = this; @@ -38,6 +41,7 @@ Phaser.Stage.prototype = { _onChange: null, + canvas: null, bounds: null, offset: null, diff --git a/src/core/World.js b/src/core/World.js index cc8bf05a..ad314366 100644 --- a/src/core/World.js +++ b/src/core/World.js @@ -19,6 +19,13 @@ Phaser.World.prototype = { _length: 0, bounds: null, + camera: null, + + boot: function () { + + this.camera = new Phaser.Camera(this.game, 0, 0, 0, this.game.width, this.game.height); + + }, add: function (gameobject) { this._container.addChild(gameobject); @@ -41,6 +48,8 @@ Phaser.World.prototype = { update: function () { + this.camera.update(); + for (var child in this._container.children) { this._container.children[child].update(); @@ -53,20 +62,12 @@ Phaser.World.prototype = { * * @param width {number} New width of the world. * @param height {number} New height of the world. - * @param [updateCameraBounds] {bool} Update camera bounds automatically or not. Default to true. */ - setSize: function (width, height, updateCameraBounds) { - - if (typeof updateCameraBounds === "undefined") { updateCameraBounds = true; } + setSize: function (width, height) { this.bounds.width = width; this.bounds.height = height; - if (updateCameraBounds == true) - { - // this.game.camera.setBounds(0, 0, width, height); - } - }, }; diff --git a/src/input/Input.js b/src/input/Input.js new file mode 100644 index 00000000..83b11f40 --- /dev/null +++ b/src/input/Input.js @@ -0,0 +1,718 @@ +/** +* Phaser.Input +* +* A game specific Input manager that looks after the mouse, keyboard and touch objects. +* This is updated by the core game loop. +*/ +Phaser.Input = function (game) { + + this.game = game; + + this.inputObjects = []; + this.totalTrackedObjects = 0; + +}; + +Phaser.Input.MOUSE_OVERRIDES_TOUCH = 0; +Phaser.Input.TOUCH_OVERRIDES_MOUSE = 1; +Phaser.Input.MOUSE_TOUCH_COMBINE = 2; + +Phaser.Input.prototype = { + + game: null, + + /** + * How often should the input pointers be checked for updates? + * A value of 0 means every single frame (60fps), a value of 1 means every other frame (30fps) and so on. + * @type {number} + */ + pollRate: 0, + _pollCounter: 0, + + /** + * A vector object representing the previous position of the Pointer. + * @property vector + * @type {Vec2} + **/ + _oldPosition: null, + + /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + _x: 0, + + /** + * X coordinate of the most recent Pointer event + * @type {Number} + * @private + */ + _y: 0, + + /** + * You can disable all Input by setting Input.disabled: true. While set all new input related events will be ignored. + * If you need to disable just one type of input, for example mouse, use Input.mouse.disabled: true instead + * @type {bool} + */ + disabled: false, + + /** + * Controls the expected behaviour when using a mouse and touch together on a multi-input device + */ + multiInputOverride: Phaser.Input.MOUSE_TOUCH_COMBINE, + + /** + * A vector object representing the current position of the Pointer. + * @property vector + * @type {Vec2} + **/ + position: null, + + /** + * A vector object representing the speed of the Pointer. Only really useful in single Pointer games, + * otherwise see the Pointer objects directly. + * @property vector + * @type {Vec2} + **/ + speed: null, + + /** + * A Circle object centered on the x/y screen coordinates of the Input. + * Default size of 44px (Apples recommended "finger tip" size) but can be changed to anything + * @property circle + * @type {Circle} + **/ + circle: null, + + /** + * The scale by which all input coordinates are multiplied, calculated by the StageScaleMode. + * In an un-scaled game the values will be x: 1 and y: 1. + * @type {Vec2} + */ + scale: null, + + /** + * The maximum number of Pointers allowed to be active at any one time. + * For lots of games it's useful to set this to 1 + * @type {Number} + */ + maxPointers: 10, + + /** + * The current number of active Pointers. + * @type {Number} + */ + currentPointers: 0, + + /** + * The number of milliseconds that the Pointer has to be pressed down and then released to be considered a tap or click + * @property tapRate + * @type {Number} + **/ + tapRate: 200, + + /** + * The number of milliseconds between taps of the same Pointer for it to be considered a double tap / click + * @property doubleTapRate + * @type {Number} + **/ + doubleTapRate: 300, + + /** + * The number of milliseconds that the Pointer has to be pressed down for it to fire a onHold event + * @property holdRate + * @type {Number} + **/ + holdRate: 2000, + + /** + * The number of milliseconds below which the Pointer is considered justPressed + * @property justPressedRate + * @type {Number} + **/ + justPressedRate: 200, + + /** + * The number of milliseconds below which the Pointer is considered justReleased + * @property justReleasedRate + * @type {Number} + **/ + justReleasedRate: 200, + + /** + * Sets if the Pointer objects should record a history of x/y coordinates they have passed through. + * The history is cleared each time the Pointer is pressed down. + * The history is updated at the rate specified in Input.pollRate + * @property recordPointerHistory + * @type {bool} + **/ + recordPointerHistory: false, + + /** + * The rate in milliseconds at which the Pointer objects should update their tracking history + * @property recordRate + * @type {Number} + */ + recordRate: 100, + + /** + * The total number of entries that can be recorded into the Pointer objects tracking history. + * If the Pointer is tracking one event every 100ms, then a trackLimit of 100 would store the last 10 seconds worth of history. + * @property recordLimit + * @type {Number} + */ + recordLimit: 100, + + /** + * A Pointer object + * @property pointer1 + * @type {Pointer} + **/ + pointer1: null, + + /** + * A Pointer object + * @property pointer2 + * @type {Pointer} + **/ + pointer2: null, + + /** + * A Pointer object + * @property pointer3 + * @type {Pointer} + **/ + pointer3: null, + + /** + * A Pointer object + * @property pointer4 + * @type {Pointer} + **/ + pointer4: null, + + /** + * A Pointer object + * @property pointer5 + * @type {Pointer} + **/ + pointer5: null, + + /** + * A Pointer object + * @property pointer6 + * @type {Pointer} + **/ + pointer6: null, + + /** + * A Pointer object + * @property pointer7 + * @type {Pointer} + **/ + pointer7: null, + + /** + * A Pointer object + * @property pointer8 + * @type {Pointer} + **/ + pointer8: null, + + /** + * A Pointer object + * @property pointer9 + * @type {Pointer} + **/ + pointer9: null, + + /** + * A Pointer object + * @property pointer10 + * @type {Pointer} + **/ + pointer10: null, + + /** + * The most recently active Pointer object. + * When you've limited max pointers to 1 this will accurately be either the first finger touched or mouse. + * @property activePointer + * @type {Pointer} + **/ + activePointer: null, + + mousePointer: null, + mouse: null, + keyboard: null, + touch: null, + mspointer: null, + + onDown: null, + onUp: null, + onTap: null, + onHold: null, + + /** + * Starts the Input Manager running + * @method start + **/ + boot: function () { + + this.mousePointer = new Phaser.Input.Pointer(this.game, 0); + this.pointer1 = new Phaser.Input.Pointer(this.game, 1); + this.pointer2 = new Phaser.Input.Pointer(this.game, 2); + + this.mouse = new Phaser.Input.Mouse(this.game); + this.keyboard = new Phaser.Input.Keyboard(this.game); + this.touch = new Phaser.Input.Touch(this.game); + this.mspointer = new Phaser.Input.MSPointer(this.game); + + this.onDown = new Phaser.Signal(); + this.onUp = new Phaser.Signal(); + this.onTap = new Phaser.Signal(); + this.onHold = new Phaser.Signal(); + + this.scale = new Phaser.Point(1, 1); + this.speed = new Phaser.Point(); + this.position = new Phaser.Point(); + this._oldPosition = new Phaser.Point(); + + this.circle = new Phaser.Circle(0, 0, 44); + + this.activePointer = this.mousePointer; + this.currentPointers = 0; + + // this.hitCanvas = document.createElement('canvas'); + // this.hitCanvas.width = 1; + // this.hitCanvas.height = 1; + // this.hitContext = this.hitCanvas.getContext('2d'); + + this.mouse.start(); + this.keyboard.start(); + this.touch.start(); + this.mspointer.start(); + this.mousePointer.active = true; + + }, + + /** + * Add a new Pointer object to the Input Manager. By default Input creates 2 pointer objects for you. If you need more + * use this to create a new one, up to a maximum of 10. + * @method addPointer + * @return {Pointer} A reference to the new Pointer object + **/ + addPointer: function () { + + var next = 0; + + for (var i = 10; i > 0; i--) + { + if (this['pointer' + i] === null) + { + next = i; + } + } + + if (next == 0) + { + console.warn("You can only have 10 Pointer objects"); + return null; + } + else + { + this['pointer' + next] = new Phaser.Input.Pointer(this.game, next); + return this['pointer' + next]; + } + + }, + + /** + * Updates the Input Manager. Called by the core Game loop. + * @method update + **/ + update: function () { + + if (this.pollRate > 0 && this._pollCounter < this.pollRate) + { + this._pollCounter++; + return; + } + + this.speed.x = this.position.x - this._oldPosition.x; + this.speed.y = this.position.y - this._oldPosition.y; + + this._oldPosition.copyFrom(this.position); + this.mousePointer.update(); + + this.pointer1.update(); + this.pointer2.update(); + + if (this.pointer3) { this.pointer3.update(); } + if (this.pointer4) { this.pointer4.update(); } + if (this.pointer5) { this.pointer5.update(); } + if (this.pointer6) { this.pointer6.update(); } + if (this.pointer7) { this.pointer7.update(); } + if (this.pointer8) { this.pointer8.update(); } + if (this.pointer9) { this.pointer9.update(); } + if (this.pointer10) { this.pointer10.update(); } + + this._pollCounter = 0; + }, + + /** + * Reset all of the Pointers and Input states + * @method reset + * @param hard {bool} A soft reset (hard = false) won't reset any signals that might be bound. A hard reset will. + **/ + reset: function (hard) { + + if (typeof hard === "undefined") { hard = false; } + + this.keyboard.reset(); + this.mousePointer.reset(); + + for (var i = 1; i <= 10; i++) + { + if (this['pointer' + i]) + { + this['pointer' + i].reset(); + } + } + + this.currentPointers = 0; + // this.game.stage.canvas.style.cursor = "default"; + + if (hard == true) + { + this.onDown.dispose(); + this.onUp.dispose(); + this.onTap.dispose(); + this.onHold.dispose(); + this.onDown = new Phaser.Signal(); + this.onUp = new Phaser.Signal(); + this.onTap = new Phaser.Signal(); + this.onHold = new Phaser.Signal(); + + for (var i = 0; i < this.totalTrackedObjects; i++) + { + if (this.inputObjects[i] && this.inputObjects[i].input) + { + this.inputObjects[i].input.reset(); + } + } + + this.inputObjects.length = 0; + this.totalTrackedObjects = 0; + } + + this._pollCounter = 0; + + }, + + resetSpeed: function (x, y) { + + this._oldPosition.setTo(x, y); + this.speed.setTo(0, 0); + + }, + + /** + * Find the first free Pointer object and start it, passing in the event data. + * @method startPointer + * @param {Any} event The event data from the Touch event + * @return {Pointer} The Pointer object that was started or null if no Pointer object is available + **/ + startPointer: function (event) { + + if (this.maxPointers < 10 && this.totalActivePointers == this.maxPointers) { + return null; + } + + if (this.pointer1.active == false) + { + return this.pointer1.start(event); + } + else if (this.pointer2.active == false) + { + return this.pointer2.start(event); + } + else + { + for (var i = 3; i <= 10; i++) + { + if (this['pointer' + i] && this['pointer' + i].active == false) + { + return this['pointer' + i].start(event); + } + } + } + + return null; + + }, + + /** + * Updates the matching Pointer object, passing in the event data. + * @method updatePointer + * @param {Any} event The event data from the Touch event + * @return {Pointer} The Pointer object that was updated or null if no Pointer object is available + **/ + updatePointer: function (event) { + + if (this.pointer1.active && this.pointer1.identifier == event.identifier) + { + return this.pointer1.move(event); + } + else if(this.pointer2.active && this.pointer2.identifier == event.identifier) + { + return this.pointer2.move(event); + } + else + { + for (var i = 3; i <= 10; i++) + { + if (this['pointer' + i] && this['pointer' + i].active && this['pointer' + i].identifier == event.identifier) + { + return this['pointer' + i].move(event); + } + } + } + + return null; + + }, + + /** + * Stops the matching Pointer object, passing in the event data. + * @method stopPointer + * @param {Any} event The event data from the Touch event + * @return {Pointer} The Pointer object that was stopped or null if no Pointer object is available + **/ + stopPointer: function (event) { + + if (this.pointer1.active && this.pointer1.identifier == event.identifier) + { + return this.pointer1.stop(event); + } + else if(this.pointer2.active && this.pointer2.identifier == event.identifier) + { + return this.pointer2.stop(event); + } + else + { + for (var i = 3; i <= 10; i++) + { + if (this['pointer' + i] && this['pointer' + i].active && this['pointer' + i].identifier == event.identifier) + { + return this['pointer' + i].stop(event); + } + } + } + + return null; + + }, + + /** + * Get the next Pointer object whos active property matches the given state + * @method getPointer + * @param {bool} state The state the Pointer should be in (false for inactive, true for active) + * @return {Pointer} A Pointer object or null if no Pointer object matches the requested state. + **/ + getPointer: function (state) { + + if (typeof state === "undefined") { state = false; } + + if (this.pointer1.active == state) + { + return this.pointer1; + } + else if(this.pointer2.active == state) + { + return this.pointer2; + } + else + { + for (var i = 3; i <= 10; i++) + { + if (this['pointer' + i] && this['pointer' + i].active == state) + { + return this['pointer' + i]; + } + } + } + + return null; + + }, + + /** + * Get the Pointer object whos identified property matches the given identifier value + * @method getPointerFromIdentifier + * @param {Number} identifier The Pointer.identifier value to search for + * @return {Pointer} A Pointer object or null if no Pointer object matches the requested identifier. + **/ + getPointerFromIdentifier: function (identifier) { + + if (this.pointer1.identifier == identifier) + { + return this.pointer1; + } + else if(this.pointer2.identifier == identifier) + { + return this.pointer2; + } + else + { + for (var i = 3; i <= 10; i++) + { + if (this['pointer' + i] && this['pointer' + i].identifier == identifier) + { + return this['pointer' + i]; + } + } + } + + return null; + + }, + + /** + * Get the distance between two Pointer objects + * @method getDistance + * @param {Pointer} pointer1 + * @param {Pointer} pointer2 + **/ + getDistance: function (pointer1, pointer2) { + // return Phaser.Vec2Utils.distance(pointer1.position, pointer2.position); + }, + + /** + * Get the angle between two Pointer objects + * @method getAngle + * @param {Pointer} pointer1 + * @param {Pointer} pointer2 + **/ + getAngle: function (pointer1, pointer2) { + // return Phaser.Vec2Utils.angle(pointer1.position, pointer2.position); + }, + + addGameObject: function() {}, + removeGameObject: function() {}, + +}; + +// Getters / Setters + +Object.defineProperty(Phaser.Input.prototype, "x", { + + /** + * The X coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenX/clientX for source values. + * @property x + * @type {Number} + **/ + get: function () { + return this._x; + }, + + set: function (value) { + this._x = Math.floor(value); + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Input.prototype, "y", { + + /** + * The Y coordinate of the most recently active pointer. + * This value takes game scaling into account automatically. See Pointer.screenY/clientY for source values. + * @property y + * @type {Number} + **/ + get: function () { + return this._y; + }, + + set: function (value) { + this._y = Math.floor(value); + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Input.prototype, "pollLocked", { + + get: function () { + return (this.pollRate > 0 && this._pollCounter < this.pollRate); + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Input.prototype, "totalInactivePointers", { + + /** + * Get the total number of inactive Pointers + * @method totalInactivePointers + * @return {Number} The number of Pointers currently inactive + **/ + get: function () { + return 10 - this.currentPointers; + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Input.prototype, "totalActivePointers", { + + /** + * Recalculates the total number of active Pointers + * @method totalActivePointers + * @return {Number} The number of Pointers currently active + **/ + get: function () { + + this.currentPointers = 0; + + for (var i = 1; i <= 10; i++) + { + if (this['pointer' + i] && this['pointer' + i].active) + { + this.currentPointers++; + } + } + + return this.currentPointers; + + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Input.prototype, "worldX", { + + get: function () { + return this.camera.worldView.x + this.x; + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Input.prototype, "worldY", { + + get: function () { + return this.camera.worldView.x + this.x; + }, + + enumerable: true, + configurable: true +}); diff --git a/src/input/Keyboard.js b/src/input/Keyboard.js new file mode 100644 index 00000000..1bb31aab --- /dev/null +++ b/src/input/Keyboard.js @@ -0,0 +1,306 @@ +Phaser.Input.Keyboard = function (game) { + + this.game = game; + this._keys = {}; + this._capture = {}; + +}; + +Phaser.Input.Keyboard.prototype = { + + game: null, + + /** + * You can disable all Input by setting disabled = true. While set all new input related events will be ignored. + * @type {bool} + */ + disabled: false, + + _onKeyDown: null, + _onKeyUp: null, + + start: function () { + + var _this = this; + + this._onKeyDown = function (event) { + return _this.onKeyDown(event); + }; + + this._onKeyUp = function (event) { + return _this.onKeyUp(event); + }; + + document.body.addEventListener('keydown', this._onKeyDown, false); + document.body.addEventListener('keyup', this._onKeyUp, false); + + }, + + stop: function () { + + document.body.removeEventListener('keydown', this._onKeyDown); + document.body.removeEventListener('keyup', this._onKeyUp); + + }, + + /** + * By default when a key is pressed Phaser will not stop the event from propagating up to the browser. + * There are some keys this can be annoying for, like the arrow keys or space bar, which make the browser window scroll. + * You can use addKeyCapture to consume the keyboard event for specific keys so it doesn't bubble up to the the browser. + * Pass in either a single keycode or an array/hash of keycodes. + * @param {Any} keycode + */ + addKeyCapture: function (keycode) { + + if (typeof keycode === 'object') + { + for (var key in keycode) + { + this._capture[keycode[key]] = true; + } + } + else + { + this._capture[keycode] = true; + } + }, + + /** + * @param {Number} keycode + */ + removeKeyCapture: function (keycode) { + + delete this._capture[keycode]; + + }, + + clearCaptures: function () { + + this._capture = {}; + + }, + + /** + * @param {KeyboardEvent} event + */ + onKeyDown: function (event) { + + if (this.game.input.disabled || this.disabled) + { + return; + } + + if (this._capture[event.keyCode]) + { + event.preventDefault(); + } + + if (!this._keys[event.keyCode]) + { + this._keys[event.keyCode] = { + isDown: true, + timeDown: this.game.time.now, + timeUp: 0 + }; + } + else + { + this._keys[event.keyCode].isDown = true; + this._keys[event.keyCode].timeDown = this.game.time.now; + } + + }, + + /** + * @param {KeyboardEvent} event + */ + onKeyUp: function (event) { + + if (this.game.input.disabled || this.disabled) + { + return; + } + + if (this._capture[event.keyCode]) + { + event.preventDefault(); + } + + if (!this._keys[event.keyCode]) + { + this._keys[event.keyCode] = { + isDown: false, + timeDown: 0, + timeUp: this.game.time.now + }; + } + else + { + this._keys[event.keyCode].isDown = false; + this._keys[event.keyCode].timeUp = this.game.time.now; + } + + }, + + reset: function () { + + for (var key in this._keys) + { + this._keys[key].isDown = false; + } + + }, + + /** + * @param {Number} keycode + * @param {Number} [duration] + * @return {bool} + */ + justPressed: function (keycode, duration) { + + if (typeof duration === "undefined") { duration = 250; } + + if (this._keys[keycode] && this._keys[keycode].isDown === true && (this.game.time.now - this._keys[keycode].timeDown < duration)) + { + return true; + } + + return false; + + }, + + /** + * @param {Number} keycode + * @param {Number} [duration] + * @return {bool} + */ + justReleased: function (keycode, duration) { + + if (typeof duration === "undefined") { duration = 250; } + + if (this._keys[keycode] && this._keys[keycode].isDown === false && (this.game.time.now - this._keys[keycode].timeUp < duration)) + { + return true; + } + + return false; + + }, + + /** + * @param {Number} keycode + * @return {bool} + */ + isDown: function (keycode) { + + if (this._keys[keycode]) + { + return this._keys[keycode].isDown; + } + + return false; + + } + +}; + +// Statics + +Phaser.Input.Keyboard.A = "A".charCodeAt(0); +Phaser.Input.Keyboard.B = "B".charCodeAt(0); +Phaser.Input.Keyboard.C = "C".charCodeAt(0); +Phaser.Input.Keyboard.D = "D".charCodeAt(0); +Phaser.Input.Keyboard.E = "E".charCodeAt(0); +Phaser.Input.Keyboard.F = "F".charCodeAt(0); +Phaser.Input.Keyboard.G = "G".charCodeAt(0); +Phaser.Input.Keyboard.H = "H".charCodeAt(0); +Phaser.Input.Keyboard.I = "I".charCodeAt(0); +Phaser.Input.Keyboard.J = "J".charCodeAt(0); +Phaser.Input.Keyboard.K = "K".charCodeAt(0); +Phaser.Input.Keyboard.L = "L".charCodeAt(0); +Phaser.Input.Keyboard.M = "M".charCodeAt(0); +Phaser.Input.Keyboard.N = "N".charCodeAt(0); +Phaser.Input.Keyboard.O = "O".charCodeAt(0); +Phaser.Input.Keyboard.P = "P".charCodeAt(0); +Phaser.Input.Keyboard.Q = "Q".charCodeAt(0); +Phaser.Input.Keyboard.R = "R".charCodeAt(0); +Phaser.Input.Keyboard.S = "S".charCodeAt(0); +Phaser.Input.Keyboard.T = "T".charCodeAt(0); +Phaser.Input.Keyboard.U = "U".charCodeAt(0); +Phaser.Input.Keyboard.V = "V".charCodeAt(0); +Phaser.Input.Keyboard.W = "W".charCodeAt(0); +Phaser.Input.Keyboard.X = "X".charCodeAt(0); +Phaser.Input.Keyboard.Y = "Y".charCodeAt(0); +Phaser.Input.Keyboard.Z = "Z".charCodeAt(0); +Phaser.Input.Keyboard.ZERO = "0".charCodeAt(0); +Phaser.Input.Keyboard.ONE = "1".charCodeAt(0); +Phaser.Input.Keyboard.TWO = "2".charCodeAt(0); +Phaser.Input.Keyboard.THREE = "3".charCodeAt(0); +Phaser.Input.Keyboard.FOUR = "4".charCodeAt(0); +Phaser.Input.Keyboard.FIVE = "5".charCodeAt(0); +Phaser.Input.Keyboard.SIX = "6".charCodeAt(0); +Phaser.Input.Keyboard.SEVEN = "7".charCodeAt(0); +Phaser.Input.Keyboard.EIGHT = "8".charCodeAt(0); +Phaser.Input.Keyboard.NINE = "9".charCodeAt(0); +Phaser.Input.Keyboard.NUMPAD_0 = 96; +Phaser.Input.Keyboard.NUMPAD_1 = 97; +Phaser.Input.Keyboard.NUMPAD_2 = 98; +Phaser.Input.Keyboard.NUMPAD_3 = 99; +Phaser.Input.Keyboard.NUMPAD_4 = 100; +Phaser.Input.Keyboard.NUMPAD_5 = 101; +Phaser.Input.Keyboard.NUMPAD_6 = 102; +Phaser.Input.Keyboard.NUMPAD_7 = 103; +Phaser.Input.Keyboard.NUMPAD_8 = 104; +Phaser.Input.Keyboard.NUMPAD_9 = 105; +Phaser.Input.Keyboard.NUMPAD_MULTIPLY = 106; +Phaser.Input.Keyboard.NUMPAD_ADD = 107; +Phaser.Input.Keyboard.NUMPAD_ENTER = 108; +Phaser.Input.Keyboard.NUMPAD_SUBTRACT = 109; +Phaser.Input.Keyboard.NUMPAD_DECIMAL = 110; +Phaser.Input.Keyboard.NUMPAD_DIVIDE = 111; +Phaser.Input.Keyboard.F1 = 112; +Phaser.Input.Keyboard.F2 = 113; +Phaser.Input.Keyboard.F3 = 114; +Phaser.Input.Keyboard.F4 = 115; +Phaser.Input.Keyboard.F5 = 116; +Phaser.Input.Keyboard.F6 = 117; +Phaser.Input.Keyboard.F7 = 118; +Phaser.Input.Keyboard.F8 = 119; +Phaser.Input.Keyboard.F9 = 120; +Phaser.Input.Keyboard.F10 = 121; +Phaser.Input.Keyboard.F11 = 122; +Phaser.Input.Keyboard.F12 = 123; +Phaser.Input.Keyboard.F13 = 124; +Phaser.Input.Keyboard.F14 = 125; +Phaser.Input.Keyboard.F15 = 126; +Phaser.Input.Keyboard.COLON = 186; +Phaser.Input.Keyboard.EQUALS = 187; +Phaser.Input.Keyboard.UNDERSCORE = 189; +Phaser.Input.Keyboard.QUESTION_MARK = 191; +Phaser.Input.Keyboard.TILDE = 192; +Phaser.Input.Keyboard.OPEN_BRACKET = 219; +Phaser.Input.Keyboard.BACKWARD_SLASH = 220; +Phaser.Input.Keyboard.CLOSED_BRACKET = 221; +Phaser.Input.Keyboard.QUOTES = 222; +Phaser.Input.Keyboard.BACKSPACE = 8; +Phaser.Input.Keyboard.TAB = 9; +Phaser.Input.Keyboard.CLEAR = 12; +Phaser.Input.Keyboard.ENTER = 13; +Phaser.Input.Keyboard.SHIFT = 16; +Phaser.Input.Keyboard.CONTROL = 17; +Phaser.Input.Keyboard.ALT = 18; +Phaser.Input.Keyboard.CAPS_LOCK = 20; +Phaser.Input.Keyboard.ESC = 27; +Phaser.Input.Keyboard.SPACEBAR = 32; +Phaser.Input.Keyboard.PAGE_UP = 33; +Phaser.Input.Keyboard.PAGE_DOWN = 34; +Phaser.Input.Keyboard.END = 35; +Phaser.Input.Keyboard.HOME = 36; +Phaser.Input.Keyboard.LEFT = 37; +Phaser.Input.Keyboard.UP = 38; +Phaser.Input.Keyboard.RIGHT = 39; +Phaser.Input.Keyboard.DOWN = 40; +Phaser.Input.Keyboard.INSERT = 45; +Phaser.Input.Keyboard.DELETE = 46; +Phaser.Input.Keyboard.HELP = 47; +Phaser.Input.Keyboard.NUM_LOCK = 144; diff --git a/src/input/MSPointer.js b/src/input/MSPointer.js new file mode 100644 index 00000000..af15d0f3 --- /dev/null +++ b/src/input/MSPointer.js @@ -0,0 +1,128 @@ +/** +* Phaser.Input.MSPointer +* +* The MSPointer class handles touch interactions with the game and the resulting Pointer objects. +* It will work only in Internet Explorer 10 and Windows Store or Windows Phone 8 apps using JavaScript. +* http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx +*/ +Phaser.Input.MSPointer = function (game) { + + this.game = game; + this.callbackContext = this.game; + + this.mouseDownCallback = null; + this.mouseMoveCallback = null; + this.mouseUpCallback = null; + +}; + +Phaser.Input.MSPointer.prototype = { + + game: null, + + /** + * You can disable all Input by setting disabled = true. While set all new input related events will be ignored. + * @type {bool} + */ + disabled: false, + + _onMSPointerDown: null, + _onMSPointerMove: null, + _onMSPointerUp: null, + + /** + * Starts the event listeners running + * @method start + */ + start: function () { + + var _this = this; + + if (this.game.device.mspointer == true) + { + this._onMSPointerDown = function (event) { + return _this.onPointerDown(event); + }; + + this._onMSPointerMove = function (event) { + return _this.onPointerMove(event); + }; + + this._onMSPointerUp = function (event) { + return _this.onPointerUp(event); + }; + + this.game.stage.canvas.addEventListener('MSPointerDown', this._onMSPointerDown, false); + this.game.stage.canvas.addEventListener('MSPointerMove', this._onMSPointerMove, false); + this.game.stage.canvas.addEventListener('MSPointerUp', this._onMSPointerUp, false); + } + + }, + + /** + * @method onPointerDown + * @param {Any} event + **/ + onPointerDown: function (event) { + + if (this.game.input.disabled || this.disabled) + { + return; + } + + event.preventDefault(); + event.identifier = event.pointerId; + + this.game.input.startPointer(event); + + }, + + /** + * @method onPointerMove + * @param {Any} event + **/ + onPointerMove: function (event) { + + if (this.game.input.disabled || this.disabled) + { + return; + } + + event.preventDefault(); + event.identifier = event.pointerId; + + this.game.input.updatePointer(event); + + }, + + /** + * @method onPointerUp + * @param {Any} event + **/ + onPointerUp: function (event) { + + if (this.game.input.disabled || this.disabled) + { + return; + } + + event.preventDefault(); + event.identifier = event.pointerId; + + this.game.input.stopPointer(event); + + }, + + /** + * Stop the event listeners + * @method stop + */ + stop: function () { + + this.game.stage.canvas.removeEventListener('MSPointerDown', this._onMSPointerDown); + this.game.stage.canvas.removeEventListener('MSPointerMove', this._onMSPointerMove); + this.game.stage.canvas.removeEventListener('MSPointerUp', this._onMSPointerUp); + + } + +}; \ No newline at end of file diff --git a/src/input/Mouse.js b/src/input/Mouse.js new file mode 100644 index 00000000..0050d0f2 --- /dev/null +++ b/src/input/Mouse.js @@ -0,0 +1,132 @@ +Phaser.Input.Mouse = function (game) { + + this.game = game; + this.callbackContext = this.game; + + this.mouseDownCallback = null; + this.mouseMoveCallback = null; + this.mouseUpCallback = null; + +}; + +Phaser.Input.Mouse.LEFT_BUTTON = 0; +Phaser.Input.Mouse.MIDDLE_BUTTON = 1; +Phaser.Input.Mouse.RIGHT_BUTTON = 2; + +Phaser.Input.Mouse.prototype = { + + game: null, + + /** + * You can disable all Input by setting disabled = true. While set all new input related events will be ignored. + * @type {bool} + */ + disabled: false, + + /** + * Starts the event listeners running + * @method start + */ + start: function () { + + var _this = this; + + if (this.game.device.android && this.game.device.chrome == false) + { + // Android stock browser fires mouse events even if you preventDefault on the touchStart, so ... + return; + } + + this._onMouseDown = function (event) { + return _this.onMouseDown(event); + }; + + this._onMouseMove = function (event) { + return _this.onMouseMove(event); + }; + + this._onMouseUp = function (event) { + return _this.onMouseUp(event); + }; + + this.game.stage.canvas.addEventListener('mousedown', this._onMouseDown, true); + this.game.stage.canvas.addEventListener('mousemove', this._onMouseMove, true); + this.game.stage.canvas.addEventListener('mouseup', this._onMouseUp, true); + }, + + /** + * @param {MouseEvent} event + */ + onMouseDown: function (event) { + + if (this.mouseDownCallback) + { + this.mouseDownCallback.call(this.callbackContext, event); + } + + if (this.game.input.disabled || this.disabled) + { + return; + } + + event['identifier'] = 0; + + this.game.input.mousePointer.start(event); + + }, + + /** + * @param {MouseEvent} event + */ + onMouseMove: function (event) { + + if (this.mouseMoveCallback) + { + this.mouseMoveCallback.call(this.callbackContext, event); + } + + if (this.game.input.disabled || this.disabled) + { + return; + } + + event['identifier'] = 0; + + this.game.input.mousePointer.move(event); + + }, + + /** + * @param {MouseEvent} event + */ + onMouseUp: function (event) { + + if (this.mouseUpCallback) + { + this.mouseUpCallback.call(this.callbackContext, event); + } + + if (this.game.input.disabled || this.disabled) + { + return; + } + + event['identifier'] = 0; + + this.game.input.mousePointer.stop(event); + + }, + + /** + * Stop the event listeners + * @method stop + */ + stop: function () { + + this.game.stage.canvas.removeEventListener('mousedown', this._onMouseDown); + this.game.stage.canvas.removeEventListener('mousemove', this._onMouseMove); + this.game.stage.canvas.removeEventListener('mouseup', this._onMouseUp); + + } + +}; \ No newline at end of file diff --git a/src/input/Pointer.js b/src/input/Pointer.js new file mode 100644 index 00000000..9527d8e9 --- /dev/null +++ b/src/input/Pointer.js @@ -0,0 +1,631 @@ +/** +* Phaser - Pointer +* +* A Pointer object is used by the Mouse, Touch and MSPoint managers and represents a single finger on the touch screen. +*/ +Phaser.Input.Pointer = function (game, id) { + + this.game = game; + this.id = id; + + this.active = false; + + this.position = new Phaser.Point(); + this.positionDown = new Phaser.Point(); + + this.circle = new Phaser.Circle(0, 0, 44); + + if (id == 0) + { + this.isMouse = true; + } + +}; + +Phaser.Input.Pointer.prototype = { + + /** + * Local private variable to store the status of dispatching a hold event + * @property _holdSent + * @type {bool} + * @private + */ + _holdSent: false, + + /** + * Local private variable storing the short-term history of pointer movements + * @property _history + * @type {Array} + * @private + */ + _history: [], + + /** + * Local private variable storing the time at which the next history drop should occur + * @property _lastDrop + * @type {Number} + * @private + */ + _nextDrop: 0, + + // Monitor events outside of a state reset loop + _stateReset: false, + + /** + * A Vector object containing the initial position when the Pointer was engaged with the screen. + * @property positionDown + * @type {Vec2} + **/ + positionDown: null, + + /** + * A Vector object containing the current position of the Pointer on the screen. + * @property position + * @type {Vec2} + **/ + position: null, + + /** + * A Circle object centered on the x/y screen coordinates of the Pointer. + * Default size of 44px (Apple's recommended "finger tip" size) + * @property circle + * @type {Circle} + **/ + circle: null, + + /** + * + * @property withinGame + * @type {bool} + */ + withinGame: false, + + /** + * The horizontal coordinate of point relative to the viewport in pixels, excluding any scroll offset + * @property clientX + * @type {Number} + */ + clientX: -1, + + /** + * The vertical coordinate of point relative to the viewport in pixels, excluding any scroll offset + * @property clientY + * @type {Number} + */ + clientY: -1, + + /** + * The horizontal coordinate of point relative to the viewport in pixels, including any scroll offset + * @property pageX + * @type {Number} + */ + pageX: -1, + + /** + * The vertical coordinate of point relative to the viewport in pixels, including any scroll offset + * @property pageY + * @type {Number} + */ + pageY: -1, + + /** + * The horizontal coordinate of point relative to the screen in pixels + * @property screenX + * @type {Number} + */ + screenX: -1, + + /** + * The vertical coordinate of point relative to the screen in pixels + * @property screenY + * @type {Number} + */ + screenY: -1, + + /** + * The horizontal coordinate of point relative to the game element. This value is automatically scaled based on game size. + * @property x + * @type {Number} + */ + x: -1, + + /** + * The vertical coordinate of point relative to the game element. This value is automatically scaled based on game size. + * @property y + * @type {Number} + */ + y: -1, + + /** + * If the Pointer is a mouse this is true, otherwise false + * @property isMouse + * @type {bool} + **/ + isMouse: false, + + /** + * If the Pointer is touching the touchscreen, or the mouse button is held down, isDown is set to true + * @property isDown + * @type {bool} + **/ + isDown: false, + + /** + * If the Pointer is not touching the touchscreen, or the mouse button is up, isUp is set to true + * @property isUp + * @type {bool} + **/ + isUp: true, + + /** + * A timestamp representing when the Pointer first touched the touchscreen. + * @property timeDown + * @type {Number} + **/ + timeDown: 0, + + /** + * A timestamp representing when the Pointer left the touchscreen. + * @property timeUp + * @type {Number} + **/ + timeUp: 0, + + /** + * A timestamp representing when the Pointer was last tapped or clicked + * @property previousTapTime + * @type {Number} + **/ + previousTapTime: 0, + + /** + * The total number of times this Pointer has been touched to the touchscreen + * @property totalTouches + * @type {Number} + **/ + totalTouches: 0, + + /** + * The number of miliseconds since the last click + * @property msSinceLastClick + * @type {Number} + **/ + msSinceLastClick: Number.MAX_VALUE, + + /** + * The Game Object this Pointer is currently over / touching / dragging. + * @property targetObject + * @type {Any} + **/ + targetObject: null, + + /** + * Called when the Pointer is pressed onto the touchscreen + * @method start + * @param {Any} event + */ + start: function (event) { + + this.identifier = event.identifier; + this.target = event.target; + + if (event.button) + { + this.button = event.button; + } + + // Fix to stop rogue browser plugins from blocking the visibility state event + // if (this.game.paused == true && this.game.stage.scale.incorrectOrientation == false) + // { + // this.game.stage.resumeGame(); + // return this; + // } + + this._history.length = 0; + this.active = true; + this.withinGame = true; + this.isDown = true; + this.isUp = false; + + // Work out how long it has been since the last click + this.msSinceLastClick = this.game.time.now - this.timeDown; + this.timeDown = this.game.time.now; + this._holdSent = false; + + // This sets the x/y and other local values + this.move(event); + + // x and y are the old values here? + this.positionDown.setTo(this.x, this.y); + + if (this.game.input.multiInputOverride == Phaser.Input.MOUSE_OVERRIDES_TOUCH || this.game.input.multiInputOverride == Phaser.Input.MOUSE_TOUCH_COMBINE || (this.game.input.multiInputOverride == Phaser.Input.TOUCH_OVERRIDES_MOUSE && this.game.input.currentPointers == 0)) + { + //this.game.input.x = this.x * this.game.input.scale.x; + //this.game.input.y = this.y * this.game.input.scale.y; + this.game.input.x = this.x; + this.game.input.y = this.y; + this.game.input.position.setTo(this.x, this.y); + this.game.input.onDown.dispatch(this); + this.game.input.resetSpeed(this.x, this.y); + } + + this._stateReset = false; + this.totalTouches++; + + if (this.isMouse == false) + { + this.game.input.currentPointers++; + } + + if (this.targetObject !== null) + { + this.targetObject.input._touchedHandler(this); + } + + return this; + + }, + + update: function () { + + if (this.active) + { + if (this._holdSent == false && this.duration >= this.game.input.holdRate) + { + if (this.game.input.multiInputOverride == Phaser.Input.MOUSE_OVERRIDES_TOUCH || this.game.input.multiInputOverride == Phaser.Input.MOUSE_TOUCH_COMBINE || (this.game.input.multiInputOverride == Phaser.Input.TOUCH_OVERRIDES_MOUSE && this.game.input.currentPointers == 0)) + { + this.game.input.onHold.dispatch(this); + } + + this._holdSent = true; + } + + // Update the droppings history + if (this.game.input.recordPointerHistory && this.game.time.now >= this._nextDrop) + { + this._nextDrop = this.game.time.now + this.game.input.recordRate; + + this._history.push({ + x: this.position.x, + y: this.position.y + }); + + if (this._history.length > this.game.input.recordLimit) + { + this._history.shift(); + } + } + + // Check which camera they are over + // this.camera = this.game.world.cameras.getCameraUnderPoint(this.x, this.y); + } + + }, + + /** + * Called when the Pointer is moved + * @method move + * @param {Any} event + */ + move: function (event) { + + if (this.game.input.pollLocked) + { + return; + } + + if (event.button) + { + this.button = event.button; + } + + this.clientX = event.clientX; + this.clientY = event.clientY; + + this.pageX = event.pageX; + this.pageY = event.pageY; + + this.screenX = event.screenX; + this.screenY = event.screenY; + + this.x = (this.pageX - this.game.stage.offset.x) * this.game.input.scale.x; + this.y = (this.pageY - this.game.stage.offset.y) * this.game.input.scale.y; + + this.position.setTo(this.x, this.y); + this.circle.x = this.x; + this.circle.y = this.y; + + if (this.game.input.multiInputOverride == Phaser.Input.MOUSE_OVERRIDES_TOUCH || this.game.input.multiInputOverride == Phaser.Input.MOUSE_TOUCH_COMBINE || (this.game.input.multiInputOverride == Phaser.Input.TOUCH_OVERRIDES_MOUSE && this.game.input.currentPointers == 0)) + { + this.game.input.activePointer = this; + this.game.input.x = this.x; + this.game.input.y = this.y; + this.game.input.position.setTo(this.game.input.x, this.game.input.y); + this.game.input.circle.x = this.game.input.x; + this.game.input.circle.y = this.game.input.y; + } + + // If the game is paused we don't process any target objects + if (this.game.paused) + { + return this; + } + + // Easy out if we're dragging something and it still exists + if (this.targetObject !== null && this.targetObject.input && this.targetObject.input.isDragged == true) + { + if (this.targetObject.input.update(this) == false) + { + this.targetObject = null; + } + + return this; + + } + + // Work out which object is on the top + this._highestRenderOrderID = -1; + this._highestRenderObject = -1; + this._highestInputPriorityID = -1; + + for (var i = 0; i < this.game.input.totalTrackedObjects; i++) + { + if (this.game.input.inputObjects[i] && this.game.input.inputObjects[i].input && this.game.input.inputObjects[i].input.checkPointerOver(this)) + { + // If the object has a higher InputManager.PriorityID OR if the priority ID is the same as the current highest AND it has a higher renderOrderID, then set it to the top + if (this.game.input.inputObjects[i].input.priorityID > this._highestInputPriorityID || (this.game.input.inputObjects[i].input.priorityID == this._highestInputPriorityID && this.game.input.inputObjects[i].renderOrderID > this._highestRenderOrderID)) + { + this._highestRenderOrderID = this.game.input.inputObjects[i].renderOrderID; + this._highestRenderObject = i; + this._highestInputPriorityID = this.game.input.inputObjects[i].input.priorityID; + } + } + } + + if (this._highestRenderObject == -1) + { + // The pointer isn't over anything, check if we've got a lingering previous target + if (this.targetObject !== null) + { + this.targetObject.input._pointerOutHandler(this); + this.targetObject = null; + } + } + else + { + if (this.targetObject == null) + { + // And now set the new one + this.targetObject = this.game.input.inputObjects[this._highestRenderObject]; + this.targetObject.input._pointerOverHandler(this); + } + else + { + // We've got a target from the last update + if (this.targetObject == this.game.input.inputObjects[this._highestRenderObject]) + { + // Same target as before, so update it + if (this.targetObject.input.update(this) == false) + { + this.targetObject = null; + } + } + else + { + // The target has changed, so tell the old one we've left it + this.targetObject.input._pointerOutHandler(this); + + // And now set the new one + this.targetObject = this.game.input.inputObjects[this._highestRenderObject]; + this.targetObject.input._pointerOverHandler(this); + } + } + } + + return this; + + }, + + /** + * Called when the Pointer leaves the target area + * @method leave + * @param {Any} event + */ + leave: function (event) { + + this.withinGame = false; + this.move(event); + + }, + + /** + * Called when the Pointer leaves the touchscreen + * @method stop + * @param {Any} event + */ + stop: function (event) { + + if (this._stateReset) + { + event.preventDefault(); + return; + } + + this.timeUp = this.game.time.now; + + if (this.game.input.multiInputOverride == Phaser.Input.MOUSE_OVERRIDES_TOUCH || this.game.input.multiInputOverride == Phaser.Input.MOUSE_TOUCH_COMBINE || (this.game.input.multiInputOverride == Phaser.Input.TOUCH_OVERRIDES_MOUSE && this.game.input.currentPointers == 0)) + { + this.game.input.onUp.dispatch(this); + + // Was it a tap? + if (this.duration >= 0 && this.duration <= this.game.input.tapRate) + { + // Was it a double-tap? + if (this.timeUp - this.previousTapTime < this.game.input.doubleTapRate) + { + // Yes, let's dispatch the signal then with the 2nd parameter set to true + this.game.input.onTap.dispatch(this, true); + } + else + { + // Wasn't a double-tap, so dispatch a single tap signal + this.game.input.onTap.dispatch(this, false); + } + + this.previousTapTime = this.timeUp; + } + } + + // Mouse is always active + if (this.id > 0) + { + this.active = false; + } + + this.withinGame = false; + this.isDown = false; + this.isUp = true; + + if (this.isMouse == false) + { + this.game.input.currentPointers--; + } + + for (var i = 0; i < this.game.input.totalTrackedObjects; i++) + { + if (this.game.input.inputObjects[i] && this.game.input.inputObjects[i].input && this.game.input.inputObjects[i].input.enabled) + { + this.game.input.inputObjects[i].input._releasedHandler(this); + } + } + + if (this.targetObject) + { + this.targetObject.input._releasedHandler(this); + } + + this.targetObject = null; + return this; + + }, + + /** + * The Pointer is considered justPressed if the time it was pressed onto the touchscreen or clicked is less than justPressedRate + * @method justPressed + * @param {Number} [duration]. + * @return {bool} + */ + justPressed: function (duration) { + + if (typeof duration === "undefined") { duration = this.game.input.justPressedRate; } + + return (this.isDown === true && (this.timeDown + duration) > this.game.time.now); + + }, + + /** + * The Pointer is considered justReleased if the time it left the touchscreen is less than justReleasedRate + * @method justReleased + * @param {Number} [duration]. + * @return {bool} + */ + justReleased: function (duration) { + + if (typeof duration === "undefined") { duration = this.game.input.justReleasedRate; } + + return (this.isUp === true && (this.timeUp + duration) > this.game.time.now); + + }, + + /** + * Resets the Pointer properties. Called by InputManager.reset when you perform a State change. + * @method reset + */ + reset: function () { + + if (this.isMouse == false) + { + this.active = false; + } + + this.identifier = null; + this.isDown = false; + this.isUp = true; + this.totalTouches = 0; + this._holdSent = false; + this._history.length = 0; + this._stateReset = true; + + if (this.targetObject && this.targetObject.input) + { + this.targetObject.input._releasedHandler(this); + } + + this.targetObject = null; + + }, + + /** + * Returns a string representation of this object. + * @method toString + * @return {String} a string representation of the instance. + **/ + toString: function () { + return "[{Pointer (id=" + this.id + " identifer=" + this.identifier + " active=" + this.active + " duration=" + this.duration + " withinGame=" + this.withinGame + " x=" + this.x + " y=" + this.y + " clientX=" + this.clientX + " clientY=" + this.clientY + " screenX=" + this.screenX + " screenY=" + this.screenY + " pageX=" + this.pageX + " pageY=" + this.pageY + ")}]"; + } + +}; + +Object.defineProperty(Phaser.Input.Pointer.prototype, "duration", { + + /** + * How long the Pointer has been depressed on the touchscreen. If not currently down it returns -1. + * @property duration + * @type {Number} + **/ + get: function () { + + if (this.isUp) + { + return -1; + } + + return this.game.time.now - this.timeDown; + + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Input.Pointer.prototype, "worldX", { + + /** + * Gets the X value of this Pointer in world coordinates based on the given camera. + * @param {Camera} [camera] + */ + get: function () { + + return this.game.world.camera.worldView.x + this.x; + + }, + + enumerable: true, + configurable: true +}); + +Object.defineProperty(Phaser.Input.Pointer.prototype, "worldY", { + + /** + * Gets the Y value of this Pointer in world coordinates based on the given camera. + * @param {Camera} [camera] + */ + get: function () { + + return this.game.world.camera.worldView.y + this.y; + + }, + + enumerable: true, + configurable: true +}); diff --git a/src/input/Touch.js b/src/input/Touch.js new file mode 100644 index 00000000..535995d1 --- /dev/null +++ b/src/input/Touch.js @@ -0,0 +1,275 @@ +/** +* Phaser - Touch +* +* The Touch class handles touch interactions with the game and the resulting Pointer objects. +* http://www.w3.org/TR/touch-events/ +* https://developer.mozilla.org/en-US/docs/DOM/TouchList +* http://www.html5rocks.com/en/mobile/touchandmouse/ +* Note: Android 2.x only supports 1 touch event at once, no multi-touch +*/ +Phaser.Input.Touch = function (game) { + + this.game = game; + this.callbackContext = this.game; + + this.touchStartCallback = null; + this.touchMoveCallback = null; + this.touchEndCallback = null; + this.touchEnterCallback = null; + this.touchLeaveCallback = null; + this.touchCancelCallback = null; + +}; + +Phaser.Input.Touch.prototype = { + + game: null, + + /** + * You can disable all Input by setting disabled = true. While set all new input related events will be ignored. + * @type {bool} + */ + disabled: false, + + _onTouchStart: null, + _onTouchMove: null, + _onTouchEnd: null, + _onTouchEnter: null, + _onTouchLeave: null, + _onTouchCancel: null, + _onTouchMove: null, + + /** + * Starts the event listeners running + * @method start + */ + start: function () { + + var _this = this; + + if (this.game.device.touch) + { + this._onTouchStart = function (event) { + return _this.onTouchStart(event); + }; + + this._onTouchMove = function (event) { + return _this.onTouchMove(event); + }; + + this._onTouchEnd = function (event) { + return _this.onTouchEnd(event); + }; + + this._onTouchEnter = function (event) { + return _this.onTouchEnter(event); + }; + + this._onTouchLeave = function (event) { + return _this.onTouchLeave(event); + }; + + this._onTouchCancel = function (event) { + return _this.onTouchCancel(event); + }; + + this._documentTouchMove = function (event) { + return _this.consumeTouchMove(event); + }; + + this.game.stage.canvas.addEventListener('touchstart', this._onTouchStart, false); + this.game.stage.canvas.addEventListener('touchmove', this._onTouchMove, false); + this.game.stage.canvas.addEventListener('touchend', this._onTouchEnd, false); + this.game.stage.canvas.addEventListener('touchenter', this._onTouchEnter, false); + this.game.stage.canvas.addEventListener('touchleave', this._onTouchLeave, false); + this.game.stage.canvas.addEventListener('touchcancel', this._onTouchCancel, false); + + document.addEventListener('touchmove', this._documentTouchMove, false); + } + + }, + + /** + * Prevent iOS bounce-back (doesn't work?) + * @method consumeTouchMove + * @param {Any} event + **/ + consumeTouchMove: function (event) { + + event.preventDefault(); + + }, + + /** + * + * @method onTouchStart + * @param {Any} event + **/ + onTouchStart: function (event) { + + if (this.touchStartCallback) + { + this.touchStartCallback.call(this.callbackContext, event); + } + + if (this.game.input.disabled || this.disabled) + { + return; + } + + event.preventDefault(); + + // event.targetTouches = list of all touches on the TARGET ELEMENT (i.e. game dom element) + // event.touches = list of all touches on the ENTIRE DOCUMENT, not just the target element + // event.changedTouches = the touches that CHANGED in this event, not the total number of them + for (var i = 0; i < event.changedTouches.length; i++) + { + this.game.input.startPointer(event.changedTouches[i]); + } + + }, + + /** + * Touch cancel - touches that were disrupted (perhaps by moving into a plugin or browser chrome) + * Occurs for example on iOS when you put down 4 fingers and the app selector UI appears + * @method onTouchCancel + * @param {Any} event + **/ + onTouchCancel: function (event) { + + if (this.touchCancelCallback) + { + this.touchCancelCallback.call(this.callbackContext, event); + } + + if (this.game.input.disabled || this.disabled) + { + return; + } + + event.preventDefault(); + + // Touch cancel - touches that were disrupted (perhaps by moving into a plugin or browser chrome) + // http://www.w3.org/TR/touch-events/#dfn-touchcancel + for (var i = 0; i < event.changedTouches.length; i++) + { + this.game.input.stopPointer(event.changedTouches[i]); + } + + }, + + /** + * For touch enter and leave its a list of the touch points that have entered or left the target + * Doesn't appear to be supported by most browsers on a canvas element yet + * @method onTouchEnter + * @param {Any} event + **/ + onTouchEnter: function (event) { + + if (this.touchEnterCallback) + { + this.touchEnterCallback.call(this.callbackContext, event); + } + + if (this.game.input.disabled || this.disabled) + { + return; + } + + event.preventDefault(); + + for (var i = 0; i < event.changedTouches.length; i++) + { + //console.log('touch enter'); + } + + }, + + /** + * For touch enter and leave its a list of the touch points that have entered or left the target + * Doesn't appear to be supported by most browsers on a canvas element yet + * @method onTouchLeave + * @param {Any} event + **/ + onTouchLeave: function (event) { + + if (this.touchLeaveCallback) + { + this.touchLeaveCallback.call(this.callbackContext, event); + } + + event.preventDefault(); + + for (var i = 0; i < event.changedTouches.length; i++) + { + //console.log('touch leave'); + } + + }, + + /** + * + * @method onTouchMove + * @param {Any} event + **/ + onTouchMove: function (event) { + + if (this.touchMoveCallback) + { + this.touchMoveCallback.call(this.callbackContext, event); + } + + event.preventDefault(); + + for (var i = 0; i < event.changedTouches.length; i++) + { + this.game.input.updatePointer(event.changedTouches[i]); + } + + }, + + /** + * + * @method onTouchEnd + * @param {Any} event + **/ + onTouchEnd: function (event) { + + if (this.touchEndCallback) + { + this.touchEndCallback.call(this.callbackContext, event); + } + + event.preventDefault(); + + // For touch end its a list of the touch points that have been removed from the surface + // https://developer.mozilla.org/en-US/docs/DOM/TouchList + // event.changedTouches = the touches that CHANGED in this event, not the total number of them + for (var i = 0; i < event.changedTouches.length; i++) + { + this.game.input.stopPointer(event.changedTouches[i]); + } + + }, + + /** + * Stop the event listeners + * @method stop + */ + stop: function () { + + if (this.game.device.touch) + { + this.game.stage.canvas.removeEventListener('touchstart', this._onTouchStart); + this.game.stage.canvas.removeEventListener('touchmove', this._onTouchMove); + this.game.stage.canvas.removeEventListener('touchend', this._onTouchEnd); + this.game.stage.canvas.removeEventListener('touchenter', this._onTouchEnter); + this.game.stage.canvas.removeEventListener('touchleave', this._onTouchLeave); + this.game.stage.canvas.removeEventListener('touchcancel', this._onTouchCancel); + + document.removeEventListener('touchmove', this._documentTouchMove); + } + + } + +}; \ No newline at end of file