├── .gitignore ├── .htaccess ├── LICENSE ├── README.md ├── audio ├── LICENSE ├── bg.ogg ├── boost.ogg ├── crash.ogg ├── destroyed.ogg └── wind.ogg ├── bkcore.coffee ├── ImageData.coffee ├── ImageData.js ├── Timer.coffee ├── Timer.js ├── Utils.coffee ├── Utils.js ├── controllers │ ├── GamepadController.coffee │ ├── GamepadController.js │ ├── OrientationController.coffee │ ├── OrientationController.js │ ├── TouchController.coffee │ └── TouchController.js ├── tests.html └── threejs │ ├── Particles.coffee │ └── Particles.js ├── bkcore ├── Audio.js ├── hexgl │ ├── CameraChase.js │ ├── Gameplay.js │ ├── HUD.js │ ├── HexGL.js │ ├── Ladder.js │ ├── RaceData.js │ ├── ShipControls.js │ ├── ShipEffects.js │ └── tracks │ │ └── Cityscape.js └── threejs │ ├── Loader.js │ ├── Particles.js │ ├── Preloader.js │ ├── RenderManager.js │ └── Shaders.js ├── cache.appcache ├── css ├── BebasNeue-webfont.eot ├── BebasNeue-webfont.svg ├── BebasNeue-webfont.ttf ├── BebasNeue-webfont.woff ├── bg.jpg ├── fonts.css ├── help-0.png ├── help-1.png ├── help-2.png ├── help-3.png ├── mobile-controls-1.jpg ├── mobile-controls-2.jpg ├── mobile-over.jpg ├── mobile.jpg ├── multi.css ├── title.png └── touchcontroller.css ├── favicon.png ├── geometries ├── bonus │ └── base │ │ └── base.js ├── booster │ └── booster.js ├── ships │ └── feisar │ │ └── feisar.js └── tracks │ ├── cityscape │ ├── bonus │ │ └── speed.js │ ├── scrapers1.js │ ├── scrapers2.js │ ├── start.js │ ├── startbanner.js │ └── track.js │ └── edge │ └── track.js ├── icon_128.png ├── icon_256.png ├── icon_32.png ├── icon_64.png ├── index.html ├── launch.coffee ├── launch.js ├── libs ├── DAT.GUI.min.js ├── Detector.js ├── Editor.html ├── Editor_files │ ├── App.js │ ├── CanvasRenderer.js │ ├── Diagram.js │ ├── Iterator.js │ ├── Links.js │ ├── ModuleList.js │ ├── Node.js │ ├── Parser.js │ ├── Project.js │ ├── Timer.js │ ├── ace.js │ ├── class.js │ ├── editor.css │ ├── font.css │ ├── gamecore.js │ ├── hashlist.js │ ├── jhashtable.js │ ├── jquery-1.8.js │ ├── kinetic.js │ ├── main.css │ ├── mode-json.js │ ├── pooled.js │ └── theme-monokai.js ├── ShaderExtras.js ├── Stats.js ├── Three.dev.js ├── Three.r53.js ├── leap-0.4.1.min.js └── postprocessing │ ├── BloomPass.js │ ├── DotScreenPass.js │ ├── EffectComposer.js │ ├── FilmPass.js │ ├── MaskPass.js │ ├── RenderPass.js │ ├── SavePass.js │ ├── ShaderPass.js │ └── TexturePass.js ├── manifest.webapp ├── package.webapp ├── package.zip ├── replays └── cityscape-casual │ └── bkcore.replay.json ├── textures.full ├── bonus │ └── base │ │ ├── diffuse.jpg │ │ ├── normal.jpg │ │ └── specular.jpg ├── checker.png ├── hud │ ├── hex.jpg │ ├── hud-bg.png │ ├── hud-fg-shield.png │ └── hud-fg-speed.png ├── particles │ ├── cloud - Copie.png │ ├── cloud.png │ ├── damage.png │ ├── spark - Copie.png │ └── spark.png ├── ships │ └── feisar │ │ ├── booster │ │ ├── booster.png │ │ └── boostersprite.jpg │ │ ├── diffuse.jpg │ │ ├── normal.jpg │ │ └── specular.jpg ├── skybox │ └── dawnclouds │ │ ├── nx.jpg │ │ ├── ny.jpg │ │ ├── nz.jpg │ │ ├── px.jpg │ │ ├── py.jpg │ │ └── pz.jpg └── tracks │ └── cityscape │ ├── collision.png │ ├── diffuse.jpg │ ├── height.png │ ├── normal.jpg │ ├── scrapers1 │ ├── diffuse.jpg │ ├── normal.jpg │ └── specular.jpg │ ├── scrapers2 │ ├── diffuse.jpg │ ├── normal.jpg │ └── specular.jpg │ ├── specular.jpg │ └── start │ ├── diffuse.jpg │ ├── normal.jpg │ ├── specular.jpg │ └── start.jpg └── textures ├── bonus └── base │ ├── diffuse.jpg │ ├── normal.jpg │ └── specular.jpg ├── checker.png ├── hud ├── hex.jpg ├── hud-bg.png ├── hud-fg-shield.png └── hud-fg-speed.png ├── particles ├── cloud - Copie.png ├── cloud.png ├── damage.png ├── spark - Copie.png └── spark.png ├── ships └── feisar │ ├── booster │ ├── booster.png │ └── boostersprite.jpg │ ├── diffuse.jpg │ ├── normal.jpg │ └── specular.jpg ├── skybox └── dawnclouds │ ├── nx.jpg │ ├── ny.jpg │ ├── nz.jpg │ ├── px.jpg │ ├── py.jpg │ └── pz.jpg └── tracks └── cityscape ├── collision.png ├── diffuse.jpg ├── height.png ├── normal.jpg ├── scrapers1 ├── diffuse.jpg ├── normal.jpg └── specular.jpg ├── scrapers2 ├── diffuse.jpg ├── normal.jpg └── specular.jpg ├── specular.jpg └── start ├── diffuse.jpg ├── normal.jpg ├── specular.jpg └── start.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | AddType application/x-web-app-manifest+json .webapp 2 | ExpiresByType application/x-web-app-manifest+json "access" 3 | AddType text/cache-manifest .appcache 4 | ExpiresByType text/cache-manifest "access" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Thibaut Despoulain 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HexGL 2 | ========= 3 | 4 | Source code of [HexGL](http://hexgl.bkcore.com), the futuristic HTML5 racing game by [Thibaut Despoulain](http://bkcore.com) 5 | 6 | ## Branches 7 | * **[Master](https://github.com/BKcore/HexGL)** - Public release (stable). 8 | 9 | ## License 10 | 11 | Unless specified in the file, HexGL's code and resources are now licensed under the *MIT License*. 12 | 13 | ## Installation 14 | 15 | cd ~/ 16 | git clone git://github.com/BKcore/HexGL.git 17 | cd HexGL 18 | python -m SimpleHTTPServer 19 | chromium index.html 20 | 21 | To use full size textures, swap the two textures/ and textures.full/ directories. 22 | 23 | ## Note 24 | 25 | The development of HexGL is in a hiatus for now until I find some time and interest to work on it again. 26 | That said, feel free to post issues, patches, or anything to make the game better and I'll gladly review and merge them. 27 | -------------------------------------------------------------------------------- /audio/LICENSE: -------------------------------------------------------------------------------- 1 | Licenses for the sound files 2 | ============================= 3 | 4 | *boost.ogg* 5 | 6 | Created by IFartInUrGeneralDirection and distributed under 7 | Creative Commons 3.0 Attribution 3.0 Unported license. 8 | 9 | *crash.ogg* 10 | Created by qubodup and is published into Public Domain. 11 | 12 | *wind.ogg* 13 | Created by kangaroovindaloo and distributed under 14 | Creative Commons 3.0 Attribution 3.0 Unported license. 15 | 16 | This SFX is further cutted and adjusted by Licson. 17 | 18 | *bg.ogg* 19 | Created by mu6k and is released into Public Domain. 20 | 21 | Further adjusted by Licson. 22 | 23 | *destroyed.ogg* 24 | Created by beman87 and is distributed under Creative Commons Attribution 3.0 Unported license. 25 | 26 | This SFX is further adjusted by Licson. 27 | 28 | All sound files converted to OGG Vorbis by baleboy using VLC Media Player. -------------------------------------------------------------------------------- /audio/bg.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/audio/bg.ogg -------------------------------------------------------------------------------- /audio/boost.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/audio/boost.ogg -------------------------------------------------------------------------------- /audio/crash.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/audio/crash.ogg -------------------------------------------------------------------------------- /audio/destroyed.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/audio/destroyed.ogg -------------------------------------------------------------------------------- /audio/wind.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/audio/wind.ogg -------------------------------------------------------------------------------- /bkcore.coffee/ImageData.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | Loads an image and gives access to pixel data. 3 | 4 | @class bkcore.ImageData 5 | @author Thibaut 'BKcore' Despoulain 6 | ### 7 | class ImageData 8 | 9 | ### 10 | Creates a new ImageData object 11 | 12 | @param path string The path of the image 13 | @param callback function A callback function to be called 14 | once th eimage is loaded 15 | ### 16 | constructor: (path, callback)-> 17 | 18 | @image = new Image 19 | @pixels = null 20 | @canvas = null 21 | @loaded = false 22 | 23 | @image.onload = ()=> 24 | 25 | @canvas = document.createElement('canvas') 26 | @canvas.width = @image.width 27 | @canvas.height = @image.height 28 | 29 | context = @canvas.getContext('2d') 30 | context.drawImage(@image, 0, 0) 31 | 32 | @pixels = context.getImageData(0,0, @canvas.width, @canvas.height) 33 | @loaded = true 34 | 35 | context = null 36 | @canvas = null 37 | @image = null 38 | 39 | callback?.call(@) 40 | 41 | @image.crossOrigin = "anonymous" 42 | @image.src = path 43 | 44 | ### 45 | Gets pixel RGBA data at given index 46 | 47 | @param x int In pixels 48 | @param y int In pixels 49 | @return Object{r,g,b,a} 50 | ### 51 | getPixel: (x, y)-> 52 | 53 | if !@pixels? or x < 0 or y < 0 or x >= @pixels.width or y >= @pixels.height 54 | return {r: 0, g: 0, b:0, a:0} 55 | 56 | i = (y*@pixels.width + x) * 4 57 | 58 | return { 59 | r: @pixels.data[i] 60 | g: @pixels.data[i+1] 61 | b: @pixels.data[i+2] 62 | a: @pixels.data[i+3] 63 | } 64 | 65 | ### 66 | Gets pixel RGBA data at given float index using bilinear interpolation 67 | 68 | @param x float In subpixels 69 | @param y float In subpixels 70 | @return Object{r,g,b,a} 71 | ### 72 | getPixelBilinear: (fx, fy)-> 73 | 74 | x = Math.floor(fx) 75 | y = Math.floor(fy) 76 | rx = fx - x - .5 77 | ry = fy - y - .5 78 | ax = Math.abs(rx) 79 | ay = Math.abs(ry) 80 | dx = if rx < 0 then -1 else 1 81 | dy = if ry < 0 then -1 else 1 82 | 83 | c = @getPixel(x, y) 84 | cx = @getPixel(x+dx, y) 85 | cy = @getPixel(x, y+dy) 86 | cxy = @getPixel(x+dx, y+dy) 87 | 88 | cf1 = [ 89 | (1-ax) * c.r + ax * cx.r 90 | (1-ax) * c.g + ax * cx.g 91 | (1-ax) * c.b + ax * cx.b 92 | (1-ax) * c.a + ax * cx.a 93 | ] 94 | 95 | cf2 = [ 96 | (1-ax) * cy.r + ax * cxy.r 97 | (1-ax) * cy.g + ax * cxy.g 98 | (1-ax) * cy.b + ax * cxy.b 99 | (1-ax) * cy.a + ax * cxy.a 100 | ] 101 | 102 | return { 103 | r: (1-ay) * cf1[0] + ay * cf2[0] 104 | g: (1-ay) * cf1[1] + ay * cf2[1] 105 | b: (1-ay) * cf1[2] + ay * cf2[2] 106 | a: (1-ay) * cf1[3] + ay * cf2[3] 107 | } 108 | 109 | ### 110 | Gets pixel data at given index 111 | as 3-bytes integer (for floating-point textures erzats, from RGB values) 112 | 113 | @param x int In pixels 114 | @param y int In pixels 115 | @return int (R + G*255 + B*255*255) 116 | ### 117 | getPixelF: (x, y)-> 118 | 119 | c = @getPixel(x, y) 120 | return c.r + c.g * 255 + c.b * 255 * 255 121 | 122 | ### 123 | Gets pixel data at given float index using bilinear interpolationas 124 | as 3-bytes integer (for floating-point textures erzats, from RGB values) 125 | 126 | @param x float In subpixels 127 | @param y float In subpixels 128 | @return Object{r,g,b,a} 129 | ### 130 | getPixelFBilinear: (fx, fy)-> 131 | 132 | c = @getPixelBilinear(fx, fy) 133 | return c.r + c.g * 255 + c.b * 255 * 255 134 | 135 | ### 136 | Exports 137 | @package bkcore 138 | ### 139 | exports = exports ? @ 140 | exports.bkcore ||= {} 141 | exports.bkcore.ImageData = ImageData -------------------------------------------------------------------------------- /bkcore.coffee/ImageData.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.4.0 2 | 3 | /* 4 | Loads an image and gives access to pixel data. 5 | 6 | @class bkcore.ImageData 7 | @author Thibaut 'BKcore' Despoulain 8 | */ 9 | 10 | 11 | (function() { 12 | var ImageData, exports; 13 | 14 | ImageData = (function() { 15 | /* 16 | Creates a new ImageData object 17 | 18 | @param path string The path of the image 19 | @param callback function A callback function to be called 20 | once th eimage is loaded 21 | */ 22 | 23 | function ImageData(path, callback) { 24 | var _this = this; 25 | this.image = new Image; 26 | this.pixels = null; 27 | this.canvas = null; 28 | this.loaded = false; 29 | this.image.onload = function() { 30 | var context; 31 | _this.canvas = document.createElement('canvas'); 32 | _this.canvas.width = _this.image.width; 33 | _this.canvas.height = _this.image.height; 34 | context = _this.canvas.getContext('2d'); 35 | context.drawImage(_this.image, 0, 0); 36 | _this.pixels = context.getImageData(0, 0, _this.canvas.width, _this.canvas.height); 37 | _this.loaded = true; 38 | context = null; 39 | _this.canvas = null; 40 | _this.image = null; 41 | return callback != null ? callback.call(_this) : void 0; 42 | }; 43 | this.image.crossOrigin = "anonymous"; 44 | this.image.src = path; 45 | } 46 | 47 | /* 48 | Gets pixel RGBA data at given index 49 | 50 | @param x int In pixels 51 | @param y int In pixels 52 | @return Object{r,g,b,a} 53 | */ 54 | 55 | 56 | ImageData.prototype.getPixel = function(x, y) { 57 | var i; 58 | if (!(this.pixels != null) || x < 0 || y < 0 || x >= this.pixels.width || y >= this.pixels.height) { 59 | return { 60 | r: 0, 61 | g: 0, 62 | b: 0, 63 | a: 0 64 | }; 65 | } 66 | i = (y * this.pixels.width + x) * 4; 67 | return { 68 | r: this.pixels.data[i], 69 | g: this.pixels.data[i + 1], 70 | b: this.pixels.data[i + 2], 71 | a: this.pixels.data[i + 3] 72 | }; 73 | }; 74 | 75 | /* 76 | Gets pixel RGBA data at given float index using bilinear interpolation 77 | 78 | @param x float In subpixels 79 | @param y float In subpixels 80 | @return Object{r,g,b,a} 81 | */ 82 | 83 | 84 | ImageData.prototype.getPixelBilinear = function(fx, fy) { 85 | var ax, ay, c, cf1, cf2, cx, cxy, cy, dx, dy, rx, ry, x, y; 86 | x = Math.floor(fx); 87 | y = Math.floor(fy); 88 | rx = fx - x - .5; 89 | ry = fy - y - .5; 90 | ax = Math.abs(rx); 91 | ay = Math.abs(ry); 92 | dx = rx < 0 ? -1 : 1; 93 | dy = ry < 0 ? -1 : 1; 94 | c = this.getPixel(x, y); 95 | cx = this.getPixel(x + dx, y); 96 | cy = this.getPixel(x, y + dy); 97 | cxy = this.getPixel(x + dx, y + dy); 98 | cf1 = [(1 - ax) * c.r + ax * cx.r, (1 - ax) * c.g + ax * cx.g, (1 - ax) * c.b + ax * cx.b, (1 - ax) * c.a + ax * cx.a]; 99 | cf2 = [(1 - ax) * cy.r + ax * cxy.r, (1 - ax) * cy.g + ax * cxy.g, (1 - ax) * cy.b + ax * cxy.b, (1 - ax) * cy.a + ax * cxy.a]; 100 | return { 101 | r: (1 - ay) * cf1[0] + ay * cf2[0], 102 | g: (1 - ay) * cf1[1] + ay * cf2[1], 103 | b: (1 - ay) * cf1[2] + ay * cf2[2], 104 | a: (1 - ay) * cf1[3] + ay * cf2[3] 105 | }; 106 | }; 107 | 108 | /* 109 | Gets pixel data at given index 110 | as 3-bytes integer (for floating-point textures erzats, from RGB values) 111 | 112 | @param x int In pixels 113 | @param y int In pixels 114 | @return int (R + G*255 + B*255*255) 115 | */ 116 | 117 | 118 | ImageData.prototype.getPixelF = function(x, y) { 119 | var c; 120 | c = this.getPixel(x, y); 121 | return c.r + c.g * 255 + c.b * 255 * 255; 122 | }; 123 | 124 | /* 125 | Gets pixel data at given float index using bilinear interpolationas 126 | as 3-bytes integer (for floating-point textures erzats, from RGB values) 127 | 128 | @param x float In subpixels 129 | @param y float In subpixels 130 | @return Object{r,g,b,a} 131 | */ 132 | 133 | 134 | ImageData.prototype.getPixelFBilinear = function(fx, fy) { 135 | var c; 136 | c = this.getPixelBilinear(fx, fy); 137 | return c.r + c.g * 255 + c.b * 255 * 255; 138 | }; 139 | 140 | return ImageData; 141 | 142 | })(); 143 | 144 | /* 145 | Exports 146 | @package bkcore 147 | */ 148 | 149 | 150 | exports = exports != null ? exports : this; 151 | 152 | exports.bkcore || (exports.bkcore = {}); 153 | 154 | exports.bkcore.ImageData = ImageData; 155 | 156 | }).call(this); 157 | -------------------------------------------------------------------------------- /bkcore.coffee/Timer.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | new Date().getTime() wrapper to use as timer. 3 | 4 | @class bkcore.Timer 5 | @author Thibaut 'BKcore' Despoulain 6 | ### 7 | class Timer 8 | 9 | ### 10 | Creates a new timer, inactive by default. 11 | Call Timer.start() to activate. 12 | ### 13 | constructor: ()-> 14 | 15 | @time = 16 | start: 0 17 | current: 0 18 | previous: 0 19 | elapsed: 0 20 | delta: 0 21 | 22 | @active = false 23 | 24 | ### 25 | Starts/restarts the timer. 26 | ### 27 | start: ()-> 28 | 29 | now = (new Date).getTime() 30 | 31 | @time.start = now 32 | @time.current = now 33 | @time.previous = now 34 | @time.elapsed = 0 35 | @time.delta = 0 36 | 37 | @active = true 38 | 39 | ### 40 | Pauses(true)/Unpauses(false) the timer. 41 | 42 | @param bool Do pause 43 | ### 44 | pause: (doPause)-> 45 | 46 | @active = not doPause 47 | 48 | ### 49 | Update method to be called inside a RAF loop 50 | ### 51 | update: ()-> 52 | 53 | if not @active then return 54 | 55 | now = (new Date).getTime() 56 | 57 | @time.current = now 58 | @time.elapsed = @time.current - @time.start 59 | @time.delta = now - @time.previous 60 | @time.previous = now 61 | 62 | ### 63 | Returns a formatted version of the current elapsed time using msToTime(). 64 | ### 65 | getElapsedTime: ()-> 66 | 67 | return @constructor.msToTime(@time.elapsed) 68 | 69 | ### 70 | Formats a millisecond integer into a h/m/s/ms object 71 | 72 | @param x int In milliseconds 73 | @return Object{h,m,s,ms} 74 | ### 75 | @msToTime: (t)-> 76 | 77 | ms = t%1000 78 | s = Math.floor((t/1000)%60) 79 | m = Math.floor((t/60000)%60) 80 | h = Math.floor(t/3600000) 81 | 82 | return {h:h, m:m, s:s, ms,ms} 83 | 84 | ### 85 | Formats a millisecond integer into a h/m/s/ms object with prefix zeros 86 | 87 | @param x int In milliseconds 88 | @return Object{h,m,s,ms} 89 | ### 90 | @msToTimeString: (t)-> 91 | 92 | time = @msToTime(t) 93 | 94 | time.h = @zfill(time.h, 2) 95 | time.m = @zfill(time.m, 2) 96 | time.s = @zfill(time.s, 2) 97 | time.ms = @zfill(time.ms, 4) 98 | 99 | return time 100 | 101 | ### 102 | Convert given integer to string and fill with heading zeros 103 | 104 | @param num int Number to convert/fill 105 | @param size int Desired string size 106 | ### 107 | @zfill: (num, size)-> 108 | 109 | len = size - num.toString().length 110 | return if len > 0 then new Array(len+1).join('0') + num else num.toString() 111 | 112 | ### 113 | Exports 114 | @package bkcore 115 | ### 116 | exports = exports ? @ 117 | exports.bkcore ||= {} 118 | exports.bkcore.Timer = Timer -------------------------------------------------------------------------------- /bkcore.coffee/Timer.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.4.0 2 | 3 | /* 4 | new Date().getTime() wrapper to use as timer. 5 | 6 | @class bkcore.Timer 7 | @author Thibaut 'BKcore' Despoulain 8 | */ 9 | 10 | 11 | (function() { 12 | var Timer, exports; 13 | 14 | Timer = (function() { 15 | /* 16 | Creates a new timer, inactive by default. 17 | Call Timer.start() to activate. 18 | */ 19 | 20 | function Timer() { 21 | this.time = { 22 | start: 0, 23 | current: 0, 24 | previous: 0, 25 | elapsed: 0, 26 | delta: 0 27 | }; 28 | this.active = false; 29 | } 30 | 31 | /* 32 | Starts/restarts the timer. 33 | */ 34 | 35 | 36 | Timer.prototype.start = function() { 37 | var now; 38 | now = (new Date).getTime(); 39 | this.time.start = now; 40 | this.time.current = now; 41 | this.time.previous = now; 42 | this.time.elapsed = 0; 43 | this.time.delta = 0; 44 | return this.active = true; 45 | }; 46 | 47 | /* 48 | Pauses(true)/Unpauses(false) the timer. 49 | 50 | @param bool Do pause 51 | */ 52 | 53 | 54 | Timer.prototype.pause = function(doPause) { 55 | return this.active = !doPause; 56 | }; 57 | 58 | /* 59 | Update method to be called inside a RAF loop 60 | */ 61 | 62 | 63 | Timer.prototype.update = function() { 64 | var now; 65 | if (!this.active) { 66 | return; 67 | } 68 | now = (new Date).getTime(); 69 | this.time.current = now; 70 | this.time.elapsed = this.time.current - this.time.start; 71 | this.time.delta = now - this.time.previous; 72 | return this.time.previous = now; 73 | }; 74 | 75 | /* 76 | Returns a formatted version of the current elapsed time using msToTime(). 77 | */ 78 | 79 | 80 | Timer.prototype.getElapsedTime = function() { 81 | return this.constructor.msToTime(this.time.elapsed); 82 | }; 83 | 84 | /* 85 | Formats a millisecond integer into a h/m/s/ms object 86 | 87 | @param x int In milliseconds 88 | @return Object{h,m,s,ms} 89 | */ 90 | 91 | 92 | Timer.msToTime = function(t) { 93 | var h, m, ms, s; 94 | ms = t % 1000; 95 | s = Math.floor((t / 1000) % 60); 96 | m = Math.floor((t / 60000) % 60); 97 | h = Math.floor(t / 3600000); 98 | return { 99 | h: h, 100 | m: m, 101 | s: s, 102 | ms: ms, 103 | ms: ms 104 | }; 105 | }; 106 | 107 | /* 108 | Formats a millisecond integer into a h/m/s/ms object with prefix zeros 109 | 110 | @param x int In milliseconds 111 | @return Object{h,m,s,ms} 112 | */ 113 | 114 | 115 | Timer.msToTimeString = function(t) { 116 | var time; 117 | time = this.msToTime(t); 118 | time.h = this.zfill(time.h, 2); 119 | time.m = this.zfill(time.m, 2); 120 | time.s = this.zfill(time.s, 2); 121 | time.ms = this.zfill(time.ms, 4); 122 | return time; 123 | }; 124 | 125 | /* 126 | Convert given integer to string and fill with heading zeros 127 | 128 | @param num int Number to convert/fill 129 | @param size int Desired string size 130 | */ 131 | 132 | 133 | Timer.zfill = function(num, size) { 134 | var len; 135 | len = size - num.toString().length; 136 | if (len > 0) { 137 | return new Array(len + 1).join('0') + num; 138 | } else { 139 | return num.toString(); 140 | } 141 | }; 142 | 143 | return Timer; 144 | 145 | })(); 146 | 147 | /* 148 | Exports 149 | @package bkcore 150 | */ 151 | 152 | 153 | exports = exports != null ? exports : this; 154 | 155 | exports.bkcore || (exports.bkcore = {}); 156 | 157 | exports.bkcore.Timer = Timer; 158 | 159 | }).call(this); 160 | -------------------------------------------------------------------------------- /bkcore.coffee/Utils.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | Various useful methods 3 | 4 | @class bkcore.Utils 5 | @author Thibaut 'BKcore' Despoulain 6 | ### 7 | class Utils 8 | 9 | ### 10 | Creates a bkcore.threejs.Shaders["normalV"|"normal"] material 11 | with given parameters 12 | ### 13 | @createNormalMaterial = (opts)-> 14 | 15 | opts ?= {} 16 | opts.ambient ?= 0x444444 17 | opts.normalScale ?= 1.0 18 | opts.reflectivity ?= 0.9 19 | opts.shininess ?= 42 20 | opts.metal ?= false 21 | 22 | shadername = if opts.perPixel then "normalV" else "normal" 23 | shader = bkcore.threejs.Shaders[shadername] 24 | uniforms = THREE.UniformsUtils.clone(shader.uniforms) 25 | 26 | uniforms["enableDiffuse"].value = true 27 | uniforms["enableSpecular"].value = true 28 | uniforms["enableReflection"].value = !!opts.cube 29 | uniforms["tNormal"].texture = opts.normal 30 | uniforms["tDiffuse"].texture = opts.diffuse 31 | uniforms["tSpecular"].texture = opts.specular 32 | uniforms["uAmbientColor"].value.setHex(opts.ambient) 33 | uniforms["uAmbientColor"].value.convertGammaToLinear() 34 | uniforms["uNormalScale"].value = opts.normalScale 35 | 36 | if opts.cube? 37 | uniforms["tCube"].texture = opts.cube 38 | uniforms["uReflectivity"].value = opts.reflectivity 39 | 40 | parameters = { 41 | fragmentShader: shader.fragmentShader 42 | vertexShader: shader.vertexShader 43 | uniforms: uniforms 44 | lights: true 45 | fog: false 46 | } 47 | 48 | material = new THREE.ShaderMaterial(parameters) 49 | material.perPixel = true 50 | material.metal = opts.metal 51 | 52 | return material 53 | 54 | ### 55 | Projects an object origin vector to screen using given camera 56 | @param THREE.Object3D object The object which origin you want to project 57 | @param THREE.Camera camera The camera of the projection 58 | @return THEE.Vector3 Projected verctor 59 | ### 60 | @projectOnScreen: (object, camera)-> 61 | 62 | mat = new THREE.Matrix4() 63 | mat.multiply(camera.matrixWorldInverse, object.matrixWorld) 64 | mat.multiply(camera.projectionMatrix , mat) 65 | 66 | c = mat.n44 67 | lPos = new THREE.Vector3(mat.n14/c, mat.n24/c, mat.n34/c) 68 | return lPos.multiplyScalar(0.5).addScalar(0.5) 69 | 70 | ### 71 | Get an url parameter 72 | @param String name Parameter slug 73 | @return Mixed 74 | ### 75 | @URLParameters: null 76 | @getURLParameter: (name)-> 77 | 78 | if !@URLParameters? 79 | @URLParameters = {} 80 | window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, (m, key, val)=> 81 | @URLParameters[key] = val 82 | ) 83 | 84 | return @URLParameters[name] 85 | 86 | ### 87 | Get top offset of an element 88 | @param obj HTMLElement 89 | ### 90 | @getOffsetTop: (obj)-> 91 | 92 | curtop = obj.offsetTop 93 | 94 | if obj.offsetParent 95 | while obj = obj.offsetParent 96 | curtop += obj.offsetTop 97 | 98 | return curtop 99 | 100 | ### 101 | Scrolls page to given element id 102 | @param string id The ID of the element 103 | ### 104 | @scrollTo: (id)-> 105 | 106 | window.scroll(0, @getOffsetTop(document.getElementById(id))) 107 | 108 | ### 109 | Add or remove a class from an element 110 | @param string id [description] 111 | @param string cssclass [description] 112 | @param bool active [description] 113 | ### 114 | @updateClass: (id, cssclass, active)-> 115 | 116 | e = document.getElementById(id) 117 | return unless e? 118 | 119 | if active 120 | e.classList.add(cssclass) 121 | else 122 | e.classList.remove(cssclass) 123 | 124 | ### 125 | Performs an XMLHttpRequest 126 | @param string url [description] 127 | @param bool postData true = POST, false = GET 128 | @param {Function} callback [description] 129 | @param {Object} data [description] 130 | ### 131 | @request: (url, postData, callback, data)-> 132 | 133 | XMLHttpFactories = [ 134 | ()-> return new XMLHttpRequest() 135 | ()-> return new ActiveXObject("Msxml2.XMLHTTP") 136 | ()-> return new ActiveXObject("Msxml3.XMLHTTP") 137 | ()-> return new ActiveXObject("Microsoft.XMLHTTP") 138 | ] 139 | 140 | createXMLHTTPObject = () -> 141 | 142 | xmlhttp = false 143 | 144 | for i in [0..XMLHttpFactories.length] 145 | try 146 | xmlhttp = XMLHttpFactories[i]() 147 | catch e 148 | continue 149 | break 150 | 151 | return xmlhttp 152 | 153 | req = createXMLHTTPObject() 154 | return unless req? 155 | 156 | method = if postData? then "POST" else "GET" 157 | 158 | qdata = "o=bk" 159 | if data? 160 | for i, val of data 161 | qdata += "&"+i+"="+val 162 | url += "?"+qdata if postData? 163 | 164 | req.open(method,url,true) 165 | 166 | if postData? 167 | req.setRequestHeader('Content-type','application/x-www-form-urlencoded') 168 | 169 | req.onreadystatechange = () -> 170 | return unless req.readyState is 4 171 | return unless req.status is 200 or req.status is 304 172 | callback?(req) 173 | 174 | req.send(qdata) 175 | 176 | return req 177 | 178 | ### 179 | Checks whether the device supports Touch input 180 | ### 181 | @isTouchDevice: ()-> 182 | 183 | return ('ontouchstart' of window) or 184 | (navigator.MaxTouchPoints > 0) or 185 | (navigator.msMaxTouchPoints > 0) 186 | 187 | ### 188 | Exports 189 | @package bkcore 190 | ### 191 | exports = exports ? @ 192 | exports.bkcore ||= {} 193 | exports.bkcore.Utils = Utils -------------------------------------------------------------------------------- /bkcore.coffee/controllers/GamepadController.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | GamepadController (Orientation + buttons) for touch devices 3 | 4 | @class bkcore.GamepadController 5 | @author Mahesh Kulkarni 6 | ### 7 | class GamepadController 8 | 9 | @isCompatible: -> 10 | return ('getGamepads' of navigator) or ('webkitGetGamepads' of navigator) 11 | 12 | ### 13 | Creates a new GamepadController 14 | ### 15 | constructor: (@buttonPressCallback) -> 16 | @active = true 17 | @leftStickArray = [] 18 | @rightStickArray = [] 19 | 20 | ### 21 | @public 22 | ### 23 | updateAvailable: -> 24 | return false if not @active 25 | gamepads = if navigator.getGamepads then navigator.getGamepads() else navigator.webkitGetGamepads() 26 | return false if not gamepads?[0] 27 | gp = gamepads[0] 28 | return if not gp.buttons? or not gp.axes? 29 | @lstickx = gp.axes[0] 30 | accel = gp.buttons[0] 31 | lt = gp.buttons[6] 32 | rt = gp.buttons[7] 33 | sel = gp.buttons[8] 34 | # API fallback 35 | @acceleration = accel.pressed ? accel 36 | @ltrigger = lt.pressed ? lt 37 | @rtrigger = rt.pressed ? rt 38 | @select = sel.pressed ? sel 39 | @buttonPressCallback this 40 | true 41 | 42 | exports = exports ? @ 43 | exports.bkcore ||= {} 44 | exports.bkcore.controllers ||= {} 45 | exports.bkcore.controllers.GamepadController = GamepadController 46 | -------------------------------------------------------------------------------- /bkcore.coffee/controllers/GamepadController.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.6.3 2 | /* 3 | GamepadController (Orientation + buttons) for touch devices 4 | 5 | @class bkcore.GamepadController 6 | @author Mahesh Kulkarni 7 | */ 8 | 9 | 10 | (function() { 11 | var GamepadController, exports, _base; 12 | 13 | GamepadController = (function() { 14 | GamepadController.isCompatible = function() { 15 | return ('getGamepads' in navigator) || ('webkitGetGamepads' in navigator); 16 | }; 17 | 18 | /* 19 | Creates a new GamepadController 20 | */ 21 | 22 | 23 | function GamepadController(buttonPressCallback) { 24 | this.buttonPressCallback = buttonPressCallback; 25 | this.active = true; 26 | this.leftStickArray = []; 27 | this.rightStickArray = []; 28 | } 29 | 30 | /* 31 | @public 32 | */ 33 | 34 | 35 | GamepadController.prototype.updateAvailable = function() { 36 | var accel, gamepads, gp, lt, rt, sel, _ref, _ref1, _ref2, _ref3; 37 | if (!this.active) { 38 | return false; 39 | } 40 | gamepads = navigator.getGamepads ? navigator.getGamepads() : navigator.webkitGetGamepads(); 41 | if (!(gamepads != null ? gamepads[0] : void 0)) { 42 | return false; 43 | } 44 | gp = gamepads[0]; 45 | if ((gp.buttons == null) || (gp.axes == null)) { 46 | return; 47 | } 48 | this.lstickx = gp.axes[0]; 49 | accel = gp.buttons[0]; 50 | lt = gp.buttons[6]; 51 | rt = gp.buttons[7]; 52 | sel = gp.buttons[8]; 53 | this.acceleration = (_ref = accel.pressed) != null ? _ref : accel; 54 | this.ltrigger = (_ref1 = lt.pressed) != null ? _ref1 : lt; 55 | this.rtrigger = (_ref2 = rt.pressed) != null ? _ref2 : rt; 56 | this.select = (_ref3 = sel.pressed) != null ? _ref3 : sel; 57 | this.buttonPressCallback(this); 58 | return true; 59 | }; 60 | 61 | return GamepadController; 62 | 63 | })(); 64 | 65 | exports = exports != null ? exports : this; 66 | 67 | exports.bkcore || (exports.bkcore = {}); 68 | 69 | (_base = exports.bkcore).controllers || (_base.controllers = {}); 70 | 71 | exports.bkcore.controllers.GamepadController = GamepadController; 72 | 73 | }).call(this); 74 | -------------------------------------------------------------------------------- /bkcore.coffee/controllers/OrientationController.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | OrientationController (Orientation + buttons) for touch devices 3 | 4 | @class bkcore.OrientationController 5 | @author Thibaut 'BKcore' Despoulain 6 | ### 7 | class OrientationController 8 | 9 | @isCompatible: -> 10 | return ('DeviceOrientationEvent' of window) 11 | 12 | ### 13 | Creates a new OrientationController 14 | 15 | @param dom DOMElement The element that will listen to touch events 16 | @param registerTouch bool Enable touch detection 17 | @param touchCallback function Callback for touches 18 | ### 19 | constructor: (@dom, @registerTouch=true, @touchCallback=null) -> 20 | @active = true 21 | @alpha = 0.0 22 | @beta = 0.0 23 | @gamma = 0.0 24 | @dalpha = null 25 | @dbeta = null 26 | @dgamma = null 27 | @touches = null 28 | 29 | window.addEventListener('deviceorientation', ((e)=> @orientationChange(e)), false) 30 | if @registerTouch 31 | @dom.addEventListener('touchstart', ((e)=> @touchStart(e)), false) 32 | @dom.addEventListener('touchend', ((e)=> @touchEnd(e)), false) 33 | 34 | ### 35 | @private 36 | ### 37 | orientationChange: (event) -> 38 | return if not @active 39 | if(@dalpha == null) 40 | console.log "calbrate", event.beta 41 | @dalpha = event.alpha 42 | @dbeta = event.beta 43 | @dgamma = event.gamma 44 | @alpha = event.alpha - @dalpha 45 | @beta = event.beta - @dbeta 46 | @gamma = event.gamma - @dgamma 47 | false 48 | 49 | ### 50 | @private 51 | ### 52 | touchStart: (event) -> 53 | return if not @active 54 | for touch in event.changedTouches 55 | @touchCallback?(on, touch, event) 56 | @touches = event.touches 57 | false 58 | 59 | ### 60 | @private 61 | ### 62 | touchEnd: (event) -> 63 | return if not @active 64 | for touch in event.changedTouches 65 | @touchCallback?(on, touch, event) 66 | @touches = event.touches 67 | false 68 | 69 | exports = exports ? @ 70 | exports.bkcore ||= {} 71 | exports.bkcore.controllers ||= {} 72 | exports.bkcore.controllers.OrientationController = OrientationController -------------------------------------------------------------------------------- /bkcore.coffee/controllers/OrientationController.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.4.0 2 | 3 | /* 4 | OrientationController (Orientation + buttons) for touch devices 5 | 6 | @class bkcore.OrientationController 7 | @author Thibaut 'BKcore' Despoulain 8 | */ 9 | 10 | 11 | (function() { 12 | var OrientationController, exports, _base; 13 | 14 | OrientationController = (function() { 15 | 16 | OrientationController.isCompatible = function() { 17 | return 'DeviceOrientationEvent' in window; 18 | }; 19 | 20 | /* 21 | Creates a new OrientationController 22 | 23 | @param dom DOMElement The element that will listen to touch events 24 | @param registerTouch bool Enable touch detection 25 | @param touchCallback function Callback for touches 26 | */ 27 | 28 | 29 | function OrientationController(dom, registerTouch, touchCallback) { 30 | var _this = this; 31 | this.dom = dom; 32 | this.registerTouch = registerTouch != null ? registerTouch : true; 33 | this.touchCallback = touchCallback != null ? touchCallback : null; 34 | this.active = true; 35 | this.alpha = 0.0; 36 | this.beta = 0.0; 37 | this.gamma = 0.0; 38 | this.dalpha = null; 39 | this.dbeta = null; 40 | this.dgamma = null; 41 | this.touches = null; 42 | window.addEventListener('deviceorientation', (function(e) { 43 | return _this.orientationChange(e); 44 | }), false); 45 | if (this.registerTouch) { 46 | this.dom.addEventListener('touchstart', (function(e) { 47 | return _this.touchStart(e); 48 | }), false); 49 | this.dom.addEventListener('touchend', (function(e) { 50 | return _this.touchEnd(e); 51 | }), false); 52 | } 53 | } 54 | 55 | /* 56 | @private 57 | */ 58 | 59 | 60 | OrientationController.prototype.orientationChange = function(event) { 61 | if (!this.active) { 62 | return; 63 | } 64 | if (this.dalpha === null) { 65 | console.log("calbrate", event.beta); 66 | this.dalpha = event.alpha; 67 | this.dbeta = event.beta; 68 | this.dgamma = event.gamma; 69 | } 70 | this.alpha = event.alpha - this.dalpha; 71 | this.beta = event.beta - this.dbeta; 72 | this.gamma = event.gamma - this.dgamma; 73 | return false; 74 | }; 75 | 76 | /* 77 | @private 78 | */ 79 | 80 | 81 | OrientationController.prototype.touchStart = function(event) { 82 | var touch, _i, _len, _ref; 83 | if (!this.active) { 84 | return; 85 | } 86 | _ref = event.changedTouches; 87 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 88 | touch = _ref[_i]; 89 | if (typeof this.touchCallback === "function") { 90 | this.touchCallback(true, touch, event); 91 | } 92 | } 93 | this.touches = event.touches; 94 | return false; 95 | }; 96 | 97 | /* 98 | @private 99 | */ 100 | 101 | 102 | OrientationController.prototype.touchEnd = function(event) { 103 | var touch, _i, _len, _ref; 104 | if (!this.active) { 105 | return; 106 | } 107 | _ref = event.changedTouches; 108 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 109 | touch = _ref[_i]; 110 | if (typeof this.touchCallback === "function") { 111 | this.touchCallback(true, touch, event); 112 | } 113 | } 114 | this.touches = event.touches; 115 | return false; 116 | }; 117 | 118 | return OrientationController; 119 | 120 | })(); 121 | 122 | exports = exports != null ? exports : this; 123 | 124 | exports.bkcore || (exports.bkcore = {}); 125 | 126 | (_base = exports.bkcore).controllers || (_base.controllers = {}); 127 | 128 | exports.bkcore.controllers.OrientationController = OrientationController; 129 | 130 | }).call(this); 131 | -------------------------------------------------------------------------------- /bkcore.coffee/controllers/TouchController.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | TouchController (stick + buttons) for touch devices 3 | Based on the touch demo by Seb Lee-Delisle 4 | 5 | @class bkcore.controllers.TouchController 6 | @author Thibaut 'BKcore' Despoulain 7 | ### 8 | class TouchController 9 | 10 | @isCompatible: -> 11 | return ('ontouchstart' of document.documentElement); 12 | 13 | ### 14 | Creates a new TouchController 15 | 16 | @param dom DOMElement The element that will listen to touch events 17 | @param stickMargin int The left margin in px for stick detection 18 | @param buttonCallback function Callback for non-stick touches 19 | ### 20 | constructor: (@dom, @stickMargin=200, @buttonCallback=null) -> 21 | @active = true 22 | @touches = null 23 | @stickID = -1 24 | @stickPos = new Vec2(0, 0) 25 | @stickStartPos = new Vec2(0, 0) 26 | @stickVector = new Vec2(0, 0) 27 | 28 | @dom.addEventListener('touchstart', ((e)=> @touchStart(e)), false) 29 | @dom.addEventListener('touchmove', ((e)=> @touchMove(e)), false) 30 | @dom.addEventListener('touchend', ((e)=> @touchEnd(e)), false) 31 | 32 | ### 33 | @private 34 | ### 35 | touchStart: (event) -> 36 | return if not @active 37 | for touch in event.changedTouches 38 | if @stickID < 0 and touch.clientX < @stickMargin 39 | @stickID = touch.identifier 40 | @stickStartPos.set(touch.clientX, touch.clientY) 41 | @stickPos.copy(@stickStartPos) 42 | @stickVector.set(0, 0) 43 | continue 44 | else 45 | @buttonCallback?(on, touch, event) 46 | @touches = event.touches 47 | false 48 | 49 | ### 50 | @private 51 | ### 52 | touchMove: (event) -> 53 | event.preventDefault() 54 | return if not @active 55 | for touch in event.changedTouches 56 | if @stickID is touch.identifier and touch.clientX < @stickMargin 57 | @stickPos.set(touch.clientX, touch.clientY) 58 | @stickVector.copy(@stickPos).substract(@stickStartPos) 59 | break 60 | @touches = event.touches 61 | false 62 | 63 | ### 64 | @private 65 | ### 66 | touchEnd: (event) -> 67 | return if not @active 68 | @touches = event.touches 69 | for touch in event.changedTouches 70 | if @stickID is touch.identifier 71 | @stickID = -1 72 | @stickVector.set(0, 0) 73 | break 74 | else 75 | @buttonCallback?(off, touch, event) 76 | false 77 | 78 | ### 79 | Internal class used for vector2 80 | @class Vec2 81 | @private 82 | ### 83 | class Vec2 84 | 85 | constructor: (@x = 0, @y = 0) -> 86 | 87 | substract: (vec) -> 88 | @x -= vec.x 89 | @y -= vec.y 90 | @ 91 | 92 | copy: (vec) -> 93 | @x = vec.x 94 | @y = vec.y 95 | @ 96 | 97 | set: (x, y) -> 98 | @x = x 99 | @y = y 100 | @ 101 | 102 | ### 103 | Exports 104 | @package bkcore 105 | ### 106 | exports = exports ? @ 107 | exports.bkcore ||= {} 108 | exports.bkcore.controllers ||= {} 109 | exports.bkcore.controllers.TouchController = TouchController -------------------------------------------------------------------------------- /bkcore.coffee/controllers/TouchController.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.7.1 2 | 3 | /* 4 | TouchController (stick + buttons) for touch devices 5 | Based on the touch demo by Seb Lee-Delisle 6 | 7 | @class bkcore.controllers.TouchController 8 | @author Thibaut 'BKcore' Despoulain 9 | */ 10 | 11 | (function() { 12 | var TouchController, Vec2, exports, _base; 13 | 14 | TouchController = (function() { 15 | TouchController.isCompatible = function() { 16 | return 'ontouchstart' in document.documentElement; 17 | }; 18 | 19 | 20 | /* 21 | Creates a new TouchController 22 | 23 | @param dom DOMElement The element that will listen to touch events 24 | @param stickMargin int The left margin in px for stick detection 25 | @param buttonCallback function Callback for non-stick touches 26 | */ 27 | 28 | function TouchController(dom, stickMargin, buttonCallback) { 29 | this.dom = dom; 30 | this.stickMargin = stickMargin != null ? stickMargin : 200; 31 | this.buttonCallback = buttonCallback != null ? buttonCallback : null; 32 | this.active = true; 33 | this.touches = null; 34 | this.stickID = -1; 35 | this.stickPos = new Vec2(0, 0); 36 | this.stickStartPos = new Vec2(0, 0); 37 | this.stickVector = new Vec2(0, 0); 38 | this.dom.addEventListener('touchstart', ((function(_this) { 39 | return function(e) { 40 | return _this.touchStart(e); 41 | }; 42 | })(this)), false); 43 | this.dom.addEventListener('touchmove', ((function(_this) { 44 | return function(e) { 45 | return _this.touchMove(e); 46 | }; 47 | })(this)), false); 48 | this.dom.addEventListener('touchend', ((function(_this) { 49 | return function(e) { 50 | return _this.touchEnd(e); 51 | }; 52 | })(this)), false); 53 | } 54 | 55 | 56 | /* 57 | @private 58 | */ 59 | 60 | TouchController.prototype.touchStart = function(event) { 61 | var touch, _i, _len, _ref; 62 | if (!this.active) { 63 | return; 64 | } 65 | _ref = event.changedTouches; 66 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 67 | touch = _ref[_i]; 68 | if (this.stickID < 0 && touch.clientX < this.stickMargin) { 69 | this.stickID = touch.identifier; 70 | this.stickStartPos.set(touch.clientX, touch.clientY); 71 | this.stickPos.copy(this.stickStartPos); 72 | this.stickVector.set(0, 0); 73 | continue; 74 | } else { 75 | if (typeof this.buttonCallback === "function") { 76 | this.buttonCallback(true, touch, event); 77 | } 78 | } 79 | } 80 | this.touches = event.touches; 81 | return false; 82 | }; 83 | 84 | 85 | /* 86 | @private 87 | */ 88 | 89 | TouchController.prototype.touchMove = function(event) { 90 | var touch, _i, _len, _ref; 91 | event.preventDefault(); 92 | if (!this.active) { 93 | return; 94 | } 95 | _ref = event.changedTouches; 96 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 97 | touch = _ref[_i]; 98 | if (this.stickID === touch.identifier && touch.clientX < this.stickMargin) { 99 | this.stickPos.set(touch.clientX, touch.clientY); 100 | this.stickVector.copy(this.stickPos).substract(this.stickStartPos); 101 | break; 102 | } 103 | } 104 | this.touches = event.touches; 105 | return false; 106 | }; 107 | 108 | 109 | /* 110 | @private 111 | */ 112 | 113 | TouchController.prototype.touchEnd = function(event) { 114 | var touch, _i, _len, _ref; 115 | if (!this.active) { 116 | return; 117 | } 118 | this.touches = event.touches; 119 | _ref = event.changedTouches; 120 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 121 | touch = _ref[_i]; 122 | if (this.stickID === touch.identifier) { 123 | this.stickID = -1; 124 | this.stickVector.set(0, 0); 125 | break; 126 | } else { 127 | if (typeof this.buttonCallback === "function") { 128 | this.buttonCallback(false, touch, event); 129 | } 130 | } 131 | } 132 | return false; 133 | }; 134 | 135 | return TouchController; 136 | 137 | })(); 138 | 139 | 140 | /* 141 | Internal class used for vector2 142 | @class Vec2 143 | @private 144 | */ 145 | 146 | Vec2 = (function() { 147 | function Vec2(x, y) { 148 | this.x = x != null ? x : 0; 149 | this.y = y != null ? y : 0; 150 | } 151 | 152 | Vec2.prototype.substract = function(vec) { 153 | this.x -= vec.x; 154 | this.y -= vec.y; 155 | return this; 156 | }; 157 | 158 | Vec2.prototype.copy = function(vec) { 159 | this.x = vec.x; 160 | this.y = vec.y; 161 | return this; 162 | }; 163 | 164 | Vec2.prototype.set = function(x, y) { 165 | this.x = x; 166 | this.y = y; 167 | return this; 168 | }; 169 | 170 | return Vec2; 171 | 172 | })(); 173 | 174 | 175 | /* 176 | Exports 177 | @package bkcore 178 | */ 179 | 180 | exports = exports != null ? exports : this; 181 | 182 | exports.bkcore || (exports.bkcore = {}); 183 | 184 | (_base = exports.bkcore).controllers || (_base.controllers = {}); 185 | 186 | exports.bkcore.controllers.TouchController = TouchController; 187 | 188 | }).call(this); 189 | -------------------------------------------------------------------------------- /bkcore.coffee/tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CoffeeScript Tests 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /bkcore.coffee/threejs/Particles.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | Particle system wrapper/helper 3 | 4 | @class bkcore.threejs.Particles 5 | @author Thibaut 'BKcore' Despoulain 6 | ### 7 | class Particles 8 | 9 | ### 10 | Creates a new particle system using given parameters 11 | 12 | @param {Object{max, spawnRate, spawn, velocity, randomness, 13 | force, spawnRadius, life, friction, color, color2, tint, 14 | texture, size, blending, depthTest, transparent, opacity}} opts 15 | ### 16 | constructor: (opts)-> 17 | 18 | @black = new THREE.Color(0x000000) 19 | @white = new THREE.Color(0xffffff) 20 | 21 | @material = new THREE.ParticleBasicMaterial( 22 | color: opts.tint ? 0xffffff 23 | map: opts.texture ? null 24 | size: opts.size ? 4 25 | blending: opts.blending ? THREE.AdditiveBlending 26 | depthTest: opts.depthTest ? false 27 | transparent: opts.transparent ? true 28 | vertexColors: true 29 | opacity: opts.opacity ? 1.0 30 | sizeAttenuation: true 31 | ) 32 | 33 | @max = opts.max ? 1000 34 | @spawnRate = opts.spawnRate ? 0 35 | 36 | @spawn = opts.spawn ? new THREE.Vector3() 37 | @velocity = opts.velocity ? new THREE.Vector3() 38 | @randomness = opts.randomness ? new THREE.Vector3() 39 | @force = opts.force ? new THREE.Vector3() 40 | @spawnRadius = opts.spawnRadius ? new THREE.Vector3() 41 | @life = opts.life ? 60 42 | @ageing = 1 / @life 43 | @friction = opts.friction ? 1.0 44 | @color = new THREE.Color(opts.color ? 0xffffff) 45 | @color2 = if opts.color2? then new THREE.Color(opts.color2) else null 46 | 47 | @position = opts.position ? new THREE.Vector3() 48 | @rotation = opts.rotation ? new THREE.Vector3() 49 | @sort = opts.sort ? false 50 | 51 | @pool = [] 52 | @buffer = [] 53 | @geometry = null 54 | @system = null 55 | 56 | @build() 57 | 58 | ### 59 | Emits given number of particles 60 | @param int count 61 | ### 62 | emit: (count)-> 63 | 64 | emitable = Math.min(count, @pool.length) 65 | 66 | for i in [0..emitable] 67 | 68 | p = @pool.pop() 69 | p.available = false 70 | 71 | p.position.copy(@spawn).addSelf( 72 | @randomVector().multiplySelf(@spawnRadius) 73 | ) 74 | p.velocity.copy(@velocity).addSelf( 75 | @randomVector().multiplySelf(@randomness) 76 | ) 77 | p.force.copy(@force) 78 | p.basecolor.copy(@color) 79 | 80 | if @color2? 81 | p.basecolor.lerpSelf(@color2, Math.random()) 82 | 83 | p.life = 1.0 84 | 85 | ### 86 | @private 87 | ### 88 | build: ()-> 89 | 90 | @geometry = new THREE.Geometry() 91 | @geometry.dynamic = true 92 | 93 | @pool = [] 94 | @buffer = [] 95 | 96 | for i in [0..@max] 97 | 98 | p = new bkcore.threejs.Particle() 99 | @pool.push(p) 100 | @buffer.push(p) 101 | @geometry.vertices.push(p.position) 102 | @geometry.colors.push(p.color) 103 | 104 | @system = new THREE.ParticleSystem(@geometry, @material) 105 | @system.position = @position 106 | @system.rotation = @rotation 107 | @system.sort = @sort 108 | 109 | ### 110 | @private 111 | ### 112 | randomVector: ()-> 113 | 114 | return new THREE.Vector3( 115 | Math.random()*2-1, 116 | Math.random()*2-1, 117 | Math.random()*2-1 118 | ) 119 | 120 | ### 121 | Updates particles (should be call in a RAF loop) 122 | @param float dt time delta ~1.0 123 | ### 124 | update: (dt)-> 125 | 126 | df = new THREE.Vector3() 127 | dv = new THREE.Vector3() 128 | 129 | for i in [0..@buffer.length] 130 | 131 | p = @buffer[i] 132 | continue if p.available 133 | 134 | p.life -= @ageing 135 | 136 | if p.life <= 0 137 | p.reset() 138 | @pool.push(p) 139 | continue 140 | 141 | 142 | l = if p.life > 0.5 then 1.0 else p.life + 0.5 143 | p.color.setRGB( 144 | l * p.basecolor.r, 145 | l * p.basecolor.g, 146 | l * p.basecolor.b 147 | ) 148 | 149 | if @friction != 1.0 150 | p.velocity.multiplyScalar(@friction) 151 | 152 | df.copy(p.force).multiplyScalar(dt) 153 | p.velocity.addSelf(df) 154 | 155 | dv.copy(p.velocity).multiplyScalar(dt) 156 | p.position.addSelf(dv) 157 | 158 | if @spawnRate > 0 159 | @emit(@spawnRate) 160 | 161 | @geometry.verticesNeedUpdate = true 162 | @geometry.colorsNeedUpdate = true 163 | 164 | ### 165 | Particle sub class 166 | 167 | @class bkcore.threejs.Particle 168 | @author Thibaut 'BKcore' Despoulain 169 | ### 170 | class Particle 171 | 172 | constructor: ()-> 173 | 174 | @position = new THREE.Vector3(-10000,-10000,-10000) 175 | @velocity = new THREE.Vector3() 176 | @force = new THREE.Vector3() 177 | @color = new THREE.Color(0x000000) 178 | @basecolor = new THREE.Color(0x000000) 179 | @life = 0.0 180 | @available = true 181 | 182 | reset: ()-> 183 | @position.set(0,-100000,0) 184 | @velocity.set(0,0,0) 185 | @force.set(0,0,0) 186 | @color.setRGB(0,0,0) 187 | @basecolor.setRGB(0,0,0) 188 | @life = 0.0 189 | @available = true 190 | 191 | ### 192 | Exports 193 | @package bkcore.threejs 194 | ### 195 | exports = exports ? @ 196 | exports.bkcore ||= {} 197 | exports.bkcore.threejs ||= {} 198 | exports.bkcore.threejs.Particle = Particle 199 | exports.bkcore.threejs.Particles = Particles 200 | -------------------------------------------------------------------------------- /bkcore.coffee/threejs/Particles.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.4.0 2 | 3 | /* 4 | Particle system wrapper/helper 5 | 6 | @class bkcore.threejs.Particles 7 | @author Thibaut 'BKcore' Despoulain 8 | */ 9 | 10 | 11 | (function() { 12 | var Particle, Particles, exports, _base; 13 | 14 | Particles = (function() { 15 | /* 16 | Creates a new particle system using given parameters 17 | 18 | @param {Object{max, spawnRate, spawn, velocity, randomness, 19 | force, spawnRadius, life, friction, color, color2, tint, 20 | texture, size, blending, depthTest, transparent, opacity}} opts 21 | */ 22 | 23 | function Particles(opts) { 24 | var _ref, _ref1, _ref10, _ref11, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9; 25 | this.black = new THREE.Color(0x000000); 26 | this.white = new THREE.Color(0xffffff); 27 | this.material = new THREE.ParticleBasicMaterial({ 28 | color: (_ref = opts.tint) != null ? _ref : 0xffffff, 29 | map: (_ref1 = opts.texture) != null ? _ref1 : null, 30 | size: (_ref2 = opts.size) != null ? _ref2 : 4, 31 | blending: (_ref3 = opts.blending) != null ? _ref3 : THREE.AdditiveBlending, 32 | depthTest: (_ref4 = opts.depthTest) != null ? _ref4 : false, 33 | transparent: (_ref5 = opts.transparent) != null ? _ref5 : true, 34 | vertexColors: true, 35 | opacity: (_ref6 = opts.opacity) != null ? _ref6 : 1.0, 36 | sizeAttenuation: true 37 | }); 38 | this.max = (_ref7 = opts.max) != null ? _ref7 : 1000; 39 | this.spawnRate = (_ref8 = opts.spawnRate) != null ? _ref8 : 0; 40 | this.spawn = (_ref9 = opts.spawn) != null ? _ref9 : new THREE.Vector3(); 41 | this.velocity = (_ref10 = opts.velocity) != null ? _ref10 : new THREE.Vector3(); 42 | this.randomness = (_ref11 = opts.randomness) != null ? _ref11 : new THREE.Vector3(); 43 | this.force = (_ref12 = opts.force) != null ? _ref12 : new THREE.Vector3(); 44 | this.spawnRadius = (_ref13 = opts.spawnRadius) != null ? _ref13 : new THREE.Vector3(); 45 | this.life = (_ref14 = opts.life) != null ? _ref14 : 60; 46 | this.ageing = 1 / this.life; 47 | this.friction = (_ref15 = opts.friction) != null ? _ref15 : 1.0; 48 | this.color = new THREE.Color((_ref16 = opts.color) != null ? _ref16 : 0xffffff); 49 | this.color2 = opts.color2 != null ? new THREE.Color(opts.color2) : null; 50 | this.position = (_ref17 = opts.position) != null ? _ref17 : new THREE.Vector3(); 51 | this.rotation = (_ref18 = opts.rotation) != null ? _ref18 : new THREE.Vector3(); 52 | this.sort = (_ref19 = opts.sort) != null ? _ref19 : false; 53 | this.pool = []; 54 | this.buffer = []; 55 | this.geometry = null; 56 | this.system = null; 57 | this.build(); 58 | } 59 | 60 | /* 61 | Emits given number of particles 62 | @param int count 63 | */ 64 | 65 | 66 | Particles.prototype.emit = function(count) { 67 | var emitable, i, p, _i, _results; 68 | emitable = Math.min(count, this.pool.length); 69 | _results = []; 70 | for (i = _i = 0; 0 <= emitable ? _i <= emitable : _i >= emitable; i = 0 <= emitable ? ++_i : --_i) { 71 | p = this.pool.pop(); 72 | p.available = false; 73 | p.position.copy(this.spawn).addSelf(this.randomVector().multiplySelf(this.spawnRadius)); 74 | p.velocity.copy(this.velocity).addSelf(this.randomVector().multiplySelf(this.randomness)); 75 | p.force.copy(this.force); 76 | p.basecolor.copy(this.color); 77 | if (this.color2 != null) { 78 | p.basecolor.lerpSelf(this.color2, Math.random()); 79 | } 80 | _results.push(p.life = 1.0); 81 | } 82 | return _results; 83 | }; 84 | 85 | /* 86 | @private 87 | */ 88 | 89 | 90 | Particles.prototype.build = function() { 91 | var i, p, _i, _ref; 92 | this.geometry = new THREE.Geometry(); 93 | this.geometry.dynamic = true; 94 | this.pool = []; 95 | this.buffer = []; 96 | for (i = _i = 0, _ref = this.max; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) { 97 | p = new bkcore.threejs.Particle(); 98 | this.pool.push(p); 99 | this.buffer.push(p); 100 | this.geometry.vertices.push(p.position); 101 | this.geometry.colors.push(p.color); 102 | } 103 | this.system = new THREE.ParticleSystem(this.geometry, this.material); 104 | this.system.position = this.position; 105 | this.system.rotation = this.rotation; 106 | return this.system.sort = this.sort; 107 | }; 108 | 109 | /* 110 | @private 111 | */ 112 | 113 | 114 | Particles.prototype.randomVector = function() { 115 | return new THREE.Vector3(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1); 116 | }; 117 | 118 | /* 119 | Updates particles (should be call in a RAF loop) 120 | @param float dt time delta ~1.0 121 | */ 122 | 123 | 124 | Particles.prototype.update = function(dt) { 125 | var df, dv, i, l, p, _i, _ref; 126 | df = new THREE.Vector3(); 127 | dv = new THREE.Vector3(); 128 | for (i = _i = 0, _ref = this.buffer.length; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) { 129 | p = this.buffer[i]; 130 | if (p.available) { 131 | continue; 132 | } 133 | p.life -= this.ageing; 134 | if (p.life <= 0) { 135 | p.reset(); 136 | this.pool.push(p); 137 | continue; 138 | } 139 | l = p.life > 0.5 ? 1.0 : p.life + 0.5; 140 | p.color.setRGB(l * p.basecolor.r, l * p.basecolor.g, l * p.basecolor.b); 141 | if (this.friction !== 1.0) { 142 | p.velocity.multiplyScalar(this.friction); 143 | } 144 | df.copy(p.force).multiplyScalar(dt); 145 | p.velocity.addSelf(df); 146 | dv.copy(p.velocity).multiplyScalar(dt); 147 | p.position.addSelf(dv); 148 | } 149 | if (this.spawnRate > 0) { 150 | this.emit(this.spawnRate); 151 | } 152 | this.geometry.verticesNeedUpdate = true; 153 | return this.geometry.colorsNeedUpdate = true; 154 | }; 155 | 156 | return Particles; 157 | 158 | })(); 159 | 160 | /* 161 | Particle sub class 162 | 163 | @class bkcore.threejs.Particle 164 | @author Thibaut 'BKcore' Despoulain 165 | */ 166 | 167 | 168 | Particle = (function() { 169 | 170 | function Particle() { 171 | this.position = new THREE.Vector3(-10000, -10000, -10000); 172 | this.velocity = new THREE.Vector3(); 173 | this.force = new THREE.Vector3(); 174 | this.color = new THREE.Color(0x000000); 175 | this.basecolor = new THREE.Color(0x000000); 176 | this.life = 0.0; 177 | this.available = true; 178 | } 179 | 180 | Particle.prototype.reset = function() { 181 | this.position.set(0, -100000, 0); 182 | this.velocity.set(0, 0, 0); 183 | this.force.set(0, 0, 0); 184 | this.color.setRGB(0, 0, 0); 185 | this.basecolor.setRGB(0, 0, 0); 186 | this.life = 0.0; 187 | return this.available = true; 188 | }; 189 | 190 | return Particle; 191 | 192 | })(); 193 | 194 | /* 195 | Exports 196 | @package bkcore.threejs 197 | */ 198 | 199 | 200 | exports = exports != null ? exports : this; 201 | 202 | exports.bkcore || (exports.bkcore = {}); 203 | 204 | (_base = exports.bkcore).threejs || (_base.threejs = {}); 205 | 206 | exports.bkcore.threejs.Particle = Particle; 207 | 208 | exports.bkcore.threejs.Particles = Particles; 209 | 210 | }).call(this); 211 | -------------------------------------------------------------------------------- /bkcore/Audio.js: -------------------------------------------------------------------------------- 1 | var bkcore = bkcore || {}; 2 | 3 | bkcore.Audio = {}; 4 | bkcore.Audio.sounds = {}; 5 | 6 | bkcore.Audio.init = function(){ 7 | if(window.AudioContext||window.webkitAudioContext){ 8 | bkcore.Audio._ctx = new (window.AudioContext||window.webkitAudioContext)(); 9 | bkcore.Audio._panner = bkcore.Audio._ctx.createPanner(); 10 | bkcore.Audio._panner.connect(bkcore.Audio._ctx.destination); 11 | } 12 | else { 13 | bkcore.Audio._ctx = null; 14 | } 15 | 16 | bkcore.Audio.posMultipler = 1.5; 17 | }; 18 | 19 | bkcore.Audio.init(); 20 | 21 | bkcore.Audio.addSound = function(src, id, loop, callback, usePanner){ 22 | var ctx = bkcore.Audio._ctx; 23 | var audio = new Audio(); 24 | 25 | if(ctx){ 26 | var audio = { src: null, gainNode: null, bufferNode: null, loop: loop }; 27 | var xhr = new XMLHttpRequest(); 28 | xhr.responseType = 'arraybuffer'; 29 | 30 | xhr.onload = function(){ 31 | ctx.decodeAudioData(xhr.response, function(b){ 32 | // Create Gain Node 33 | var gainNode = ctx.createGain(); 34 | 35 | if(usePanner === true){ 36 | gainNode.connect(bkcore.Audio._panner); 37 | } 38 | else { 39 | gainNode.connect(ctx.destination); 40 | } 41 | 42 | // Add the audio source 43 | audio.src = b; 44 | 45 | //Remember the gain node 46 | audio.gainNode = gainNode; 47 | 48 | callback(); 49 | }, function(e){ 50 | console.error('Audio decode failed!', e); 51 | }); 52 | }; 53 | 54 | xhr.open('GET', src, true); 55 | xhr.send(null); 56 | } 57 | else { 58 | // Workaround for old Safari 59 | audio.addEventListener('canplay', function(){ 60 | audio.pause(); 61 | audio.currentTime = 0; 62 | 63 | callback(); 64 | }, false); 65 | 66 | audio.autoplay = true; 67 | audio.loop = loop; 68 | audio.src = src; 69 | } 70 | 71 | bkcore.Audio.sounds[id] = audio; 72 | }; 73 | 74 | bkcore.Audio.play = function(id){ 75 | var ctx = bkcore.Audio._ctx; 76 | 77 | if(ctx){ 78 | var sound = ctx.createBufferSource(); 79 | sound.connect(bkcore.Audio.sounds[id].gainNode); 80 | 81 | sound.buffer = bkcore.Audio.sounds[id].src; 82 | sound.loop = bkcore.Audio.sounds[id].loop; 83 | 84 | bkcore.Audio.sounds[id].gainNode.gain.value = 1; 85 | bkcore.Audio.sounds[id].bufferNode = sound; 86 | 87 | sound.start ? sound.start(0) : sound.noteOn(0); 88 | } 89 | else { 90 | if(bkcore.Audio.sounds[id].currentTime > 0){ 91 | bkcore.Audio.sounds[id].pause(); 92 | bkcore.Audio.sounds[id].currentTime = 0; 93 | } 94 | 95 | bkcore.Audio.sounds[id].play(); 96 | } 97 | }; 98 | 99 | bkcore.Audio.stop = function(id){ 100 | var ctx = bkcore.Audio._ctx; 101 | 102 | if(ctx){ 103 | if(bkcore.Audio.sounds[id].bufferNode !== null){ 104 | var bufferNode = bkcore.Audio.sounds[id].bufferNode; 105 | bufferNode.stop ? bufferNode.stop(ctx.currentTime) : bufferNode.noteOff(ctx.currentTime); 106 | } 107 | } 108 | else { 109 | bkcore.Audio.sounds[id].pause(); 110 | bkcore.Audio.sounds[id].currentTime = 0; 111 | } 112 | }; 113 | 114 | bkcore.Audio.volume = function(id, volume){ 115 | var ctx = bkcore.Audio._ctx; 116 | 117 | if(ctx){ 118 | bkcore.Audio.sounds[id].gainNode.gain.value = volume; 119 | } 120 | else { 121 | bkcore.Audio.sounds[id].volume = volume; 122 | } 123 | }; 124 | 125 | bkcore.Audio.setListenerPos = function(vec){ 126 | if(bkcore.Audio._ctx){ 127 | var panner = bkcore.Audio._panner; 128 | var vec2 = vec.normalize(); 129 | panner.setPosition( 130 | vec2.x * bkcore.Audio.posMultipler, 131 | vec2.y * bkcore.Audio.posMultipler, 132 | vec2.z * bkcore.Audio.posMultipler 133 | ); 134 | } 135 | }; 136 | 137 | bkcore.Audio.setListenerVelocity = function(vec){ 138 | if(bkcore.Audio._ctx){ 139 | var panner = bkcore.Audio._panner; 140 | //panner.setVelocity(vec.x, vec.y, vec.z); 141 | } 142 | }; -------------------------------------------------------------------------------- /bkcore/hexgl/CameraChase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * HexGL 3 | * @author Thibaut 'BKcore' Despoulain 4 | * @license This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 Unported License. 5 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/. 6 | */ 7 | 8 | var bkcore = bkcore || {}; 9 | bkcore.hexgl = bkcore.hexgl || {}; 10 | 11 | bkcore.hexgl.CameraChase = function(opts) 12 | { 13 | this.dir = new THREE.Vector3(0,0,1); 14 | this.up = new THREE.Vector3(0,1,0); 15 | this.target = new THREE.Vector3(); 16 | this.speedOffset = 0; 17 | this.speedOffsetMax = 10; 18 | this.speedOffsetStep = 0.05; 19 | 20 | this.modes = { 21 | CHASE: 0, 22 | ORBIT: 1 23 | } 24 | this.mode = this.modes.CHASE; 25 | 26 | this.camera = opts.camera; 27 | this.targetObject = opts.target; 28 | this.cameraCube = opts.cameraCube == undefined ? null : opts.cameraCube; 29 | 30 | this.yoffset = opts.yoffest == undefined ? 8.0 : opts.yoffest; 31 | this.zoffset = opts.zoffset == undefined ? 10.0 : opts.zoffset; 32 | this.viewOffset = opts.viewOffset == undefined ? 10.0 : opts.viewOffset; 33 | this.orbitOffset = 12; 34 | this.lerp = opts.lerp == undefined ? 0.5 : opts.lerp; 35 | this.time = 0.0; 36 | } 37 | 38 | bkcore.hexgl.CameraChase.prototype.update = function(dt, ratio) 39 | { 40 | if(this.mode == this.modes.CHASE) 41 | { 42 | this.dir.set(0,0,1); 43 | this.up.set(0,1,0); 44 | 45 | this.targetObject.matrix.rotateAxis(this.up); 46 | this.targetObject.matrix.rotateAxis(this.dir); 47 | 48 | this.speedOffset += (this.speedOffsetMax*ratio - this.speedOffset) * Math.min(1, 0.3*dt); 49 | 50 | this.target.copy(this.targetObject.position); 51 | this.target.subSelf(this.dir.multiplyScalar(this.zoffset + this.speedOffset)); 52 | this.target.addSelf(this.up.multiplyScalar(this.yoffset)); 53 | this.target.y += -this.up.y + this.yoffset; 54 | this.camera.position.copy(this.target); 55 | 56 | this.camera.lookAt(this.dir.normalize().multiplyScalar(this.viewOffset).addSelf(this.targetObject.position)); 57 | } 58 | else if(this.mode == this.modes.ORBIT) 59 | { 60 | this.time += dt*.008; 61 | this.dir.set( 62 | Math.cos(this.time)*this.orbitOffset, 63 | this.yoffset/2, 64 | Math.sin(this.time)*this.orbitOffset 65 | ); 66 | this.target.copy(this.targetObject.position).addSelf(this.dir); 67 | this.camera.position.copy(this.target); 68 | this.camera.lookAt(this.targetObject.position); 69 | } 70 | 71 | if(this.cameraCube != null) 72 | this.cameraCube.rotation.copy(this.camera.rotation); 73 | } -------------------------------------------------------------------------------- /bkcore/hexgl/Gameplay.js: -------------------------------------------------------------------------------- 1 | /* 2 | * HexGL 3 | * @author Thibaut 'BKcore' Despoulain 4 | * @license This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 Unported License. 5 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/. 6 | */ 7 | 8 | var bkcore = bkcore || {}; 9 | bkcore.hexgl = bkcore.hexgl || {}; 10 | 11 | bkcore.hexgl.Gameplay = function(opts) 12 | { 13 | var self = this; 14 | 15 | this.startDelay = opts.hud == null ? 0 : 1000; 16 | this.countDownDelay = opts.hud == null ? 1000 : 1500; 17 | 18 | this.active = false; 19 | this.timer = new bkcore.Timer(); 20 | this.modes = { 21 | 'timeattack':null, 22 | 'survival':null, 23 | 'replay':null 24 | }; 25 | this.mode = opts.mode == undefined || !(opts.mode in this.modes) ? "timeattack" : opts.mode; 26 | this.step = 0; 27 | 28 | this.hud = opts.hud; 29 | this.shipControls = opts.shipControls; 30 | this.cameraControls = opts.cameraControls; 31 | this.track = opts.track; 32 | this.analyser = opts.analyser; 33 | this.pixelRatio = opts.pixelRatio; 34 | 35 | this.previousCheckPoint = -1; 36 | 37 | this.results = { 38 | FINISH: 1, 39 | DESTROYED: 2, 40 | WRONGWAY: 3, 41 | REPLAY: 4, 42 | NONE: -1 43 | }; 44 | this.result = this.results.NONE; 45 | 46 | this.lap = 1; 47 | this.lapTimes = []; 48 | this.lapTimeElapsed = 0; 49 | this.maxLaps = 3; 50 | this.score = null; 51 | this.finishTime = null; 52 | this.onFinish = opts.onFinish == undefined ? function(){console.log("FINISH");} : opts.onFinish; 53 | 54 | this.raceData = null; 55 | 56 | this.modes.timeattack = function() 57 | { 58 | self.raceData.tick(this.timer.time.elapsed); 59 | 60 | self.hud != null && self.hud.updateTime(self.timer.getElapsedTime()); 61 | var cp = self.checkPoint(); 62 | 63 | if(cp == self.track.checkpoints.start && self.previousCheckPoint == self.track.checkpoints.last) 64 | { 65 | self.previousCheckPoint = cp; 66 | var t = self.timer.time.elapsed; 67 | self.lapTimes.push(t - self.lapTimeElapsed); 68 | self.lapTimeElapsed = t; 69 | 70 | if(self.lap == this.maxLaps) 71 | { 72 | self.end(self.results.FINISH); 73 | } 74 | else 75 | { 76 | self.lap++; 77 | self.hud != null && self.hud.updateLap(self.lap, self.maxLaps); 78 | 79 | if(self.lap == self.maxLaps) 80 | self.hud != null && self.hud.display("Final lap", 0.5); 81 | } 82 | } 83 | else if(cp != -1 && cp != self.previousCheckPoint) 84 | { 85 | self.previousCheckPoint = cp; 86 | //self.hud.display("Checkpoint", 0.5); 87 | } 88 | 89 | if(self.shipControls.destroyed == true) 90 | { 91 | self.end(self.results.DESTROYED); 92 | } 93 | }; 94 | 95 | this.modes.replay = function() 96 | { 97 | self.raceData.applyInterpolated(this.timer.time.elapsed); 98 | 99 | if(self.raceData.seek == self.raceData.last) 100 | { 101 | self.end(self.result.REPLAY); 102 | } 103 | }; 104 | } 105 | 106 | bkcore.hexgl.Gameplay.prototype.simu = function() 107 | { 108 | this.lapTimes = [92300, 91250, 90365]; 109 | this.finishTime = this.lapTimes[0]+this.lapTimes[1]+this.lapTimes[2]; 110 | if(this.hud != null) this.hud.display("Finish"); 111 | this.step = 100; 112 | this.result = this.results.FINISH; 113 | this.shipControls.active = false; 114 | } 115 | 116 | bkcore.hexgl.Gameplay.prototype.start = function(opts) 117 | { 118 | this.finishTime = null; 119 | this.score = null; 120 | this.lap = 1; 121 | 122 | this.shipControls.reset(this.track.spawn, this.track.spawnRotation); 123 | this.shipControls.active = false; 124 | 125 | this.previousCheckPoint = this.track.checkpoints.start; 126 | 127 | this.raceData = new bkcore.hexgl.RaceData(this.track.name, this.mode, this.shipControls); 128 | if(this.mode == 'replay') 129 | { 130 | this.cameraControls.mode = this.cameraControls.modes.ORBIT; 131 | if(this.hud != null) this.hud.messageOnly = true; 132 | 133 | try { 134 | var d = localStorage['race-'+this.track.name+'-replay']; 135 | if(d == undefined) 136 | { 137 | console.error('No replay data for '+'race-'+this.track.name+'-replay'+'.'); 138 | return false; 139 | } 140 | this.raceData.import( 141 | JSON.parse(d) 142 | ); 143 | } 144 | catch(e) { console.error('Bad replay format : '+e); return false; } 145 | } 146 | 147 | this.active = true; 148 | this.step = 0; 149 | this.timer.start(); 150 | if(this.hud != null) 151 | { 152 | this.hud.resetTime(); 153 | this.hud.display("Get ready", 1); 154 | this.hud.updateLap(this.lap, this.maxLaps); 155 | } 156 | } 157 | 158 | bkcore.hexgl.Gameplay.prototype.end = function(result) 159 | { 160 | this.score = this.timer.getElapsedTime(); 161 | this.finishTime = this.timer.time.elapsed; 162 | this.timer.start(); 163 | this.result = result; 164 | 165 | this.shipControls.active = false; 166 | 167 | if(result == this.results.FINISH) 168 | { 169 | if(this.hud != null) this.hud.display("Finish"); 170 | this.step = 100; 171 | } 172 | else if(result == this.results.DESTROYED) 173 | { 174 | if(this.hud != null) this.hud.display("Destroyed"); 175 | this.step = 100; 176 | } 177 | } 178 | 179 | bkcore.hexgl.Gameplay.prototype.update = function() 180 | { 181 | if(!this.active) return; 182 | 183 | this.timer.update(); 184 | 185 | if(this.step == 0 && this.timer.time.elapsed >= this.countDownDelay+this.startDelay) 186 | { 187 | if(this.hud != null) this.hud.display("3"); 188 | this.step = 1; 189 | } 190 | else if(this.step == 1 && this.timer.time.elapsed >= 2*this.countDownDelay+this.startDelay) 191 | { 192 | if(this.hud != null) this.hud.display("2"); 193 | this.step = 2; 194 | } 195 | else if(this.step == 2 && this.timer.time.elapsed >= 3*this.countDownDelay+this.startDelay) 196 | { 197 | if(this.hud != null) this.hud.display("1"); 198 | this.step = 3; 199 | } 200 | else if(this.step == 3 && this.timer.time.elapsed >= 4*this.countDownDelay+this.startDelay) 201 | { 202 | if(this.hud != null) this.hud.display("Go", 0.5); 203 | this.step = 4; 204 | this.timer.start(); 205 | 206 | if(this.mode != "replay") 207 | this.shipControls.active = true; 208 | } 209 | else if(this.step == 4) 210 | { 211 | this.modes[this.mode].call(this); 212 | } 213 | else if(this.step == 100 && this.timer.time.elapsed >= 2000) 214 | { 215 | this.active = false; 216 | this.onFinish.call(this); 217 | } 218 | } 219 | 220 | bkcore.hexgl.Gameplay.prototype.checkPoint = function() 221 | { 222 | var x = Math.round(this.analyser.pixels.width/2 + this.shipControls.dummy.position.x * this.pixelRatio); 223 | var z = Math.round(this.analyser.pixels.height/2 + this.shipControls.dummy.position.z * this.pixelRatio); 224 | 225 | var color = this.analyser.getPixel(x, z); 226 | 227 | if(color.r == 255 && color.g == 255 && color.b < 250) 228 | return color.b; 229 | else 230 | return -1; 231 | } -------------------------------------------------------------------------------- /bkcore/hexgl/Ladder.js: -------------------------------------------------------------------------------- 1 | /* 2 | * HexGL 3 | * @author Thibaut 'BKcore' Despoulain 4 | * @license This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 Unported License. 5 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/. 6 | */ 7 | 8 | var bkcore = bkcore || {}; 9 | bkcore.hexgl = bkcore.hexgl || {}; 10 | 11 | bkcore.hexgl.Ladder = {}; 12 | bkcore.hexgl.Ladder.global = {}; 13 | 14 | bkcore.hexgl.Ladder.load = function(callback) 15 | { 16 | var s = encodeURIComponent(window.location.href); 17 | bkcore.Utils.request("nothing", false, function(req) 18 | { 19 | try { 20 | bkcore.Ladder.global = JSON.parse(req.responseText); 21 | if(callback) callback.call(window); 22 | } 23 | catch(e) 24 | { 25 | console.warn('Unable to load ladder. '+e); 26 | } 27 | }, 28 | { 29 | u: s 30 | }); 31 | } 32 | 33 | bkcore.hexgl.Ladder.displayLadder = function(id, track, mode, num) 34 | { 35 | var d = document.getElementById(id); 36 | if(d == undefined || bkcore.Ladder.global[track] == undefined || !bkcore.Ladder.global[track][mode] == undefined) 37 | { 38 | console.warn('Undefined ladder.'); 39 | return; 40 | } 41 | 42 | var l = bkcore.Ladder.global[track][mode]; 43 | var h = ''; 44 | var m = Math.min((num == undefined ? 10 : num), l.length-1); 45 | for(var i = 0; i < l.length-1; i++) 46 | { 47 | var t = bkcore.Timer.msToTime(l[i]['score']); 48 | h += ''+(i+1)+'. '+l[i]['name']+''+t.m+'\''+t.s+'\'\''+t.ms+''; 49 | } 50 | 51 | d.innerHTML = h; 52 | } -------------------------------------------------------------------------------- /bkcore/hexgl/RaceData.js: -------------------------------------------------------------------------------- 1 | /* 2 | * HexGL 3 | * @author Thibaut 'BKcore' Despoulain 4 | * @license This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 Unported License. 5 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/. 6 | */ 7 | 8 | var bkcore = bkcore || {}; 9 | bkcore.hexgl = bkcore.hexgl || {}; 10 | 11 | bkcore.hexgl.RaceData = function(track, mode, shipControls) 12 | { 13 | this.track = track; 14 | this.mode = mode; 15 | this.shipControls = shipControls; 16 | 17 | this.rate = 2; // 1 / rate 18 | this.rateState = 1; 19 | 20 | this.data = []; 21 | this.last = -1; 22 | this.seek = 0; 23 | 24 | this._p = new THREE.Vector3(); 25 | this._pp = new THREE.Vector3(); 26 | this._np = new THREE.Vector3(); 27 | this._q = new THREE.Quaternion(); 28 | this._pq = new THREE.Quaternion(); 29 | this._nq = new THREE.Quaternion(); 30 | } 31 | 32 | bkcore.hexgl.RaceData.prototype.tick = function(time) 33 | { 34 | if(this.rateState == 1) 35 | { 36 | var p = this.shipControls.getPosition(); 37 | var q = this.shipControls.getQuaternion(); 38 | this.data.push([ 39 | time, 40 | p.x, p.y, p.z, 41 | q.x, q.y, q.z, q.w 42 | ]); 43 | ++this.last; 44 | } 45 | else if(this.rateState == this.rate) 46 | { 47 | this.rateState = 0; 48 | } 49 | 50 | this.rate++; 51 | } 52 | 53 | bkcore.hexgl.RaceData.prototype.applyInterpolated = function(time) 54 | { 55 | while(this.seek < this.last && this.data[this.seek+1][0] < time) 56 | ++this.seek; 57 | 58 | var prev = this.data[this.seek]; 59 | this._pp.set(prev[1], prev[2], prev[3]); 60 | this._pq.set(prev[4], prev[5], prev[6], prev[7]); 61 | 62 | if(this.seek < 0) 63 | { 64 | console.warn('Bad race data.'); 65 | return; 66 | } 67 | 68 | // no interpolation 69 | if(this.seek == this.last || this.seek == 0) 70 | this.shipControls.teleport(this._pp, this._pq); 71 | 72 | // interpolation 73 | var next = this.data[this.seek+1]; 74 | this._np.set(next[1], next[2], next[3]); 75 | this._nq.set(next[4], next[5], next[6], next[7]); 76 | 77 | var t = (time-prev[0]) / (next[0]-prev[0]); 78 | this._p.copy(this._pp).lerpSelf(this._np, t); 79 | this._q.copy(this._pq).slerpSelf(this._nq, t); 80 | 81 | this.shipControls.teleport(this._p, this._q); 82 | } 83 | 84 | bkcore.hexgl.RaceData.prototype.reset = function() 85 | { 86 | this.seek = 0; 87 | } 88 | 89 | bkcore.hexgl.RaceData.prototype.export = function() 90 | { 91 | return this.data; 92 | } 93 | 94 | bkcore.hexgl.RaceData.prototype.import = function(imp) 95 | { 96 | this.data = imp; 97 | this.last = this.data.length-1; 98 | console.log(this.data); 99 | } -------------------------------------------------------------------------------- /bkcore/hexgl/ShipEffects.js: -------------------------------------------------------------------------------- 1 | /* 2 | * HexGL 3 | * @author Thibaut 'BKcore' Despoulain 4 | * @license This work is licensed under the Creative Commons Attribution-NonCommercial 3.0 Unported License. 5 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/3.0/. 6 | */ 7 | 8 | var bkcore = bkcore || {}; 9 | bkcore.hexgl = bkcore.hexgl || {}; 10 | 11 | bkcore.hexgl.ShipEffects = function(opts) 12 | { 13 | this.scene = opts.scene; 14 | this.shipControls = opts.shipControls; 15 | 16 | this.booster = opts.booster; 17 | this.boosterLight = opts.boosterLight; 18 | this.boosterSprite = opts.boosterSprite; 19 | 20 | this.useParticles = opts.useParticles; 21 | 22 | if(this.useParticles) 23 | { 24 | this.pVel = new THREE.Vector3(0.5,0,0); 25 | this.pOffset = new THREE.Vector3(-3,-0.3,0); 26 | this.pRad = new THREE.Vector3(0,0,1.5); 27 | 28 | this.shipVelocity = new THREE.Vector3(); 29 | 30 | this.pVelS = this.pVel.length(); 31 | this.pOffsetS = this.pOffset.length(); 32 | this.pRadS = this.pRad.length(); 33 | 34 | this.pVel.normalize(); 35 | this.pOffset.normalize(); 36 | this.pRad.normalize(); 37 | 38 | this.particles = { 39 | 40 | leftSparks: new bkcore.threejs.Particles( 41 | { 42 | randomness: new THREE.Vector3(0.4,0.4,0.4), 43 | tint: 0xffffff, 44 | color: 0xffc000, 45 | color2: 0xffffff, 46 | texture: opts.textureSpark, 47 | size: 2, 48 | life: 60, 49 | max: 200 50 | }), 51 | 52 | leftClouds: new bkcore.threejs.Particles( 53 | { 54 | opacity: 0.8, 55 | tint: 0xffffff, 56 | color: 0x666666, 57 | color2: 0xa4f1ff, 58 | texture: opts.textureCloud, 59 | size: 6, 60 | blending: THREE.NormalBlending, 61 | life: 60, 62 | max: 200, 63 | spawn: new THREE.Vector3(3,-0.3,0), 64 | spawnRadius: new THREE.Vector3(1,1,2), 65 | velocity: new THREE.Vector3(0,0,-0.4), 66 | randomness: new THREE.Vector3(0.05,0.05,0.1) 67 | }), 68 | 69 | rightSparks: new bkcore.threejs.Particles( 70 | { 71 | randomness: new THREE.Vector3(0.4,0.4,0.4), 72 | tint: 0xffffff, 73 | color: 0xffc000, 74 | color2: 0xffffff, 75 | texture: opts.textureSpark, 76 | size: 2, 77 | life: 60, 78 | max: 200 79 | }), 80 | 81 | rightClouds: new bkcore.threejs.Particles( 82 | { 83 | opacity: 0.8, 84 | tint: 0xffffff, 85 | color: 0x666666, 86 | color2: 0xa4f1ff, 87 | texture: opts.textureCloud, 88 | size: 6, 89 | blending: THREE.NormalBlending, 90 | life: 60, 91 | max: 200, 92 | spawn: new THREE.Vector3(-3,-0.3,0), 93 | spawnRadius: new THREE.Vector3(1,1,2), 94 | velocity: new THREE.Vector3(0,0,-0.4), 95 | randomness: new THREE.Vector3(0.05,0.05,0.1) 96 | }) 97 | }; 98 | 99 | this.shipControls.mesh.add(this.particles.leftClouds.system); 100 | this.shipControls.mesh.add(this.particles.rightClouds.system); 101 | this.scene.add(this.particles.leftSparks.system); 102 | this.scene.add(this.particles.rightSparks.system); 103 | } 104 | } 105 | 106 | bkcore.hexgl.ShipEffects.prototype.update = function(dt) 107 | { 108 | var boostRatio, opacity, scale, intensity, random; 109 | 110 | if(this.shipControls.destroyed) 111 | { 112 | opacity = 0; 113 | scale = 0; 114 | intensity = 0; 115 | random = 0; 116 | } 117 | else 118 | { 119 | boostRatio = this.shipControls.getBoostRatio(); 120 | opacity = this.shipControls.key.forward ? 0.8 : 0.3 + boostRatio * 0.4; 121 | scale = (this.shipControls.key.forward ? 1.0 : 0.8) + boostRatio * 0.5; 122 | intensity = this.shipControls.key.forward ? 4.0 : 2.0; 123 | random = Math.random()*0.2; 124 | } 125 | 126 | if(this.booster) 127 | { 128 | this.booster.rotation.z += 1; 129 | this.booster.scale.set(scale, scale, scale); 130 | this.booster.material.opacity = random+opacity; 131 | this.boosterSprite.opacity = random+opacity; 132 | this.boosterLight.intensity = intensity*(random+0.8); 133 | } 134 | 135 | // PARTICLES 136 | if(this.useParticles) 137 | { 138 | this.shipVelocity.copy(this.shipControls.currentVelocity).multiplyScalar(0.7); 139 | 140 | this.particles.rightSparks.velocity.copy(this.pVel); 141 | this.particles.rightSparks.spawnRadius.copy(this.pRad); 142 | this.particles.rightSparks.spawn.copy(this.pOffset); 143 | 144 | this.particles.leftSparks.velocity.copy(this.pVel).x *= -1; 145 | this.particles.leftSparks.spawn.copy(this.pOffset).x *= -1; 146 | 147 | if(this.shipControls.mesh) 148 | { 149 | // RIGHT 150 | this.shipControls.mesh.matrix.rotateAxis(this.particles.rightSparks.spawn); 151 | this.particles.rightSparks.spawn.multiplyScalar(this.pOffsetS).addSelf(this.shipControls.dummy.position); 152 | 153 | this.shipControls.mesh.matrix.rotateAxis(this.particles.rightSparks.velocity); 154 | this.particles.rightSparks.velocity.multiplyScalar(this.pVelS).addSelf(this.shipVelocity); 155 | 156 | this.shipControls.mesh.matrix.rotateAxis(this.particles.rightSparks.spawnRadius); 157 | this.particles.rightSparks.spawnRadius.multiplyScalar(this.pRadS); 158 | 159 | // LEFT 160 | this.shipControls.mesh.matrix.rotateAxis(this.particles.leftSparks.spawn); 161 | this.particles.leftSparks.spawn.multiplyScalar(this.pOffsetS).addSelf(this.shipControls.dummy.position); 162 | 163 | this.shipControls.mesh.matrix.rotateAxis(this.particles.leftSparks.velocity); 164 | this.particles.leftSparks.velocity.multiplyScalar(this.pVelS).addSelf(this.shipVelocity); 165 | 166 | this.particles.leftSparks.spawnRadius.copy(this.particles.rightSparks.spawnRadius); 167 | } 168 | 169 | if(this.shipControls.collision.right) 170 | { 171 | this.particles.rightSparks.emit(10); 172 | this.particles.rightClouds.emit(5); 173 | } 174 | 175 | if(this.shipControls.collision.left) 176 | { 177 | this.particles.leftSparks.emit(10); 178 | this.particles.leftClouds.emit(5); 179 | } 180 | 181 | this.particles.rightSparks.update(dt); 182 | this.particles.rightClouds.update(dt); 183 | this.particles.leftSparks.update(dt); 184 | this.particles.leftClouds.update(dt); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /bkcore/threejs/Loader.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * @class bkcore.threejs.Loader 3 | * 4 | * Loads multiple recources, get progress, callback friendly. 5 | * Supports textures, texturesCube, geometries, analysers, images. 6 | * 7 | * @author Thibaut 'BKcore' Despoulain 8 | */ 9 | 10 | /*! 11 | * @package bkcore.threejs 12 | */ 13 | var bkcore = bkcore || {}; 14 | bkcore.threejs = bkcore.threejs || {}; 15 | 16 | bkcore.NONE = undefined; 17 | 18 | /** 19 | * Creates a new loader 20 | * @param {Object{onLoad, onError, onProgress}} opts Callbacks 21 | */ 22 | bkcore.threejs.Loader = function(opts) 23 | { 24 | var self = this; 25 | 26 | this.jsonLoader = new THREE.JSONLoader(); 27 | 28 | this.errorCallback = opts.onError == undefined ? function(s){ console.warn("Error while loading %s.".replace("%s", s)) } : opts.onError; 29 | this.loadCallback = opts.onLoad == undefined ? function(){ console.log("Loaded.") } : opts.onLoad; 30 | this.progressCallback = opts.onProgress == undefined ? function(progress, type, name){ /**/ } : opts.onProgress; 31 | 32 | this.types = { 33 | textures: null, 34 | texturesCube: null, 35 | geometries: null, 36 | analysers: null, 37 | images: null, 38 | sounds: null 39 | }; 40 | 41 | this.states = {}; 42 | this.data = {}; 43 | 44 | for(var t in this.types) 45 | { 46 | this.data[t] = {}; 47 | this.states[t] = {}; 48 | } 49 | 50 | this.progress = { 51 | total: 0, 52 | remaining: 0, 53 | loaded: 0, 54 | finished: false 55 | }; 56 | } 57 | 58 | /** 59 | * Load the given list of resources 60 | * @param {textures, texturesCube, geometries, analysers, images} data 61 | */ 62 | bkcore.threejs.Loader.prototype.load = function(data) 63 | { 64 | var self = this; 65 | 66 | for(var k in this.types) 67 | { 68 | if(k in data) 69 | { 70 | var size = 0; 71 | for(var j in data[k]) 72 | size++; 73 | this.progress.total += size; 74 | this.progress.remaining += size; 75 | } 76 | } 77 | 78 | for(var t in data.textures) 79 | this.loadTexture(t, data.textures[t]); 80 | 81 | for(var c in data.texturesCube) 82 | this.loadTextureCube(c, data.texturesCube[c]); 83 | 84 | for(var g in data.geometries) 85 | this.loadGeometry(g, data.geometries[g]); 86 | 87 | for(var a in data.analysers) 88 | this.loadAnalyser(a, data.analysers[a]); 89 | 90 | for(var i in data.images) 91 | this.loadImage(i, data.images[i]); 92 | 93 | for(var s in data.sounds) 94 | this.loadSound(data.sounds[s].src, s, data.sounds[s].loop, data.sounds[s].usePanner); 95 | 96 | this.progressCallback.call(this, this.progress); 97 | } 98 | 99 | bkcore.threejs.Loader.prototype.updateState = function(type, name, state) 100 | { 101 | if(!(type in this.types)) 102 | { 103 | console.warn("Unkown loader type."); 104 | return; 105 | } 106 | 107 | if(state == true) 108 | { 109 | this.progress.remaining--; 110 | this.progress.loaded++; 111 | this.progressCallback.call(this, this.progress, type, name); 112 | } 113 | 114 | this.states[type][name] = state; 115 | 116 | 117 | if(this.progress.loaded == this.progress.total) 118 | { 119 | this.loadCallback.call(this); 120 | } 121 | } 122 | 123 | /** 124 | * Get loaded resource 125 | * @param string type [textures, texturesCube, geometries, analysers, images] 126 | * @param string name 127 | * @return Mixed 128 | */ 129 | bkcore.threejs.Loader.prototype.get = function(type, name) 130 | { 131 | if(!(type in this.types)) 132 | { 133 | console.warn("Unkown loader type."); 134 | return null; 135 | } 136 | if(!(name in this.data[type])) 137 | { 138 | console.warn("Unkown file."); 139 | return null; 140 | } 141 | 142 | return this.data[type][name]; 143 | } 144 | 145 | bkcore.threejs.Loader.prototype.loaded = function(type, name) 146 | { 147 | if(!(type in this.types)) 148 | { 149 | console.warn("Unkown loader type."); 150 | return null; 151 | } 152 | if(!(name in this.states[type])) 153 | { 154 | console.warn("Unkown file."); 155 | return null; 156 | } 157 | 158 | return this.states[type][name]; 159 | } 160 | 161 | bkcore.threejs.Loader.prototype.loadTexture = function(name, url) 162 | { 163 | var self = this; 164 | this.updateState("textures", name, false); 165 | this.data.textures[name] = THREE.ImageUtils.loadTexture( 166 | url, 167 | bkcore.NONE, 168 | function(){ 169 | self.updateState("textures", name, true); 170 | }, 171 | function(){ 172 | self.errorCallback.call(self, name); 173 | } 174 | ); 175 | } 176 | 177 | bkcore.threejs.Loader.prototype.loadTextureCube = function(name, url) 178 | { 179 | var self = this; 180 | 181 | var urls = [ 182 | url.replace("%1", "px"), url.replace("%1", "nx"), 183 | url.replace("%1", "py"), url.replace("%1", "ny"), 184 | url.replace("%1", "pz"), url.replace("%1", "nz") 185 | ]; 186 | 187 | this.updateState("texturesCube", name, false); 188 | this.data.texturesCube[name] = THREE.ImageUtils.loadTextureCube( 189 | urls, 190 | new THREE.CubeRefractionMapping(), 191 | function(){ 192 | self.updateState("texturesCube", name, true); 193 | } 194 | ); 195 | } 196 | 197 | bkcore.threejs.Loader.prototype.loadGeometry = function(name, url) 198 | { 199 | var self = this; 200 | this.data.geometries[name] = null; 201 | this.updateState("geometries", name, false); 202 | this.jsonLoader.load( 203 | url, 204 | function(a){ 205 | self.data.geometries[name] = a; 206 | self.updateState("geometries", name, true); 207 | } 208 | ); 209 | } 210 | 211 | bkcore.threejs.Loader.prototype.loadAnalyser = function(name, url) 212 | { 213 | var self = this; 214 | this.updateState("analysers", name, false); 215 | this.data.analysers[name] = new bkcore.ImageData( 216 | url, 217 | function(){ 218 | self.updateState("analysers", name, true); 219 | } 220 | ); 221 | } 222 | 223 | bkcore.threejs.Loader.prototype.loadImage = function(name, url) 224 | { 225 | var self = this; 226 | this.updateState("images", name, false); 227 | var e = new Image(); 228 | e.onload = function() { 229 | self.updateState("images", name, true) ; 230 | }; 231 | e.crossOrigin = "anonymous"; 232 | e.src = url; 233 | this.data.images[name] = e; 234 | } 235 | 236 | bkcore.threejs.Loader.prototype.loadSound = function(src, name, loop){ 237 | var self = this; 238 | this.updateState("sounds", name, false); 239 | 240 | bkcore.Audio.addSound( 241 | src, 242 | name, 243 | loop, 244 | function(){ 245 | self.updateState("sounds", name, true); 246 | } 247 | ); 248 | 249 | this.data.sounds[name] = { 250 | play: function(){ 251 | bkcore.Audio.play(name); 252 | }, 253 | stop: function(){ 254 | bkcore.Audio.stop(name); 255 | }, 256 | volume: function(vol){ 257 | bkcore.Audio.volume(name, vol); 258 | } 259 | }; 260 | }; -------------------------------------------------------------------------------- /bkcore/threejs/Particles.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * @class bkcore.threejs.Particles 3 | * 4 | * Particle system wrapper/helper 5 | * 6 | * @author Thibaut 'BKcore' Despoulain 7 | */ 8 | 9 | /*! 10 | * @package bkcore.threejs 11 | */ 12 | var bkcore = bkcore || {}; 13 | bkcore.threejs = bkcore.threejs || {}; 14 | 15 | /** 16 | * Creates a new particle system using given parameters 17 | * @param {Object{max, spawnRate, spawn, velocity, randomness, force, spawnRadius, life, friction, color, color2, tint, texture, size, blending, depthTest, transparent, opacity}} opts 18 | */ 19 | bkcore.threejs.Particles = function(opts) 20 | { 21 | this.black = new THREE.Color(0x000000); 22 | this.white = new THREE.Color(0xffffff); 23 | 24 | this.material = new THREE.ParticleBasicMaterial({ 25 | color: opts.tint == undefined ? 0xffffff : opts.tint, 26 | map: opts.texture == undefined ? null : opts.texture, 27 | size: opts.size == undefined ? 4 : opts.size, 28 | blending: opts.blending == undefined ? THREE.AdditiveBlending : opts.blending, 29 | depthTest: opts.depthTest == undefined ? false : opts.depthTest, 30 | transparent: opts.transparent == undefined ? true : opts.transparent, 31 | vertexColors: true, 32 | opacity: opts.opacity == undefined ? 1.0 : opts.opacity, 33 | sizeAttenuation: true 34 | }); 35 | 36 | this.max = opts.max == undefined ? 1000 : opts.max; 37 | this.spawnRate = opts.spawnRate == undefined ? 0 : opts.spawnRate; 38 | 39 | this.spawn = opts.spawn == undefined ? new THREE.Vector3() : opts.spawn; 40 | this.velocity = opts.velocity == undefined ? new THREE.Vector3() : opts.velocity; 41 | this.randomness = opts.randomness == undefined ? new THREE.Vector3() : opts.randomness; 42 | this.force = opts.force == undefined ? new THREE.Vector3() : opts.force; 43 | this.spawnRadius = opts.spawnRadius == undefined ? new THREE.Vector3() : opts.spawnRadius; 44 | this.life = opts.life == undefined ? 60 : opts.life; 45 | this.ageing = 1 / this.life; 46 | this.friction = opts.friction == undefined ? 1.0 : opts.friction; 47 | this.color = new THREE.Color(opts.color == undefined ? 0xffffff : opts.color); 48 | this.color2 = opts.color2 == undefined ? null : new THREE.Color(opts.color2); 49 | 50 | this.position = opts.position == undefined ? new THREE.Vector3() : opts.position; 51 | this.rotation = opts.rotation == undefined ? new THREE.Vector3() : opts.rotation; 52 | this.sort = opts.sort == undefined ? false : opts.sort; 53 | 54 | this.pool = []; 55 | this.buffer = []; 56 | this.geometry = null; 57 | this.system = null; 58 | 59 | this.build(); 60 | } 61 | 62 | bkcore.threejs.Particles.prototype.build = function() 63 | { 64 | this.geometry = new THREE.Geometry(); 65 | this.geometry.dynamic = true; 66 | 67 | this.pool = []; 68 | this.buffer = []; 69 | 70 | for(var i = 0; i < this.max; ++i) 71 | { 72 | var p = new bkcore.threejs.Particle(); 73 | this.pool.push(p); 74 | this.buffer.push(p); 75 | this.geometry.vertices.push(p.position); 76 | this.geometry.colors.push(p.color); 77 | } 78 | 79 | this.system = new THREE.ParticleSystem(this.geometry, this.material); 80 | this.system.position = this.position; 81 | this.system.rotation = this.rotation; 82 | this.system.sort = this.sort; 83 | } 84 | 85 | /** 86 | * Emits given number of particles 87 | * @param int count 88 | */ 89 | bkcore.threejs.Particles.prototype.emit = function(count) 90 | { 91 | var emitable = Math.min(count, this.pool.length); 92 | for(var i = 0; i < emitable; ++i) 93 | { 94 | var p = this.pool.pop(); 95 | p.available = false; 96 | p.position.copy(this.spawn) 97 | .addSelf( 98 | this.randomVector() 99 | .multiplySelf(this.spawnRadius) 100 | ); 101 | p.velocity.copy(this.velocity) 102 | .addSelf( 103 | this.randomVector() 104 | .multiplySelf(this.randomness) 105 | ); 106 | p.force.copy(this.force); 107 | p.basecolor.copy(this.color); 108 | if(this.color2 != undefined) p.basecolor.lerpSelf(this.color2, Math.random()); 109 | p.life = 1.0; 110 | } 111 | } 112 | 113 | bkcore.threejs.Particles.prototype.randomVector = function() 114 | { 115 | return new THREE.Vector3( 116 | Math.random()*2-1, 117 | Math.random()*2-1, 118 | Math.random()*2-1 119 | ); 120 | } 121 | 122 | /** 123 | * Updates particles (should be call in a RAF loop) 124 | * @param float dt time delta ~1.0 125 | */ 126 | bkcore.threejs.Particles.prototype.update = function(dt) 127 | { 128 | var p, l; 129 | var df = new THREE.Vector3(); 130 | var dv = new THREE.Vector3(); 131 | for(var i = 0; i < this.buffer.length; ++i) 132 | { 133 | 134 | p = this.buffer[i]; 135 | 136 | if(p.available) continue; 137 | 138 | p.life -= this.ageing; 139 | 140 | if(p.life <= 0 && !p.available) 141 | { 142 | p.reset(); 143 | this.pool.push(p); 144 | continue; 145 | } 146 | 147 | l = p.life > 0.5 ? 1.0 : p.life + 0.5; 148 | p.color.setRGB( 149 | l * p.basecolor.r, 150 | l * p.basecolor.g, 151 | l * p.basecolor.b 152 | ); 153 | 154 | if(this.friction != 1.0) 155 | p.velocity.multiplyScalar(this.friction); 156 | 157 | df.copy(p.force).multiplyScalar(dt); 158 | p.velocity.addSelf(df); 159 | 160 | dv.copy(p.velocity).multiplyScalar(dt); 161 | p.position.addSelf(dv); 162 | } 163 | 164 | if(this.spawnRate > 0) 165 | this.emit(this.spawnRate); 166 | 167 | this.geometry.verticesNeedUpdate = true; 168 | this.geometry.colorsNeedUpdate = true; 169 | } 170 | 171 | bkcore.threejs.Particle = function() 172 | { 173 | this.position = new THREE.Vector3(-10000,-10000,-10000); 174 | this.velocity = new THREE.Vector3(); 175 | this.force = new THREE.Vector3(); 176 | this.color = new THREE.Color(0x000000); 177 | this.basecolor = new THREE.Color(0x000000); 178 | this.life = 0.0; 179 | this.available = true; 180 | } 181 | 182 | bkcore.threejs.Particle.prototype.reset = function() 183 | { 184 | this.position.set(0,-100000,0); 185 | this.velocity.set(0,0,0); 186 | this.force.set(0,0,0); 187 | this.color.setRGB(0,0,0); 188 | this.basecolor.setRGB(0,0,0); 189 | this.life = 0.0; 190 | this.available = true; 191 | } -------------------------------------------------------------------------------- /bkcore/threejs/Preloader.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * @class bkcore.threejs.Preloader 3 | * 4 | * Displays a small 3D preloader scene 5 | * 6 | * @author Thibaut 'BKcore' Despoulain 7 | */ 8 | 9 | /*! 10 | * @package bkcore.threejs 11 | */ 12 | var bkcore = bkcore || {}; 13 | bkcore.threejs = bkcore.threejs || {}; 14 | 15 | /** 16 | * Creates a new preloader scene. 17 | * You have to update Preloader.ratio with the % loaded info (float 0.0-1.0) 18 | * @param {Object{width, height, scale, line}} opts 19 | */ 20 | bkcore.threejs.Preloader = function(opts) 21 | { 22 | this.document = opts.document || document; 23 | 24 | this.end = false; 25 | 26 | this.time = 0.0; 27 | this.y = 0.3; 28 | this.ratio = 0.0; 29 | 30 | this.height = opts.height; 31 | this.width = opts.width; 32 | 33 | this.scale = opts.scale == undefined ? 10 : opts.scale 34 | this.line = opts.line == undefined ? 3 : opts.line; 35 | 36 | this.container = opts.container; 37 | 38 | this.renderer = new THREE.CanvasRenderer({ 39 | clearColor: 0xffffff 40 | }); 41 | this.renderer.setSize( opts.width, opts.height ); 42 | 43 | this.container.appendChild( this.renderer.domElement ); 44 | 45 | this.ctx = this.renderer.domElement.getContext('2d'); 46 | this.ctx.textAlign = "center"; 47 | 48 | this.scene = new THREE.Scene(); 49 | 50 | this.camera = new THREE.PerspectiveCamera( 70, opts.width / opts.height, 1, 1000 ); 51 | this.camera.position.z = 100; 52 | this.scene.add( this.camera ); 53 | 54 | this.stage = new THREE.Object3D(); 55 | this.stage.position.set(0,10,0); 56 | this.scene.add(this.stage); 57 | 58 | this.cube = new THREE.Mesh( new THREE.CubeGeometry( this.scale, this.scale, this.scale, 1, 1, 1 ), 59 | new THREE.MeshBasicMaterial( { color: 0x999999 } ) ); 60 | 61 | this.cube.scale.set(0.0,0.0,0.0); 62 | this.stage.add(this.cube); 63 | 64 | this.cubew = new THREE.Mesh( new THREE.CubeGeometry( this.scale, this.scale, this.scale, 1, 1, 1 ), 65 | new THREE.MeshBasicMaterial( { 66 | wireframe: true, 67 | wireframeLinewidth: this.line, 68 | //wireframeLinecap: 'square', 69 | //wireframeLinejoin: 'square', 70 | color: 0xffffff 71 | } ) ); 72 | this.cube.add(this.cubew); 73 | 74 | this.outercube = new THREE.Mesh( new THREE.CubeGeometry( this.scale, this.scale, this.scale, 1, 1, 1 ), 75 | new THREE.MeshBasicMaterial( { 76 | wireframe: true, 77 | wireframeLinewidth: this.line, 78 | //wireframeLinecap: 'square', 79 | //wireframeLinejoin: 'square', 80 | color: 0x0093d8 81 | } ) ); 82 | this.stage.add(this.outercube); 83 | 84 | var self = this; 85 | 86 | function raf() 87 | { 88 | if(!self.end) 89 | { 90 | requestAnimationFrame( raf ); 91 | self.render(); 92 | } 93 | } 94 | raf(); 95 | 96 | function mm(e){ 97 | self.mouseMove.call(self, e); 98 | } 99 | 100 | this.mmsave = mm; 101 | 102 | this.document.addEventListener( 'mousemove', mm, false ); 103 | } 104 | 105 | /** 106 | * Render method to be called from a RAF loop 107 | */ 108 | bkcore.threejs.Preloader.prototype.render = function() 109 | { 110 | this.time += 0.02; 111 | 112 | this.ctx.clearRect(0 , 0 , this.width , this.height); 113 | 114 | var s = (this.ratio - this.cube.scale.x) * 0.3; 115 | 116 | this.cube.scale.addScalar(s); 117 | this.cube.rotation.y = this.time; 118 | this.outercube.rotation.y = this.time; 119 | 120 | this.stage.rotation.x += (this.y - this.stage.rotation.x)*0.3; 121 | 122 | this.renderer.render( this.scene, this.camera ); 123 | 124 | this.ctx.save(); 125 | this.ctx.font = "40px Arial"; 126 | this.ctx.fillStyle = "rgb(200, 200, 200)"; 127 | this.ctx.fillText(Math.round(this.ratio*100), this.width/2, this.height/2+30); 128 | this.ctx.restore(); 129 | } 130 | 131 | bkcore.threejs.Preloader.prototype.mouseMove = function(event) 132 | { 133 | var h2 = this.height/2; 134 | this.y = -(event.clientY - h2)/h2+0.3; 135 | } 136 | 137 | /** 138 | * Deletes the Preloader 139 | */ 140 | bkcore.threejs.Preloader.prototype.remove = function() 141 | { 142 | this.document.removeEventListener( 'mousemove', this.mm, false ); 143 | this.end = true; 144 | this.renderer = null; 145 | this.scene = null; 146 | this.stage = null; 147 | this.cube = null; 148 | this.cubew = null; 149 | this.innercube = null; 150 | this.container.innerHTML = ""; 151 | } -------------------------------------------------------------------------------- /bkcore/threejs/RenderManager.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bkcore.threejs.RenderManager helps handling multiple scenes, cameras and render loops. 3 | * 4 | * @author Thibaut 'BKcore' Despoulain 5 | * @license MIT 6 | * 7 | * Initialize the a RenderManager by passing a Renderer object: 8 | * var renderManager = new bkcore.threejs.RenderManager(new THREE.WebGLRenderer()); 9 | * 10 | * A render setup structure : 11 | * { 12 | * id : render setup ID, 13 | * scene : main scene, 14 | * camera : main camera, 15 | * render : render loop called when render setup is active (current), 16 | * objects : object references accessible in the render loop via this.objects 17 | * } 18 | * 19 | * The render method's context will be the render setup's object, so in your render loop: 20 | * function(delta, renderer) 21 | * { 22 | * this.scene; 23 | * this.camera; 24 | * this.id; 25 | * this.objects; 26 | * renderer.render(...); 27 | * } 28 | * 29 | * Use the "objects" attribute to store useful references and variables like time, geometries, materials, etc. 30 | * Example: 31 | * renderManager.add('mySetup', scene, camera, function(delta, renderer) 32 | * { 33 | * this.objects.timer += delta; 34 | * this.objects.torus.rotation.z = Math.PI * Math.cos(this.objects.timer); 35 | * renderer.render(this.scene, this.camera); 36 | * }, 37 | * { 38 | * timer: 0, 39 | * torus: torusMesh 40 | * }); 41 | */ 42 | 43 | var bkcore = bkcore || {}; 44 | bkcore.threejs = bkcore.threejs || {}; 45 | 46 | (function(w){ 47 | var perfNow; 48 | var perfNowNames = ['now', 'webkitNow', 'msNow', 'mozNow']; 49 | if(!!w['performance']) for(var i = 0; i < perfNowNames.length; ++i) 50 | { 51 | var n = perfNowNames[i]; 52 | if(!!w['performance'][n]) 53 | { 54 | perfNow = function(){return w['performance'][n]()}; 55 | break; 56 | } 57 | } 58 | if(!perfNow) 59 | { 60 | perfNow = Date.now; 61 | } 62 | w.perfNow = perfNow; 63 | })(window); 64 | 65 | bkcore.threejs.RenderManager = function(renderer) 66 | { 67 | this.renderer = renderer; 68 | this.time = window.perfNow(); 69 | 70 | this.renders = {}; 71 | this.current = {}; 72 | this.size = 0; 73 | 74 | this.defaultRenderMethod = function(delta, renderer) 75 | { 76 | renderer.render(this.scene, this.camera); 77 | }; 78 | }; 79 | 80 | bkcore.threejs.RenderManager.prototype.add = function(id, scene, camera, render, objects) 81 | { 82 | render = render || this.defaultRenderMethod; 83 | objects = objects || {}; 84 | 85 | this.renders[id] = { 86 | id: id, 87 | scene: scene, 88 | camera: camera, 89 | render: render, 90 | objects: objects 91 | }; 92 | 93 | if(this.size == 0) this.current = this.renders[id]; 94 | 95 | this.size++; 96 | }; 97 | 98 | bkcore.threejs.RenderManager.prototype.get = function(id) 99 | { 100 | return this.renders[id]; 101 | }; 102 | 103 | bkcore.threejs.RenderManager.prototype.remove = function(id) 104 | { 105 | if(id in this.renders) 106 | { 107 | delete this.renders[id]; 108 | this.size--; 109 | } 110 | }; 111 | 112 | bkcore.threejs.RenderManager.prototype.renderCurrent = function() 113 | { 114 | if(this.current && this.current.render) 115 | { 116 | var now = window.perfNow(); 117 | var delta = now - this.time; 118 | this.time = now; 119 | 120 | this.current.render.call(this.current, delta, this.renderer); 121 | } 122 | else console.warn('RenderManager: No current render defined.'); 123 | }; 124 | 125 | bkcore.threejs.RenderManager.prototype.setCurrent = function(id) 126 | { 127 | if(id in this.renders) 128 | { 129 | this.current = this.renders[id]; 130 | } 131 | else console.warn('RenderManager: Render "'+id+'" not found.'); 132 | }; -------------------------------------------------------------------------------- /cache.appcache: -------------------------------------------------------------------------------- 1 | CACHE MANIFEST 2 | # v1.0.1-ffos-201302192207 3 | # HexGL by Thibaut Despoulain (BKcore.com) 4 | index.html 5 | css/BebasNeue-webfont.eot 6 | css/BebasNeue-webfont.ttf 7 | css/fonts.css 8 | css/mobile-controls-2.jpg 9 | css/mobile-over.jpg 10 | css/BebasNeue-webfont.svg 11 | css/BebasNeue-webfont.woff 12 | css/mobile-controls-1.jpg 13 | css/mobile.jpg 14 | css/touchcontroller.css 15 | libs/Three.dev.js 16 | libs/ShaderExtras.js 17 | libs/postprocessing/EffectComposer.js 18 | libs/postprocessing/RenderPass.js 19 | libs/postprocessing/BloomPass.js 20 | libs/postprocessing/ShaderPass.js 21 | libs/postprocessing/MaskPass.js 22 | libs/Detector.js 23 | libs/Stats.js 24 | libs/DAT.GUI.min.js 25 | bkcore.coffee/controllers/TouchController.js 26 | bkcore.coffee/controllers/OrientationController.js 27 | bkcore/Timer.js 28 | bkcore/ImageData.js 29 | bkcore/Utils.js 30 | bkcore/threejs/RenderManager.js 31 | bkcore/threejs/Shaders.js 32 | bkcore/threejs/Particles.js 33 | bkcore/threejs/Loader.js 34 | bkcore/hexgl/HUD.js 35 | bkcore/hexgl/RaceData.js 36 | bkcore/hexgl/ShipControls.js 37 | bkcore/hexgl/ShipEffects.js 38 | bkcore/hexgl/CameraChase.js 39 | bkcore/hexgl/Gameplay.js 40 | bkcore/hexgl/tracks/Cityscape.js 41 | bkcore/hexgl/HexGL.js 42 | geometries/bonus/base/base.js 43 | geometries/booster/booster.js 44 | geometries/ships/feisar/feisar.js 45 | geometries/tracks/cityscape/scrapers1.js 46 | geometries/tracks/cityscape/scrapers2.js 47 | geometries/tracks/cityscape/startbanner.js 48 | geometries/tracks/cityscape/start.js 49 | geometries/tracks/cityscape/track.js 50 | geometries/tracks/cityscape/bonus/speed.js 51 | textures/tracks/cityscape/collision.png 52 | textures/tracks/cityscape/diffuse.jpg 53 | textures/tracks/cityscape/height.png 54 | textures/tracks/cityscape/start/diffuse.jpg 55 | textures/tracks/cityscape/start/start.jpg 56 | textures/tracks/cityscape/scrapers2/diffuse.jpg 57 | textures/tracks/cityscape/scrapers1/diffuse.jpg 58 | textures/skybox/dawnclouds/nx.jpg 59 | textures/skybox/dawnclouds/ny.jpg 60 | textures/skybox/dawnclouds/nz.jpg 61 | textures/skybox/dawnclouds/px.jpg 62 | textures/skybox/dawnclouds/pz.jpg 63 | textures/skybox/dawnclouds/py.jpg 64 | textures/ships/feisar/diffuse.jpg 65 | textures/ships/feisar/booster/booster.png 66 | textures/ships/feisar/booster/boostersprite.jpg 67 | textures/bonus/base/diffuse.jpg 68 | textures/particles/cloud.png 69 | textures/particles/damage.png 70 | textures/particles/spark.png 71 | textures/hud/hud-bg.png 72 | textures/hud/hex.jpg 73 | textures/hud/hud-fg-speed.png 74 | textures/hud/hud-fg-shield.png -------------------------------------------------------------------------------- /css/BebasNeue-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/BebasNeue-webfont.eot -------------------------------------------------------------------------------- /css/BebasNeue-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/BebasNeue-webfont.ttf -------------------------------------------------------------------------------- /css/BebasNeue-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/BebasNeue-webfont.woff -------------------------------------------------------------------------------- /css/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/bg.jpg -------------------------------------------------------------------------------- /css/fonts.css: -------------------------------------------------------------------------------- 1 | /* Generated by Font Squirrel (http://www.fontsquirrel.com) on July 28, 2012 03:24:04 PM America/New_York */ 2 | 3 | 4 | 5 | @font-face { 6 | font-family: 'BebasNeueRegular'; 7 | src: url('BebasNeue-webfont.eot'); 8 | src: url('BebasNeue-webfont.eot?#iefix') format('embedded-opentype'), 9 | url('BebasNeue-webfont.woff') format('woff'), 10 | url('BebasNeue-webfont.ttf') format('truetype'), 11 | url('BebasNeue-webfont.svg#BebasNeueRegular') format('svg'); 12 | font-weight: normal; 13 | font-style: normal; 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /css/help-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/help-0.png -------------------------------------------------------------------------------- /css/help-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/help-1.png -------------------------------------------------------------------------------- /css/help-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/help-2.png -------------------------------------------------------------------------------- /css/help-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/help-3.png -------------------------------------------------------------------------------- /css/mobile-controls-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/mobile-controls-1.jpg -------------------------------------------------------------------------------- /css/mobile-controls-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/mobile-controls-2.jpg -------------------------------------------------------------------------------- /css/mobile-over.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/mobile-over.jpg -------------------------------------------------------------------------------- /css/mobile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/mobile.jpg -------------------------------------------------------------------------------- /css/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/css/title.png -------------------------------------------------------------------------------- /css/touchcontroller.css: -------------------------------------------------------------------------------- 1 | * { 2 | -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ 3 | -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ 4 | /* make transparent link selection, adjust last value opacity 0 to 1.0 */ 5 | -webkit-tap-highlight-color: rgba(0,0,0,0); 6 | -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */ 7 | -webkit-tap-highlight-color: rgba(0,0,0,0); 8 | } -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/favicon.png -------------------------------------------------------------------------------- /geometries/booster/booster.js: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "metadata" : 4 | { 5 | "formatVersion" : 3.1, 6 | "sourceFile" : "booster.obj", 7 | "generatedBy" : "OBJConverter", 8 | "vertices" : 48, 9 | "faces" : 72, 10 | "normals" : 48, 11 | "colors" : 0, 12 | "uvs" : 52, 13 | "materials" : 1 14 | }, 15 | 16 | "scale" : 1.000000, 17 | 18 | "materials": [ { 19 | "DbgColor" : 15658734, 20 | "DbgIndex" : 0, 21 | "DbgName" : "02___Default", 22 | "colorAmbient" : [0.588235, 0.588235, 0.588235], 23 | "colorDiffuse" : [0.588235, 0.588235, 0.588235], 24 | "colorSpecular" : [0.0, 0.0, 0.0], 25 | "illumination" : 2, 26 | "opticalDensity" : 1.5, 27 | "specularCoef" : 9.999999, 28 | "transparency" : 0.0 29 | }], 30 | 31 | "vertices": [0.177146,0.211115,-0.000000,0.258970,0.094257,0.000000,0.369958,0.134654,-0.121302,0.253066,0.301592,-0.121302,0.271404,-0.047856,0.000000,0.387720,-0.068365,-0.121302,0.211115,-0.177146,0.000000,0.301592,-0.253066,-0.121302,0.094257,-0.258970,0.000000,0.134654,-0.369958,-0.121302,-0.047856,-0.271404,0.000000,-0.068365,-0.387720,-0.121302,-0.177146,-0.211115,0.000000,-0.253066,-0.301592,-0.121302,-0.258970,-0.094258,-0.000000,-0.369958,-0.134654,-0.121302,-0.271404,0.047856,-0.000000,-0.387720,0.068365,-0.121302,-0.211115,0.177146,-0.000000,-0.301592,0.253066,-0.121302,-0.094258,0.258970,-0.000000,-0.134654,0.369958,-0.121302,0.047856,0.271404,-0.000000,0.068365,0.387720,-0.121302,0.480945,0.175050,-0.659920,0.328986,0.392070,-0.659920,0.504035,-0.088875,-0.659920,0.392070,-0.328986,-0.659920,0.175050,-0.480945,-0.659920,-0.088875,-0.504035,-0.659920,-0.328986,-0.392070,-0.659920,-0.480945,-0.175050,-0.659920,-0.504035,0.088875,-0.659920,-0.392070,0.328985,-0.659920,-0.175050,0.480945,-0.659920,0.088875,0.504035,-0.659920,0.266370,0.096951,-2.900593,0.182208,0.217146,-2.900593,0.279158,-0.049223,-2.900593,0.217146,-0.182208,-2.900593,0.096951,-0.266370,-2.900593,-0.049223,-0.279158,-2.900593,-0.182207,-0.217146,-2.900593,-0.266369,-0.096951,-2.900593,-0.279158,0.049223,-2.900593,-0.217146,0.182207,-2.900593,-0.096951,0.266369,-2.900593,0.049223,0.279158,-2.900593], 32 | 33 | "morphTargets": [], 34 | 35 | "morphColors": [], 36 | 37 | "normals": [0.46054,0.54885,0.69762,0.67326,0.24505,0.69762,0.83624,0.30436,0.45615,0.57202,0.68171,0.45615,0.70559,-0.12441,0.69762,0.87638,-0.15453,0.45615,0.54885,-0.46054,0.69762,0.68171,-0.57202,0.45615,0.24505,-0.67326,0.69762,0.30436,-0.83624,0.45615,-0.12441,-0.70559,0.69762,-0.15453,-0.87638,0.45615,-0.46054,-0.54885,0.69762,-0.57202,-0.68171,0.45615,-0.67326,-0.24505,0.69762,-0.83624,-0.30436,0.45615,-0.70559,0.12441,0.69762,-0.87638,0.15453,0.45615,-0.54885,0.46054,0.69762,-0.68171,0.57202,0.45615,-0.24505,0.67326,0.69762,-0.30436,0.83624,0.45615,0.12441,0.70559,0.69762,0.15453,0.87638,0.45615,0.93823,0.34149,0.055692,0.64179,0.76486,0.055692,0.98328,-0.17338,0.055692,0.76486,-0.64179,0.055692,0.34149,-0.93823,0.055692,-0.17338,-0.98328,0.055692,-0.64179,-0.76486,0.055692,-0.93823,-0.34149,0.055692,-0.98328,0.17338,0.055692,-0.76486,0.64179,0.055692,-0.34149,0.93823,0.055692,0.17338,0.98328,0.055692,0.93485,0.34026,-0.10139,0.63948,0.7621,-0.10139,0.97973,-0.17275,-0.10139,0.7621,-0.63948,-0.10139,0.34026,-0.93485,-0.10139,-0.17275,-0.97973,-0.10139,-0.63948,-0.7621,-0.10139,-0.93485,-0.34026,-0.10139,-0.97973,0.17275,-0.10139,-0.7621,0.63948,-0.10139,-0.34026,0.93485,-0.10139,0.17275,0.97973,-0.10139], 38 | 39 | "colors": [], 40 | 41 | "uvs": [[0.58311,1.0001,0.49977,1.0001,0.49977,0.9583,0.58311,0.9583,0.41644,1.0001,0.41644,0.9583,0.33311,1.0001,0.33311,0.9583,0.24977,1.0001,0.24977,0.9583,0.16644,1.0001,0.16644,0.9583,0.083106,1.0001,0.083106,0.9583,-0.000227,1.0001,-0.000227,0.9583,0.99977,1.0001,0.91644,1.0001,0.91644,0.9583,0.99977,0.9583,0.83311,1.0001,0.83311,0.9583,0.74977,1.0001,0.74977,0.9583,0.66644,1.0001,0.66644,0.9583,0.49977,0.77261,0.58311,0.77261,0.41644,0.77261,0.33311,0.77261,0.24977,0.77261,0.16644,0.77261,0.083106,0.77261,-0.000227,0.77261,0.91644,0.77261,0.99977,0.77261,0.83311,0.77261,0.74977,0.77261,0.66644,0.77261,0.49977,0.000123,0.58311,0.000123,0.41644,0.000123,0.33311,0.000123,0.24977,0.000123,0.16644,0.000123,0.083106,0.000123,-0.000227,0.000123,0.91644,0.000123,0.99977,0.000123,0.83311,0.000123,0.74977,0.000123,0.66644,0.000123]], 42 | 43 | "faces": [42,0,1,2,0,0,1,2,0,1,2,42,2,3,0,0,2,3,0,2,3,0,42,1,4,5,0,1,4,5,1,4,5,42,5,2,1,0,5,2,1,5,2,1,42,4,6,7,0,4,6,7,4,6,7,42,7,5,4,0,7,5,4,7,5,4,42,6,8,9,0,6,8,9,6,8,9,42,9,7,6,0,9,7,6,9,7,6,42,8,10,11,0,8,10,11,8,10,11,42,11,9,8,0,11,9,8,11,9,8,42,10,12,13,0,10,12,13,10,12,13,42,13,11,10,0,13,11,10,13,11,10,42,12,14,15,0,12,14,15,12,14,15,42,15,13,12,0,15,13,12,15,13,12,42,14,16,17,0,16,17,18,14,16,17,42,17,15,14,0,18,19,16,17,15,14,42,16,18,19,0,17,20,21,16,18,19,42,19,17,16,0,21,18,17,19,17,16,42,18,20,21,0,20,22,23,18,20,21,42,21,19,18,0,23,21,20,21,19,18,42,20,22,23,0,22,24,25,20,22,23,42,23,21,20,0,25,23,22,23,21,20,42,22,0,3,0,24,0,3,22,0,3,42,3,23,22,0,3,25,24,3,23,22,42,3,2,24,0,3,2,26,3,2,24,42,24,25,3,0,26,27,3,24,25,3,42,2,5,26,0,2,5,28,2,5,26,42,26,24,2,0,28,26,2,26,24,2,42,5,7,27,0,5,7,29,5,7,27,42,27,26,5,0,29,28,5,27,26,5,42,7,9,28,0,7,9,30,7,9,28,42,28,27,7,0,30,29,7,28,27,7,42,9,11,29,0,9,11,31,9,11,29,42,29,28,9,0,31,30,9,29,28,9,42,11,13,30,0,11,13,32,11,13,30,42,30,29,11,0,32,31,11,30,29,11,42,13,15,31,0,13,15,33,13,15,31,42,31,30,13,0,33,32,13,31,30,13,42,15,17,32,0,19,18,34,15,17,32,42,32,31,15,0,34,35,19,32,31,15,42,17,19,33,0,18,21,36,17,19,33,42,33,32,17,0,36,34,18,33,32,17,42,19,21,34,0,21,23,37,19,21,34,42,34,33,19,0,37,36,21,34,33,19,42,21,23,35,0,23,25,38,21,23,35,42,35,34,21,0,38,37,23,35,34,21,42,23,3,25,0,25,3,27,23,3,25,42,25,35,23,0,27,38,25,25,35,23,42,25,24,36,0,27,26,39,25,24,36,42,36,37,25,0,39,40,27,36,37,25,42,24,26,38,0,26,28,41,24,26,38,42,38,36,24,0,41,39,26,38,36,24,42,26,27,39,0,28,29,42,26,27,39,42,39,38,26,0,42,41,28,39,38,26,42,27,28,40,0,29,30,43,27,28,40,42,40,39,27,0,43,42,29,40,39,27,42,28,29,41,0,30,31,44,28,29,41,42,41,40,28,0,44,43,30,41,40,28,42,29,30,42,0,31,32,45,29,30,42,42,42,41,29,0,45,44,31,42,41,29,42,30,31,43,0,32,33,46,30,31,43,42,43,42,30,0,46,45,32,43,42,30,42,31,32,44,0,35,34,47,31,32,44,42,44,43,31,0,47,48,35,44,43,31,42,32,33,45,0,34,36,49,32,33,45,42,45,44,32,0,49,47,34,45,44,32,42,33,34,46,0,36,37,50,33,34,46,42,46,45,33,0,50,49,36,46,45,33,42,34,35,47,0,37,38,51,34,35,47,42,47,46,34,0,51,50,37,47,46,34,42,35,25,37,0,38,27,40,35,25,37,42,37,47,35,0,40,51,38,37,47,35] 44 | 45 | } 46 | -------------------------------------------------------------------------------- /geometries/tracks/cityscape/startbanner.js: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "metadata" : 4 | { 5 | "formatVersion" : 3.1, 6 | "sourceFile" : "startbanner.obj", 7 | "generatedBy" : "OBJConverter", 8 | "vertices" : 12, 9 | "faces" : 10, 10 | "normals" : 6, 11 | "colors" : 0, 12 | "uvs" : 12, 13 | "materials" : 1 14 | }, 15 | 16 | "scale" : 1.000000, 17 | 18 | "materials": [ { 19 | "DbgColor" : 15658734, 20 | "DbgIndex" : 0, 21 | "DbgName" : "13___Default", 22 | "colorAmbient" : [0.588235, 0.588235, 0.588235], 23 | "colorDiffuse" : [0.588235, 0.588235, 0.588235], 24 | "colorSpecular" : [0.0, 0.0, 0.0], 25 | "illumination" : 2, 26 | "opticalDensity" : 1.5, 27 | "specularCoef" : 9.999999, 28 | "transparency" : 0.0 29 | }], 30 | 31 | "vertices": [-2308.439453,424.299988,-633.529297,-2290.839355,424.299988,-625.660400,-2290.839355,407.919983,-625.660400,-2308.439453,407.919983,-633.529297,-2273.239502,424.299988,-621.725891,-2273.239502,407.919983,-621.725891,-2255.639404,424.299988,-621.725891,-2255.639404,407.919983,-621.725891,-2238.039551,424.299988,-625.660400,-2238.039551,407.919983,-625.660400,-2220.439453,424.299988,-633.529297,-2220.439453,407.919983,-633.529297], 32 | 33 | "morphTargets": [], 34 | 35 | "morphColors": [], 36 | 37 | "normals": [0.40816,-0,-0.91291,0.31474,-0,-0.94918,0.10974,-0,-0.99396,-0.10974,-0,-0.99396,-0.31474,-0,-0.94918,-0.40816,-0,-0.91291], 38 | 39 | "colors": [], 40 | 41 | "uvs": [[1,1,0.8,1,0.8,0,1,0,0.6,1,0.6,0,0.4,1,0.4,0,0.2,1,0.2,0,0,1,0,0]], 42 | 43 | "faces": [42,0,1,2,0,0,1,2,0,1,1,42,2,3,0,0,2,3,0,1,0,0,42,1,4,5,0,1,4,5,1,2,2,42,5,2,1,0,5,2,1,2,1,1,42,4,6,7,0,4,6,7,2,3,3,42,7,5,4,0,7,5,4,3,2,2,42,6,8,9,0,6,8,9,3,4,4,42,9,7,6,0,9,7,6,4,3,3,42,8,10,11,0,8,10,11,4,5,5,42,11,9,8,0,11,9,8,5,4,4] 44 | 45 | } 46 | -------------------------------------------------------------------------------- /icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/icon_128.png -------------------------------------------------------------------------------- /icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/icon_256.png -------------------------------------------------------------------------------- /icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/icon_32.png -------------------------------------------------------------------------------- /icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/icon_64.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HexGL by BKcore 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 32 | 43 | 44 | 45 | 46 |
47 |
48 |
49 |
50 | 60 |
61 | 64 | 67 | 71 | 75 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /launch.coffee: -------------------------------------------------------------------------------- 1 | $ = (_) -> document.getElementById _ 2 | 3 | init = (controlType, quality, hud, godmode) -> 4 | hexGL = new bkcore.hexgl.HexGL( 5 | document: document 6 | width: window.innerWidth 7 | height: window.innerHeight 8 | container: $ 'main' 9 | overlay: $ 'overlay' 10 | gameover: $ 'step-5' 11 | quality: quality 12 | difficulty: 0 13 | hud: hud is 1 14 | controlType: controlType 15 | godmode: godmode 16 | track: 'Cityscape' 17 | ) 18 | window.hexGL=hexGL 19 | 20 | progressbar = $ 'progressbar' 21 | hexGL.load( 22 | onLoad: -> 23 | console.log 'LOADED.' 24 | hexGL.init() 25 | $('step-3').style.display = 'none' 26 | $('step-4').style.display = 'block' 27 | hexGL.start() 28 | onError: (s) -> 29 | console.error "Error loading #{ s }." 30 | onProgress: (p, t, n) -> 31 | console.log("LOADED "+t+" : "+n+" ( "+p.loaded+" / "+p.total+" ).") 32 | progressbar.style.width = "#{ p.loaded / p.total * 100 }%" 33 | ) 34 | 35 | u = bkcore.Utils.getURLParameter 36 | 37 | defaultControls = if bkcore.Utils.isTouchDevice() then 1 else 0 38 | 39 | s = [ 40 | ['controlType', ['KEYBOARD', 'TOUCH', 'LEAP MOTION CONTROLLER', 41 | 'GAMEPAD'], defaultControls, defaultControls, 'Controls: '] 42 | ['quality', ['LOW', 'MID', 'HIGH', 'VERY HIGH'], 3, 3, 'Quality: '] 43 | ['hud', ['OFF', 'ON'], 1, 1, 'HUD: '] 44 | ['godmode', ['OFF', 'ON'], 0, 1, 'Godmode: '] 45 | ] 46 | 47 | for a in s 48 | do(a)-> 49 | a[3] = u(a[0]) ? a[2] 50 | e = $ "s-#{a[0]}" 51 | (f = -> e.innerHTML = a[4]+a[1][a[3]])() 52 | e.onclick = -> f(a[3] = (a[3]+1)%a[1].length) 53 | $('step-2').onclick = -> 54 | $('step-2').style.display = 'none' 55 | $('step-3').style.display = 'block' 56 | init s[0][3], s[1][3], s[2][3], s[3][3] 57 | $('step-5').onclick = -> 58 | window.location.reload() 59 | $('s-credits').onclick = -> 60 | $('step-1').style.display = 'none' 61 | $('credits').style.display = 'block' 62 | $('credits').onclick = -> 63 | $('step-1').style.display = 'block' 64 | $('credits').style.display = 'none' 65 | 66 | hasWebGL = -> 67 | gl = null 68 | canvas = document.createElement('canvas'); 69 | try 70 | gl = canvas.getContext("webgl") 71 | if not gl? 72 | try 73 | gl = canvas.getContext("experimental-webgl") 74 | return gl? 75 | 76 | if not hasWebGL() 77 | getWebGL = $('start') 78 | getWebGL.innerHTML = 'WebGL is not supported!' 79 | getWebGL.onclick = -> 80 | window.location.href = 'http://get.webgl.org/' 81 | else 82 | $('start').onclick = -> 83 | $('step-1').style.display = 'none' 84 | $('step-2').style.display = 'block' 85 | $('step-2').style.backgroundImage = "url(css/help-#{s[0][3]}.png)" 86 | -------------------------------------------------------------------------------- /launch.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.7.1 2 | (function() { 3 | var $, a, defaultControls, getWebGL, hasWebGL, init, s, u, _fn, _i, _len; 4 | 5 | $ = function(_) { 6 | return document.getElementById(_); 7 | }; 8 | 9 | init = function(controlType, quality, hud, godmode) { 10 | var hexGL, progressbar; 11 | hexGL = new bkcore.hexgl.HexGL({ 12 | document: document, 13 | width: window.innerWidth, 14 | height: window.innerHeight, 15 | container: $('main'), 16 | overlay: $('overlay'), 17 | gameover: $('step-5'), 18 | quality: quality, 19 | difficulty: 0, 20 | hud: hud === 1, 21 | controlType: controlType, 22 | godmode: godmode, 23 | track: 'Cityscape' 24 | }); 25 | window.hexGL = hexGL; 26 | progressbar = $('progressbar'); 27 | return hexGL.load({ 28 | onLoad: function() { 29 | console.log('LOADED.'); 30 | hexGL.init(); 31 | $('step-3').style.display = 'none'; 32 | $('step-4').style.display = 'block'; 33 | return hexGL.start(); 34 | }, 35 | onError: function(s) { 36 | return console.error("Error loading " + s + "."); 37 | }, 38 | onProgress: function(p, t, n) { 39 | console.log("LOADED " + t + " : " + n + " ( " + p.loaded + " / " + p.total + " )."); 40 | return progressbar.style.width = "" + (p.loaded / p.total * 100) + "%"; 41 | } 42 | }); 43 | }; 44 | 45 | u = bkcore.Utils.getURLParameter; 46 | 47 | defaultControls = bkcore.Utils.isTouchDevice() ? 1 : 0; 48 | 49 | s = [['controlType', ['KEYBOARD', 'TOUCH', 'LEAP MOTION CONTROLLER', 'GAMEPAD'], defaultControls, defaultControls, 'Controls: '], ['quality', ['LOW', 'MID', 'HIGH', 'VERY HIGH'], 3, 3, 'Quality: '], ['hud', ['OFF', 'ON'], 1, 1, 'HUD: '], ['godmode', ['OFF', 'ON'], 0, 1, 'Godmode: ']]; 50 | 51 | _fn = function(a) { 52 | var e, f, _ref; 53 | a[3] = (_ref = u(a[0])) != null ? _ref : a[2]; 54 | e = $("s-" + a[0]); 55 | (f = function() { 56 | return e.innerHTML = a[4] + a[1][a[3]]; 57 | })(); 58 | return e.onclick = function() { 59 | return f(a[3] = (a[3] + 1) % a[1].length); 60 | }; 61 | }; 62 | for (_i = 0, _len = s.length; _i < _len; _i++) { 63 | a = s[_i]; 64 | _fn(a); 65 | } 66 | 67 | $('step-2').onclick = function() { 68 | $('step-2').style.display = 'none'; 69 | $('step-3').style.display = 'block'; 70 | return init(s[0][3], s[1][3], s[2][3], s[3][3]); 71 | }; 72 | 73 | $('step-5').onclick = function() { 74 | return window.location.reload(); 75 | }; 76 | 77 | $('s-credits').onclick = function() { 78 | $('step-1').style.display = 'none'; 79 | return $('credits').style.display = 'block'; 80 | }; 81 | 82 | $('credits').onclick = function() { 83 | $('step-1').style.display = 'block'; 84 | return $('credits').style.display = 'none'; 85 | }; 86 | 87 | hasWebGL = function() { 88 | var canvas, gl; 89 | gl = null; 90 | canvas = document.createElement('canvas'); 91 | try { 92 | gl = canvas.getContext("webgl"); 93 | } catch (_error) {} 94 | if (gl == null) { 95 | try { 96 | gl = canvas.getContext("experimental-webgl"); 97 | } catch (_error) {} 98 | } 99 | return gl != null; 100 | }; 101 | 102 | if (!hasWebGL()) { 103 | getWebGL = $('start'); 104 | getWebGL.innerHTML = 'WebGL is not supported!'; 105 | getWebGL.onclick = function() { 106 | return window.location.href = 'http://get.webgl.org/'; 107 | }; 108 | } else { 109 | $('start').onclick = function() { 110 | $('step-1').style.display = 'none'; 111 | $('step-2').style.display = 'block'; 112 | return $('step-2').style.backgroundImage = "url(css/help-" + s[0][3] + ".png)"; 113 | }; 114 | } 115 | 116 | }).call(this); 117 | -------------------------------------------------------------------------------- /libs/Detector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author mr.doob / http://mrdoob.com/ 4 | */ 5 | 6 | var Detector = { 7 | 8 | canvas: !! window.CanvasRenderingContext2D, 9 | webgl: ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )(), 10 | workers: !! window.Worker, 11 | fileapi: window.File && window.FileReader && window.FileList && window.Blob, 12 | 13 | getWebGLErrorMessage: function () { 14 | 15 | var element = document.createElement( 'div' ); 16 | element.id = 'webgl-error-message'; 17 | element.style.fontFamily = 'monospace'; 18 | element.style.fontSize = '13px'; 19 | element.style.fontWeight = 'normal'; 20 | element.style.textAlign = 'center'; 21 | element.style.background = '#fff'; 22 | element.style.color = '#000'; 23 | element.style.padding = '1.5em'; 24 | element.style.width = '400px'; 25 | element.style.margin = '5em auto 0'; 26 | 27 | if ( ! this.webgl ) { 28 | 29 | element.innerHTML = window.WebGLRenderingContext ? [ 30 | 'Your graphics card does not seem to support WebGL.
', 31 | 'Find out how to get it here.' 32 | ].join( '\n' ) : [ 33 | 'Your browser does not seem to support WebGL.
', 34 | 'Find out how to get it here.' 35 | ].join( '\n' ); 36 | 37 | } 38 | 39 | return element; 40 | 41 | }, 42 | 43 | addGetWebGLMessage: function ( parameters ) { 44 | 45 | var parent, id, element; 46 | 47 | parameters = parameters || {}; 48 | 49 | parent = parameters.parent !== undefined ? parameters.parent : document.body; 50 | id = parameters.id !== undefined ? parameters.id : 'oldie'; 51 | 52 | element = Detector.getWebGLErrorMessage(); 53 | element.id = id; 54 | 55 | parent.appendChild( element ); 56 | 57 | } 58 | 59 | }; 60 | -------------------------------------------------------------------------------- /libs/Editor_files/App.js: -------------------------------------------------------------------------------- 1 | var pgli = pgli || {}; 2 | 3 | pgli.App = gamecore.Base.extend("App", 4 | { // static 5 | 6 | }, 7 | { // instance 8 | 9 | project: null, 10 | moduleList: null, 11 | editor: null, 12 | diagram: null, 13 | preview: null, 14 | nodeCount: 0, 15 | console: null, 16 | debug: 2, // 0:none, 1:inapp, 2:console, 3:both 17 | 18 | init: function(domDiagram, domModuleList, domEditor, domPreview) 19 | { 20 | var self = this; 21 | 22 | this.moduleList = new pgli.ui.ModuleList(domModuleList); 23 | 24 | this.editor = ace.edit(domEditor); 25 | this.editor.setFontSize("16px"); 26 | this.editor.setTheme("ace/theme/monokai"); 27 | this.editor.getSession().setMode("ace/mode/json"); 28 | 29 | this.diagram = new pgli.diagram.Diagram(domDiagram, 30); 30 | 31 | this.preview = new pgli.render.CanvasRenderer(domPreview); 32 | 33 | this.console = $('#console-text'); 34 | 35 | this.bindEvents(); 36 | 37 | pgli.lang.Parser.debug = self.debug; 38 | 39 | window.trace = function(args) 40 | { 41 | if(!self.debug) return; 42 | for(var i=0, len=arguments.length; i 0) 88 | { 89 | this.redrawDelay = 1000 / autoRedraw; 90 | this.timer = new bkcore.Timer(); 91 | this.timer.start(); 92 | this.autoRedraw(true); 93 | } 94 | }, 95 | 96 | addNode: function(node) 97 | { 98 | this.nodes.push(node); 99 | this.layers.nodes.add(node.shape); 100 | this.layers.nodes.draw(); 101 | }, 102 | 103 | getNode: function(nodeKey) 104 | { 105 | var i = 0, len = this.nodes.length; 106 | while(i < len) 107 | { 108 | if(this.nodes[i].key == nodeKey) 109 | return this.nodes[i]; 110 | i++; 111 | } 112 | console.warn("Error in Diagram: Unable to find node["+nodeKey+"]"); 113 | return false; 114 | }, 115 | 116 | draw: function() 117 | { 118 | this.layers.background.draw(); 119 | this.layers.nodes.draw(); 120 | this.layers.links.draw(); 121 | }, 122 | 123 | autoRedraw: function(keep) 124 | { 125 | var self = this; 126 | 127 | if(this.timer.update() > this.redrawDelay) 128 | { 129 | this.timer.start(); 130 | this.draw(); 131 | } 132 | 133 | if(keep) 134 | requestAnimFrame(function(){ 135 | self.autoRedraw(true); 136 | }); 137 | }, 138 | 139 | resize: function() 140 | { 141 | this.width = this.container.width(); 142 | this.height = this.container.height(); 143 | this.stage.setSize(this.width, this.height); 144 | this.background.setSize(this.width, this.height); 145 | this.draw(); 146 | } 147 | 148 | }); -------------------------------------------------------------------------------- /libs/Editor_files/Iterator.js: -------------------------------------------------------------------------------- 1 | var pgli = pgli || {}; 2 | pgli.lang = pgli.lang || {}; 3 | 4 | pgli.lang.Iterator = gamecore.Base.extend('Iterator', 5 | // Static 6 | { 7 | MAX_ITERATIONS: 1000, 8 | 9 | COMPARATORS: { 10 | "<": 0, 11 | ">": 1, 12 | "<=": 2, 13 | ">=": 3 14 | }, 15 | 16 | genComparatorMethod: function(type) 17 | { 18 | switch(type) 19 | { 20 | case 0: 21 | return function(a, b){ return a < b }; 22 | case 1: 23 | return function(a, b){ return a > b }; 24 | case 2: 25 | return function(a, b){ return a <= b }; 26 | case 3: 27 | return function(a, b){ return a >= b }; 28 | default: 29 | return function(a, b){ return false }; 30 | } 31 | }, 32 | 33 | genStepMethod: function(type, scope, attr) 34 | { 35 | switch(type) 36 | { 37 | case 1: 38 | case 3: 39 | return function(){ return --scope[attr] }; 40 | case 0: 41 | case 2: 42 | default: 43 | return function(){ return ++scope[attr] }; 44 | } 45 | } 46 | }, 47 | // Instance 48 | { 49 | varname: "i", 50 | start: 0, 51 | end: 1, 52 | comparator: 0, 53 | compMethod: null, 54 | stepMethod: null, 55 | step: 0, 56 | iter: 0, 57 | 58 | init: function(name, start, comparator, end) 59 | { 60 | var static = pgli.lang.Iterator; 61 | 62 | if(comparator in static.COMPARATORS) 63 | this.comparator = static.COMPARATORS[comparator]; 64 | else 65 | this.comparator = static.COMPARATORS["<"]; 66 | 67 | this.start = start; 68 | this.end = end; 69 | this.step = start; 70 | 71 | this.varname = name; 72 | this.compMethod = static.genComparatorMethod(this.comparator); 73 | this.stepMethod = static.genStepMethod(this.comparator, this, "step"); 74 | }, 75 | 76 | loop: function() 77 | { 78 | return (this.iter < pgli.lang.Iterator.MAX_ITERATIONS && this.compMethod(this.step, this.end)); 79 | }, 80 | 81 | next: function() 82 | { 83 | ++this.iter; 84 | return this.stepMethod(); 85 | }, 86 | 87 | toString: function() 88 | { 89 | return "Iterator("+this.varname+") "+this.start+" - "+this.step+" - "+this.end; 90 | } 91 | 92 | }); -------------------------------------------------------------------------------- /libs/Editor_files/Links.js: -------------------------------------------------------------------------------- 1 | var pgli = pgli || {}; 2 | pgli.diagram = pgli.diagram || {}; 3 | 4 | pgli.diagram.Links = gamecore.Base.extend('Links', 5 | { // static 6 | bezierOffset: 50 7 | }, 8 | { // instance 9 | diagram: null, 10 | 11 | shape: null, 12 | 13 | init: function(diagram) 14 | { 15 | var static = pgli.diagram.Links; 16 | var self = this; 17 | 18 | this.diagram = diagram; 19 | 20 | this.shape = new Kinetic.Shape({ 21 | drawFunc: function(ctx){ 22 | ctx.beginPath(); 23 | 24 | for(var i = 0, len = self.diagram.nodes.length; i < len; i++) 25 | { 26 | var node = self.diagram.nodes[i]; 27 | 28 | if(! ("layers" in node.module)) continue; 29 | 30 | for(var j = 0, _len = node.module.layers.length; j < _len; j++) 31 | { 32 | if(! ("use" in node.module.layers[j])) continue; 33 | 34 | var start = node.getLayerSlot(j); 35 | var tNode = self.diagram.getNode(node.module.layers[j].use); 36 | if(!tNode) continue; 37 | var end = tNode.getSlot(); 38 | 39 | ctx.moveTo(start[0], start[1]); 40 | ctx.bezierCurveTo( 41 | start[0]+static.bezierOffset, start[1], 42 | end[0]-static.bezierOffset, end[1], 43 | end[0], end[1]); 44 | } 45 | } 46 | 47 | this.stroke(ctx); 48 | }, 49 | x: 0, 50 | y: 0, 51 | stroke: "#999", 52 | strokeWidth: 3, 53 | lineCap: "round" 54 | }); 55 | } 56 | }); -------------------------------------------------------------------------------- /libs/Editor_files/ModuleList.js: -------------------------------------------------------------------------------- 1 | var pgli = pgli || {}; 2 | pgli.ui = pgli.ui || {}; 3 | 4 | pgli.ui.ModuleList = gamecore.Base.extend('ModuleList', 5 | { // static 6 | tplModuleItem: "
  • $name
  • ", 7 | tplModuleList: "
      $list
    " 8 | }, 9 | { // instance 10 | 11 | project: null, 12 | container: null, 13 | 14 | init: function(domContainer) 15 | { 16 | this.container = $('#'+domContainer); 17 | this.container.on("click", "li", {object: this}, this.onModuleClick); 18 | }, 19 | 20 | bindProject: function(project) 21 | { 22 | this.project = project; 23 | }, 24 | 25 | draw: function() 26 | { 27 | var static = pgli.ui.ModuleList; 28 | var modules = ""; 29 | var module = null; 30 | if(!this.project.isEmpty()) for(var i = 0, len = this.project.getModulesCount(); i < len; ++i) 31 | { 32 | key = this.project.getModuleKey(i); 33 | module = this.project.getModule(key); 34 | modules += static.tplModuleItem.replace("$path", key).replace("$name", key); 35 | } 36 | this.container.html(static.tplModuleList.replace("$list", modules)); 37 | }, 38 | 39 | onModuleClick: function(event) 40 | { 41 | event.data.object.project.rememberActiveFile(); 42 | event.data.object.project.getAppInstance().showInEditor($(this).attr("data-path")); 43 | event.data.object.container.find('li').removeClass('active'); 44 | $(this).addClass('active'); 45 | } 46 | 47 | }); -------------------------------------------------------------------------------- /libs/Editor_files/Node.js: -------------------------------------------------------------------------------- 1 | var pgli = pgli || {}; 2 | pgli.diagram = pgli.diagram || {}; 3 | 4 | pgli.diagram.Node = gamecore.Base.extend('Node', 5 | { // static 6 | layersWidth: 20, 7 | layersMargin: 20, 8 | layersHeight: 16, 9 | headerHeight: 40, 10 | slotX: 10, 11 | slotY: 14, 12 | slotRadius: 6 13 | }, 14 | { // instance 15 | module: null, 16 | 17 | key: null, 18 | 19 | shape: null, 20 | background: null, 21 | name: null, 22 | layers: null, 23 | slot: null, 24 | 25 | sockets: [], 26 | 27 | width: 150, 28 | height: 200, 29 | 30 | init: function(key, module, x, y) 31 | { 32 | var static = pgli.diagram.Node; 33 | 34 | this.key = key; 35 | this.module = module; 36 | 37 | this.shape = new Kinetic.Group({ 38 | x: x == undefined ? 0 : x, 39 | y: y == undefined ? 0 : y, 40 | draggable: true 41 | }); 42 | 43 | var layerCount = (module.layers != undefined ? module.layers.length : 0) + 1; 44 | 45 | this.height = static.headerHeight + layerCount * static.layersHeight; 46 | 47 | this.background = new Kinetic.Rect({ 48 | x: 0, 49 | y: 0, 50 | width: this.width, 51 | height: this.height, 52 | fill: "#222", 53 | stroke: "#000", 54 | strokeWidth: 0.5, 55 | shadow: { 56 | color: "black", 57 | blur: 6, 58 | offset: [0, 0], 59 | opacity: 0.5 60 | } 61 | }); 62 | 63 | this.layers = new Kinetic.Shape({ 64 | drawFunc: function(ctx){ 65 | ctx.beginPath(); 66 | for(var i=0, len = this.attrs.count; i < len; ++i) 67 | ctx.arc(10, 10+i*static.layersHeight, static.slotRadius, 0, Math.PI*2, true); 68 | ctx.closePath(); 69 | this.fill(ctx); 70 | }, 71 | x: this.width-static.layersWidth, 72 | y: static.layersMargin, 73 | count: layerCount, 74 | fill: "#111" 75 | }); 76 | 77 | this.slot = new Kinetic.Circle({ 78 | x: static.slotX, 79 | y: static.slotY, 80 | radius: static.slotRadius, 81 | fill: "#111" 82 | }); 83 | 84 | this.name = new Kinetic.Text({ 85 | x: 20, 86 | y: 6, 87 | text: module.name, 88 | fontSize: 13, 89 | fontFamily: "Ubuntu Mono", 90 | textFill: "#aaa" 91 | }); 92 | 93 | this.shape.on('mousedown', function(){ 94 | this.moveToTop(); 95 | }); 96 | 97 | this.shape.add(this.background); 98 | this.shape.add(this.name); 99 | this.shape.add(this.layers); 100 | this.shape.add(this.slot); 101 | }, 102 | 103 | updateLayers: function() 104 | { 105 | var layerCount = (module.layers != undefined ? module.layers.length : 0) + 1; 106 | this.layers.attrs.count = layerCount; 107 | }, 108 | 109 | getSlot: function() 110 | { 111 | var static = pgli.diagram.Node; 112 | return [this.shape.getX()+static.slotX, 113 | this.shape.getY()+static.slotY]; 114 | }, 115 | 116 | getLayerSlot: function(index) 117 | { 118 | var static = pgli.diagram.Node; 119 | return [this.shape.getX()+this.width-static.layersWidth/2, 120 | this.shape.getY()+10+index*static.layersHeight+static.layersMargin]; 121 | } 122 | }); -------------------------------------------------------------------------------- /libs/Editor_files/Parser.js: -------------------------------------------------------------------------------- 1 | var pgli = pgli || {}; 2 | pgli.lang = pgli.lang || {}; 3 | 4 | pgli.lang.Parser = gamecore.Base.extend('Parser', 5 | { 6 | 7 | xStruct: { 8 | "scale": 0, 9 | "x": 1, 10 | "y": 2, 11 | "width": 3, 12 | "height": 4 13 | }, 14 | 15 | 16 | patternVar:/\@(\w+)/g, 17 | patternMethod: /\#(\w+)(\(([^\)]+)\))/g, 18 | 19 | debug: 1, 20 | 21 | 22 | parseExpression: function(string, scope, xform) 23 | { 24 | static = pgli.lang.Parser; 25 | 26 | var self = this; 27 | var orig = string; 28 | var s = (scope !== null && typeof(scope) !== "undefined") 29 | var x = (xform !== null && typeof(xform) !== "undefined" && xform.length > 0) 30 | 31 | if(typeof(string) != "string") 32 | return string; 33 | 34 | if(scope != undefined) 35 | { 36 | string = string.replace(this.patternVar,function(match,varName) 37 | { 38 | if(x && varName in static.xStruct) 39 | return xform[static.xStruct[varName]]; 40 | else if(s && varName in scope) 41 | return scope[varName] 42 | else 43 | return 0 44 | }); 45 | } 46 | 47 | string = string.replace(this.patternMethod,function(match,methodName,a,params) 48 | { 49 | if(self.debug < 2) console.log(arguments); 50 | return self.execFunction(methodName, params); 51 | }); 52 | 53 | if(self.debug < 2) console.log("#Parsed expr: '"+string+"' from '"+orig+"'"); 54 | 55 | try { 56 | return eval(string); 57 | } catch (e) { 58 | return string; 59 | } 60 | 61 | 62 | }, 63 | 64 | parseRepeat: function(string, scope) 65 | { 66 | var items = string.split(" "); 67 | 68 | if(items.length != 4) 69 | throw "Syntax error in repeat expression"; 70 | 71 | if(self.debug < 2) console.warn(items[0].substr(1)) 72 | if(self.debug < 2) console.warn(Number(this.parseExpression(items[1], scope))) 73 | if(self.debug < 2) console.warn(items[2]) 74 | if(self.debug < 2) console.warn(Number(this.parseExpression(items[3], scope))) 75 | 76 | return new pgli.lang.Iterator( 77 | items[0].substr(1), 78 | Number(this.parseExpression(items[1], scope)), 79 | items[2], 80 | Number(this.parseExpression(items[3], scope)) 81 | ); 82 | }, 83 | 84 | parseModule: function(string) 85 | { 86 | try 87 | { 88 | return JSON.parse(string); 89 | } 90 | catch(e) 91 | { 92 | trace("(!) Syntax error in module."); 93 | return {error:"unable to parse module"}; 94 | } 95 | }, 96 | 97 | execFunction: function(methodName, params) 98 | { 99 | var hasP = params != undefined; 100 | var p = hasP ? params.replace(" ", "").split(',') : []; 101 | 102 | if(methodName == "random") 103 | { 104 | var r = Math.random(); 105 | if(hasP && p.length == 2) try 106 | { 107 | var min = eval(p[0]); 108 | var max = eval(p[1]); 109 | r = Math.round(r * (max-min) + min); 110 | } catch(e) { 111 | console.warn('Bad method format: '+methodName+' / '+params); 112 | return 0; 113 | } 114 | return r; 115 | } 116 | else if(methodName == "mod") 117 | { 118 | if(hasP && p.length == 2) try 119 | { 120 | var base = eval(p[0]); 121 | var div = eval(p[1]); 122 | if(div == 0) throw "Divide by 0"; 123 | return Math.floor(base/div); 124 | } catch(e) { 125 | console.warn('Bad method format: '+methodName+' / '+params); 126 | } 127 | return 0; 128 | } 129 | else 130 | { 131 | console.warn("Unsupported method : "+methodName); 132 | return 0; 133 | } 134 | } 135 | }, 136 | { 137 | 138 | }); 139 | 140 | 141 | -------------------------------------------------------------------------------- /libs/Editor_files/Project.js: -------------------------------------------------------------------------------- 1 | var pgli = pgli || {}; 2 | 3 | 4 | pgli.Project = gamecore.Base.extend('Project', 5 | { 6 | patternRoot: /\/([a-z]+\.pmod)/ig, 7 | patternPath: /([a-z\/]+\/)[a-z]+\.pmod/ig 8 | 9 | }, 10 | 11 | { 12 | appInstance: null, 13 | modules: null, 14 | activeFile: null, 15 | files:null, 16 | keys :[], 17 | name: "default", 18 | path: "/files/", 19 | root: "default.pmod", 20 | diagram: null, 21 | loadingQueue: [], 22 | onLoad: function() { console.log("Project loaded."); }, 23 | 24 | 25 | 26 | init : function(projectFile, onLoad) 27 | { 28 | this.onLoad = onLoad; 29 | this.modules = new gamecore.Hashtable(); 30 | this.files = new gamecore.Hashtable(); 31 | this.path = pgli.Project.patternPath.exec(projectFile)[1]; 32 | this.root = pgli.Project.patternRoot.exec(projectFile)[1]; 33 | 34 | var self = this; 35 | 36 | this.loadFile(projectFile,this.root,true,true); 37 | 38 | }, 39 | 40 | loadFile: function(path,name,doDependencies,doDiagram) 41 | { 42 | trace("#Loading ["+name+"]."); 43 | var self = this; 44 | var request = $.ajax({ 45 | url: path, 46 | type: 'get', 47 | dataType: "text", 48 | }) 49 | .success(function(data) 50 | { 51 | self.files.put(name, data); 52 | self.keys.push(name); 53 | 54 | var object = pgli.lang.Parser.parseModule(data); 55 | self.modules.put(name, object); 56 | 57 | if(doDependencies == true) 58 | self.loadDependencies(object); 59 | 60 | if(doDiagram == true) 61 | self.getAppInstance().addDiagramNode(name, object); 62 | 63 | trace("#["+name+"] loaded"); 64 | 65 | self.onLoad(); 66 | }) 67 | .error(function() 68 | { 69 | throw "Unable to load file: " + path; 70 | }); 71 | }, 72 | 73 | loadDependencies: function(object) 74 | { 75 | 76 | if(!("layers" in object)) 77 | return; 78 | 79 | var layers = object.layers; 80 | var self = this; 81 | 82 | for (var i=0, len = layers.length; i 7 | */ 8 | 9 | /** 10 | * RAF shim 11 | */ 12 | window.requestAnimFrame = (function(){ 13 | return window.requestAnimationFrame || 14 | window.webkitRequestAnimationFrame || 15 | window.mozRequestAnimationFrame || 16 | window.oRequestAnimationFrame || 17 | window.msRequestAnimationFrame || 18 | function( callback ){ 19 | window.setTimeout(callback, 1000 / 60); 20 | }; 21 | })(); 22 | 23 | /*! 24 | * @package bkcore 25 | */ 26 | var bkcore = bkcore || {}; 27 | 28 | /*! 29 | * Creates a new timer, inactive by default. 30 | * Call Timer.start() to activate. 31 | */ 32 | bkcore.Timer = function() 33 | { 34 | this.time = { 35 | start: 0, 36 | current: 0, 37 | previous: 0, 38 | elapsed: 0, 39 | delta: 0 40 | } 41 | 42 | this.active = false; 43 | } 44 | 45 | /*! 46 | * Starts/restarts the timer. 47 | */ 48 | bkcore.Timer.prototype.start = function() 49 | { 50 | var now = new Date().getTime(); 51 | 52 | this.time.start = now; 53 | this.time.current = now; 54 | this.time.previous = now; 55 | this.time.elapsed = 0; 56 | this.time.delta = 0; 57 | 58 | this.active = true; 59 | } 60 | 61 | /*! 62 | * Restarts timer, returning last ms tick 63 | */ 64 | bkcore.Timer.prototype.restart = function() 65 | { 66 | var now = new Date().getTime(); 67 | var e = now - this.time.start; 68 | 69 | this.time.start = now; 70 | this.time.current = now; 71 | this.time.previous = now; 72 | this.time.elapsed = 0; 73 | this.time.delta = 0; 74 | 75 | this.active = true; 76 | 77 | return e; 78 | } 79 | 80 | /*! 81 | * Pauses(true)/Unpauses(false) the timer. 82 | * 83 | * @param bool Do pause 84 | */ 85 | bkcore.Timer.prototype.pause = function(bool) 86 | { 87 | this.active = !bool; 88 | } 89 | 90 | /*! 91 | * Update method to be called inside a RAF loop 92 | */ 93 | bkcore.Timer.prototype.update = function() 94 | { 95 | if(!this.active) return; 96 | 97 | var now = new Date().getTime(); 98 | 99 | this.time.current = now; 100 | this.time.elapsed = this.time.current - this.time.start; 101 | this.time.delta = now - this.time.previous; 102 | this.time.previous = now; 103 | 104 | return this.time.elapsed; 105 | } 106 | 107 | /*! 108 | * Returns elapsed milliseconds 109 | */ 110 | bkcore.Timer.prototype.getElapsed = function() 111 | { 112 | return this.time.elapsed; 113 | } 114 | 115 | /*! 116 | * Returns a formatted version of the current elapsed time using msToTime(). 117 | * 118 | * 119 | */ 120 | bkcore.Timer.prototype.getElapsedTime = function() 121 | { 122 | return bkcore.Timer.msToTime(this.time.elapsed); 123 | } 124 | 125 | /*! 126 | * Formats a millisecond integer into a h/m/s/ms object 127 | * 128 | * @param x int In milliseconds 129 | * @return Object{h,m,s,ms} 130 | */ 131 | bkcore.Timer.msToTime = function(t) 132 | { 133 | var ms, s, m, h; 134 | 135 | ms = t%1000; 136 | 137 | s = Math.floor((t/1000)%60); 138 | 139 | m = Math.floor((t/60000)%60); 140 | h = Math.floor((t/3600000)); 141 | 142 | return {h:h, m:m, s:s, ms:ms}; 143 | } 144 | 145 | /*! 146 | * Formats a millisecond integer into a h/m/s/ms object with prefix zeros 147 | * 148 | * @param x int In milliseconds 149 | * @return Object{h,m,s,ms} 150 | */ 151 | bkcore.Timer.msToTimeString = function(t) 152 | { 153 | var ms, s, m, h; 154 | 155 | ms = t%1000; 156 | if(ms < 10) ms = "00"+ms; 157 | else if(ms < 100) ms = "0"+ms; 158 | 159 | s = Math.floor((t/1000)%60); 160 | if(s < 10) s = "0"+s; 161 | 162 | m = Math.floor((t/60000)%60); 163 | h = Math.floor((t/3600000)); 164 | 165 | return {h:h, m:m, s:s, ms:ms}; 166 | } -------------------------------------------------------------------------------- /libs/Editor_files/editor.css: -------------------------------------------------------------------------------- 1 | .ace_gutter { 2 | -webkit-touch-callout: none; 3 | -webkit-user-select: none; 4 | -khtml-user-select: none; 5 | -moz-user-select: none; 6 | -ms-user-select: none; 7 | user-select: none; 8 | } 9 | 10 | .ace_sb { 11 | overflow-y: hidden !important; 12 | } 13 | 14 | #editor { 15 | background: #272822; 16 | } -------------------------------------------------------------------------------- /libs/Editor_files/font.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Ubuntu Mono'; 3 | font-style: normal; 4 | font-weight: 700; 5 | src: local('Ubuntu Mono Bold'), local('UbuntuMono-Bold'), url(bold.woff) format('woff'); 6 | } 7 | @font-face { 8 | font-family: 'Ubuntu Mono'; 9 | font-style: normal; 10 | font-weight: 400; 11 | src: local('Ubuntu Mono'), local('UbuntuMono-Regular'), url(normal.woff) format('woff'); 12 | } 13 | @font-face { 14 | font-family: 'Ubuntu Mono'; 15 | font-style: italic; 16 | font-weight: 700; 17 | src: local('Ubuntu Mono Bold Italic'), local('UbuntuMono-BoldItalic'), url(bolditalic.woff) format('woff'); 18 | } 19 | @font-face { 20 | font-family: 'Ubuntu Mono'; 21 | font-style: italic; 22 | font-weight: 400; 23 | src: local('Ubuntu Mono Italic'), local('UbuntuMono-Italic'), url(italic.woff) format('woff'); 24 | } 25 | -------------------------------------------------------------------------------- /libs/Editor_files/gamecore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * gamecore.js - Copyright 2012 Playcraft Labs, Inc. (see licence.txt) 3 | * gamecore.js 4 | * Namespace wrappers and the base class 5 | */ 6 | 7 | window.gamecore = {}; 8 | gamecore.Class = $.Class; 9 | 10 | /** 11 | * @class gamecore.Base 12 | * A base class providing logging, object counting and unique object id's 13 | * Examples: 14 | * 15 | * Unique ID and total objects: 16 | * 17 | * var Fighter = gamecore.Base.extend('Fighter', {}, {}); 18 | * var fighter1 = new Fighter(); 19 | * var fighter2 = new Fighter(); 20 | * fighter1.uniqueId; // -> 'Fighter:0' 21 | * fighter2.uniqueId; // -> 'Fighter:1' 22 | * Fighter.totalObjects; // -> 2 23 | * 24 | * 25 | * Logging: (log, info, warn, error, debug) 26 | * 27 | * fighter1.warn('oops'); // == console.log('Fighter:0 [WARN] oops'); 28 | */ 29 | 30 | gamecore.Base = gamecore.Class('gamecore.Base', 31 | /// 32 | /// STATIC 33 | /// 34 | { 35 | totalObjects: 0, 36 | WARN: 'WARN', 37 | DEBUG: 'DEBUG', 38 | ERROR: 'ERROR', 39 | INFO: 'INFO', 40 | 41 | log: function(id, type, message) 42 | { 43 | var idString = ''; 44 | if (id) idString = ':'+id; 45 | console.log(this.fullName + idString + ' [' + type + '] ' + message); 46 | }, 47 | 48 | warn: function (message) 49 | { 50 | this.log(null, this.WARN, message); 51 | }, 52 | 53 | debug: function (message) 54 | { 55 | this.log(null, this.DEBUG, message); 56 | }, 57 | 58 | error: function (message) 59 | { 60 | this.log(null, this.ERROR, message); 61 | }, 62 | 63 | info: function (message) 64 | { 65 | this.log(null, this.INFO, message); 66 | }, 67 | 68 | assert: function(msg, condition) 69 | { 70 | if (!condition) 71 | throw msg; 72 | } 73 | 74 | }, 75 | /// 76 | /// INSTANCE 77 | /// 78 | { 79 | objectId: 0, 80 | uniqueId: null, 81 | 82 | init: function() 83 | { 84 | }, 85 | 86 | setup: function() 87 | { 88 | this.objectId = this.Class.totalObjects++; 89 | this.uniqueId = this.Class.fullName + ':' + this.objectId; 90 | }, 91 | 92 | /** 93 | * @returns {String} A system-wide unique Id for this object instance 94 | */ 95 | getUniqueId: function() 96 | { 97 | // if you see a null error here, then likely you have forgotten to call 98 | // this._super in a subclassed init method. 99 | return this.uniqueId; 100 | }, 101 | 102 | /** 103 | * @returns {String} A hash matching this object. Override this to implement different 104 | * kinds of object hashing in derived classes. 105 | */ 106 | hashCode: function() 107 | { 108 | return this.getUniqueId(); 109 | }, 110 | 111 | warn: function (message) 112 | { 113 | this.Class.log(this.objectId, this.Class.WARN, message); 114 | }, 115 | debug: function (message) 116 | { 117 | this.Class.log(this.objectId, this.Class.DEBUG, message); 118 | }, 119 | error: function (message) 120 | { 121 | this.Class.log(this.objectId, this.Class.ERROR, message); 122 | }, 123 | info: function (message) 124 | { 125 | this.Class.log(this.objectId, this.Class.INFO, message); 126 | }, 127 | 128 | toString: function() 129 | { 130 | return this.Class.fullName + ' [id: ' + this.objectId + ']'; 131 | } 132 | }); 133 | 134 | -------------------------------------------------------------------------------- /libs/Editor_files/hashlist.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * A map of linked lists mapped by a string value 4 | */ 5 | gamecore.HashList = gamecore.Base.extend('gamecore.HashList', 6 | {}, 7 | { 8 | hashtable: null, 9 | 10 | init: function() 11 | { 12 | this.hashtable = new gamecore.Hashtable(); 13 | }, 14 | 15 | add: function(key, object) 16 | { 17 | // find the list associated with this key and add the object to it 18 | var list = this.hashtable.get(key); 19 | if (list == null) 20 | { 21 | // no list associated with this key yet, so let's make one 22 | list = new pc.LinkedList(); 23 | this.hashtable.put(key, list); 24 | } 25 | list.add(object); 26 | }, 27 | 28 | remove: function(key, object) 29 | { 30 | var list = this.hashtable.get(key); 31 | if (list == null) throw "No list for a key in hashlist when removing"; 32 | list.remove(object); 33 | }, 34 | 35 | get: function(key) 36 | { 37 | return this.hashtable.get(key); 38 | } 39 | 40 | 41 | }); 42 | -------------------------------------------------------------------------------- /libs/Editor_files/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow: hidden; 3 | font-family: "Ubuntu sans", Arial, sans-serif; 4 | font-size: 14px; 5 | color: #ddd; 6 | line-height: 1em; 7 | background: #1e1e1e; 8 | } 9 | 10 | #panel-center { 11 | margin: 0; 12 | position: absolute; 13 | z-index: 20; 14 | top: 0; 15 | bottom: 0; 16 | left: 200px; 17 | right: 400px; 18 | } 19 | 20 | #panel-left { 21 | margin: 0; 22 | position: absolute; 23 | z-index: 10; 24 | top: 0; 25 | bottom: 0; 26 | left: 0; 27 | width: 200px; 28 | 29 | background: #191919; 30 | } 31 | 32 | #panel-right { 33 | margin: 0; 34 | position: absolute; 35 | z-index: 30; 36 | top: 0; 37 | bottom: 0; 38 | right: 0; 39 | width: 400px; 40 | 41 | background: #191919; 42 | } 43 | 44 | #editor { 45 | margin: 0; 46 | position: absolute; 47 | top: 0; 48 | bottom: 50%; 49 | left: 0; 50 | right: 0; 51 | z-index: 100; 52 | } 53 | 54 | #diagram { 55 | margin: 0; 56 | position: absolute; 57 | bottom: 0; 58 | top: 50%; 59 | left: 0; 60 | right: 0; 61 | z-index: 200; 62 | } 63 | 64 | #editor-separator, #preview-separator { 65 | margin: 0; 66 | position: absolute; 67 | top: 50%; 68 | left: 0; 69 | right: 0; 70 | height: 3px; 71 | z-index: 300; 72 | background: #191919; 73 | border-top: 1px solid #292929; 74 | border-bottom: 1px solid #292929; 75 | } 76 | #preview-separator { 77 | z-index: 400; 78 | left: 3px; 79 | } 80 | 81 | #left-separator { 82 | margin: 0; 83 | position: absolute; 84 | top: 0; 85 | bottom: 0; 86 | right: 0; 87 | width: 3px; 88 | z-index: 300; 89 | background: #191919; 90 | } 91 | 92 | #right-separator { 93 | margin: 0; 94 | position: absolute; 95 | top: 0; 96 | bottom: 0; 97 | left: 0; 98 | width: 3px; 99 | z-index: 300; 100 | background: #191919; 101 | } 102 | 103 | #preview { 104 | margin: 0; 105 | position: absolute; 106 | top: 0; 107 | bottom: 50%; 108 | left: 3px; 109 | width: 396px; 110 | 111 | background: #1e1e1e; 112 | border-left: 1px solid #292929; 113 | z-index: 210; 114 | } 115 | 116 | #console { 117 | margin: 0; 118 | position: absolute; 119 | bottom: 0; 120 | top: 50%; 121 | left: 0; 122 | left: 3px; 123 | width: 396px; 124 | z-index: 220; 125 | background: #1e1e1e; 126 | border-left: 1px solid #292929; 127 | } 128 | 129 | #console-text { 130 | background: transparent; 131 | border: none; 132 | width: 100%; 133 | height: 100%; 134 | color: #666; 135 | text-shadow: 0px 1px 1px #000000; 136 | filter: dropshadow(color=#000000, offx=0, offy=1); 137 | padding: 6px; 138 | outline: none; 139 | overflow: hidden; 140 | scroll: none; 141 | } 142 | 143 | #preview canvas { 144 | background: #161616; 145 | } 146 | 147 | #modules { 148 | margin: 0; 149 | position: absolute; 150 | top: 0; 151 | bottom: 0; 152 | left: 0; 153 | width: 196px; 154 | 155 | font-size: 13px; 156 | 157 | background: #1e1e1e; 158 | border-right: 1px solid #292929; 159 | } 160 | 161 | #modules ul { 162 | -webkit-touch-callout: none; 163 | -webkit-user-select: none; 164 | -khtml-user-select: none; 165 | -moz-user-select: none; 166 | -ms-user-select: none; 167 | user-select: none; 168 | 169 | list-style: none; 170 | margin: 10px 0; 171 | padding: 0; 172 | } 173 | 174 | #modules li { 175 | list-style: none; 176 | line-height: 2.0em; 177 | padding: 0 20px; 178 | background: #1e1e1e; 179 | cursor: pointer; 180 | 181 | text-shadow: 0px 1px 1px #000000; 182 | filter: dropshadow(color=#000000, offx=0, offy=1); 183 | } 184 | 185 | #modules li:hover { 186 | background: #434343; /* Old browsers */ 187 | background: -moz-linear-gradient(top, #888 0%, #4e4e4e 4%, #434343 96%, #1e1e1e 100%); /* FF3.6+ */ 188 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#888), color-stop(4%,#4e4e4e), color-stop(96%,#434343), color-stop(100%,#1e1e1e)); /* Chrome,Safari4+ */ 189 | background: -webkit-linear-gradient(top, #888 0%, #4e4e4e 4%, #434343 96%, #1e1e1e 100%); /* Chrome10+,Safari5.1+ */ 190 | background: -o-linear-gradient(top, #888 0%, #4e4e4e 4%, #434343 96%, #1e1e1e 100%); /* Opera 11.10+ */ 191 | background: -ms-linear-gradient(top, #888 0%, #4e4e4e 4%, #434343 96%, #1e1e1e 100%); /* IE10+ */ 192 | background: linear-gradient(to bottom, #888 0%, #4e4e4e 4%, #434343 96%, #1e1e1e 100%); /* W3C */ 193 | 194 | } 195 | 196 | #modules li.active { 197 | background: #292929; 198 | } 199 | 200 | #render 201 | { 202 | position: absolute; 203 | z-index: 9999999; 204 | } -------------------------------------------------------------------------------- /libs/Editor_files/theme-monokai.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-monokai",b.cssText=".ace-monokai .ace_editor { border: 2px solid rgb(159, 159, 159)}.ace-monokai .ace_editor.ace_focus { border: 2px solid #327fbd}.ace-monokai .ace_gutter { background: #2f3129; color: #f1f1f1}.ace-monokai .ace_print_margin { width: 1px; background: #555651}.ace-monokai .ace_scroller { background-color: #272822}.ace-monokai .ace_text-layer { color: #F8F8F2}.ace-monokai .ace_cursor { border-left: 2px solid #F8F8F0}.ace-monokai .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #F8F8F0}.ace-monokai .ace_marker-layer .ace_selection { background: #49483E}.ace-monokai.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #272822; border-radius: 2px}.ace-monokai .ace_marker-layer .ace_step { background: rgb(102, 82, 0)}.ace-monokai .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #49483E}.ace-monokai .ace_marker-layer .ace_active_line { background: #202020}.ace-monokai .ace_gutter_active_line { background-color: #272727}.ace-monokai .ace_marker-layer .ace_selected_word { border: 1px solid #49483E}.ace-monokai .ace_invisible { color: #49483E}.ace-monokai .ace_entity.ace_name.ace_tag,.ace-monokai .ace_keyword,.ace-monokai .ace_meta,.ace-monokai .ace_storage { color: #F92672}.ace-monokai .ace_constant.ace_character,.ace-monokai .ace_constant.ace_language,.ace-monokai .ace_constant.ace_numeric,.ace-monokai .ace_constant.ace_other { color: #AE81FF}.ace-monokai .ace_invalid { color: #F8F8F0; background-color: #F92672}.ace-monokai .ace_invalid.ace_deprecated { color: #F8F8F0; background-color: #AE81FF}.ace-monokai .ace_support.ace_constant,.ace-monokai .ace_support.ace_function { color: #66D9EF}.ace-monokai .ace_fold { background-color: #A6E22E; border-color: #F8F8F2}.ace-monokai .ace_storage.ace_type,.ace-monokai .ace_support.ace_class,.ace-monokai .ace_support.ace_type { font-style: italic; color: #66D9EF}.ace-monokai .ace_entity.ace_name.ace_function,.ace-monokai .ace_entity.ace_other.ace_attribute-name,.ace-monokai .ace_variable { color: #A6E22E}.ace-monokai .ace_variable.ace_parameter { font-style: italic; color: #FD971F}.ace-monokai .ace_string { color: #E6DB74}.ace-monokai .ace_comment { color: #75715E}.ace-monokai .ace_markup.ace_underline { text-decoration: underline}.ace-monokai .ace_indent-guide { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQ11D6z7Bq1ar/ABCKBG6g04U2AAAAAElFTkSuQmCC) right repeat-y}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) -------------------------------------------------------------------------------- /libs/Stats.js: -------------------------------------------------------------------------------- 1 | // stats.js r10 - http://github.com/mrdoob/stats.js 2 | var Stats=function(){var l=Date.now(),m=l,g=0,n=1E3,o=0,h=0,p=1E3,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px"; 3 | i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div"); 4 | k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display= 5 | "block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height= 6 | a+"px",m=b,r=0);return b},update:function(){l=this.end()}}}; 7 | -------------------------------------------------------------------------------- /libs/postprocessing/BloomPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.BloomPass = function ( strength, kernelSize, sigma, resolution ) { 6 | 7 | strength = ( strength !== undefined ) ? strength : 1; 8 | kernelSize = ( kernelSize !== undefined ) ? kernelSize : 25; 9 | sigma = ( sigma !== undefined ) ? sigma : 4.0; 10 | resolution = ( resolution !== undefined ) ? resolution : 256; 11 | 12 | // render targets 13 | 14 | var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat }; 15 | 16 | this.renderTargetX = new THREE.WebGLRenderTarget( resolution, resolution, pars ); 17 | this.renderTargetY = new THREE.WebGLRenderTarget( resolution, resolution, pars ); 18 | 19 | // screen material 20 | 21 | var screenShader = THREE.ShaderExtras[ "screen" ]; 22 | 23 | this.screenUniforms = THREE.UniformsUtils.clone( screenShader.uniforms ); 24 | 25 | this.screenUniforms[ "opacity" ].value = strength; 26 | 27 | this.materialScreen = new THREE.ShaderMaterial( { 28 | 29 | uniforms: this.screenUniforms, 30 | vertexShader: screenShader.vertexShader, 31 | fragmentShader: screenShader.fragmentShader, 32 | blending: THREE.AdditiveBlending, 33 | transparent: true 34 | 35 | } ); 36 | 37 | // convolution material 38 | 39 | var convolutionShader = THREE.ShaderExtras[ "convolution" ]; 40 | 41 | this.convolutionUniforms = THREE.UniformsUtils.clone( convolutionShader.uniforms ); 42 | 43 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurx; 44 | this.convolutionUniforms[ "cKernel" ].value = THREE.ShaderExtras.buildKernel( sigma ); 45 | 46 | this.materialConvolution = new THREE.ShaderMaterial( { 47 | 48 | uniforms: this.convolutionUniforms, 49 | vertexShader: "#define KERNEL_SIZE " + kernelSize + ".0\n" + convolutionShader.vertexShader, 50 | fragmentShader: "#define KERNEL_SIZE " + kernelSize + "\n" + convolutionShader.fragmentShader 51 | 52 | } ); 53 | 54 | this.enabled = true; 55 | this.needsSwap = false; 56 | this.clear = false; 57 | 58 | }; 59 | 60 | THREE.BloomPass.prototype = { 61 | 62 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 63 | 64 | if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST ); 65 | 66 | // Render quad with blured scene into texture (convolution pass 1) 67 | 68 | THREE.EffectComposer.quad.material = this.materialConvolution; 69 | 70 | this.convolutionUniforms[ "tDiffuse" ].texture = readBuffer; 71 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX; 72 | 73 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetX, true ); 74 | 75 | 76 | // Render quad with blured scene into texture (convolution pass 2) 77 | 78 | this.convolutionUniforms[ "tDiffuse" ].texture = this.renderTargetX; 79 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY; 80 | 81 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetY, true ); 82 | 83 | // Render original scene with superimposed blur to texture 84 | 85 | THREE.EffectComposer.quad.material = this.materialScreen; 86 | 87 | this.screenUniforms[ "tDiffuse" ].texture = this.renderTargetY; 88 | 89 | if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST ); 90 | 91 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer, this.clear ); 92 | 93 | } 94 | 95 | }; 96 | 97 | THREE.BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 ); 98 | THREE.BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 ); 99 | 100 | 101 | -------------------------------------------------------------------------------- /libs/postprocessing/DotScreenPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.DotScreenPass = function ( center, angle, scale ) { 6 | 7 | var shader = THREE.ShaderExtras[ "dotscreen" ]; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | if ( center !== undefined ) 12 | this.uniforms[ "center" ].value.copy( center ); 13 | 14 | if ( angle !== undefined ) this.uniforms[ "angle"].value = angle; 15 | if ( scale !== undefined ) this.uniforms[ "scale"].value = scale; 16 | 17 | this.material = new THREE.ShaderMaterial( { 18 | 19 | uniforms: this.uniforms, 20 | vertexShader: shader.vertexShader, 21 | fragmentShader: shader.fragmentShader 22 | 23 | } ); 24 | 25 | this.enabled = true; 26 | this.renderToScreen = false; 27 | this.needsSwap = true; 28 | 29 | }; 30 | 31 | THREE.DotScreenPass.prototype = { 32 | 33 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 34 | 35 | this.uniforms[ "tDiffuse" ].texture = readBuffer; 36 | this.uniforms[ "tSize" ].value.set( readBuffer.width, readBuffer.height ); 37 | 38 | THREE.EffectComposer.quad.material = this.material; 39 | 40 | if ( this.renderToScreen ) { 41 | 42 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 43 | 44 | } else { 45 | 46 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, false ); 47 | 48 | } 49 | 50 | } 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /libs/postprocessing/EffectComposer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.EffectComposer = function ( renderer, renderTarget ) { 6 | 7 | this.renderer = renderer; 8 | 9 | this.renderTarget1 = renderTarget; 10 | 11 | if ( this.renderTarget1 === undefined ) { 12 | 13 | var width = window.innerWidth || 1; 14 | var height = window.innerHeight || 1; 15 | 16 | this.renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 17 | this.renderTarget1 = new THREE.WebGLRenderTarget( width, height, this.renderTargetParameters ); 18 | 19 | } 20 | 21 | this.renderTarget2 = this.renderTarget1.clone(); 22 | 23 | this.writeBuffer = this.renderTarget1; 24 | this.readBuffer = this.renderTarget2; 25 | 26 | this.passes = []; 27 | 28 | this.copyPass = new THREE.ShaderPass( THREE.ShaderExtras[ "screen" ] ); 29 | 30 | }; 31 | 32 | THREE.EffectComposer.prototype = { 33 | 34 | swapBuffers: function() { 35 | 36 | var tmp = this.readBuffer; 37 | this.readBuffer = this.writeBuffer; 38 | this.writeBuffer = tmp; 39 | 40 | }, 41 | 42 | addPass: function ( pass ) { 43 | 44 | this.passes.push( pass ); 45 | 46 | }, 47 | 48 | render: function ( delta ) { 49 | 50 | this.writeBuffer = this.renderTarget1; 51 | this.readBuffer = this.renderTarget2; 52 | 53 | var maskActive = false; 54 | 55 | var pass, i, il = this.passes.length; 56 | 57 | for ( i = 0; i < il; i ++ ) { 58 | 59 | pass = this.passes[ i ]; 60 | 61 | if ( !pass.enabled ) continue; 62 | 63 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); 64 | 65 | if ( pass.needsSwap ) { 66 | 67 | if ( maskActive ) { 68 | 69 | var context = this.renderer.context; 70 | 71 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); 72 | 73 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); 74 | 75 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); 76 | 77 | } 78 | 79 | this.swapBuffers(); 80 | 81 | } 82 | 83 | if ( pass instanceof THREE.MaskPass ) { 84 | 85 | maskActive = true; 86 | 87 | } else if ( pass instanceof THREE.ClearMaskPass ) { 88 | 89 | maskActive = false; 90 | 91 | } 92 | 93 | } 94 | 95 | }, 96 | 97 | reset: function ( renderTarget ) { 98 | 99 | this.renderTarget1 = renderTarget; 100 | 101 | if ( this.renderTarget1 === undefined ) { 102 | 103 | this.renderTarget1 = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters ); 104 | 105 | } 106 | 107 | this.renderTarget2 = this.renderTarget1.clone(); 108 | 109 | this.writeBuffer = this.renderTarget1; 110 | this.readBuffer = this.renderTarget2; 111 | 112 | THREE.EffectComposer.quad.scale.set( window.innerWidth, window.innerHeight, 1 ); 113 | 114 | THREE.EffectComposer.camera.left = window.innerWidth / - 2; 115 | THREE.EffectComposer.camera.right = window.innerWidth / 2; 116 | THREE.EffectComposer.camera.top = window.innerHeight / 2; 117 | THREE.EffectComposer.camera.bottom = window.innerHeight / - 2; 118 | 119 | THREE.EffectComposer.camera.updateProjectionMatrix(); 120 | 121 | } 122 | 123 | }; 124 | 125 | // shared ortho camera 126 | 127 | THREE.EffectComposer.initWidth = window.innerWidth || 1; 128 | THREE.EffectComposer.initHeight = window.innerHeight || 1; 129 | 130 | THREE.EffectComposer.camera = new THREE.OrthographicCamera( THREE.EffectComposer.initWidth / - 2, THREE.EffectComposer.initWidth / 2, THREE.EffectComposer.initHeight / 2, THREE.EffectComposer.initHeight / - 2, -10000, 10000 ); 131 | 132 | // shared fullscreen quad scene 133 | 134 | THREE.EffectComposer.geometry = new THREE.PlaneGeometry( 1, 1 ); 135 | THREE.EffectComposer.geometry.applyMatrix( new THREE.Matrix4().makeRotationX( Math.PI / 2 ) ); 136 | 137 | THREE.EffectComposer.quad = new THREE.Mesh( THREE.EffectComposer.geometry, null ); 138 | THREE.EffectComposer.quad.position.z = -100; 139 | THREE.EffectComposer.quad.scale.set( THREE.EffectComposer.initWidth, THREE.EffectComposer.initHeight, 1 ); 140 | 141 | THREE.EffectComposer.scene = new THREE.Scene(); 142 | THREE.EffectComposer.scene.add( THREE.EffectComposer.quad ); 143 | THREE.EffectComposer.scene.add( THREE.EffectComposer.camera ); 144 | -------------------------------------------------------------------------------- /libs/postprocessing/FilmPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.FilmPass = function ( noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale ) { 6 | 7 | var shader = THREE.ShaderExtras[ "film" ]; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | this.material = new THREE.ShaderMaterial( { 12 | 13 | uniforms: this.uniforms, 14 | vertexShader: shader.vertexShader, 15 | fragmentShader: shader.fragmentShader 16 | 17 | } ); 18 | 19 | if ( grayscale !== undefined ) this.uniforms.grayscale.value = grayscale; 20 | if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity; 21 | if ( scanlinesIntensity !== undefined ) this.uniforms.sIntensity.value = scanlinesIntensity; 22 | if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount; 23 | 24 | this.enabled = true; 25 | this.renderToScreen = false; 26 | this.needsSwap = true; 27 | 28 | }; 29 | 30 | THREE.FilmPass.prototype = { 31 | 32 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 33 | 34 | this.uniforms[ "tDiffuse" ].texture = readBuffer; 35 | this.uniforms[ "time" ].value += delta; 36 | 37 | THREE.EffectComposer.quad.material = this.material; 38 | 39 | if ( this.renderToScreen ) { 40 | 41 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 42 | 43 | } else { 44 | 45 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, false ); 46 | 47 | } 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /libs/postprocessing/MaskPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.MaskPass = function ( scene, camera ) { 6 | 7 | this.scene = scene; 8 | this.camera = camera; 9 | 10 | this.enabled = true; 11 | this.clear = true; 12 | this.needsSwap = false; 13 | 14 | this.inverse = false; 15 | 16 | }; 17 | 18 | THREE.MaskPass.prototype = { 19 | 20 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 21 | 22 | var context = renderer.context; 23 | 24 | // don't update color or depth 25 | 26 | context.colorMask( false, false, false, false ); 27 | context.depthMask( false ); 28 | 29 | // set up stencil 30 | 31 | var writeValue, clearValue; 32 | 33 | if ( this.inverse ) { 34 | 35 | writeValue = 0; 36 | clearValue = 1; 37 | 38 | } else { 39 | 40 | writeValue = 1; 41 | clearValue = 0; 42 | 43 | } 44 | 45 | context.enable( context.STENCIL_TEST ); 46 | context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE ); 47 | context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff ); 48 | context.clearStencil( clearValue ); 49 | 50 | // draw into the stencil buffer 51 | 52 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 53 | renderer.render( this.scene, this.camera, writeBuffer, this.clear ); 54 | 55 | // re-enable update of color and depth 56 | 57 | context.colorMask( true, true, true, true ); 58 | context.depthMask( true ); 59 | 60 | // only render where stencil is set to 1 61 | 62 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1 63 | context.stencilOp( context.KEEP, context.KEEP, context.KEEP ); 64 | 65 | } 66 | 67 | }; 68 | 69 | 70 | THREE.ClearMaskPass = function () { 71 | 72 | this.enabled = true; 73 | 74 | }; 75 | 76 | THREE.ClearMaskPass.prototype = { 77 | 78 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 79 | 80 | var context = renderer.context; 81 | 82 | context.disable( context.STENCIL_TEST ); 83 | 84 | } 85 | 86 | }; 87 | -------------------------------------------------------------------------------- /libs/postprocessing/RenderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) { 6 | 7 | this.scene = scene; 8 | this.camera = camera; 9 | 10 | this.overrideMaterial = overrideMaterial; 11 | 12 | this.clearColor = clearColor; 13 | this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1; 14 | 15 | this.oldClearColor = new THREE.Color(); 16 | this.oldClearAlpha = 1; 17 | 18 | this.enabled = true; 19 | this.clear = true; 20 | this.needsSwap = false; 21 | 22 | this.prePass = null; 23 | this.postPass = null; 24 | }; 25 | 26 | THREE.RenderPass.prototype = { 27 | 28 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 29 | 30 | if( this.prePass ) 31 | { 32 | this.prePass.call(this, renderer); 33 | } 34 | 35 | this.scene.overrideMaterial = this.overrideMaterial; 36 | 37 | if ( this.clearColor ) { 38 | 39 | this.oldClearColor.copy( renderer.getClearColor() ); 40 | this.oldClearAlpha = renderer.getClearAlpha(); 41 | 42 | renderer.setClearColor( this.clearColor, this.clearAlpha ); 43 | 44 | } 45 | 46 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 47 | 48 | if ( this.clearColor ) { 49 | 50 | renderer.setClearColor( this.oldClearColor, this.oldClearAlpha ); 51 | 52 | } 53 | 54 | this.scene.overrideMaterial = null; 55 | 56 | if( this.postPass ) 57 | { 58 | this.postPass.call(this, renderer); 59 | } 60 | 61 | } 62 | 63 | }; 64 | -------------------------------------------------------------------------------- /libs/postprocessing/SavePass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.SavePass = function ( renderTarget ) { 6 | 7 | var shader = THREE.ShaderExtras[ "screen" ]; 8 | 9 | this.textureID = "tDiffuse"; 10 | 11 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 12 | 13 | this.material = new THREE.ShaderMaterial( { 14 | 15 | uniforms: this.uniforms, 16 | vertexShader: shader.vertexShader, 17 | fragmentShader: shader.fragmentShader 18 | 19 | } ); 20 | 21 | this.renderTarget = renderTarget; 22 | 23 | if ( this.renderTarget === undefined ) { 24 | 25 | this.renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 26 | this.renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters ); 27 | 28 | } 29 | 30 | this.enabled = true; 31 | this.needsSwap = false; 32 | this.clear = false; 33 | 34 | }; 35 | 36 | THREE.SavePass.prototype = { 37 | 38 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 39 | 40 | if ( this.uniforms[ this.textureID ] ) { 41 | 42 | this.uniforms[ this.textureID ].texture = readBuffer; 43 | 44 | } 45 | 46 | THREE.EffectComposer.quad.material = this.material; 47 | 48 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTarget, this.clear ); 49 | 50 | } 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /libs/postprocessing/ShaderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.ShaderPass = function ( shader, textureID ) { 6 | 7 | this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse"; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | this.material = new THREE.ShaderMaterial( { 12 | 13 | uniforms: this.uniforms, 14 | vertexShader: shader.vertexShader, 15 | fragmentShader: shader.fragmentShader 16 | 17 | } ); 18 | 19 | this.renderToScreen = false; 20 | 21 | this.enabled = true; 22 | this.needsSwap = true; 23 | this.clear = false; 24 | 25 | }; 26 | 27 | THREE.ShaderPass.prototype = { 28 | 29 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 30 | 31 | if ( this.uniforms[ this.textureID ] ) { 32 | 33 | this.uniforms[ this.textureID ].texture = readBuffer; 34 | 35 | } 36 | 37 | THREE.EffectComposer.quad.material = this.material; 38 | 39 | if ( this.renderToScreen ) { 40 | 41 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 42 | 43 | } else { 44 | 45 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, this.clear ); 46 | 47 | } 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /libs/postprocessing/TexturePass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.TexturePass = function ( texture, opacity ) { 6 | 7 | var shader = THREE.ShaderExtras[ "screen" ]; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | this.uniforms[ "opacity" ].value = ( opacity !== undefined ) ? opacity : 1.0; 12 | this.uniforms[ "tDiffuse" ].texture = texture; 13 | 14 | this.material = new THREE.ShaderMaterial( { 15 | 16 | uniforms: this.uniforms, 17 | vertexShader: shader.vertexShader, 18 | fragmentShader: shader.fragmentShader 19 | 20 | } ); 21 | 22 | this.enabled = true; 23 | this.needsSwap = false; 24 | 25 | }; 26 | 27 | THREE.TexturePass.prototype = { 28 | 29 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 30 | 31 | THREE.EffectComposer.quad.material = this.material; 32 | 33 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer ); 34 | 35 | } 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /manifest.webapp: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HexGL", 3 | "description": "HexGL v1.0.1-ffos", 4 | "launch_path": "/index-mobile.html", 5 | "icons": { 6 | "32": "/icon_32.png", 7 | "64": "/icon_64.png", 8 | "128": "/icon_128.png", 9 | "256": "/icon_256.png" 10 | }, 11 | "developer": { 12 | "name": "Thibaut Despoulain (BKcore)", 13 | "url": "http://bkcore.com" 14 | }, 15 | "installs_allowed_from": ["*"], 16 | "default_locale": "en", 17 | "orientation": ["landscape"] 18 | } 19 | -------------------------------------------------------------------------------- /package.webapp: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HexGL", 3 | "description": "HexGL v1.0.1-ffos", 4 | "package_path" : "package.zip", 5 | "version": "1", 6 | "developer": { 7 | "name": "Thibaut Despoulain (BKcore)", 8 | "url": "http://bkcore.com" 9 | } 10 | } -------------------------------------------------------------------------------- /package.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/package.zip -------------------------------------------------------------------------------- /textures.full/bonus/base/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/bonus/base/diffuse.jpg -------------------------------------------------------------------------------- /textures.full/bonus/base/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/bonus/base/normal.jpg -------------------------------------------------------------------------------- /textures.full/bonus/base/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/bonus/base/specular.jpg -------------------------------------------------------------------------------- /textures.full/checker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/checker.png -------------------------------------------------------------------------------- /textures.full/hud/hex.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/hud/hex.jpg -------------------------------------------------------------------------------- /textures.full/hud/hud-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/hud/hud-bg.png -------------------------------------------------------------------------------- /textures.full/hud/hud-fg-shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/hud/hud-fg-shield.png -------------------------------------------------------------------------------- /textures.full/hud/hud-fg-speed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/hud/hud-fg-speed.png -------------------------------------------------------------------------------- /textures.full/particles/cloud - Copie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/particles/cloud - Copie.png -------------------------------------------------------------------------------- /textures.full/particles/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/particles/cloud.png -------------------------------------------------------------------------------- /textures.full/particles/damage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/particles/damage.png -------------------------------------------------------------------------------- /textures.full/particles/spark - Copie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/particles/spark - Copie.png -------------------------------------------------------------------------------- /textures.full/particles/spark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/particles/spark.png -------------------------------------------------------------------------------- /textures.full/ships/feisar/booster/booster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/ships/feisar/booster/booster.png -------------------------------------------------------------------------------- /textures.full/ships/feisar/booster/boostersprite.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/ships/feisar/booster/boostersprite.jpg -------------------------------------------------------------------------------- /textures.full/ships/feisar/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/ships/feisar/diffuse.jpg -------------------------------------------------------------------------------- /textures.full/ships/feisar/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/ships/feisar/normal.jpg -------------------------------------------------------------------------------- /textures.full/ships/feisar/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/ships/feisar/specular.jpg -------------------------------------------------------------------------------- /textures.full/skybox/dawnclouds/nx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/skybox/dawnclouds/nx.jpg -------------------------------------------------------------------------------- /textures.full/skybox/dawnclouds/ny.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/skybox/dawnclouds/ny.jpg -------------------------------------------------------------------------------- /textures.full/skybox/dawnclouds/nz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/skybox/dawnclouds/nz.jpg -------------------------------------------------------------------------------- /textures.full/skybox/dawnclouds/px.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/skybox/dawnclouds/px.jpg -------------------------------------------------------------------------------- /textures.full/skybox/dawnclouds/py.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/skybox/dawnclouds/py.jpg -------------------------------------------------------------------------------- /textures.full/skybox/dawnclouds/pz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/skybox/dawnclouds/pz.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/collision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/collision.png -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/diffuse.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/height.png -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/normal.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/scrapers1/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/scrapers1/diffuse.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/scrapers1/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/scrapers1/normal.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/scrapers1/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/scrapers1/specular.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/scrapers2/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/scrapers2/diffuse.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/scrapers2/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/scrapers2/normal.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/scrapers2/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/scrapers2/specular.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/specular.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/start/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/start/diffuse.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/start/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/start/normal.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/start/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/start/specular.jpg -------------------------------------------------------------------------------- /textures.full/tracks/cityscape/start/start.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures.full/tracks/cityscape/start/start.jpg -------------------------------------------------------------------------------- /textures/bonus/base/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/bonus/base/diffuse.jpg -------------------------------------------------------------------------------- /textures/bonus/base/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/bonus/base/normal.jpg -------------------------------------------------------------------------------- /textures/bonus/base/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/bonus/base/specular.jpg -------------------------------------------------------------------------------- /textures/checker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/checker.png -------------------------------------------------------------------------------- /textures/hud/hex.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/hud/hex.jpg -------------------------------------------------------------------------------- /textures/hud/hud-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/hud/hud-bg.png -------------------------------------------------------------------------------- /textures/hud/hud-fg-shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/hud/hud-fg-shield.png -------------------------------------------------------------------------------- /textures/hud/hud-fg-speed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/hud/hud-fg-speed.png -------------------------------------------------------------------------------- /textures/particles/cloud - Copie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/particles/cloud - Copie.png -------------------------------------------------------------------------------- /textures/particles/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/particles/cloud.png -------------------------------------------------------------------------------- /textures/particles/damage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/particles/damage.png -------------------------------------------------------------------------------- /textures/particles/spark - Copie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/particles/spark - Copie.png -------------------------------------------------------------------------------- /textures/particles/spark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/particles/spark.png -------------------------------------------------------------------------------- /textures/ships/feisar/booster/booster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/ships/feisar/booster/booster.png -------------------------------------------------------------------------------- /textures/ships/feisar/booster/boostersprite.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/ships/feisar/booster/boostersprite.jpg -------------------------------------------------------------------------------- /textures/ships/feisar/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/ships/feisar/diffuse.jpg -------------------------------------------------------------------------------- /textures/ships/feisar/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/ships/feisar/normal.jpg -------------------------------------------------------------------------------- /textures/ships/feisar/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/ships/feisar/specular.jpg -------------------------------------------------------------------------------- /textures/skybox/dawnclouds/nx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/skybox/dawnclouds/nx.jpg -------------------------------------------------------------------------------- /textures/skybox/dawnclouds/ny.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/skybox/dawnclouds/ny.jpg -------------------------------------------------------------------------------- /textures/skybox/dawnclouds/nz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/skybox/dawnclouds/nz.jpg -------------------------------------------------------------------------------- /textures/skybox/dawnclouds/px.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/skybox/dawnclouds/px.jpg -------------------------------------------------------------------------------- /textures/skybox/dawnclouds/py.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/skybox/dawnclouds/py.jpg -------------------------------------------------------------------------------- /textures/skybox/dawnclouds/pz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/skybox/dawnclouds/pz.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/collision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/collision.png -------------------------------------------------------------------------------- /textures/tracks/cityscape/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/diffuse.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/height.png -------------------------------------------------------------------------------- /textures/tracks/cityscape/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/normal.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/scrapers1/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/scrapers1/diffuse.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/scrapers1/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/scrapers1/normal.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/scrapers1/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/scrapers1/specular.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/scrapers2/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/scrapers2/diffuse.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/scrapers2/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/scrapers2/normal.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/scrapers2/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/scrapers2/specular.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/specular.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/start/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/start/diffuse.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/start/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/start/normal.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/start/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/start/specular.jpg -------------------------------------------------------------------------------- /textures/tracks/cityscape/start/start.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/HexGL/6addc95a2fce3bf05f4d751823cc054c61a16d68/textures/tracks/cityscape/start/start.jpg --------------------------------------------------------------------------------