├── .eslintrc.json
├── .gitignore
├── .prettierrc.json
├── README.md
├── package-lock.json
├── package.json
├── pool.jpg
├── public
├── favicon.ico
├── index.html
├── manifest.json
└── robots.txt
└── src
├── App.js
├── Assets
└── textures
│ ├── 0.png
│ ├── 1.png
│ ├── 10.png
│ ├── 11.png
│ ├── 12.png
│ ├── 13.png
│ ├── 14.png
│ ├── 15.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ ├── 9.png
│ ├── cloth.jpg
│ ├── hardwood2_bump.jpg
│ ├── hardwood2_diffuse.jpg
│ ├── hardwood2_roughness.jpg
│ └── hardwood_floor.jpg
├── GlobalStyles.js
├── components
├── Button.js
├── Controls.js
├── Cue.js
├── Floor.js
├── Light.js
├── Modal.js
├── PoolBall.js
└── PoolTable.js
├── index.js
├── svg
└── ic_code.svg
├── utils
├── Constants.js
├── KeyDownListener.js
└── Physics.js
└── views
└── Scene.js
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true
5 | },
6 | "extends": ["airbnb", "prettier", "prettier/react"],
7 | "globals": {
8 | "Atomics": "readonly",
9 | "SharedArrayBuffer": "readonly"
10 | },
11 | "parser": "babel-eslint",
12 | "parserOptions": {
13 | "ecmaFeatures": {
14 | "jsx": true
15 | },
16 | "ecmaVersion": 2018,
17 | "sourceType": "module"
18 | },
19 | "plugins": ["react", "prettier", "react-hooks"],
20 | "rules": {
21 | "no-console": "off",
22 | "no-param-reassign": "off",
23 | "react/jsx-filename-extension": [
24 | 1,
25 | {
26 | "extensions": [".js", ".jsx"]
27 | }
28 | ],
29 | "react/jsx-props-no-spreading": 0,
30 | "react-hooks/rules-of-hooks": "error",
31 | "react-hooks/exhaustive-deps": "warn"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "singleQuote": true,
4 | "printWidth": 80,
5 | "jsxBracketSameLine": true,
6 | "jsxSingleQuote": true
7 | }
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pool table
2 |
3 | A rudimentary game of pooltable made using React, three js and react-three-fiber alongwith a fairly rough and small implementation of a physics engine from scratch. **However, this is not a complete game**. A lot of improvements and refinements can be made.
4 |
5 | ---
6 |
7 | ## Demo
8 |
9 | A working demo can be found [here](https://manan30.github.io/billiards/)
10 |
11 | 
12 |
13 | ## Running it locally
14 |
15 | - Clone the repo.
16 | - `npm install`
17 | - `npm start`
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "billiards",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "prop-types": "15.7.2",
7 | "react": "16.13.1",
8 | "react-dom": "16.13.1",
9 | "react-scripts": "3.2.0",
10 | "react-three-fiber": "3.0.3",
11 | "styled-components": "4.4.0",
12 | "three": "0.109.0"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "predeploy": "npm run build",
18 | "deploy": "gh-pages -d build"
19 | },
20 | "homepage": "https://manan30.github.io/billiards/",
21 | "eslintConfig": {
22 | "extends": "react-app"
23 | },
24 | "browserslist": {
25 | "production": [
26 | ">0.2%",
27 | "not dead",
28 | "not op_mini all"
29 | ],
30 | "development": [
31 | "last 1 chrome version",
32 | "last 1 firefox version",
33 | "last 1 safari version"
34 | ]
35 | },
36 | "devDependencies": {
37 | "eslint": "6.5.1",
38 | "eslint-config-airbnb": "18.0.1",
39 | "eslint-config-prettier": "6.3.0",
40 | "eslint-plugin-import": "2.18.2",
41 | "eslint-plugin-jsx-a11y": "6.2.3",
42 | "eslint-plugin-prettier": "3.1.1",
43 | "eslint-plugin-react": "7.15.1",
44 | "eslint-plugin-react-hooks": "1.7.0",
45 | "gh-pages": "3.1.0"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/pool.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manan30/billiards/0e9e2e640f8f44cc1a99823b5837739fff65a405/pool.jpg
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manan30/billiards/0e9e2e640f8f44cc1a99823b5837739fff65a405/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | Billiards
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 |
3 | import { Canvas, CodeFAB } from './GlobalStyles';
4 | import Modal from './components/Modal';
5 | import Scene from './views/Scene';
6 | import Controls from './components/Controls';
7 | import Button from './components/Button';
8 |
9 | import Icon from './svg/ic_code.svg';
10 |
11 | function App() {
12 | const [modal, setModal] = useState(true);
13 | const [coeff, setCoeff] = useState(0.01);
14 | return (
15 | <>
16 | {modal && (
17 | {
19 | setModal(!modal);
20 | }}
21 | />
22 | )}
23 |
26 |