diff --git a/.env.example b/.env.example index f46c8c7..821e903 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,5 @@ POSTGRES_PORT=5432 EXPRESS_PORT=3000 -FRONTEND_PORT=8080 POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres diff --git a/README.md b/README.md index 82d8404..71ff3b6 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,163 @@ # RaspberryRocketeer -## How to run +## Class Diagram of all classes -### Copy .env -First you need to copy the `.env.example`. +```mermaid +classDiagram +direction BT +class Collidable { + collides(o: Entity) boolean +} +class Database { + any _db + any db +} +class Entity { + constructor(position: Position, width: number, height: number, fill: number) + Position _position + number _width + number _height + number fill + boolean _showHitbox + update() void + draw() void + Position position + number width + number height + boolean showHitbox +} +class Game { + number id + number score + string playtime + Date date + number userId +} +class GamePgPromiseRepository { + insert(game: Game) Promise~Game~ + serialize(raw: any) Game +} +class GameRepository { + insert(game: Game) Promise~Game~ +} +class HighscoreLeaderboard +class HighscoreLeaderboardPgPromiseRepository { + getAll() Promise~HighscoreLeaderboard~ + serialize(raw: any) HighscoreLeaderboard +} +class HighscoreLeaderboardRepository { + getAll() Promise~HighscoreLeaderboard~ +} +class Leaderboard +class LeaderboardEntry { + number username + number rank + T score +} +class Obstacle { + constructor(position: Position, obstacleWidth: number, obstacleHeight: number, pipeImagePath: string) + Pipe pipeTop + Pipe pipeBottom + number padding + number speed + number _distanceBetweenPipes + number _startX + resetPosition() void + randomizeHeight() void + randomRange(min: number, max: number) number + update() void + draw() void + collides(o: Entity) boolean + any startX + any distanceBetweenPipes +} +class Pipe { + constructor(positionX: number, width: number, height: number) + any _image + update() void + draw() void + move(speed: number) void + collides(o: Entity) boolean + any image +} +class Position { + constructor(x: number, y: number) + number _x + number _y + number x + number y +} +class Raspberry { + constructor(image: string) + number lift + number gravity + number _velocity + any _image + Position position + number maxVelocity + number WIDTH + number HEIGHT + number FILL + update() void + applyGravity() void + forceBoundaries() void + boost() void + draw() void + number velocity + any image +} +class TimeLeaderboard +class TimeLeaderboardPgPromiseRepository { + getAll() Promise~TimeLeaderboard~ + serialize(raw: any) TimeLeaderboard +} +class TimeLeaderboardRepository { + getAll() Promise~TimeLeaderboard~ +} +class User { + number id + string name +} +class UserPgPromiseRepository { + getById(id: number) Promise~User~ + getByName(name: string) Promise~User~ + withIdExists(id: number) Promise~boolean~ + withNameExists(name: string) Promise~boolean~ + insert(user: Omit~User, "id"~) Promise~User~ + serialize(raw: any) User +} +class UserRepository { + getById(id: number) Promise~User~ + getByName(name: string) Promise~User~ + withIdExists(userId: number) Promise~boolean~ + withNameExists(username: string) Promise~boolean~ + insert(user: Omit~User, "id"~) Promise~User~ +} +class UserScores { + number userId + number highscore + number totalScore + string totalPlaytime + number averageScore + number gamesPlayed +} +class UserScoresPgPromiseRepository { + getById(id: number) Promise~UserScores~ + serialize(raw: any) UserScores +} +class UserScoresRepository { + getById(userId: number) Promise~UserScores~ +} + +GamePgPromiseRepository --> GameRepository +HighscoreLeaderboardPgPromiseRepository --> HighscoreLeaderboardRepository +Obstacle ..> Collidable +Obstacle --> Entity +Pipe ..> Collidable +Pipe --> Entity +Raspberry --> Entity +TimeLeaderboardPgPromiseRepository --> TimeLeaderboardRepository +UserPgPromiseRepository --> UserRepository +UserScoresPgPromiseRepository --> UserScoresRepository -```shell -cp .env.example .env ``` - -Note: It is recommended to change the values for the database user. - -### Install node packages -Go into the frontend folder using -```shell -cd frontend -``` -and run: -```shell -npm install -``` - -### Start the container (in the project root) - -```shell -docker compose up --build -``` - -You can then access the website on `localhost:8080` diff --git a/backend/api/src/gameRoute.ts b/backend/api/src/gameRoute.ts index 0de3e2c..2ac9175 100644 --- a/backend/api/src/gameRoute.ts +++ b/backend/api/src/gameRoute.ts @@ -9,9 +9,6 @@ export const gameRoute = express.Router() gameRoute.use(express.json()) -/** - * Test - */ gameRoute.post( '/add', body('playtime') @@ -21,8 +18,6 @@ gameRoute.post( body('userId') .isInt({min: 1}) .custom(userWithIdExists), - body('score') - .isInt({min: 0}), /** * After processing the errors of express-validator, inserts the game into the DB * @param req diff --git a/backend/api/src/leaderboardRoute.ts b/backend/api/src/leaderboardRoute.ts index 699180c..0c5ce51 100644 --- a/backend/api/src/leaderboardRoute.ts +++ b/backend/api/src/leaderboardRoute.ts @@ -27,7 +27,7 @@ leaderboardRoute.get('/highscore', //endregion const highscoreLeaderboardRepo: HighscoreLeaderboardRepository = new HighscoreLeaderboardPgPromiseRepository; let highscoreLeaderboard: HighscoreLeaderboard; - if (req.query.pagination == true) { + if (req.query.pagination) { const entriesPerPage = req.query.entriesPerPage; const page = req.query.page; highscoreLeaderboard = await highscoreLeaderboardRepo.getPage(entriesPerPage, page); @@ -53,7 +53,6 @@ leaderboardRoute.get('/totalplaytime', */ async (req, res) => { try { - console.log(req.query) //region validate parameters const errors = validationResult(req); if (!errors.isEmpty()) { @@ -62,8 +61,7 @@ leaderboardRoute.get('/totalplaytime', //endregion const timeLeaderboardRepo: TimeLeaderboardRepository = new TimeLeaderboardPgPromiseRepository; let timeLeaderboard: TimeLeaderboard; - console.log(req.query) - if (req.query.pagination == true) { + if (req.query.pagination) { const entriesPerPage = req.query.entriesPerPage; const page = req.query.page; timeLeaderboard = await timeLeaderboardRepo.getPage(entriesPerPage, page); diff --git a/backend/api/src/userRoute.ts b/backend/api/src/userRoute.ts index 4061969..e87056f 100644 --- a/backend/api/src/userRoute.ts +++ b/backend/api/src/userRoute.ts @@ -84,30 +84,3 @@ userRoute.get('/:userId/scores', } } ) - -userRoute.get('/:name', - param('name') - .isString() - .isLength({min: 3, max: 32}) - .matches(USERNAME_VALIDATION_REGEX), - - async (req, res) => { - const errors = validationResult(req); - if (!errors.isEmpty()) { - return res.status(400).json({ errors: errors.array() }); - } - - const name: string = req.params.name; - console.log(name) - - try { - // get & return data - const userRepo: UserPgPromiseRepository = new UserPgPromiseRepository(); - const user = await userRepo.getByName(name); - res.json(user); - } catch (error) { - // handle errors - console.log(error) - res.status(500).json({ errors: [{msg: "Internal server error"}]}) - } - }) diff --git a/backend/db/initScripts/loadMockData.sql b/backend/db/initScripts/loadMockData.sql new file mode 100644 index 0000000..7735cc9 --- /dev/null +++ b/backend/db/initScripts/loadMockData.sql @@ -0,0 +1,40 @@ +insert into "user" (name) values ('dpettus0'); +insert into "user" (name) values ('egreetland1'); +insert into "user" (name) values ('smontford2'); +insert into "user" (name) values ('idagwell3'); +insert into "user" (name) values ('lgagan4'); +insert into "user" (name) values ('acarmont5'); +insert into "user" (name) values ('kjermyn6'); +insert into "user" (name) values ('dokieran7'); +insert into "user" (name) values ('pdrinkel8'); + +insert into game (user_id, score, playtime, date) values ('1', 74, '19:59', '2022-07-19'); +insert into game (user_id, score, playtime, date) values ('1', 86, '20:32', '2022-11-24'); +insert into game (user_id, score, playtime, date) values ('1', 68, '10:41', '2022-03-24'); +insert into game (user_id, score, playtime, date) values ('2', 39, '5:55', '2022-06-01'); +insert into game (user_id, score, playtime, date) values ('2', 20, '9:23', '2022-03-12'); +insert into game (user_id, score, playtime, date) values ('2', 28, '23:45', '2022-04-01'); +insert into game (user_id, score, playtime, date) values ('2', 44, '18:43', '2022-06-24'); +insert into game (user_id, score, playtime, date) values ('3', 92, '14:54', '2022-11-06'); +insert into game (user_id, score, playtime, date) values ('3', 73, '0:45', '2022-07-26'); +insert into game (user_id, score, playtime, date) values ('3', 27, '2:49', '2022-02-03'); +insert into game (user_id, score, playtime, date) values ('4', 26, '2:32', '2022-07-19'); +insert into game (user_id, score, playtime, date) values ('4', 12, '17:03', '2022-04-25'); +insert into game (user_id, score, playtime, date) values ('4', 6, '8:49', '2021-12-03'); +insert into game (user_id, score, playtime, date) values ('4', 22, '22:27', '2022-03-02'); +insert into game (user_id, score, playtime, date) values ('5', 94, '1:04', '2022-10-19'); +insert into game (user_id, score, playtime, date) values ('5', 2, '2:14', '2022-04-06'); +insert into game (user_id, score, playtime, date) values ('5', 21, '17:18', '2022-06-03'); +insert into game (user_id, score, playtime, date) values ('6', 33, '16:01', '2022-02-02'); +insert into game (user_id, score, playtime, date) values ('6', 27, '7:03', '2022-02-06'); +insert into game (user_id, score, playtime, date) values ('6', 62, '0:45', '2022-11-15'); +insert into game (user_id, score, playtime, date) values ('7', 12, '8:54', '2022-06-29'); +insert into game (user_id, score, playtime, date) values ('7', 63, '16:01', '2022-11-05'); +insert into game (user_id, score, playtime, date) values ('7', 29, '0:46', '2022-10-01'); +insert into game (user_id, score, playtime, date) values ('8', 67, '1:27', '2022-09-29'); +insert into game (user_id, score, playtime, date) values ('8', 84, '10:37', '2021-12-18'); +insert into game (user_id, score, playtime, date) values ('8', 14, '19:14', '2022-01-31'); +insert into game (user_id, score, playtime, date) values ('9', 21, '19:04', '2022-03-08'); +insert into game (user_id, score, playtime, date) values ('9', 46, '2:34', '2022-04-18'); +insert into game (user_id, score, playtime, date) values ('9', 78, '9:33', '2022-09-10'); +insert into game (user_id, score, playtime, date) values ('9', 82, '11:19', '2022-11-29'); \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 2672685..f21adcc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,32 +1,23 @@ -version: '3.1' - -services: - db: - build: backend/db - container_name: postgres-db - environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - ports: - - "${POSTGRES_PORT}:5432" - volumes: - - ./backend/pgdata:/var/lib/postgresql/data - - api: - build: backend/api - depends_on: - - db - container_name: express-api - ports: - - "${EXPRESS_PORT}:3000" - - vue: - build: frontend - container_name: frontend - ports: - - "${FRONTEND_PORT}:8080" - - - volumes: - - ./frontend:/app +version: '3.1' + +services: + db: + build: backend/db + container_name: postgres-db + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + ports: + - "${POSTGRES_PORT}:5432" + volumes: + - ./backend/pgdata:/var/lib/postgresql/data + + api: + build: backend/api + depends_on: + - db + container_name: express-api + ports: + - "${EXPRESS_PORT}:3000" + diff --git a/frontend/.dockerignore b/frontend/.dockerignore deleted file mode 100644 index 3298622..0000000 --- a/frontend/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -.gitignore -README.md diff --git a/frontend/Dockerfile b/frontend/Dockerfile deleted file mode 100644 index e8524c9..0000000 --- a/frontend/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM node:18 - -COPY . /app -WORKDIR /app - -RUN npm install - -EXPOSE 8080 - -ENTRYPOINT ["npm", "run", "serve"] - diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 52c94eb..e0d7807 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,7 +8,9 @@ "name": "raspberryrocketeer", "version": "0.1.0", "dependencies": { + "@types/p5": "^1.4.3", "bootstrap": "^5.2.3", + "p5": "^1.5.0", "vue": "^3.2.13" }, "devDependencies": { @@ -829,6 +831,11 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "node_modules/@types/p5": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/p5/-/p5-1.4.3.tgz", + "integrity": "sha512-UjgBi1/VU0Dz1/JxzRZrDKlC54rMELWW+6oHx1pRKzKkVgwzvP+dEjZ1JbeMjK12VJMUjDx4lhGUmnUL2jBASQ==" + }, "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -6187,6 +6194,11 @@ "node": ">=6" } }, + "node_modules/p5": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/p5/-/p5-1.5.0.tgz", + "integrity": "sha512-zZFMVUmGkXe2G5H6Sw7xsVhgdxMyEN/6SZnZqYdQ51513kTqPslLnukkwTbGf8YtW0RetTU0FTjYQMXnFD7KnQ==" + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz", @@ -9869,6 +9881,11 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "@types/p5": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/p5/-/p5-1.4.3.tgz", + "integrity": "sha512-UjgBi1/VU0Dz1/JxzRZrDKlC54rMELWW+6oHx1pRKzKkVgwzvP+dEjZ1JbeMjK12VJMUjDx4lhGUmnUL2jBASQ==" + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -14188,6 +14205,11 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "p5": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/p5/-/p5-1.5.0.tgz", + "integrity": "sha512-zZFMVUmGkXe2G5H6Sw7xsVhgdxMyEN/6SZnZqYdQ51513kTqPslLnukkwTbGf8YtW0RetTU0FTjYQMXnFD7KnQ==" + }, "param-case": { "version": "3.0.4", "resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz", diff --git a/frontend/package.json b/frontend/package.json index a11bdcd..5a8b651 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,12 +9,14 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "@types/p5": "^1.4.3", "bootstrap": "^5.2.3", - "vue": "^3.2.13", - "@vue/cli-service": "~5.0.0" + "p5": "^1.5.0", + "vue": "^3.2.13" }, "devDependencies": { "@vue/cli-plugin-typescript": "~5.0.0", + "@vue/cli-service": "~5.0.0", "typescript": "~4.5.5" } } diff --git a/frontend/public/game.js b/frontend/public/game.js deleted file mode 100644 index 3b51b91..0000000 --- a/frontend/public/game.js +++ /dev/null @@ -1,519 +0,0 @@ -var __extends = (this && this.__extends) || (function(){ - var extendStatics = function(d, b){ - extendStatics = Object.setPrototypeOf || - ({__proto__: []} instanceof Array && function(d, b){ - d.__proto__ = b; - }) || - function(d, b){ - for(var p in b) if(Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; - }; - return extendStatics(d, b); - }; - return function(d, b){ - if(typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - - function __(){ - this.constructor = d; - } - - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -var PIPE_IMAGE_PATH = "resources/dell-pc-min-min-small.png"; -var BACKGROUND_IMAGE_PATH = "resources/htl-steyr-front.jpg"; -var RASPBERRY_IMAGE_PATH = "resources/raspberry-rocket.png"; -var FLOOR_IMAGE_PATH = "resources/table-min-min.png"; -var FONT_PATH = "resources/PressStart2P-Regular.ttf"; -var OBSTACLE_COUNT = 3; -var BOOST_KEYS = ["k", " "]; -var floorHeight; -var obstacleWidth; -var obstacleOffset; -var backgroundImage; -var pipeImage; -var floorImage; -var font; -var obstacles = []; -var raspberry; -var startTime; -var playTime; -var score = 0; -var paused; -var hasAlreadyScored = false; -var hasDied = true; -var ready = true; - -function preload(){ - font = loadFont(FONT_PATH); - backgroundImage = loadImage(BACKGROUND_IMAGE_PATH); - pipeImage = loadImage(PIPE_IMAGE_PATH); - floorImage = loadImage(FLOOR_IMAGE_PATH); -} - -function setup(){ - createCanvas(1085, 600); - floorHeight = height / 5; - setupObstacleConsts(); - setupFont(); - setupGame(); - var originalSetItem = localStorage.setItem; - localStorage.setItem = function(key, value){ - var event = new Event('itemInserted'); - - event.value = value; // Optional.. - event.key = key; // Optional.. - window.dispatchEvent(event); - originalSetItem.apply(this, arguments); - }; -} - -function setupObstacleConsts(){ - obstacleOffset = width / OBSTACLE_COUNT; - obstacleWidth = width / 22.727272727272727272; - Obstacle.distanceBetweenPipes = height / 2.5; - Obstacle.startX = width; -} - -function setupFont(){ - textSize(75); - textAlign(CENTER); - textFont(font); -} - -function setupGame(){ - paused = true; - raspberry = new Raspberry(RASPBERRY_IMAGE_PATH); - setupObstacles(); -} - -function setupObstacles(){ - obstacles = []; - instantiateObstacles(OBSTACLE_COUNT); - obstacles.forEach(function(obstacle){ - return obstacle.randomizeHeight(); - }); -} - -function instantiateObstacles(number){ - for(var i = 0; i < number; i++){ - obstacles.push(new Obstacle(new Position(width + obstacleOffset * i, 0), obstacleWidth, height, pipeImage)); - } -} - -function draw(){ - update(); - gameLoop(); - drawGame(); -} - -function drawGame(){ - drawScenery(); - drawEntities(); - displayScore(); -} - -function drawScenery(){ - background(backgroundImage); - drawFloor(); -} - -function drawFloor(){ - push(); - noFill(); - image(floorImage, 0, height - floorHeight, width, floorHeight); - rect(0, height - floorHeight, width, floorHeight); - pop(); -} - -function drawEntities(){ - raspberry.draw(); - drawObstacles(); -} - -function drawObstacles(){ - obstacles.forEach(function(obstacle){ - obstacle.draw(); - }); -} - -function gameLoop(){ - if(!paused){ - collisionCheck(obstacles[0]); - checkRaspberryScore(); - } -} - -function collisionCheck(o){ - if(o.collides(raspberry)){ - die(); - setupGame(); - } -} - -function die(){ - if(localStorage.getItem("frontend-ready") == "false") - return; - - ready = false; - hasDied = true; - playTime = Date.now() - startTime; - exportToLocalStorage(); - setTimeout(function(){ - return ready = true; - }, 1000); -} - -function exportToLocalStorage(){ - localStorage.setItem("game-playTime", String(playTime)); - localStorage.setItem("game-score", String(score)); - localStorage.setItem("game-isRunning", String(!hasDied)); -} - -function displayScore(){ - push(); - fill(195, 33, 34); - text(score, 0, height / 8, width, height); - pop(); -} - -function update(){ - if(!paused){ - raspberry.update(); - } - obstacles.forEach(function(obstacle){ - if(!paused){ - obstacle.update(); - checkObstacleReset(obstacle); - } - }); -} - -function checkObstacleReset(obstacle){ - if(obstacle.position.x < -obstacleWidth){ - obstacle.resetPosition(); - obstacles.shift(); - obstacles.push(obstacle); - hasAlreadyScored = false; - } -} - -function checkRaspberryScore(){ - if((obstacles[0].position.x + obstacles[0].width / 2) < (raspberry.position.x + raspberry.width / 2) - && !hasAlreadyScored){ - score += 1; - hasAlreadyScored = true; - } -} - -function resetScore(){ - if(!hasDied || localStorage.getItem("frontend-ready") == "false") - return; - - hasDied = false; - score = 0; - hasAlreadyScored = false; - startTime = Date.now(); - exportToLocalStorage(); -} - -function keyPressed(){ - if(!ready) - return; - if(BOOST_KEYS.includes(key.toLowerCase())){ - resetScore(); - raspberry.boost(); - } - if(key == "Escape"){ - paused = !paused; - } else if(paused){ - paused = false; - } -} - -var Entity = (function(){ - function Entity(position, width, height, fill){ - this.position = position; - this.width = width; - this.height = height; - this.fill = fill; - this._showHitbox = false; - } - - Object.defineProperty(Entity.prototype, "position", { - get: function(){ - return this._position; - }, - set: function(value){ - this._position = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Entity.prototype, "width", { - get: function(){ - return this._width; - }, - set: function(value){ - this._width = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Entity.prototype, "height", { - get: function(){ - return this._height; - }, - set: function(value){ - this._height = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Entity.prototype, "showHitbox", { - get: function(){ - return this._showHitbox; - }, - set: function(value){ - this._showHitbox = value; - }, - enumerable: false, - configurable: true - }); - Entity.prototype.draw = function(){ - push(); - fill(this.fill); - rect(this.position.x, this.position.y, this.width, this.height); - pop(); - }; - return Entity; -}()); -var Obstacle = (function(_super){ - __extends(Obstacle, _super); - - function Obstacle(position, obstacleWidth, obstacleHeight, image){ - var _this = _super.call(this, position, obstacleWidth, obstacleHeight, 0) || this; - _this.speed = 3; - _this.padding = height / 6.6666666666666666; - _this.createPipes(position, obstacleHeight, obstacleWidth, image); - return _this; - } - - Object.defineProperty(Obstacle, "startX", { - set: function(value){ - this._startX = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Obstacle, "distanceBetweenPipes", { - set: function(value){ - this._distanceBetweenPipes = value; - }, - enumerable: false, - configurable: true - }); - Obstacle.prototype.createPipes = function(position, obstacleHeight, obstacleWidth, pipeImage){ - this.pipeTop = new Pipe(position.x, obstacleWidth, obstacleHeight, pipeImage); - this.pipeBottom = new Pipe(position.x, obstacleWidth, obstacleHeight, pipeImage); - }; - Obstacle.prototype.resetPosition = function(){ - this.randomizeHeight(); - this.pipeBottom.position.x = Obstacle._startX; - this.pipeTop.position.x = Obstacle._startX; - }; - Obstacle.prototype.randomizeHeight = function(){ - this.pipeTop.height = this.randomRange(this.padding, height - this.padding - Obstacle._distanceBetweenPipes); - this.pipeBottom.position.y = this.pipeTop.height + Obstacle._distanceBetweenPipes; - this.pipeBottom.height = height - this.pipeTop.height - this.padding; - }; - Obstacle.prototype.randomRange = function(min, max){ - return Math.random() * (max - min) + min; - }; - Obstacle.prototype.update = function(){ - this.pipeTop.move(this.speed); - this.pipeBottom.move(this.speed); - this.position.x = this.pipeTop.position.x; - }; - Obstacle.prototype.draw = function(){ - this.pipeTop.draw(); - this.pipeBottom.draw(); - }; - Obstacle.prototype.collides = function(o){ - return this.pipeTop.collides(o) || this.pipeBottom.collides(o); - }; - return Obstacle; -}(Entity)); -var Pipe = (function(_super){ - __extends(Pipe, _super); - - function Pipe(positionX, width, height, image){ - var _this = _super.call(this, new Position(positionX, 0), width, height, 0) || this; - _this.image = image; - return _this; - } - - Pipe.prototype.update = function(){ - }; - Pipe.prototype.draw = function(){ - push(); - noFill(); - var imageAspectRatio = this.image.height / this.image.width; - var computedImageHeight = imageAspectRatio * this.width; - this.drawImage(computedImageHeight, imageAspectRatio); - rect(this.position.x, this.position.y, this.width, this.height); - pop(); - }; - Pipe.prototype.drawImage = function(computedImageHeight, imageAspectRatio){ - if(this.height > computedImageHeight){ - var maxImageYPos = Math.ceil(this.height / computedImageHeight) * computedImageHeight; - for(var imageYPosition = 0; imageYPosition < maxImageYPos; imageYPosition += computedImageHeight){ - if(imageYPosition + computedImageHeight >= maxImageYPos){ - this.cropLastImage(imageYPosition, computedImageHeight, imageAspectRatio); - break; - } - image(this.image, this.position.x, this.position.y + imageYPosition, this.width, computedImageHeight); - } - } else{ - image(this.image, this.position.x, this.position.y, this.width, this.height); - } - }; - Pipe.prototype.cropLastImage = function(imageYPosition, computedImageHeight, imageAspectRatio){ - var amountOfImages = Math.floor(imageYPosition / computedImageHeight); - var heightToEdge = this.height - (amountOfImages * computedImageHeight); - var croppedImage = this.image.get(0, 0, this.image.width, this.image.height - (heightToEdge * imageAspectRatio)); - image(croppedImage, this.position.x, this.position.y + imageYPosition, this.width, heightToEdge); - }; - Pipe.prototype.move = function(speed){ - this.position.x -= speed; - }; - Pipe.prototype.collides = function(o){ - return this.position.x < (o.position.x + o.width) && - (this.position.x + this.width) > o.position.x && - this.position.y < (o.position.y + o.height) && - (this.position.y + this.height) > o.position.y; - }; - return Pipe; -}(Entity)); -var Position = (function(){ - function Position(x, y){ - this._x = x; - this._y = y; - } - - Object.defineProperty(Position.prototype, "x", { - get: function(){ - return this._x; - }, - set: function(value){ - this._x = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Position.prototype, "y", { - get: function(){ - return this._y; - }, - set: function(value){ - this._y = value; - }, - enumerable: false, - configurable: true - }); - return Position; -}()); -var Raspberry = (function(_super){ - __extends(Raspberry, _super); - - function Raspberry(image){ - var _this = this; - Raspberry.position = new Position(width / 6, height / 2); - Raspberry.height = height / 14.2857142857142857; - Raspberry.width = width / 11.1111111111111111; - _this = _super.call(this, Raspberry.position, Raspberry.width, Raspberry.height, Raspberry.FILL) || this; - _this.lift = -15; - _this.gravity = 0.45; - _this._velocity = 0; - Raspberry.bottomFloorOffset = (height / 5) - (height / 15 / 2); - _this.image = image; - return _this; - } - - Object.defineProperty(Raspberry.prototype, "velocity", { - get: function(){ - return this._velocity; - }, - set: function(value){ - this._velocity = (Math.abs(this.velocity) > Raspberry.maxVelocity) ? Raspberry.maxVelocity : value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Raspberry.prototype, "image", { - get: function(){ - return this._image; - }, - set: function(path){ - this._image = loadImage(path); - }, - enumerable: false, - configurable: true - }); - Raspberry.prototype.update = function(){ - this.applyGravity(); - this.forceBoundaries(); - }; - Raspberry.prototype.applyGravity = function(){ - this.velocity += this.gravity; - this.position.y += this.velocity; - }; - Raspberry.prototype.forceBoundaries = function(){ - this.boundaryTop(); - this.boundaryBottom(); - }; - Raspberry.prototype.boundaryTop = function(){ - if(this.position.y < 0){ - this.position.y = 0; - this.velocity = 0; - } - }; - Raspberry.prototype.boundaryBottom = function(){ - if(this.position.y + this.height + Raspberry.bottomFloorOffset > height){ - this.position.y = height - this.height - Raspberry.bottomFloorOffset; - this.velocity = 0; - } - }; - Raspberry.prototype.boost = function(){ - this.velocity += this.lift; - }; - Raspberry.prototype.draw = function(){ - push(); - noFill(); - this.setPose(); - this.drawObject(); - pop(); - }; - Raspberry.prototype.drawObject = function(){ - this.drawHitBox(); - this.drawRocket(); - }; - Raspberry.prototype.drawRocket = function(){ - image(this.image, 0, 0, this.width, this.height); - rect(0, 0, this.width, this.height); - }; - Raspberry.prototype.drawHitBox = function(){ - if(!this.showHitbox){ - noStroke(); - } - }; - Raspberry.prototype.setPose = function(){ - translate(this.position.x, this.position.y); - rotate((PI / 2) * (this.velocity / Raspberry.maxVelocity)); - }; - Raspberry.maxVelocity = 75; - Raspberry.FILL = 0; - return Raspberry; -}(Entity)); -//# sourceMappingURL=build.js.map diff --git a/frontend/public/index.html b/frontend/public/index.html index fb663ea..ead5f8f 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -10,8 +10,8 @@