├── Single-Page-App-with-REST-API ├── frontend │ ├── Final │ │ ├── views │ │ │ ├── error.pug │ │ │ ├── index.pug │ │ │ └── layout.pug │ │ ├── package.json │ │ ├── routes │ │ │ ├── users.js │ │ │ └── index.js │ │ ├── bin │ │ │ └── www │ │ ├── public │ │ │ ├── stylesheets │ │ │ │ └── style.css │ │ │ └── javascripts │ │ │ │ └── scripts.js │ │ └── app.js │ ├── Start │ │ ├── layout.pug │ │ ├── index.js │ │ ├── style.css │ │ └── scripts.js │ └── README.md ├── backend │ ├── data │ │ ├── mockgen.js │ │ ├── game.js │ │ ├── guess.js │ │ └── new.js │ ├── .vscode │ │ └── launch.json │ ├── README.md │ ├── package.json │ ├── handlers │ │ ├── game.js │ │ ├── new.js │ │ └── guess.js │ ├── server.js │ ├── api.json │ └── config │ │ └── swagger.json └── README.md ├── BabylonJS-game-with-WebVR ├── after │ ├── textures │ │ ├── skybox_nx.jpg │ │ ├── skybox_ny.jpg │ │ ├── skybox_nz.jpg │ │ ├── skybox_px.jpg │ │ ├── skybox_py.jpg │ │ └── skybox_pz.jpg │ ├── index.html │ ├── css │ │ └── stylesheet.css │ └── js │ │ └── main.js ├── before │ ├── textures │ │ ├── skybox_nx.jpg │ │ ├── skybox_ny.jpg │ │ ├── skybox_nz.jpg │ │ ├── skybox_px.jpg │ │ ├── skybox_py.jpg │ │ └── skybox_pz.jpg │ ├── index.html │ ├── css │ │ └── stylesheet.css │ └── js │ │ └── main.js └── README.md ├── README.md ├── LICENSE ├── SECURITY.md ├── .gitignore └── ThirdPartyNotices.txt /Single-Page-App-with-REST-API/frontend/Final/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/after/textures/skybox_nx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/after/textures/skybox_nx.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/after/textures/skybox_ny.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/after/textures/skybox_ny.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/after/textures/skybox_nz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/after/textures/skybox_nz.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/after/textures/skybox_px.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/after/textures/skybox_px.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/after/textures/skybox_py.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/after/textures/skybox_py.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/after/textures/skybox_pz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/after/textures/skybox_pz.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/before/textures/skybox_nx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/before/textures/skybox_nx.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/before/textures/skybox_ny.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/before/textures/skybox_ny.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/before/textures/skybox_nz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/before/textures/skybox_nz.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/before/textures/skybox_px.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/before/textures/skybox_px.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/before/textures/skybox_py.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/before/textures/skybox_py.jpg -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/before/textures/skybox_pz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Windows-tutorials-web/HEAD/BabylonJS-game-with-WebVR/before/textures/skybox_pz.jpg -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/data/mockgen.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var Swagmock = require('swagmock'); 3 | var Path = require('path'); 4 | var apiPath = Path.resolve(__dirname, '../config/swagger.json'); 5 | var mockgen; 6 | 7 | module.exports = function () { 8 | /** 9 | * Cached mock generator 10 | */ 11 | mockgen = mockgen || Swagmock(apiPath); 12 | return mockgen; 13 | }; 14 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Final/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "memorygamesample", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.17.1", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.3", 12 | "express": "~4.15.2", 13 | "morgan": "~1.8.1", 14 | "pug": "~2.0.0-beta11", 15 | "serve-favicon": "~2.4.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Final/views/index.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | 5 | .container-fluid 6 | form(method="GET") 7 | select(id="selectGameSize" class="form-control" onchange="newGame()") 8 | option(value="0") New Game 9 | option(value="2") 2 Matches 10 | option(value="4") 4 Matches 11 | option(value="6") 6 Matches 12 | option(value="8") 8 Matches 13 | #game-board.row-fluid 14 | script restoreGame(); -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "program": "${workspaceRoot}/server.js" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Start/layout.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous') 6 | script(type="text/javascript" src=" http://code.jquery.com/jquery-3.1.1.min.js") 7 | script(type='text/javascript' src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js' integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa' crossorigin='anonymous') 8 | link(rel='stylesheet', href='/stylesheets/style.css') 9 | script(type='text/javascript' src='/javascripts/scripts.js') 10 | body 11 | block content 12 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Final/views/layout.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous') 6 | script(type="text/javascript" src=" http://code.jquery.com/jquery-3.1.1.min.js") 7 | script(type='text/javascript' src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js' integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa' crossorigin='anonymous') 8 | link(rel='stylesheet', href='/stylesheets/style.css') 9 | script(type='text/javascript' src='/javascripts/scripts.js') 10 | body 11 | block content 12 | -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | languages: 4 | - javascript 5 | products: 6 | - windows 7 | statusNotificationTargets: 8 | - codefirst@microsoft.com 9 | urlFragment: get-started-webvr-babylon 10 | description: "This is the complete sample code for the getting started tutorial on WebVR and Babylon.js." 11 | --- 12 | 13 | # Get Started Tutorial: Adding WebVR support to a 3D Babylon.js game 14 | 15 | This is the complete sample code for the [Get Started Tutorial: Adding WebVR support to a 3D Babylon.js game](https://docs.microsoft.com/windows/uwp/get-started/adding-webvr-to-a-babylonjs-game) on [Windows Dev Center](https://developer.microsoft.com/windows). 16 | 17 | This sample takes a Babylon.js game (located in the **before** folder) and adds WebVR support to it so that the game can be viewed with a VR headset. 18 | The final game is located within the **after** folder. 19 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/README.md: -------------------------------------------------------------------------------- 1 | # REST API sample (Memory Game API) 2 | 3 | This is the complete code for Part I of [Get Started Tutorial: A single-page web app + REST API](https://docs.microsoft.com/en-us/windows/uwp/get-started/get-started-tutorial-fullstack-web-app). This code demonstrates the game logic for a simple game of *Memory* (also known as [Concentration](https://en.wikipedia.org/wiki/Concentration_(game))) using a cloud-hostable REST API service. 4 | 5 | ## Requirements: 6 | 7 | - [Node.js](https://nodejs.org/en/download/) - Be sure to select the option to add Node to your PATH. 8 | 9 | ## To run the sample: 10 | 11 | 1. Copy down this folder and open your favorite shell to it. 12 | 13 | 2. Run `npm install` to install the dependencies. 14 | 15 | 3. Run `npm start` to start the Node server. 16 | 17 | 4. Navigate to [http://localhost:8000/](http://localhost:8000/), which provides a [Swagger UI](http://swagger.io/swagger-ui/) that documents the operations provided by the Memory Game API and provides a manual testing interface. 18 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | languages: 4 | - javascript 5 | products: 6 | - windows 7 | statusNotificationTargets: 8 | - codefirst@microsoft.com 9 | urlFragment: get-started-single-page-app 10 | description: "This is the complete sample code for the tutorial on getting started with single page web apps and REST API." 11 | --- 12 | 13 | # Get Started Tutorial: A single-page web app + REST API - Sample Code 14 | 15 | This is the complete sample code for the [Get Started Tutorial: A single-page web app + REST API](https://docs.microsoft.com/windows/uwp/get-started/get-started-tutorial-fullstack-web-app) on [Windows Dev Center](https://developer.microsoft.com/windows). 16 | 17 | This 2-part sample uses popular fullstack web technologies to run a simple *Memory* game that both works in the browser and as a Hosted Web App for the Microsoft Store. 18 | 19 | The [backend](backend/README.md) folder demonstrates a simple REST API service for the cloud-hostable game logic, such that game state is preserved when playing across different devices. 20 | 21 | The [frontend](frontend/README.md) folder demonstrates a single-page web application with responsive layout for the game itself. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Windows Tutorials for Web Technologies - Sample Code 2 | 3 | This is the code sample repository for web-related tutorials on [Windows Dev Center](https://developer.microsoft.com/en-us/windows), including: 4 | 5 | - [Get Started Tutorial: Adding WebVR support to a 3D Babylon.js game](https://docs.microsoft.com/windows/uwp/get-started/adding-webvr-to-a-babylonjs-game) 6 | - [Get Started Tutorial: Single-page web app + REST API backend](https://docs.microsoft.com/windows/uwp/get-started/get-started-tutorial-fullstack-web-app) 7 | 8 | Refer to the README file in each sample's folder for requirements and instructions on running. 9 | 10 | ## Contributing 11 | 12 | We welcome your input on issues and suggestions for new samples! Please file them as issues on this GitHub repo. At this time we are not accepting new samples from the public, but please check back as we evolve our contribution model. 13 | 14 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 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 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "memorygameapisample", 3 | "description": "", 4 | "version": "1.0.0", 5 | "author": "Microsoft Corporation", 6 | "contributors": [], 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/Microsoft/Windows-tutorials-web/" 10 | }, 11 | "bugs": "http://github.com/Microsoft/Windows-tutorials-web/issues", 12 | "publishConfig": { 13 | "registry": "https://registry.npmjs.org" 14 | }, 15 | "dependencies": { 16 | "body-parser": "^1.15.0", 17 | "express": "^4.0.0", 18 | "swaggerize-express": "^4.0.0", 19 | "swaggerize-ui": "^1.0.1", 20 | "swagmock": "~0.0.2" 21 | }, 22 | "devDependencies": { 23 | "eslint": "^2", 24 | "istanbul": "~0.4.3", 25 | "is-my-json-valid": "^2.13.1", 26 | "js-yaml": "^3.2.6", 27 | "supertest": "^1.2.0", 28 | "swagger-parser": "^3.4.1", 29 | "tape": "^4" 30 | }, 31 | "scripts": { 32 | "test": "tape 'tests/**/*.js'", 33 | "cover": "istanbul cover tape -- 'tests/**/*.js'", 34 | "lint": "eslint .", 35 | "regenerate": "yo swaggerize:test --framework express --apiPath './config/swagger.json'" 36 | }, 37 | "generator-swaggerize": { 38 | "version": "3.1.0" 39 | }, 40 | "main": "./server" 41 | } 42 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/README.md: -------------------------------------------------------------------------------- 1 | # Single-page web app sample (Memory Game app) 2 | 3 | This folder contains the initial and completed front-end code for Part II of [Get Started Tutorial: A single-page web app + REST API](https://docs.microsoft.com/en-us/windows/uwp/get-started/get-started-tutorial-fullstack-web-app). This code demonstrates the UI for simple game of *Memory* (also known as [Concentration](https://en.wikipedia.org/wiki/Concentration_(game))) as a single-page web app that works across devices. 4 | 5 | ## Requirements: 6 | 7 | - [Node.js](https://nodejs.org/en/download/) - Be sure to select the option to add Node to your PATH. 8 | 9 | - [Express generator](http://expressjs.com/en/starter/generator.html)- After you install Node, install Express by running `npm install express-generator -g` 10 | 11 | ## To run the sample: 12 | 13 | 1. Copy down the parent folder *Single-Page-App-with-REST-API* for both the backend and frontend samples. 14 | 15 | 2. Follow the README directions in the [.\backend](..\backend\README.md) folder to start running the REST API service (on [http://localhost:8000/](http://localhost:8000/)). 16 | 17 | 3. Open your favorite shell to the *.\frontend\Final* subfolder. 18 | 19 | 4. Run `npm install` to install the dependencies. 20 | 21 | 5. Run `npm start` to start the Node server. 22 | 23 | 6. Navigate to [http://localhost:3000/](http://localhost:3000/). Select a new game from the dropdown menu, and start clicking on cards to reveal their values and find matches. 24 | -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/after/index.html: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/before/index.html: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Start/index.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | module.exports = function (app) { 25 | 26 | app.get('/', function (req, res, next) { 27 | 28 | res.render('index', { title: 'Memory Game Sample' }); 29 | 30 | }); 31 | 32 | }; 33 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Final/routes/users.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | var express = require('express'); 25 | var router = express.Router(); 26 | 27 | /* GET users listing. */ 28 | router.get('/', function(req, res, next) { 29 | res.send('respond with a resource'); 30 | }); 31 | 32 | module.exports = router; 33 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Final/routes/index.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | var express = require('express'); 25 | var router = express.Router(); 26 | 27 | /* GET home page. */ 28 | router.get('/', function(req, res, next) { 29 | res.render('index', { title: 'Memory Game Sample' }); 30 | }); 31 | 32 | module.exports = router; 33 | -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/after/css/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* 2 | // --------------------------------------------------------------------------------- 3 | // Copyright (c) Microsoft Corporation. All rights reserved. 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // --------------------------------------------------------------------------------- 25 | */ 26 | 27 | html, body { 28 | overflow: hidden; 29 | width : 100%; 30 | height : 100%; 31 | margin : 0; 32 | padding : 0; 33 | } 34 | 35 | #renderCanvas { 36 | width : 100%; 37 | height : 100%; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/before/css/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* 2 | // --------------------------------------------------------------------------------- 3 | // Copyright (c) Microsoft Corporation. All rights reserved. 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // --------------------------------------------------------------------------------- 25 | */ 26 | 27 | html, body { 28 | overflow: hidden; 29 | width : 100%; 30 | height : 100%; 31 | margin : 0; 32 | padding : 0; 33 | } 34 | 35 | #renderCanvas { 36 | width : 100%; 37 | height : 100%; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Final/bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('memory:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/handlers/game.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | 'use strict'; 25 | var dataProvider = require('../data/game.js'); 26 | /** 27 | * Operations on /game 28 | */ 29 | module.exports = { 30 | /** 31 | * summary: Retrieves the current state of the memory game board. 32 | * parameters: (none) 33 | * produces: application/json, text/json 34 | * responses: 200, 400 35 | */ 36 | get: function game_get(req, res, next) { 37 | var status; 38 | var message; 39 | 40 | // If there's a game in progress, retrieve its current state 41 | if (global.board){ 42 | status = 200; 43 | var provider = dataProvider['get']['200']; 44 | var board = provider(req, res, function (err, data) { 45 | if (err) { 46 | next(err); 47 | return; 48 | } 49 | }); 50 | res.json(board); 51 | } 52 | else { // No game in progress: set bad request error 53 | status = 400; 54 | message = "Please start a new game (POST '/new?size={# of matches}')." 55 | } 56 | res.status(status).send(message); 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/data/game.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | 'use strict'; 25 | var Mockgen = require('./mockgen.js'); 26 | /** 27 | * Operations on /game 28 | */ 29 | module.exports = { 30 | /** 31 | * summary: Retrieves the current state of the game 32 | * description: Returns an array of card objects, where position in 33 | * the array indicates card ID and the "cleared" property indicates 34 | * if its match has already been found. The value of cleared cards is also 35 | * reported. 36 | * 37 | * parameters: (none) 38 | * produces: application/json, text/json 39 | * responses: 200 40 | * operationId: game_get 41 | */ 42 | get: { 43 | 200: function (req, res, callback) { 44 | // Only reveal cleared card values 45 | var currentBoardState = []; 46 | var board = global.board; 47 | 48 | for (var i=0; i < board.length; i++){ 49 | var card = {}; 50 | card.cleared = board[i].cleared; 51 | if ("true" == card.cleared) { // To debug the board, comment this line 52 | card.value = board[i].value; 53 | } // And this line 54 | currentBoardState.push(card); 55 | } 56 | return currentBoardState; 57 | } 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/data/guess.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | 'use strict'; 25 | var Mockgen = require('./mockgen.js'); 26 | var card1 = null; 27 | /** 28 | * Operations on /guess 29 | */ 30 | module.exports = { 31 | /** 32 | * summary: Reveals the specified card and checks for match to the previous. 33 | * description: Each guess consists of 2 specified cards. 34 | * parameters: card 35 | * produces: application/json, text/json 36 | * responses: 200 37 | * operationId: game_guess 38 | */ 39 | put: { 40 | 200: function (req, res, callback) { 41 | // Obtain the card values 42 | var response = {}; 43 | var card = req.query.card; 44 | 45 | response.id = card; 46 | response.value = global.board[card].value; 47 | 48 | // If 1st card has been specified, check if this 2nd card matches 49 | if (card1 !== null){ 50 | if (global.board[card1].value === global.board[card].value){ 51 | global.board[card1].cleared = 52 | global.board[card].cleared = "true"; 53 | } 54 | card1 = null; 55 | } else { // This is the 1st card of the guess 56 | card1 = card; 57 | } 58 | 59 | return Array(response); 60 | } 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Start/style.css: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | /* general styles */ 12 | 13 | body { 14 | background: #000000; 15 | color: #000000; 16 | } 17 | 18 | html, body, .container-fluid, .row-fluid { 19 | height: 96%; 20 | } 21 | 22 | /* Boostrap overrides */ 23 | 24 | .form-control { 25 | width: 15%; 26 | min-width: 150px; 27 | float: right; 28 | margin-top: 10px; 29 | margin-right: 5px; 30 | } 31 | 32 | .btn { 33 | margin: 5px; 34 | } 35 | 36 | .col-xs-3 { 37 | padding: 0; 38 | } 39 | 40 | .container-fluid { 41 | min-width: 305px; 42 | min-height: 305px; 43 | } 44 | 45 | 46 | /* game setup */ 47 | 48 | #game-board { 49 | margin: 0 auto; 50 | position: relative; 51 | clear: both; 52 | } 53 | 54 | #playAgain { 55 | text-align: center; 56 | } 57 | 58 | 59 | #playAgain p { 60 | margin: 0 auto; 61 | color: #5fe883; 62 | font-size: 2em; 63 | } 64 | 65 | /* cards */ 66 | 67 | .flipContainer { 68 | position: relative; 69 | border: 1vh solid transparent; 70 | min-height: 50px; 71 | min-width: 50px; 72 | /* add code from Part 5.1 here */ 73 | } 74 | 75 | .cards { 76 | position: absolute; 77 | width: 100%; 78 | height: 100%; 79 | border: solid 3px #000000; 80 | /* add code from Part 5.2 here */ 81 | } 82 | 83 | .cards div { 84 | margin: 0; 85 | width: 100%; 86 | height: 100%; 87 | display: block; 88 | position: absolute; 89 | backface-visibility: hidden; 90 | } 91 | 92 | .cards .front { 93 | background-color: #ffffff; 94 | text-align: center; 95 | display: table; 96 | } 97 | 98 | .cards .back { 99 | transform: rotateY(180deg); 100 | background-color: #D3D3D3; 101 | text-align: center; 102 | display: table; 103 | } 104 | 105 | .cards.matched .back { 106 | background-color: #5fe883; 107 | } 108 | 109 | .cards .back .glyphicon { 110 | display: table-cell; 111 | vertical-align: middle; 112 | font-size: 8vh; 113 | } 114 | 115 | .cards .front .glyphicon { 116 | display: table-cell; 117 | vertical-align: middle; 118 | font-size: 8vh; 119 | } 120 | 121 | .cards.flip { 122 | /* add code from Part 5.3 here */ 123 | } 124 | 125 | .rows1 { 126 | height: 100%; 127 | } 128 | 129 | .rows2 { 130 | height: 50%; 131 | } 132 | 133 | .rows3 { 134 | height: 33%; 135 | } 136 | 137 | .rows4 { 138 | height: 25%; 139 | } 140 | 141 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Final/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | /* general styles */ 12 | 13 | body { 14 | background: #000000; 15 | color: #000000; 16 | } 17 | 18 | html, body, .container-fluid, .row-fluid { 19 | height: 96%; 20 | } 21 | 22 | /* Boostrap overrides */ 23 | 24 | .form-control { 25 | width: 15%; 26 | min-width: 150px; 27 | float: right; 28 | margin-top: 10px; 29 | margin-right: 5px; 30 | } 31 | 32 | .btn { 33 | margin: 5px; 34 | } 35 | 36 | .col-xs-3 { 37 | padding: 0; 38 | } 39 | 40 | .container-fluid { 41 | min-width: 305px; 42 | min-height: 305px; 43 | } 44 | 45 | 46 | /* game setup */ 47 | 48 | #game-board { 49 | margin: 0 auto; 50 | position: relative; 51 | clear: both; 52 | } 53 | 54 | #playAgain { 55 | text-align: center; 56 | } 57 | 58 | 59 | #playAgain p { 60 | margin: 0 auto; 61 | color: #5fe883; 62 | font-size: 2em; 63 | } 64 | 65 | /* cards */ 66 | 67 | .flipContainer { 68 | position: relative; 69 | border: 1vh solid transparent; 70 | min-height: 50px; 71 | min-width: 50px; 72 | perspective: 1000px; 73 | } 74 | 75 | .cards { 76 | position: absolute; 77 | width: 100%; 78 | height: 100%; 79 | border: solid 3px #000000; 80 | transform-style: preserve-3d; 81 | transition-duration: 1s; 82 | } 83 | 84 | .cards div { 85 | margin: 0; 86 | width: 100%; 87 | height: 100%; 88 | display: block; 89 | position: absolute; 90 | backface-visibility: hidden; 91 | } 92 | 93 | .cards .front { 94 | background-color: #ffffff; 95 | text-align: center; 96 | display: table; 97 | } 98 | 99 | .cards .back { 100 | transform: rotateY(180deg); 101 | background-color: #D3D3D3; 102 | text-align: center; 103 | display: table; 104 | } 105 | 106 | .cards.matched .back { 107 | background-color: #5fe883; 108 | } 109 | 110 | .cards .back .glyphicon { 111 | display: table-cell; 112 | vertical-align: middle; 113 | font-size: 8vh; 114 | } 115 | 116 | .cards .front .glyphicon { 117 | display: table-cell; 118 | vertical-align: middle; 119 | font-size: 8vh; 120 | } 121 | 122 | .cards.flip { 123 | transform: rotateY(180deg); 124 | } 125 | 126 | .rows1 { 127 | height: 100%; 128 | } 129 | 130 | .rows2 { 131 | height: 50%; 132 | } 133 | 134 | .rows3 { 135 | height: 33%; 136 | } 137 | 138 | .rows4 { 139 | height: 25%; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Final/app.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | var express = require('express'); 25 | var path = require('path'); 26 | var favicon = require('serve-favicon'); 27 | var logger = require('morgan'); 28 | var cookieParser = require('cookie-parser'); 29 | var bodyParser = require('body-parser'); 30 | 31 | var index = require('./routes/index'); 32 | var users = require('./routes/users'); 33 | 34 | var app = express(); 35 | 36 | // view engine setup 37 | app.set('views', path.join(__dirname, 'views')); 38 | app.set('view engine', 'pug'); 39 | 40 | // uncomment after placing your favicon in /public 41 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 42 | app.use(logger('dev')); 43 | app.use(bodyParser.json()); 44 | app.use(bodyParser.urlencoded({ extended: false })); 45 | app.use(cookieParser()); 46 | app.use(express.static(path.join(__dirname, 'public'))); 47 | 48 | app.use('/', index); 49 | app.use('/users', users); 50 | 51 | // catch 404 and forward to error handler 52 | app.use(function(req, res, next) { 53 | var err = new Error('Not Found'); 54 | err.status = 404; 55 | next(err); 56 | }); 57 | 58 | // error handler 59 | app.use(function(err, req, res, next) { 60 | // set locals, only providing error in development 61 | res.locals.message = err.message; 62 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 63 | 64 | // render the error page 65 | res.status(err.status || 500); 66 | res.render('error'); 67 | }); 68 | 69 | module.exports = app; 70 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/handlers/new.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | 'use strict'; 25 | var dataProvider = require('../data/new.js'); 26 | var MAX_MATCHES = 20; 27 | /** 28 | * Operations on /new 29 | */ 30 | module.exports = { 31 | /** 32 | * summary: Initializes a new game board of the specified size (# of matches) 33 | * parameters: size 34 | * produces: application/json, text/json 35 | * responses: 200, 400 36 | */ 37 | post: function game_new(req, res, next) { 38 | var status; 39 | var message; 40 | global.board = null; // Null out the current game 41 | 42 | // This is a valid game size: initialize new game board 43 | if ((req.query.size > 0)&&(req.query.size <= MAX_MATCHES)){ 44 | status = 200; 45 | var provider = dataProvider['post']['200']; 46 | 47 | // Call the data layer to shuffle up a new game 48 | var board = provider(req, res, function (err, data) { 49 | if (err) { 50 | next(err); 51 | return; 52 | } 53 | }); 54 | message = "Ready to play! Matches to find = " + 55 | req.query.size; 56 | } else { // Invalid # of matches specified: set bad request error 57 | status = 400; 58 | message = "Size of game (# of matches) must be between 1 and " + 59 | MAX_MATCHES + ". Specified size = " + req.query.size; 60 | } 61 | res.status(status).send(message); 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/server.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | 'use strict'; 25 | 26 | var port = process.env.PORT || 8000; // Better flexibility than hardcoding the port 27 | 28 | var Http = require('http'); 29 | var Express = require('express'); 30 | var BodyParser = require('body-parser'); 31 | var Swaggerize = require('swaggerize-express'); 32 | var SwaggerUi = require('swaggerize-ui'); // Provides UI for testing our API 33 | var Path = require('path'); 34 | 35 | var App = Express(); 36 | var Server = Http.createServer(App); 37 | 38 | App.use(function(req, res, next) { // Enable cross origin resource sharing (for app frontend) 39 | res.header('Access-Control-Allow-Origin', '*'); 40 | res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,OPTIONS'); 41 | res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With'); 42 | 43 | // Prevents CORS preflight request (for PUT game_guess) from redirecting 44 | if ('OPTIONS' == req.method) { 45 | res.send(200); 46 | } 47 | else { 48 | next(); // Passes control to next (Swagger) handler 49 | } 50 | }); 51 | 52 | App.use(BodyParser.json()); 53 | App.use(BodyParser.urlencoded({ 54 | extended: true 55 | })); 56 | 57 | App.use(Swaggerize({ 58 | api: Path.resolve('./config/swagger.json'), 59 | handlers: Path.resolve('./handlers'), 60 | docspath: '/swagger' // Hooks up the testing UI 61 | })); 62 | 63 | App.use('/', SwaggerUi({ // Serves the testing UI from our base URL 64 | docs: '/swagger' // 65 | })); 66 | 67 | Server.listen(port, function () { // Starts server with our modfied port settings 68 | }); 69 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/handlers/guess.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | 'use strict'; 25 | var dataProvider = require('../data/guess.js'); 26 | /** 27 | * Operations on /guess 28 | */ 29 | module.exports = { 30 | /** 31 | * summary: Specifies a card (ID) to reveal 32 | * parameters: card 33 | * produces: application/json, text/json 34 | * responses: 200, 400 35 | */ 36 | put: function game_guess(req, res, next) { 37 | var status, message; 38 | var validGuess = true; 39 | var board = global.board; 40 | var guess = req.query.card; 41 | 42 | // Ensure there's a game running 43 | if (!board){ 44 | validGuess = false; 45 | message = "Please start a new game (POST '/new?size={# of matches}')." 46 | } 47 | // Ensure card isn't out of range 48 | else if ((guess < 0)||(guess > board.length)){ 49 | validGuess = false; 50 | message = "Please specify card ids within the range of 0 to " + 51 | String(board.length-1) + "."; 52 | } 53 | // Check that card hasn't been cleared 54 | else if ("true" == board[guess].cleared) { 55 | validGuess = false; 56 | message = "Please specify a card which hasn't been cleared." 57 | } 58 | 59 | // This is a valid guess: reveal the card 60 | if (validGuess){ 61 | status = 200; 62 | var provider = dataProvider['put']['200']; 63 | var card = provider(req, res, function (err, data) { 64 | if (err) { 65 | next(err); 66 | return; 67 | } 68 | }); 69 | res.json(card); 70 | } else { // This is not a valid guess: set bad request error 71 | status = 400; 72 | } 73 | 74 | res.status(status).send(message); 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/backend/data/new.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | 'use strict'; 25 | var Mockgen = require('./mockgen.js'); 26 | 27 | // Knuth shuffle courtesy of https://www.kirupa.com/html5/shuffling_array_js.htm 28 | Array.prototype.shuffle = function() { 29 | var input = this; 30 | for (var i=input.length-1; i >=0; i--){ 31 | var randomIndex = Math.floor(Math.random()*(i+1)); 32 | var itemAtIndex = input[randomIndex]; 33 | input[randomIndex] = input[i]; 34 | input[i] = itemAtIndex; 35 | } 36 | return input; 37 | }; 38 | /** 39 | * Operations on /new 40 | */ 41 | module.exports = { 42 | /** 43 | * summary: Sets up a new game board with specified # of matches 44 | * description: The game board is a global array of "card" objects, where 45 | * their position in the array indicates their ID, and their "value" and 46 | * "cleared" properties represent their value and game status. For example, 47 | * a new board of size=1 (1 matches) would be generated as: 48 | * [  49 | * { "cleared":"false",  50 | *    "value":"0",  51 | * },  52 | * { "cleared":"false",  53 | *     "value":"0",  54 | * } 55 | * ] 56 | * parameters: size 57 | * produces: application/json, text/json 58 | * responses: 200 59 | * operationId: game_new 60 | */ 61 | post: { 62 | 200: function (req, res, callback) { 63 | // Generate random [0...size] value pairs and shuffle them 64 | var values = Array.from(Array(req.query.size).keys()); 65 | var deck = values.concat(values.slice()); 66 | deck.shuffle(); 67 | 68 | // Create corresponding card objects 69 | var board = []; 70 | for (var i=0; i"; 195 | } 196 | } 197 | 198 | return value; 199 | } 200 | -------------------------------------------------------------------------------- /Single-Page-App-with-REST-API/frontend/Final/public/javascripts/scripts.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------- 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // 4 | // The MIT License (MIT) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // --------------------------------------------------------------------------------- 24 | var gameBoardSize = 0; 25 | var cardsFlipped = 0; 26 | 27 | var selectedCards = []; 28 | var selectedCardsValues = []; 29 | 30 | function newGame() { 31 | // reset the game 32 | gameBoardSize = 0; 33 | cardsFlipped = 0; 34 | 35 | // extract game size selection from user 36 | var size = $("#selectGameSize").val(); 37 | 38 | // parse game size value 39 | size = parseInt(size, 10); 40 | 41 | 42 | // check if this is a valid selection 43 | if (size === 0) { 44 | // show an error message 45 | alert("Please choose a size!"); 46 | } else { 47 | // fetch the game board array from the server 48 | $.post("http://localhost:8000/new?size=" + size, function (response) { 49 | // store game data * 2 for card number 50 | gameBoardSize = size * 2; 51 | 52 | // create an empty game board 53 | var board = []; 54 | for (var i = 0; i < gameBoardSize; i++) { 55 | board.push({ 56 | "cleared": "false", 57 | "value": null 58 | }); 59 | } 60 | 61 | // draw the game board 62 | drawGameBoard(board); 63 | }); 64 | } 65 | } 66 | 67 | function restoreGame() { 68 | // reset the game 69 | gameBoardSize = 0; 70 | cardsFlipped = 0; 71 | 72 | // fetch the game state from the server 73 | $.get("http://localhost:8000/game", function (response) { 74 | // store game board size 75 | gameBoardSize = response.length; 76 | 77 | // draw the game board 78 | drawGameBoard(response); 79 | }); 80 | } 81 | 82 | function drawGameBoard(board) { 83 | // create output 84 | var output = ""; 85 | // detect board size CSS class 86 | var css = ""; 87 | switch (board.length / 4) { 88 | case 1: 89 | css = "rows1"; 90 | break; 91 | case 2: 92 | css = "rows2"; 93 | break; 94 | case 3: 95 | css = "rows3"; 96 | break; 97 | case 4: 98 | css = "rows4"; 99 | break; 100 | } 101 | // generate HTML for each card and append to the output 102 | for (var i = 0; i < board.length; i++) { 103 | if (board[i].cleared == "true") { 104 | // if the card has been cleared apply the .flip class 105 | output += "
\ 106 |
\ 107 |
" + lookUpGlyphicon(board[i].value) + "
\ 108 |
"; 109 | } else { 110 | output += "
\ 111 |
\ 112 |
\ 113 |
"; 114 | } 115 | } 116 | // place the output on the page 117 | $("#game-board").html(output); 118 | } 119 | 120 | function flipCard(card) { 121 | // prevent the user from selecting a flipped card 122 | if ($(card).hasClass("flip")) { 123 | return; 124 | } 125 | 126 | // only allow the user to select two cards at a time 127 | if (selectedCards.length < 2) { 128 | 129 | $(card).toggleClass("flip"); 130 | 131 | // check if this is the first card selection or the second 132 | if (selectedCards.length == 0) { 133 | // store the first card selection 134 | selectedCards.push(card.id); 135 | 136 | // post this guess to the server and get this card's value 137 | $.ajax({ 138 | url: "http://localhost:8000/guess?card=" + selectedCards[0], 139 | type: 'PUT', 140 | success: function (response) { 141 | // display first card value 142 | $("#" + selectedCards[0] + " .back").html(lookUpGlyphicon(response[0].value)); 143 | 144 | // store the first card value 145 | selectedCardsValues.push(response[0].value); 146 | } 147 | }); 148 | } 149 | else if (selectedCards.length == 1) { 150 | // store the second card selection 151 | selectedCards.push(card.id); 152 | 153 | // post this guess to the server and get this card's value 154 | $.ajax({ 155 | url: "http://localhost:8000/guess?card=" + selectedCards[1], 156 | type: 'PUT', 157 | success: function (response) { 158 | // display first card value 159 | $("#" + selectedCards[1] + " .back").html(lookUpGlyphicon(response[0].value)); 160 | 161 | // store the first card value 162 | selectedCardsValues.push(response[0].value); 163 | 164 | // check if this was a match 165 | if (selectedCardsValues[0] == selectedCardsValues[1]) { 166 | // increment our flipped cards counter 167 | cardsFlipped += 2; 168 | 169 | // assign the matched class 170 | $("#" + selectedCards[0]).addClass("matched"); 171 | $("#" + selectedCards[1]).addClass("matched"); 172 | 173 | // reset our selection arrays 174 | selectedCards = []; 175 | selectedCardsValues = []; 176 | 177 | // check if the user won the game 178 | 179 | if (cardsFlipped == gameBoardSize) { 180 | setTimeout(function () { 181 | output = "

You Win!

"; 182 | $("#game-board").html(output); 183 | }, 1000); 184 | } 185 | 186 | } 187 | else { 188 | // wait three seconds, then flip the cards back 189 | setTimeout(function () { 190 | // reset the background color 191 | $("#" + selectedCards[0]).toggleClass("flip"); 192 | $("#" + selectedCards[1]).toggleClass("flip"); 193 | 194 | // reset our selection arrays 195 | selectedCards = []; 196 | selectedCardsValues = []; 197 | }, 1000); 198 | } 199 | } 200 | }); 201 | } 202 | } 203 | } 204 | 205 | // glyphicon value map 206 | var valuesMap = [ 207 | { 208 | "value": "0", 209 | "glyphicon": "glyphicon glyphicon-cloud" 210 | }, 211 | { 212 | "value": "1", 213 | "glyphicon": "glyphicon glyphicon-heart" 214 | }, 215 | { 216 | "value": "2", 217 | "glyphicon": "glyphicon glyphicon-star" 218 | }, 219 | { 220 | "value": "3", 221 | "glyphicon": "glyphicon glyphicon-home" 222 | }, 223 | { 224 | "value": "4", 225 | "glyphicon": "glyphicon glyphicon-glass" 226 | }, 227 | { 228 | "value": "5", 229 | "glyphicon": "glyphicon glyphicon-music" 230 | }, 231 | { 232 | "value": "6", 233 | "glyphicon": "glyphicon glyphicon-fire" 234 | }, 235 | { 236 | "value": "7", 237 | "glyphicon": "glyphicon glyphicon-globe" 238 | }, 239 | { 240 | "value": "8", 241 | "glyphicon": "glyphicon glyphicon-tree-conifer" 242 | } 243 | ]; 244 | 245 | // get gylphicon for value 246 | function lookUpGlyphicon(value) { 247 | for (var i = 0; i < valuesMap.length; i++) { 248 | if (valuesMap[i].value == value) { 249 | return ""; 250 | } 251 | } 252 | 253 | return value; 254 | } 255 | -------------------------------------------------------------------------------- /ThirdPartyNotices.txt: -------------------------------------------------------------------------------- 1 | Do Not Translate or Localize 2 | 3 | This file incorporates components from the projects listed below. Microsoft licenses these components to you under Microsoft’s software licensing terms, except that components licensed under open source licenses requiring that such components remain under their original license are being made available to you by Microsoft under their original licensing terms. 4 | 5 | The original copyright notices and the licenses under which Microsoft received such components are set forth below for informational purposes. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise. 6 | 7 | For those third party components licensed under open source licenses with source code availability obligations you may obtain the complete corresponding source code from Microsoft if and as required under the relevant open source licenses by sending a money order or check for $5.00 to: Source Code Compliance Team, Microsoft Corporation, 1 Microsoft Way, Redmond, WA 98052 USA. Please write “third party source code [Third Party IP]” in the memo line of your payment. We may also make the source available at http://3rdpartysource.microsoft.com/. 8 | 9 | ------------------------------------------------------------ 10 | 11 | This repository uses nodejs/node. 12 | 13 | Copyright Node.js contributors. All rights reserved. 14 | 15 | Provided for Informational Purposes Only 16 | 17 | MIT License 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | ----- 26 | 27 | This repository uses expressjs/express. 28 | 29 | Copyright (c) 2009-2014 TJ Holowaychuk 30 | Copyright (c) 2013-2014 Roman Shtylman 31 | Copyright (c) 2014-2015 Douglas Christopher Wilson 32 | 33 | Provided for Informational Purposes Only 34 | 35 | MIT License 36 | 37 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 38 | 39 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 42 | 43 | ----- 44 | 45 | This repository uses body-parser. 46 | 47 | Copyright (c) 2014 Jonathan Ong 48 | Copyright (c) 2014-2015 Douglas Christopher Wilson 49 | 50 | Provided for Informational Purposes Only 51 | 52 | MIT License 53 | 54 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 55 | 56 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 57 | 58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 59 | 60 | ----- 61 | 62 | This repository uses swagger-api/swagger-ui. 63 | 64 | Copyright 2017 SmartBear Software 65 | 66 | Provided for Informational Purposes Only 67 | 68 | Apache 2.0 License 69 | 70 | Licensed under the Apache License, Version 2.0 (the License); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 71 | 72 | THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 73 | 74 | See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. 75 | 76 | ----- 77 | 78 | This repository uses bootstrap. 79 | 80 | Copyright (c) 2011-2017 Twitter, Inc. 81 | Copyright (c) 2011-2017 The Bootstrap Authors 82 | 83 | Provided for Informational Purposes Only 84 | 85 | MIT License 86 | 87 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 88 | 89 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 90 | 91 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 92 | 93 | ----- 94 | 95 | This repository uses jquery/jquery. 96 | 97 | Copyright JS Foundation and other contributors, https://js.foundation/ 98 | 99 | This software consists of voluntary contributions made by many individuals. For exact contribution history, see the revision history available at https://github.com/jquery/jquery 100 | 101 | Provided for Informational Purposes Only 102 | 103 | The following license applies to all parts of this software except as 104 | documented below: 105 | 106 | ==== 107 | 108 | Permission is hereby granted, free of charge, to any person obtaining 109 | a copy of this software and associated documentation files (the 110 | "Software"), to deal in the Software without restriction, including 111 | without limitation the rights to use, copy, modify, merge, publish, 112 | distribute, sublicense, and/or sell copies of the Software, and to 113 | permit persons to whom the Software is furnished to do so, subject to 114 | the following conditions: 115 | 116 | The above copyright notice and this permission notice shall be 117 | included in all copies or substantial portions of the Software. 118 | 119 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 120 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 121 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 122 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 123 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 124 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 125 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 126 | 127 | ==== 128 | 129 | All files located in the node_modules and external directories are 130 | externally maintained libraries used by this software which have their 131 | own licenses; we recommend you read them, as their terms may differ from 132 | the terms above. 133 | 134 | ----- 135 | 136 | This repository uses BabylonJS/Babylon.js 137 | 138 | Provided for Informational Purposes Only 139 | 140 | Apache 2.0 License 141 | 142 | Licensed under the Apache License, Version 2.0 (the License); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 143 | 144 | THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 145 | 146 | See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/before/js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | // --------------------------------------------------------------------------------- 3 | // Copyright (c) Microsoft Corporation. All rights reserved. 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // --------------------------------------------------------------------------------- 25 | */ 26 | 27 | window.addEventListener('DOMContentLoaded', function () { 28 | 29 | const UNITWIDTH = 90; // Width of the cubes in the maze 30 | const UNITHEIGHT = 45; // Height of the cubes in the maze 31 | const CATCHOFFSET = 170; // How close dino can get before game over 32 | const CHASERANGE = 200; // How close dino can get before triggering the chase 33 | const DINOSCALE = 20; // How much to multiple the size of the dino by 34 | const DINOSPEED = 1600; // How fast the dino will move 35 | 36 | const DINORAYLENGTH = 55; // How close dino can get to collidable objects 37 | const ROARDIVISOR = 250; // How many frames to wait between roar animations (Once game over) 38 | 39 | 40 | // Game states 41 | var begin = false; // Flag to determine whether the game should begin 42 | var gameOver = false; // Flag to determines whether the game is over 43 | 44 | 45 | var camera; // The camera for the scene 46 | var ground; // The ground plane mesh 47 | var totalCubesWide; // How many wall cubes can make the width of the map 48 | var mapSize; // Height and width of the maze ground plane 49 | var collidableObjects = []; // Array holding all meshes that are collidable 50 | var dino; // The dino mesh 51 | var dinoVelocity = new BABYLON.Vector3(0, 0, 0); // The direction to apply the movement velocity of dino 52 | 53 | 54 | // Connects an xbox controller has been plugged in and and a button/trigger moved 55 | function onNewGamepadConnected(gamepad) { 56 | var xboxpad = gamepad 57 | 58 | xboxpad.onbuttondown(function (buttonValue) { 59 | // When the A button is pressed, either start or reload the game depending on the game state 60 | if (buttonValue == BABYLON.Xbox360Button.A) { 61 | 62 | // Game is over, reload it 63 | if (gameOver) { 64 | location.href = location.href; 65 | } 66 | // Game has begun 67 | else { 68 | // Hide "Press A to start" UI 69 | startUI.isVisible = false; 70 | begin = true; 71 | // Start looping the dino walking animation 72 | scene.beginAnimation(dino.skeleton, 111, 130, true, 1); 73 | } 74 | } 75 | }); 76 | } 77 | 78 | // Get all connected gamepads 79 | var gamepads = new BABYLON.Gamepads(function (gamepad) { onNewGamepadConnected(gamepad); }); 80 | 81 | 82 | // Grab where we'll be displayed the game 83 | var canvas = document.getElementById('renderCanvas'); 84 | 85 | // load the 3D engine 86 | var engine = new BABYLON.Engine(canvas, true); 87 | 88 | 89 | // Creates and return the scene 90 | var createScene = function () { 91 | 92 | // Create the Babylon scene 93 | var scene = new BABYLON.Scene(engine); 94 | 95 | // Apply gravity so that any Y axis movement is ignored 96 | scene.gravity = new BABYLON.Vector3(0, -9.81, 0); 97 | 98 | // Turn on fog for cool effects 99 | scene.fogMode = BABYLON.Scene.FOGMODE_EXP; 100 | scene.fogDensity = 0.001; 101 | scene.fogColor = new BABYLON.Color3(0.9, 0.9, 0.85); 102 | 103 | 104 | camera = new BABYLON.UniversalCamera("camera", new BABYLON.Vector3(0, 18, -45), scene); 105 | camera.rotation.y += degreesToRadians(90); 106 | 107 | // Set the ellipsoid around the camera. This will act as the collider box for when the player runs into walls 108 | camera.ellipsoid = new BABYLON.Vector3(1, 9, 1); 109 | camera.applyGravity = true; 110 | 111 | // Custom input, adding Xbox controller support for left analog stick to map to keyboard arrows 112 | camera.inputs.attached.keyboard.keysUp.push(211); // Left analog up 113 | camera.inputs.attached.keyboard.keysDown.push(212); // Left analog down 114 | camera.inputs.attached.keyboard.keysLeft.push(214); // Left analog left 115 | camera.inputs.attached.keyboard.keysRight.push(213); // Left analog right 116 | 117 | // Allow camera to be controlled 118 | camera.attachControl(canvas, true); 119 | 120 | // Create the skybox 121 | var skybox = BABYLON.Mesh.CreateBox("skyBox", 5000.0, scene); 122 | var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene); 123 | skyboxMaterial.backFaceCulling = false; 124 | skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/skybox", scene); 125 | skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE; 126 | skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0); 127 | skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0); 128 | skyboxMaterial.disableLighting = true; 129 | skybox.material = skyboxMaterial; 130 | 131 | // GUI 132 | var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI"); 133 | 134 | // Distance counter UI 135 | distanceCounterUI = new BABYLON.GUI.TextBlock(); 136 | distanceCounterUI.color = "red"; 137 | distanceCounterUI.fontSize = 24; 138 | advancedTexture.addControl(distanceCounterUI); 139 | distanceCounterUI.isVisible = false; 140 | 141 | // Game over UI 142 | gameOverUI = new BABYLON.GUI.Rectangle("start"); 143 | gameOverUI.background = "black" 144 | gameOverUI.alpha = .8; 145 | gameOverUI.thickness = 0; 146 | gameOverUI.height = "78px"; 147 | gameOverUI.width = "440px"; 148 | advancedTexture.addControl(gameOverUI); 149 | var tex1 = new BABYLON.GUI.TextBlock(); 150 | tex1.text = "GAME OVER"; 151 | tex1.color = "red"; 152 | tex1.fontSize = 70; 153 | gameOverUI.addControl(tex1); 154 | gameOverUI.isVisible = false; 155 | 156 | 157 | // Start UI 158 | startUI = new BABYLON.GUI.Rectangle("start"); 159 | startUI.background = "black" 160 | startUI.alpha = .8; 161 | startUI.thickness = 0; 162 | startUI.height = "60px"; 163 | startUI.width = "400px"; 164 | advancedTexture.addControl(startUI); 165 | var tex2 = new BABYLON.GUI.TextBlock(); 166 | tex2.text = "Stay away from the dinosaur! \n Plug in an Xbox controller and press A to start"; 167 | tex2.color = "white"; 168 | startUI.addControl(tex2); 169 | 170 | // return the created scene 171 | return scene; 172 | } 173 | 174 | // Listen for if the window changes sizes and adjust 175 | window.addEventListener('resize', onWindowResize, false); 176 | // Create the scene 177 | var scene = createScene(); 178 | 179 | // Load the dinosaur model 180 | BABYLON.SceneLoader.ImportMesh("Dino", "models/", "dino.babylon", scene, function (newMeshes) { 181 | 182 | dino = newMeshes[0]; 183 | 184 | // Set the initial size and position of the dino 185 | dino.scaling = new BABYLON.Vector3(DINOSCALE, DINOSCALE, DINOSCALE); 186 | dino.position = new BABYLON.Vector3(500, 18, -30); 187 | // Set the size of the ellips-shaped collider around dino 188 | dino.ellipsoid = new BABYLON.Vector3(.5, .5, .5); 189 | dino.rotation.y = degreesToRadians(90); 190 | 191 | // Enable blending of animations (i.e. transitioning from standing to walking animation smoothly) 192 | dino.skeleton.enableBlending(0.1) 193 | 194 | // Start looping the standing animation before the game begins 195 | dino.skeleton.beginAnimation("stand", true, .5); 196 | 197 | 198 | // Run the render loop (fired every time a new frame is rendered) 199 | animate(); 200 | 201 | }); 202 | 203 | // Create the walls/ground 204 | createMazeCubes(); 205 | addLights(); 206 | createGround(); 207 | createPerimWalls(); 208 | enableAndCheckCollisions(); 209 | 210 | // Create some lights to brighten up our scene 211 | function addLights() { 212 | var light0 = new BABYLON.PointLight('light0', new BABYLON.Vector3(1, 10, 0), scene); 213 | light0.groundColor = new BABYLON.Color3(0, 0, 0); 214 | 215 | var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); 216 | light1.diffuse = new BABYLON.Color3(.5, .5, .5); 217 | light1.specular = new BABYLON.Color3(.5, .5, .5); 218 | light1.groundColor = new BABYLON.Color3(0, 0, 0); 219 | } 220 | 221 | // Create a maze of cubes whose postions are based off a 2D array 222 | function createMazeCubes() { 223 | // Maze wall mapping, assuming matrix 224 | // 1's are cubes, 0's are empty space 225 | var map = [ 226 | [0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,], 227 | [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,], 228 | [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0,], 229 | [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 230 | [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 231 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 232 | [1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 233 | [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 234 | [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,], 235 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,], 236 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1,], 237 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0,], 238 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1,], 239 | [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,], 240 | [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0,], 241 | [1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0,], 242 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,], 243 | [1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,], 244 | [0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,], 245 | [0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,] 246 | ]; 247 | 248 | // Create wall material 249 | var wallMat = new BABYLON.StandardMaterial("wallTex", scene); 250 | wallMat.diffuseColor = new BABYLON.Color3.FromInts(129, 207, 224); 251 | wallMat.specularColor = new BABYLON.Color3.FromInts(0, 0, 0); 252 | 253 | 254 | 255 | // Keep cubes within boundry walls 256 | var widthOffset = UNITWIDTH / 2; 257 | // Put the bottom of the cube at y = 0 258 | var heightOffset = UNITHEIGHT / 2; 259 | 260 | // See how wide the map is by checking how long the first array is 261 | totalCubesWide = map[0].length; 262 | 263 | // Place cubes where 1`s are 264 | for (var i = 0; i < totalCubesWide; i++) { 265 | for (var j = 0; j < map[i].length; j++) { 266 | // If a 1 is found, add a cube at the corresponding position 267 | if (map[i][j]) { 268 | // Make the cube 269 | var cube = BABYLON.MeshBuilder.CreateBox("cube", { height: UNITHEIGHT, width: UNITWIDTH, depth: UNITWIDTH }, scene); 270 | cube.material = wallMat; 271 | // Set the cube position 272 | cube.position.z = (i - totalCubesWide / 2) * UNITWIDTH + widthOffset; 273 | cube.position.y = heightOffset; 274 | cube.position.x = (j - totalCubesWide / 2) * UNITWIDTH + widthOffset; 275 | 276 | // Make the cube collidable 277 | collidableObjects.push(cube); 278 | 279 | } 280 | } 281 | } 282 | // Set what the size of the ground should be based on the map size the matrix/cube size produced 283 | mapSize = totalCubesWide * UNITWIDTH; 284 | } 285 | 286 | 287 | 288 | // Create the ground plane that the maze sits on top of 289 | function createGround() { 290 | var groundMat = new BABYLON.StandardMaterial("groundTex", scene); 291 | groundMat.diffuseColor = new BABYLON.Color3.FromInts(110, 82, 45); 292 | 293 | ground = BABYLON.Mesh.CreateGround('ground', mapSize, mapSize, 2, scene); 294 | ground.material = groundMat; 295 | } 296 | 297 | 298 | // Make the four perimeter walls for the maze 299 | function createPerimWalls() { 300 | var halfMap = mapSize / 2; // Half the size of the map 301 | var sign = 1; // Used to make an amount positive or negative 302 | 303 | var perimMat = new BABYLON.StandardMaterial("perimTex", scene); 304 | perimMat.diffuseColor = new BABYLON.Color3.FromInts(70, 70, 70); 305 | perimMat.specularColor = new BABYLON.Color3.FromInts(70, 70, 70); 306 | perimMat.ambientColor = new BABYLON.Color3.FromInts(70, 70, 70); 307 | 308 | // Loop through twice, making two perimeter walls at a time 309 | for (var i = 0; i < 2; i++) { 310 | // Make a left/right wall and a front/back wall 311 | var perimWallLR = BABYLON.MeshBuilder.CreateBox("planeLR", { height: UNITHEIGHT, width: mapSize, depth: 1 }, scene); 312 | var perimWallFB = BABYLON.MeshBuilder.CreateBox("planeFB", { height: UNITHEIGHT, width: mapSize, depth: 1 }, scene); 313 | 314 | // Create left/right walls 315 | perimWallLR.position = new BABYLON.Vector3(-halfMap * sign, UNITHEIGHT / 2, 0); 316 | perimWallLR.rotation.y = degreesToRadians(90); 317 | 318 | // Create front/back walls 319 | perimWallFB.position = new BABYLON.Vector3(0, UNITHEIGHT / 2, halfMap * sign); 320 | collidableObjects.push(perimWallLR); 321 | collidableObjects.push(perimWallFB); 322 | sign = -1; // Swap to negative value 323 | } 324 | } 325 | 326 | 327 | // Enable collision checks for environment meshes and the camera 328 | function enableAndCheckCollisions() { 329 | scene.collisionsEnabled = true; 330 | camera.checkCollisions = true; 331 | ground.checkCollisions = true; 332 | 333 | // Loop through all walls and make them collidable 334 | for (var i = 0; i < collidableObjects.length; i++) { 335 | collidableObjects[i].checkCollisions = true; 336 | } 337 | } 338 | 339 | // Run the render loop (fired every time a new frame is rendered) 340 | function animate() { 341 | 342 | engine.runRenderLoop(function () { 343 | scene.render(); 344 | 345 | // Get the change in time between the last frame and the current frame 346 | var delta = engine.getDeltaTime() / 1000; 347 | 348 | // Check if A has been pressed to start the game 349 | if (begin == true) { 350 | 351 | // Calculate the distance between the camera and dino 352 | dinoDistanceFromPlayer = Math.round(BABYLON.Vector3.Distance(dino.position, camera.position)); 353 | // Round the distance, and use CATCHOFFSET to specify how far away we want dino to be to trigger game over 354 | dinoDistanceFromPlayer = Math.round(dinoDistanceFromPlayer - CATCHOFFSET); 355 | 356 | // If dino is within range, begin the chase 357 | beginChase(dinoDistanceFromPlayer); 358 | 359 | // Dino has made it to the catch distance, trigger end of game 360 | if (dinoDistanceFromPlayer <= 0) { 361 | caught(); 362 | } 363 | // Player has moved out of chase range, hide distance counter UI 364 | else { 365 | // Decrement to keep speed consistent 366 | dinoVelocity.z -= dinoVelocity.z * delta; 367 | 368 | // No collision, apply movement velocity 369 | if (detectDinoCollision() == false) { 370 | dinoVelocity.z += DINOSPEED * delta / 1000; 371 | // Move the dino forward 372 | dino.translate(new BABYLON.Vector3(0, 0, -1), dinoVelocity.z * delta); 373 | // Collision. Adjust direction 374 | } else { 375 | // An array of direction multiples that will correspond to -90, 90, and 180 degree rotations 376 | var directionMultiples = [-1, 1, 2]; 377 | // Generate a randon direciton multiple 378 | var randomIndex = getRandomInt(0, 2); 379 | 380 | // Add the new direction to dino's current rotation 381 | dino.rotation.y += degreesToRadians(90 * directionMultiples[randomIndex]); 382 | } 383 | } 384 | } 385 | }); 386 | } 387 | 388 | // Taking a distance, determines if the dino is close enough to the player to start chasing them. 389 | // If too far away, that chase ends/doesn't start and the distance counter UI is hidden. 390 | function beginChase(distanceAway) { 391 | // Dino in chasing range, display the distance counter UI and point dino is player direction 392 | if (distanceAway < CHASERANGE) { 393 | startUI.isVisible = false; 394 | distanceCounterUI.text = "Dino has spotted you! Distance from you: " + distanceAway; 395 | distanceCounterUI.isVisible = true; 396 | 397 | dino.lookAt(new BABYLON.Vector3(camera.position.x, dino.position.y, camera.position.z)); 398 | // Dino not in chasing range, make sure distance counter is hidden 399 | } else { 400 | distanceCounterUI.isVisible = false; 401 | } 402 | } 403 | 404 | // Set a counter to keep track of animation timing for the end game animations 405 | var frameCount = 0; 406 | 407 | // Updates the game state and begins the ending animations for the game 408 | function caught() { 409 | // Show game over UI and hide the distance counter 410 | gameOverUI.isVisible = true; 411 | distanceCounterUI.isVisible = false; 412 | 413 | // Update game state 414 | gameOver = true; 415 | 416 | // Disable player camera movement 417 | camera.detachControl(canvas); 418 | // Make player look at dino 419 | camera.lockedTarget = new BABYLON.Vector3(dino.position.x, dino.position.y + (DINOSCALE / 2), dino.position.z) 420 | 421 | 422 | // Every ROARDIVISOR frames make the dino roar 423 | if (frameCount % ROARDIVISOR == 0) { 424 | dino.skeleton.beginAnimation("roar", false, .5, function () { 425 | // Roar complete, do the standing animation in between roars 426 | dino.skeleton.beginAnimation("stand", true, .5); 427 | }); 428 | } 429 | frameCount++; 430 | } 431 | 432 | // Check to see if the raycaster of the dino has hit a collidable mesh 433 | function detectDinoCollision() { 434 | var origin = dino.position; 435 | 436 | // Get the forward vector of the dino 437 | var forward = new BABYLON.Vector3(0, 0, -1); 438 | forward = vecToLocal(forward, dino); 439 | 440 | // Get the unit vector for direction 441 | var direction = forward.subtract(origin); 442 | direction = BABYLON.Vector3.Normalize(direction); 443 | 444 | // Create the ray coming out of the front of the dino mesh 445 | var ray = new BABYLON.Ray(origin, direction, DINORAYLENGTH); 446 | 447 | // Check to see if the ray has hit anything 448 | var hit = scene.pickWithRay(ray); 449 | 450 | // If we hit a collidable mesh, return true 451 | if (hit.pickedMesh) { 452 | return true; 453 | } 454 | return false; 455 | } 456 | 457 | 458 | // Helper function that generates a random integer within a range 459 | function getRandomInt(min, max) { 460 | min = Math.ceil(min); 461 | max = Math.floor(max); 462 | return Math.floor(Math.random() * (max - min)) + min; 463 | } 464 | 465 | 466 | // Helper function that converts degrees to radians 467 | function degreesToRadians(degrees) { 468 | return degrees * Math.PI / 180; 469 | } 470 | 471 | // Helper function that converts radians to degrees 472 | function radiansToDegrees(radians) { 473 | return radians * 180 / Math.PI; 474 | } 475 | 476 | // Helper function to compute a directional vector in the frame of reference of a mesh 477 | function vecToLocal(vector, mesh) { 478 | // Get the position of the mesh compared to the world 479 | var m = mesh.getWorldMatrix(); 480 | // Get direction vector in relation to mesh 481 | var v = BABYLON.Vector3.TransformCoordinates(vector, m); 482 | return v; 483 | } 484 | 485 | 486 | // When the window resizes, adjust the engine size 487 | function onWindowResize() { 488 | engine.resize(); 489 | } 490 | }); 491 | -------------------------------------------------------------------------------- /BabylonJS-game-with-WebVR/after/js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | // --------------------------------------------------------------------------------- 3 | // Copyright (c) Microsoft Corporation. All rights reserved. 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // --------------------------------------------------------------------------------- 25 | */ 26 | 27 | 28 | var headset; // Active VR headset 29 | 30 | // If a VR headset is connected, get its info 31 | navigator.getVRDisplays().then(function (displays) { 32 | if (displays[0]) { 33 | headset = displays[0]; 34 | } 35 | }); 36 | 37 | window.addEventListener('DOMContentLoaded', function () { 38 | 39 | const UNITWIDTH = 90; // Width of the cubes in the maze 40 | const UNITHEIGHT = 45; // Height of the cubes in the maze 41 | const CATCHOFFSET = 170; // How close dino can get before game over 42 | const CHASERANGE = 200; // How close dino can get before tirggering the chase 43 | const DINOSCALE = 20; // How much to multiple the size of the dino by 44 | const DINOSPEED = 1600; // How fast the dino will move 45 | 46 | const DINORAYLENGTH = 55; // How close dino can get to collidable objects 47 | const ROARDIVISOR = 250; // How many frames to wait between roar animations (Once game over) 48 | 49 | // Game states 50 | var begin = false; // Flag to determine whether the game should begin 51 | var gameOver = false; // Flag to determines whether the game is over 52 | 53 | 54 | var camera; // The camera for the scene 55 | var ground; // The ground plane mesh 56 | var totalCubesWide; // How many wall cubes can make the width of the map 57 | var mapSize; // Height and width of the maze ground plane 58 | var collidableObjects = []; // Array holding all meshes that are collidable 59 | var dino; // The dino mesh 60 | var dinoVelocity = new BABYLON.Vector3(0, 0, 0); // The direction to apply the movement velocity of dino 61 | 62 | 63 | // Connects an xbox controller has been plugged in and and a button/trigger moved 64 | function onNewGamepadConnected(gamepad) { 65 | var xboxpad = gamepad 66 | 67 | xboxpad.onbuttondown(function (buttonValue) { 68 | // When the A button is pressed, either start or reload the game depending on the game state 69 | if (buttonValue == BABYLON.Xbox360Button.A) { 70 | 71 | // Game is over, reload it 72 | if (gameOver) { 73 | location.href = location.href; 74 | } 75 | // Game has begun 76 | else { 77 | // Hide "Press A to start" UI 78 | startUI.isVisible = false; 79 | begin = true; 80 | // Start looping the dino walking animation 81 | scene.beginAnimation(dino.skeleton, 111, 130, true, 1); 82 | } 83 | } 84 | }); 85 | } 86 | 87 | // Get all connected gamepads 88 | var gamepads = new BABYLON.Gamepads(function (gamepad) { onNewGamepadConnected(gamepad); }); 89 | 90 | 91 | // Grab where we'll be displayed the game 92 | var canvas = document.getElementById('renderCanvas'); 93 | 94 | // load the 3D engine 95 | var engine = new BABYLON.Engine(canvas, true); 96 | 97 | 98 | // Creates and return the scene 99 | var createScene = function () { 100 | 101 | // Create the Babylon scene 102 | var scene = new BABYLON.Scene(engine); 103 | 104 | // Apply gravity so that any Y axis movement is ignored 105 | scene.gravity = new BABYLON.Vector3(0, -9.81, 0); 106 | 107 | // Turn on fog for cool effects 108 | scene.fogMode = BABYLON.Scene.FOGMODE_EXP; 109 | scene.fogDensity = 0.001; 110 | scene.fogColor = new BABYLON.Color3(0.9, 0.9, 0.85); 111 | 112 | // create a UniversalCamera that be controlled with gamepad or keyboard 113 | if(headset){ 114 | // Create a WebVR camera with the trackPosition property set to false so that we can control movement with the gamepad 115 | camera = new BABYLON.WebVRFreeCamera("vrcamera", new BABYLON.Vector3(0, 14, 0), scene, true, { trackPosition: false }); 116 | camera.deviceScaleFactor = 1; 117 | } else { 118 | // No headset, use universal camera 119 | camera = new BABYLON.UniversalCamera("camera", new BABYLON.Vector3(0, 18, -45), scene); 120 | } 121 | camera.rotation.y += degreesToRadians(90); 122 | 123 | 124 | // Set the ellipsoid around the camera. This will act as the collider box for when the player runs into walls 125 | camera.ellipsoid = new BABYLON.Vector3(1, 9, 1); 126 | camera.applyGravity = true; 127 | 128 | scene.onPointerDown = function () { 129 | scene.onPointerDown = undefined 130 | camera.attachControl(canvas, true); 131 | } 132 | 133 | // Custom input, adding Xbox controller support for left analog stick to map to keyboard arrows 134 | camera.inputs.attached.keyboard.keysUp.push(211); // Left analog up 135 | camera.inputs.attached.keyboard.keysDown.push(212); // Left analog down 136 | camera.inputs.attached.keyboard.keysLeft.push(214); // Left analog left 137 | camera.inputs.attached.keyboard.keysRight.push(213); // Left analog right 138 | 139 | // Allow camera to be controlled 140 | camera.attachControl(canvas, true); 141 | 142 | // Create the skybox 143 | var skybox = BABYLON.Mesh.CreateBox("skyBox", 5000.0, scene); 144 | var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene); 145 | skyboxMaterial.backFaceCulling = false; 146 | skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/skybox", scene); 147 | skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE; 148 | skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0); 149 | skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0); 150 | skyboxMaterial.disableLighting = true; 151 | skybox.material = skyboxMaterial; 152 | 153 | // GUI 154 | var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI"); 155 | 156 | // Distance counter UI 157 | distanceCounterUI = new BABYLON.GUI.TextBlock(); 158 | distanceCounterUI.color = "red"; 159 | distanceCounterUI.fontSize = 24; 160 | advancedTexture.addControl(distanceCounterUI); 161 | distanceCounterUI.isVisible = false; 162 | 163 | // Game over UI 164 | gameOverUI = new BABYLON.GUI.Rectangle("start"); 165 | gameOverUI.background = "black" 166 | gameOverUI.alpha = .8; 167 | gameOverUI.thickness = 0; 168 | gameOverUI.height = "78px"; 169 | gameOverUI.width = "440px"; 170 | advancedTexture.addControl(gameOverUI); 171 | var tex1 = new BABYLON.GUI.TextBlock(); 172 | tex1.text = "GAME OVER"; 173 | tex1.color = "red"; 174 | tex1.fontSize = 70; 175 | gameOverUI.addControl(tex1); 176 | gameOverUI.isVisible = false; 177 | 178 | 179 | // Start UI 180 | startUI = new BABYLON.GUI.Rectangle("start"); 181 | startUI.background = "black" 182 | startUI.alpha = .8; 183 | startUI.thickness = 0; 184 | startUI.height = "60px"; 185 | startUI.width = "400px"; 186 | advancedTexture.addControl(startUI); 187 | var tex2 = new BABYLON.GUI.TextBlock(); 188 | tex2.text = "Stay away from the dinosaur! \n Plug in an Xbox controller and press A to start"; 189 | tex2.color = "white"; 190 | startUI.addControl(tex2); 191 | 192 | // return the created scene 193 | return scene; 194 | } 195 | 196 | // Listen for if the window changes sizes and adjust 197 | window.addEventListener('resize', onWindowResize, false); 198 | // Create the scene 199 | var scene = createScene(); 200 | 201 | // Load the dinosaur model 202 | BABYLON.SceneLoader.ImportMesh("Dino", "models/", "dino.babylon", scene, function (newMeshes) { 203 | 204 | dino = newMeshes[0]; 205 | 206 | // Set the initial size and position of the dino 207 | dino.scaling = new BABYLON.Vector3(DINOSCALE, DINOSCALE, DINOSCALE); 208 | dino.position = new BABYLON.Vector3(500, 18, -30); 209 | // Set the size of the ellips-shaped collider around dino 210 | dino.ellipsoid = new BABYLON.Vector3(.5, .5, .5); 211 | dino.rotation.y = degreesToRadians(90); 212 | 213 | // Enable blending of animations (i.e. transitioning from standing to walking animation smoothly) 214 | dino.skeleton.enableBlending(0.1) 215 | 216 | // Start looping the standing animation before the game begins 217 | dino.skeleton.beginAnimation("stand", true, .5); 218 | 219 | 220 | // Run the render loop (fired every time a new frame is rendered) 221 | animate(); 222 | 223 | }); 224 | 225 | // Create the walls/ground 226 | createMazeCubes(); 227 | addLights(); 228 | createGround(); 229 | createPerimWalls(); 230 | enableAndCheckCollisions(); 231 | 232 | // Create some lights to brighten up our scene 233 | function addLights() { 234 | var light0 = new BABYLON.PointLight('light0', new BABYLON.Vector3(1, 10, 0), scene); 235 | light0.groundColor = new BABYLON.Color3(0, 0, 0); 236 | 237 | var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); 238 | light1.diffuse = new BABYLON.Color3(.5, .5, .5); 239 | light1.specular = new BABYLON.Color3(.5, .5, .5); 240 | light1.groundColor = new BABYLON.Color3(0, 0, 0); 241 | } 242 | 243 | // Create a maze of cubes whose postions are based off a 2D array 244 | function createMazeCubes() { 245 | // Maze wall mapping, assuming matrix 246 | // 1's are cubes, 0's are empty space 247 | var map = [ 248 | [0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,], 249 | [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,], 250 | [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0,], 251 | [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 252 | [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 253 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 254 | [1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 255 | [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,], 256 | [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,], 257 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,], 258 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1,], 259 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0,], 260 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1,], 261 | [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,], 262 | [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0,], 263 | [1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0,], 264 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,], 265 | [1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,], 266 | [0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,], 267 | [0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,] 268 | ]; 269 | 270 | // Create wall material 271 | var wallMat = new BABYLON.StandardMaterial("wallTex", scene); 272 | wallMat.diffuseColor = new BABYLON.Color3.FromInts(129, 207, 224); 273 | wallMat.specularColor = new BABYLON.Color3.FromInts(0, 0, 0); 274 | 275 | 276 | 277 | // Keep cubes within boundry walls 278 | var widthOffset = UNITWIDTH / 2; 279 | // Put the bottom of the cube at y = 0 280 | var heightOffset = UNITHEIGHT / 2; 281 | 282 | // See how wide the map is by checking how long the first array is 283 | totalCubesWide = map[0].length; 284 | 285 | // Place cubes where 1`s are 286 | for (var i = 0; i < totalCubesWide; i++) { 287 | for (var j = 0; j < map[i].length; j++) { 288 | // If a 1 is found, add a cube at the corresponding position 289 | if (map[i][j]) { 290 | // Make the cube 291 | var cube = BABYLON.MeshBuilder.CreateBox("cube", { height: UNITHEIGHT, width: UNITWIDTH, depth: UNITWIDTH }, scene); 292 | cube.material = wallMat; 293 | // Set the cube position 294 | cube.position.z = (i - totalCubesWide / 2) * UNITWIDTH + widthOffset; 295 | cube.position.y = heightOffset; 296 | cube.position.x = (j - totalCubesWide / 2) * UNITWIDTH + widthOffset; 297 | 298 | // Make the cube collidable 299 | collidableObjects.push(cube); 300 | 301 | } 302 | } 303 | } 304 | // Set what the size of the ground should be based on the map size the matrix/cube size produced 305 | mapSize = totalCubesWide * UNITWIDTH; 306 | } 307 | 308 | 309 | 310 | // Create the ground plane that the maze sits on top of 311 | function createGround() { 312 | var groundMat = new BABYLON.StandardMaterial("groundTex", scene); 313 | groundMat.diffuseColor = new BABYLON.Color3.FromInts(110, 82, 45); 314 | 315 | ground = BABYLON.Mesh.CreateGround('ground', mapSize, mapSize, 2, scene); 316 | ground.material = groundMat; 317 | } 318 | 319 | 320 | // Make the four perimeter walls for the maze 321 | function createPerimWalls() { 322 | var halfMap = mapSize / 2; // Half the size of the map 323 | var sign = 1; // Used to make an amount positive or negative 324 | 325 | var perimMat = new BABYLON.StandardMaterial("perimTex", scene); 326 | perimMat.diffuseColor = new BABYLON.Color3.FromInts(70, 70, 70); 327 | perimMat.specularColor = new BABYLON.Color3.FromInts(70, 70, 70); 328 | perimMat.ambientColor = new BABYLON.Color3.FromInts(70, 70, 70); 329 | 330 | // Loop through twice, making two perimeter walls at a time 331 | for (var i = 0; i < 2; i++) { 332 | // Make a left/right wall and a front/back wall 333 | var perimWallLR = BABYLON.MeshBuilder.CreateBox("planeLR", { height: UNITHEIGHT, width: mapSize, depth: 1 }, scene); 334 | var perimWallFB = BABYLON.MeshBuilder.CreateBox("planeFB", { height: UNITHEIGHT, width: mapSize, depth: 1 }, scene); 335 | 336 | // Create left/right walls 337 | perimWallLR.position = new BABYLON.Vector3(-halfMap * sign, UNITHEIGHT / 2, 0); 338 | perimWallLR.rotation.y = degreesToRadians(90); 339 | 340 | // Create front/back walls 341 | perimWallFB.position = new BABYLON.Vector3(0, UNITHEIGHT / 2, halfMap * sign); 342 | collidableObjects.push(perimWallLR); 343 | collidableObjects.push(perimWallFB); 344 | sign = -1; // Swap to negative value 345 | } 346 | } 347 | 348 | 349 | // Enable collision checks for environment meshes and the camera 350 | function enableAndCheckCollisions() { 351 | scene.collisionsEnabled = true; 352 | camera.checkCollisions = true; 353 | ground.checkCollisions = true; 354 | 355 | // Loop through all walls and make them collidable 356 | for (var i = 0; i < collidableObjects.length; i++) { 357 | collidableObjects[i].checkCollisions = true; 358 | } 359 | } 360 | 361 | // Run the render loop (fired every time a new frame is rendered) 362 | function animate() { 363 | 364 | engine.runRenderLoop(function () { 365 | // Determine which camera should be showing depending on whether or not the headset is presenting 366 | if (headset) { 367 | if (!(headset.isPresenting)) { 368 | var camera2 = new BABYLON.UniversalCamera("Camera", new BABYLON.Vector3(0, 18, -45), scene); 369 | scene.activeCamera = camera2; 370 | } else { 371 | scene.activeCamera = camera; 372 | } 373 | } 374 | scene.render(); 375 | 376 | // Get the change in time between the last frame and the current frame 377 | var delta = engine.getDeltaTime() / 1000; 378 | 379 | // Check if A has been pressed to start the game 380 | if (begin == true) { 381 | 382 | // Calculate the distance between the camera and dino 383 | dinoDistanceFromPlayer = Math.round(BABYLON.Vector3.Distance(dino.position, camera.position)); 384 | // Round the distance, and use CATCHOFFSET to specify how far away we want dino to be to trigger game over 385 | dinoDistanceFromPlayer = Math.round(dinoDistanceFromPlayer - CATCHOFFSET); 386 | 387 | // If dino is within range, begin the chase 388 | beginChase(dinoDistanceFromPlayer); 389 | 390 | // Dino has made it to the catch distance, trigger end of game 391 | if (dinoDistanceFromPlayer <= 0) { 392 | caught(); 393 | } 394 | // Player has moved out of chase range, hide distance counter UI 395 | else { 396 | // Decrement to keep speed consistent 397 | dinoVelocity.z -= dinoVelocity.z * delta; 398 | 399 | // No collision, apply movement velocity 400 | if (detectDinoCollision() == false) { 401 | dinoVelocity.z += DINOSPEED * delta / 1000; 402 | // Move the dino forward 403 | dino.translate(new BABYLON.Vector3(0, 0, -1), dinoVelocity.z * delta); 404 | // Collision. Adjust direction 405 | } else { 406 | // An array of direction multiples that will correspond to -90, 90, and 180 degree rotations 407 | var directionMultiples = [-1, 1, 2]; 408 | // Generate a randon direciton multiple 409 | var randomIndex = getRandomInt(0, 2); 410 | 411 | // Add the new direction to dino's current rotation 412 | dino.rotation.y += degreesToRadians(90 * directionMultiples[randomIndex]); 413 | } 414 | } 415 | } 416 | }); 417 | } 418 | 419 | // Taking a distance, determines if the dino is close enough to the player to start chasing them. 420 | // If too far away, that chase ends/doesn't start and the distance counter UI is hidden. 421 | function beginChase(distanceAway) { 422 | // Dino in chasing range, display the distance counter UI and point dino is player direction 423 | if (distanceAway < CHASERANGE) { 424 | startUI.isVisible = false; 425 | distanceCounterUI.text = "Dino has spotted you! Distance from you: " + distanceAway; 426 | distanceCounterUI.isVisible = true; 427 | 428 | dino.lookAt(new BABYLON.Vector3(camera.position.x, dino.position.y, camera.position.z)); 429 | // Dino not in chasing range, make sure distance counter is hidden 430 | } else { 431 | distanceCounterUI.isVisible = false; 432 | } 433 | } 434 | 435 | // Set a counter to keep track of animation timing for the end game animations 436 | var frameCount = 0; 437 | 438 | // Updates the game state and begins the ending animations for the game 439 | function caught() { 440 | // Show game over UI and hide the distance counter 441 | gameOverUI.isVisible = true; 442 | distanceCounterUI.isVisible = false; 443 | 444 | // Update game state 445 | gameOver = true; 446 | 447 | // Disable player camera movement 448 | camera.inputs.clear(); 449 | // Make player look at dino 450 | camera.lockedTarget = dino; 451 | 452 | 453 | // Every ROARDIVISOR frames make the dino roar 454 | if (frameCount % ROARDIVISOR == 0) { 455 | dino.skeleton.beginAnimation("roar", false, .5, function () { 456 | // Roar complete, do the standing animation in between roars 457 | dino.skeleton.beginAnimation("stand", true, .5); 458 | }); 459 | } 460 | frameCount++; 461 | } 462 | 463 | // Check to see if the raycaster of the dino has hit a collidable mesh 464 | function detectDinoCollision() { 465 | var origin = dino.position; 466 | 467 | // Get the forward vector of the dino 468 | var forward = new BABYLON.Vector3(0, 0, -1); 469 | forward = vecToLocal(forward, dino); 470 | 471 | // Get the unit vector for direction 472 | var direction = forward.subtract(origin); 473 | direction = BABYLON.Vector3.Normalize(direction); 474 | 475 | // Create the ray coming out of the front of the dino mesh 476 | var ray = new BABYLON.Ray(origin, direction, DINORAYLENGTH); 477 | 478 | // Check to see if the ray has hit anything 479 | var hit = scene.pickWithRay(ray); 480 | 481 | // If we hit a collidable mesh, return true 482 | if (hit.pickedMesh) { 483 | return true; 484 | } 485 | return false; 486 | } 487 | 488 | 489 | // Helper function that generates a random integer within a range 490 | function getRandomInt(min, max) { 491 | min = Math.ceil(min); 492 | max = Math.floor(max); 493 | return Math.floor(Math.random() * (max - min)) + min; 494 | } 495 | 496 | 497 | // Helper function that converts degrees to radians 498 | function degreesToRadians(degrees) { 499 | return degrees * Math.PI / 180; 500 | } 501 | 502 | // Helper function that converts radians to degrees 503 | function radiansToDegrees(radians) { 504 | return radians * 180 / Math.PI; 505 | } 506 | 507 | // Helper function to compute a directional vector in the frame of reference of a mesh 508 | function vecToLocal(vector, mesh) { 509 | // Get the position of the mesh compared to the world 510 | var m = mesh.getWorldMatrix(); 511 | // Get direction vector in relation to mesh 512 | var v = BABYLON.Vector3.TransformCoordinates(vector, m); 513 | return v; 514 | } 515 | 516 | 517 | // When the window resizes, adjust the engine size 518 | function onWindowResize() { 519 | engine.resize(); 520 | } 521 | }); --------------------------------------------------------------------------------