commit b516324a8d6ce6c9542989c142e6a21457b74fc3 Author: Loosen-IT Date: Sat Dec 2 19:45:57 2023 +0100 02/12/2023 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/JS_Games.iml b/.idea/JS_Games.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/JS_Games.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c9828be --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml new file mode 100644 index 0000000..f324872 --- /dev/null +++ b/.idea/php.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/flappy-bird/README.md b/flappy-bird/README.md new file mode 100644 index 0000000..2e0921d --- /dev/null +++ b/flappy-bird/README.md @@ -0,0 +1,54 @@ + + + + +# Flappy Bird + +A 2D Flappy bird remake built using HTML, CSS & JS ,in which the player can control the movement of the flappy bird using right mouse click to avoid incoming obstacle. + + +![GitHub top language](https://img.shields.io/github/languages/top/amoldalwai/FlappyBird?style=plastic) +![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/amoldalwai/FlappyBird?style=plastic) +![Website](https://img.shields.io/website?style=plastic&url=https%3A%2F%2Famoldalwai.github.io%2FFlappyBird%2F) + +#### Table of Contents +[Features](#Features) +[Youtube](#Youtube)\ +[Installing](#Installing) + + +![Demonstartion Video](https://j.gifs.com/3Q84An.gif) + + +## Demo Link :point_right: [https://amoldalwai.github.io/FlappyBird/](https://amoldalwai.github.io/FlappyBird/) + + + + +## Features + +- [x] Control Flappy Bird movement with right mouse click +- [x] Collision Detection +- [x] Score tracking + + + +## Youtube + + + +![YouTube Video Views](https://img.shields.io/youtube/views/9rQIVyJJymk?style=plastic) +![YouTube Video Votes](https://img.shields.io/youtube/likes/9rQIVyJJymk?style=social&withDislikes) +![YouTube Video Comments](https://img.shields.io/youtube/comments/9rQIVyJJymk?style=social) + + +### Installing + +``` +Run index.html on browser (eg. Chrome) +``` + +![Badge](https://img.shields.io/badge/Made%20by-Amol%20Dalwai-red?style=for-the-badge) + diff --git a/flappy-bird/back1.png b/flappy-bird/back1.png new file mode 100644 index 0000000..c2c4b66 Binary files /dev/null and b/flappy-bird/back1.png differ diff --git a/flappy-bird/back2.png b/flappy-bird/back2.png new file mode 100644 index 0000000..2e6ec75 Binary files /dev/null and b/flappy-bird/back2.png differ diff --git a/flappy-bird/background.png b/flappy-bird/background.png new file mode 100644 index 0000000..33d6f12 Binary files /dev/null and b/flappy-bird/background.png differ diff --git a/flappy-bird/daybackground.html b/flappy-bird/daybackground.html new file mode 100644 index 0000000..e5f86c5 --- /dev/null +++ b/flappy-bird/daybackground.html @@ -0,0 +1,177 @@ + + + + + + + + +
+ + + + diff --git a/flappy-bird/flappybird.png b/flappy-bird/flappybird.png new file mode 100644 index 0000000..d17b49f Binary files /dev/null and b/flappy-bird/flappybird.png differ diff --git a/flappy-bird/index.html b/flappy-bird/index.html new file mode 100644 index 0000000..f2e933c --- /dev/null +++ b/flappy-bird/index.html @@ -0,0 +1,10 @@ + + + + diff --git a/flappy-bird/menu.png b/flappy-bird/menu.png new file mode 100644 index 0000000..abb256a Binary files /dev/null and b/flappy-bird/menu.png differ diff --git a/flappy-bird/modeselect.html b/flappy-bird/modeselect.html new file mode 100644 index 0000000..afedf72 --- /dev/null +++ b/flappy-bird/modeselect.html @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/flappy-bird/modeselect.png b/flappy-bird/modeselect.png new file mode 100644 index 0000000..dc640b2 Binary files /dev/null and b/flappy-bird/modeselect.png differ diff --git a/flappy-bird/nightbackground.html b/flappy-bird/nightbackground.html new file mode 100644 index 0000000..2effe4a --- /dev/null +++ b/flappy-bird/nightbackground.html @@ -0,0 +1,177 @@ + + + + + + + + +
+ + + + diff --git a/flappy-bird/pipe.png b/flappy-bird/pipe.png new file mode 100644 index 0000000..f3eeb3b Binary files /dev/null and b/flappy-bird/pipe.png differ diff --git a/flappy-bird/rotatedpipe.png b/flappy-bird/rotatedpipe.png new file mode 100644 index 0000000..2b4109f Binary files /dev/null and b/flappy-bird/rotatedpipe.png differ diff --git a/images/popcorn.svg b/images/popcorn.svg new file mode 100644 index 0000000..2ebef59 --- /dev/null +++ b/images/popcorn.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..5283ed1 --- /dev/null +++ b/index.php @@ -0,0 +1,71 @@ + + + + + + + Kergart Browser Games LTD + + +
+ Popcorn Icon +

Kergart Browser Games Ltd.

+

A premium amateur **** selection.
Only available on https://kergart.testgelaende.de!

+
+ +
+ + +
+ +

Flappy Jan

+

+ Flappy-Jan, the wing-challenged avian adventurer, is the epitome of gravity-defying absurdity in the pixelated realm. With feathers that seem to have missed the memo on aerodynamics, Flappy-Jan embarks on a mission to redefine the art of flight – or rather, the lack thereof. Navigating through a world of pipes that apparently moonlight as overzealous decorators, our feathered friend flaps with a determination that suggests it's on a quest to discover the meaning of life, or perhaps just trying to avoid a feathery fiasco. The comical clumsiness of Flappy-Jan is a testament to the hilariously frustrating nature of the game, where every tap of the screen sends our feathered hero soaring into the chaotic symphony of pipe collisions. It's a bird-brained ballet that will leave you questioning not only your gaming skills but also the very fabric of avian physics. Good luck trying to keep a straight face while Flappy-Jan clumsily flutters through the whimsical mayhem! +

+ Play Now +
+ +
+ +

Need for Kergi

+

+ "Need for Kergi," the turbocharged extravaganza that transforms the asphalt into a runway for speed demons, takes the art of illegal street racing to a whole new level of fur and fury. Picture this: adrenaline-pumping cheetahs, raccoon gearheads, and hip-hop beats that even a hedgehog would breakdance to. In this anthropomorphic race fest, the asphalt jungle becomes the playground for turbocharged turtles and sleek sloths vying for supremacy in the world of underground racing. The streets are lined with neon lights, and instead of dodging traffic, our speed-hungry critters navigate through an obstacle course of acorns, banana peels, and the occasional mischievous squirrel. It's pedal-to-the-metal madness, where even the slow and steady are revving up their engines for a chance at glory. Buckle up for a wild ride as Need for Kergi unleashes the inner racer in every creature, proving that speed knows no species in this zany and fur-tastic racing adventure! +

+ Play Now +
+ +
+ +

Jan, Jan, Jan

+

+ In the cosmic realm of "Jan, Jan, Jan," the janitorial universe unveils its quirky rendition of the classic Rock, Paper, Scissors game. Picture this whimsical jamboree: our steadfast custodian, Jan, takes the spotlight armed not with conventional weapons but equipped with a trusty mop, facing off against the formidable trio transformed into sweeping brooms, crumpled paper balls, and interlocking dustpans. The battle unfolds in a celestial dance, where the mighty mop triumphs over the unruly broom, the crumpled paper gracefully yields to the all-encompassing dustpan, and the interlocking dustpans deftly outmaneuver the crisscrossing bristles of the sweeping broom. Each round becomes a janitorial masterpiece, a testament to the cosmic prowess of Jan in this interstellar janitorial adventure. "Jan, Jan, Jan" becomes a celestial choreography where cleanliness meets the cosmos, and victory is defined by the mastery of janitorial tools in this cosmic rendition of the timeless game! +

+ Play Now +
+ +
+ +

Space Kergi

+

+ Space Jan, the cosmic maverick with a mop and a mission, embarks on an intergalactic cleaning spree that turns the vastness of space into a sparkling sanctuary. Armed with a space-age vacuum and a helmet that looks suspiciously like a janitor's cap, Space Jan maneuvers through asteroid fields and cosmic dust bunnies, tidying up the universe one celestial body at a time. Instead of dodging aliens, our celestial custodian faces off against rogue space debris and unruly stardust, determined to leave no corner of the cosmos untouched by cleanliness. The vacuum roars with the power of a rocket engine as Space Jan zips and zooms, turning space into a spick-and-span spectacle. It's not just a space adventure; it's an out-of-this-world cleanup mission that proves even the vacuum of space can't escape the meticulous touch of our cosmic custodian! +

+ Play Now +
+ +
+ +

Tik-Tok-Jan

+

+ Tik-Tok-Jan, the trendsetting sensation of the grid, is a whirlwind of choreographed moves and catchy beats that transforms the classic game of tic-tac-toe into a dance-off extravaganza. Picture this: Xs and Os boogieing to the rhythm, with every move punctuated by a perfectly timed dab, floss, or maybe even a moonwalk. The grid becomes a virtual dance floor where each square is a stage for Tik-Tok-Jan to showcase its viral dance moves. Instead of the usual stoic Xs and Os, our charismatic characters strut their stuff with style, and victory isn't just about three in a row – it's about achieving the perfect dance combo. Get ready for a tic-tac-toe experience that's not only strategic but also a dance party where every move leaves you tapping your feet and wondering if you're witnessing the birth of the next big TikTok trend. It's toe-tapping, grid-hopping fun that proves tic-tac-toe isn't just a game; it's a dance revolution waiting to happen! +

+ Play Now +
+
+ + + + diff --git a/need-for-speed/README.md b/need-for-speed/README.md new file mode 100644 index 0000000..4debd0f --- /dev/null +++ b/need-for-speed/README.md @@ -0,0 +1,12 @@ +# Need For Speed - A car racing game (using JS and CSS) + +Need for Speed using Javascript(JS) and CSS only. +Play here: https://ashimregme.github.io/need-for-speed + +## Controls + +``` +Space -> Fires weapon +Left and Right Arrows -> Avoid Obstacle +``` +![alt Sample Screenshot](https://github.com/ashimregme/need-for-speed/blob/master/sample.png?raw=true) diff --git a/need-for-speed/css/reset.css b/need-for-speed/css/reset.css new file mode 100644 index 0000000..b6d933b --- /dev/null +++ b/need-for-speed/css/reset.css @@ -0,0 +1,4 @@ +*{ + margin: 0; + padding: 0; +} \ No newline at end of file diff --git a/need-for-speed/css/style.css b/need-for-speed/css/style.css new file mode 100644 index 0000000..c7197ae --- /dev/null +++ b/need-for-speed/css/style.css @@ -0,0 +1,76 @@ +.title{ + + width: 40%; + margin: 0 auto; + text-align: center; +} + +.wrapper { + margin: 0 auto; + position: relative; + overflow: hidden; + border: 1px solid black; + height: 500px; + width: 302px; + top: 15px; +} + +.container { + height: 2000px; + width: 100%; + background-image: url('../images/road.png'); + background-size: contain; + background-repeat: repeat-y; +} + +.lane { + float: left; + width: 33.33%; + height: 500px; + min-height: 500px; + display: inline-block; +} + +.lane > .car { + + display: block; + position: absolute; + bottom: 10px; + margin: 0 auto; + width: 40px; + height: 80px; + margin-left: 10%; +} + +.box { + position: absolute; + height: 40px; + width: 40px; + border: 2px solid black; +} + +.obstacle{ + + width: 100px; + position: absolute; +} + +.bullets{ + + display: block; + position: absolute; + margin-left: 13%; + bottom: 90px; +} + +.game-over{ + + position: absolute; + top: 40%; + background: red; + width: 80%; + padding: 10%; + text-align: center; + color: white; + font-size: 27px; +} diff --git a/need-for-speed/images/bullets.png b/need-for-speed/images/bullets.png new file mode 100644 index 0000000..19b6306 Binary files /dev/null and b/need-for-speed/images/bullets.png differ diff --git a/need-for-speed/images/car.png b/need-for-speed/images/car.png new file mode 100644 index 0000000..f3c8a97 Binary files /dev/null and b/need-for-speed/images/car.png differ diff --git a/need-for-speed/images/obstacle.png b/need-for-speed/images/obstacle.png new file mode 100644 index 0000000..35d46d1 Binary files /dev/null and b/need-for-speed/images/obstacle.png differ diff --git a/need-for-speed/images/road.png b/need-for-speed/images/road.png new file mode 100644 index 0000000..59b5d3c Binary files /dev/null and b/need-for-speed/images/road.png differ diff --git a/need-for-speed/index.html b/need-for-speed/index.html new file mode 100644 index 0000000..2c27fb0 --- /dev/null +++ b/need-for-speed/index.html @@ -0,0 +1,32 @@ + + + + + Need for Kergi + + + + + +
+

Need for Kergi - Most Wanted

+ Spacebar fires bullets +
+ Press 'start' to begin +
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/need-for-speed/js/nfs.js b/need-for-speed/js/nfs.js new file mode 100644 index 0000000..a592609 --- /dev/null +++ b/need-for-speed/js/nfs.js @@ -0,0 +1,401 @@ +var NFS_HEIGHT = 500; +var CAR_BOTTOM = 10; +var CAR_HEIGHT = 80 + CAR_BOTTOM; +var CAR_WIDTH = 40; +var OBSTACLE_WIDTH = 100; +var OBSTACLE_HEIGHT = 33.328; +var OBSTACLE_APPEARANCE_GAP = 1000; //1 second +var OBSTACLE_APPEARANCE_DX = 100; +var PX_DX = 3; +var PX_DX_DX = 0.05; +var GAME_TIME = 1; +var GAME_TIME_DX = 11; +var INITIAL_BULLETS_BOTTOM = CAR_HEIGHT; + +function Util() {} + +Util.getRandomInt = function(min, max) { + + return Math.floor(Math.random() * (max - min + 1)) + min; +}; + +function Obstacle(lanes, laneNo) { + + var _this = this; + this._init = function() { + + this.element = document.createElement('img'); + this.laneNo = laneNo; + this.lanes = lanes; + this.element.className = 'obstacle'; + this.element.setAttribute('src', 'images/obstacle.png'); + this.lanes[laneNo].appendChild(this.element); + this.dynamicMarginTop = 1; + }; + + this._init(); +} + +function ObstacleManager(lanes, car) { + + var _this = this; + this._init = function() { + + this.lanes = lanes; + this.car = car; + this.obstacles = []; + }; + + this.generateObstacles = function() { + + _this.obstacleGeneratorId = setInterval(_this._generateObstacle, OBSTACLE_APPEARANCE_GAP); + }; + + this._generateObstacle = function() { + + if (_this.obstacles.length < 3) { + + var laneNo; + laneNo = Util.getRandomInt(0, _this.lanes.length - 1); + var obstacle = new Obstacle(_this.lanes, laneNo); + _this.obstacles.push(obstacle); + + return obstacle; + } + }; + + this.refreshObstacles = function() { + + var updatedObstacles = []; + for (var i = 0; i < _this.obstacles.length; i++) { + + _this.obstacles[i].element.style.top = _this.obstacles[i].dynamicMarginTop + 'px'; + if (!(parseInt(_this.obstacles[i].element.style.top) > NFS_HEIGHT - CAR_BOTTOM)) { + + _this.obstacles[i].dynamicMarginTop += PX_DX; + updatedObstacles.push(_this.obstacles[i]); + } else { + + _this.obstacles[i].element.parentElement.removeChild(_this.obstacles[i].element); + for (var j = 0; j < _this.obstacles.length; j++) { + + if (_this.obstacles[j].element.parentElement === _this.obstacles[i].element.parentElement) { + + _this.obstacles[j].element.style.top = _this.obstacles[j].dynamicMarginTop + OBSTACLE_HEIGHT + 'px'; + } + } + } + } + _this.obstacles = updatedObstacles; + }; + + this.removeObstacle = function(obstacle){ + + var index = this.obstacles.indexOf(obstacle); + + if(index !== -1){ + console.log(this.obstacles[index].parentElement); + this.obstacles[index].element.parentElement.removeChild(this.obstacles[index].element); + this.obstacles.splice(index, 1); + } + }; + + this.getOldestObstacleInLane = function(bulletLane){ + + var obstacle; + for(var i = 0; i < _this.obstacles.length; i++){ + + if(_this.obstacles[i].laneNo == bulletLane){ + + if(obstacle === undefined || _this.obstacles[i].dynamicMarginTop > obstacle.dynamicMarginTop){ + + obstacle = _this.obstacles[i]; + } + } + } + + return obstacle; + }; + + this.stop = function() { + + if (this.obstacleGeneratorId) { + clearInterval(this.obstacleGeneratorId); + this.obstacleGeneratorId = false; + } + }; + + this._init(); +} + +function CollisionHandler(car, obstacleManager) { + + var _this = this; + this._init = function() { + + this.car = car; + this.obstacleManager = obstacleManager; + }; + + this.checkCollisions = function() { + + for (var i = 0; i < _this.obstacleManager.obstacles.length; i++) + return _this._checkCollision(_this.obstacleManager.obstacles[i]); + }; + + this._checkCollision = function(obstacleO) { + + if ((obstacleO.dynamicMarginTop + OBSTACLE_HEIGHT > NFS_HEIGHT - CAR_HEIGHT) && (obstacleO.laneNo == _this.car.currentLane)) { + + return true; + } + }; + + this.checkShot = function(){ + + var bulletLane; + + for(var i = 0; i < _this.obstacleManager.lanes.length; i++){ + + if(_this.obstacleManager.lanes[i].getElementsByClassName('bullets').length > 0) { + bulletLane = i; + break; + } + } + + var oldestObstacleInCurrentLane = obstacleManager.getOldestObstacleInLane(bulletLane); + if(oldestObstacleInCurrentLane !== undefined && _this.car.gun.bullets !== undefined) { + if (_this.car.gun.dynamicBulletBottom + oldestObstacleInCurrentLane.dynamicMarginTop + CAR_HEIGHT + OBSTACLE_HEIGHT > NFS_HEIGHT) { + + _this.car.gun.stop(); + _this.car.enableGun(); + _this.obstacleManager.removeObstacle(oldestObstacleInCurrentLane); + } + } + if(_this.car.gun.dynamicBulletBottom + CAR_HEIGHT > NFS_HEIGHT){ + + _this.car.gun.stop(); + _this.car.enableGun(); + } + }; + + this._init(); +} + +function Car(currentLane, lanes) { + + var _this = this; + this._init = function() { + + this.currentLane = currentLane; + this.lanes = lanes; + this.element = document.createElement('img'); + this.element.className = 'car'; + this.element.setAttribute('src', 'images/car.png'); + this.lanes[this.currentLane].appendChild(this.element); + this.gun = new Gun(this.lanes); + }; + + this._changeLane = function(laneNumber) { + + + if (_this.currentLane != laneNumber) { + + _this.lanes[laneNumber].appendChild(_this.element); + } + if (_this.currentLane > laneNumber) { + + _this.currentLane--; + } else if (_this.currentLane < laneNumber) { + + _this.currentLane++; + } + }; + + this._keyNavigation = function(e) { + + switch (e.which) { + case 37: // left + _this._changeLane((_this.currentLane - 1) < 0 ? 0 : (_this.currentLane - 1)); + break; + + case 39: // right + _this._changeLane((_this.currentLane + 1) > _this.lanes.length - 1 ? _this.lanes.length - 1 : (_this.currentLane + 1)); + break; + + default: + return; // exit this handler for other keys + } + }; + + + this._fireGunEvent = function(e){ + + switch (e.which){ + + case 32: + _this._disableGun(); + _this.gun.fireBullets(_this.currentLane); + break; + } + }; + + this.enableGun = function(){ + + document.addEventListener('keyup', this._fireGunEvent, false); + }; + + this._disableGun = function(){ + + document.removeEventListener('keyup', this._fireGunEvent, false); + }; + + this._initEvents = function() { + + document.addEventListener('keydown', this._keyNavigation, false); + this.enableGun(); + }; + + this._removeEvents = function() { + + document.removeEventListener('keydown', this._keyNavigation, false); + this._disableGun(); + }; + + this.stop = function() { + + _this._removeEvents(); + }; + + this._init(); +} + +function Gun(lanes){ + + var _this = this; + this._init = function(){ + + this.lanes = lanes; + }; + + this.fireBullets = function(currentLane){ + + var bullets = document.createElement('img'); + bullets.setAttribute('src', 'images/bullets.png'); + bullets.className = 'bullets'; + _this.lanes[currentLane].appendChild(bullets); + _this.bullets = bullets; + _this.dynamicBulletBottom = INITIAL_BULLETS_BOTTOM; + + _this.bulletId = requestAnimationFrame(_this.animateFireBullets); + }; + + this.animateFireBullets = function () { + + _this.dynamicBulletBottom += PX_DX; + _this.bullets.style.bottom = _this.dynamicBulletBottom + 'px'; + + _this.bulletId = requestAnimationFrame(_this.animateFireBullets); + }; + + _this.stop = function () { + + if(_this.bulletId){ + + cancelAnimationFrame(_this.bulletId); + _this.bulletId = false; + _this.bullets.parentElement.removeChild(_this.bullets); + _this.bullets = undefined; + } + }; + + this._init(); +} + +function NFS() { + + var _this = this; + + this._init = function() { + + this.lanes = document.getElementsByClassName('lane'); + this.container = document.getElementById('container'); + this.obstacles = []; + this.car = new Car(Util.getRandomInt(0, this.lanes.length - 1), this.lanes); + this.obstacleManager = new ObstacleManager(this.lanes, this.car); + this.collisionHander = new CollisionHandler(this.car, this.obstacleManager); + + this.dynamicBackgroundPositionY = 1; + + document.getElementById('toggle').addEventListener('click', function() { + + if (this.innerHTML == 'Start') { + _this.obstacleManager.generateObstacles(); + _this.play(); + _this.car._initEvents(); + _this._startTime(); + this.innerHTML = 'Pause'; + } else if (this.innerHTML == 'Pause') { + _this.stop(); + this.innerHTML = 'Start'; + } + }); + }; + + this._startTime = function(){ + + this.timeId = setInterval(function(){GAME_TIME++;}, 1000); + }; + + this._stopTime = function(){ + + if(this.timeId){ + + clearInterval(this.timeId); + this.timeId = false; + } + }; + + this.play = function() { + + _this.dynamicBackgroundPositionY += PX_DX; + _this.container.style.backgroundPositionY = _this.dynamicBackgroundPositionY + 'px'; + + _this.obstacleManager.refreshObstacles(); + + if(GAME_TIME % GAME_TIME_DX == 0) { + PX_DX += PX_DX_DX; + OBSTACLE_APPEARANCE_GAP -= OBSTACLE_APPEARANCE_DX; + } + + _this.playId = window.requestAnimationFrame(_this.play); + + if (_this.collisionHander.checkCollisions()) { + + _this.gameOver(); + } + + _this.collisionHander.checkShot(); + }; + + this.gameOver = function(){ + + var gameOver = document.createElement('div'); + gameOver.className = 'game-over'; + gameOver.innerHTML = 'GAME OVER'; + _this.container.appendChild(gameOver); + _this.stop(); + }; + + this.stop = function() { + + this.obstacleManager.stop(); + window.cancelAnimationFrame(_this.playId); + _this.car.stop(); + _this._stopTime(); + }; + + this._init(); +} + +var nfs = new NFS(); diff --git a/need-for-speed/sample.png b/need-for-speed/sample.png new file mode 100644 index 0000000..fbf5d0d Binary files /dev/null and b/need-for-speed/sample.png differ diff --git a/rock-paper-scissor/LICENSE b/rock-paper-scissor/LICENSE new file mode 100644 index 0000000..61d30a7 --- /dev/null +++ b/rock-paper-scissor/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 AtharvaKulkarniIT + +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: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. diff --git a/rock-paper-scissor/README.md b/rock-paper-scissor/README.md new file mode 100644 index 0000000..085d12d --- /dev/null +++ b/rock-paper-scissor/README.md @@ -0,0 +1,48 @@ +# Rock, Paper, Scissors Game + +This is a Rock, Paper, Scissors game built with HTML, CSS, and JavaScript. You can play this classic hand game against the computer. The game is fully responsive and can be played on both desktop and mobile devices. + +## Features + +- Play Rock, Paper, Scissors against the computer. +- Simple and intuitive user interface. +- Responsive design for both desktop and mobile devices. +- Tracks your wins, losses, and ties. + +## How to Play + +1. Choose your move: Rock, Paper, or Scissors by clicking on the respective button. +2. The computer will randomly select its move. +3. The winner of the round will be displayed on the screen. +4. Keep playing and try to beat the computer! + +## Installation + +To run the game locally, follow these steps: + +1. Clone this repository to your local machine using Git: + + ```bash + git clone https://github.com/AtharvaKulkarniIT/Rock-Paper-Scissor.git + +That's it! You don't need to install any additional dependencies. + +## Usage + +Simply open the `index.html` file in your web browser. You can start playing the game immediately. + +## Contributing + +Contributions are welcome! If you want to contribute to this project, follow these steps: + +1. Fork the repository. +2. Create a new branch for your feature or bug fix: `git checkout -b feature/your-feature`. +3. Make your changes and commit them: `git commit -m 'Add a new feature'`. +4. Push to the branch: `git push origin feature/your-feature`. +5. Create a pull request. + +Please ensure your pull request is in line with the project's coding style and standards. + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. diff --git a/rock-paper-scissor/index.html b/rock-paper-scissor/index.html new file mode 100644 index 0000000..968f013 --- /dev/null +++ b/rock-paper-scissor/index.html @@ -0,0 +1,64 @@ + + + + + Jan, Jan, Jan + + + + +
+ +
+

Jan, Jan, Jan

+
+
+ + +

Select your ammo:

+ +
+ +
+ rock +
+ +
+ paper +
+ +
+ scissors +
+ +
+ + +
+ +

Who will win the first game?

+ +
+

Your score: 0

+

Computer's score: 0

+

Draws: 0

+ + +
+ +
+ +
+ +
+

By Atharva Kulkarni

+

+ +

+
+ +
+ + + diff --git a/rock-paper-scissor/paper1.png b/rock-paper-scissor/paper1.png new file mode 100644 index 0000000..ce48f50 Binary files /dev/null and b/rock-paper-scissor/paper1.png differ diff --git a/rock-paper-scissor/rock-paper-scissor(AtharvaKulkarniIT.png b/rock-paper-scissor/rock-paper-scissor(AtharvaKulkarniIT.png new file mode 100644 index 0000000..37b81c0 Binary files /dev/null and b/rock-paper-scissor/rock-paper-scissor(AtharvaKulkarniIT.png differ diff --git a/rock-paper-scissor/rock1.png b/rock-paper-scissor/rock1.png new file mode 100644 index 0000000..88bd6f7 Binary files /dev/null and b/rock-paper-scissor/rock1.png differ diff --git a/rock-paper-scissor/scissor1.png b/rock-paper-scissor/scissor1.png new file mode 100644 index 0000000..82e0eef Binary files /dev/null and b/rock-paper-scissor/scissor1.png differ diff --git a/rock-paper-scissor/script.js b/rock-paper-scissor/script.js new file mode 100644 index 0000000..c4e0286 --- /dev/null +++ b/rock-paper-scissor/script.js @@ -0,0 +1,126 @@ +let userScore = 0; +let computerScore = 0; +let draws = 0 ; + +const drawsSpan = document.getElementById("draws"); +const userScoreSpan = document.getElementById("user-score"); +const computerScoreSpan = document.getElementById("computer-score"); +const resultDiv = document.querySelector("#message"); +const resetButton = document.getElementById("reset-button") + +const rockDiv = document.getElementById("rock"); +const paperDiv = document.getElementById("paper"); +const scissorsDiv = document.getElementById("scissors"); + + +const getComputerChoice = () => { + const choiceList = ["rock", "paper", "scissors"]; + const randomNumber = Math.floor(Math.random()*3); + return (choiceList[randomNumber]); +}; + + +const convertToUp = (word) => { + switch(word) { + case "rock": + return "Jan"; + break; + case "paper": + return "Jan"; + break; + case "scissors": + return "Jan"; + break; + } +}; + +const win = (userChoice, computerChoice) => { + userScore++; + userScoreSpan.innerHTML = userScore; + const randomWin = ["beats", "smashes", "destroys", "obliterates"]; + const randomNumber = Math.floor(Math.random() * 4); + const winEmojis = ["🀠","πŸŽ‰", "✨","🎊","🀩","πŸ‘Œ"] + const randomNumberEmoji = Math.floor(Math.random() * 6); + + resultDiv.innerHTML = `${convertToUp(userChoice)} ${randomWin[randomNumber]} ${convertToUp(computerChoice)}. You win! ${winEmojis[randomNumberEmoji]}`; + + document.getElementById(userChoice).classList.add('win-border') + setTimeout(() => document.getElementById(userChoice).classList.remove('win-border'), 600); +}; + +const lose = (userChoice, computerChoice) => { + computerScore++; + computerScoreSpan.innerHTML = computerScore; + const randomWin = ["beats", "smashes", "destroys", "obliterates"]; + const randomNumber = Math.floor(Math.random() * 4); + const loseEmojis = ["😩", "πŸ˜₯ ", "😭","πŸ˜΅β€πŸ’«","πŸ˜”", "🀦🏽"] + const randomNumberEmoji = Math.floor(Math.random() * 6); + resultDiv.innerHTML = `${convertToUp(computerChoice)} ${randomWin[randomNumber]} ${convertToUp(userChoice)}. You lose! ${loseEmojis[randomNumberEmoji]}`; + + document.getElementById(userChoice).classList.add('lose-border'); + setTimeout(() => document.getElementById(userChoice).classList.remove('lose-border'), 600); + +}; + +const tie = (userChoice, computerChoice) => { + draws++; + drawsSpan.innerHTML = draws ; + const tieEmojis = ["πŸ€”", " 😱", "πŸ™ˆ", "🧐", "πŸ™€", "πŸ™ƒ"]; + const randomNumberEmoji = Math.floor(Math.random() * 6); + resultDiv.innerHTML = `${convertToUp(computerChoice)} matches ${convertToUp(userChoice)}. It's a tie! ${tieEmojis[randomNumberEmoji]}`; + + document.getElementById(userChoice).classList.add('tie-border'); + setTimeout(() => document.getElementById(userChoice).classList.remove('tie-border'), 600); +}; + + + + +const game = (userChoice) => { + const computerChoice = getComputerChoice(); + + switch (userChoice + computerChoice) { + case "paperrock": + case "rockscissors": + case "scissorspaper": + win(userChoice, computerChoice); + break; + + case "rockpaper": + case "scissorsrock": + case "paperscissors": + lose(userChoice, computerChoice); + break; + + case "rockrock": + case "paperpaper": + case "scissorsscissors": + tie(userChoice, computerChoice); + break; + } + +}; + + +const resetScores = () => { + computerScore = 0; + computerScoreSpan.innerHTML = computerScore + userScore = 0; + userScoreSpan.innerHTML = userScore; + draws = 0; + drawsSpan.innerHTML = draws ; + resultDiv.innerHTML = 'Who will win this match ?'; +}; + +const main = () => { + rockDiv.addEventListener('click', () => game("rock")); + + paperDiv.addEventListener('click', () => game("paper")); + + scissorsDiv.addEventListener('click', () => game("scissors")); + + resetButton.addEventListener('click', () => resetScores()); +}; + + +main(); diff --git a/rock-paper-scissor/style.css b/rock-paper-scissor/style.css new file mode 100644 index 0000000..5067371 --- /dev/null +++ b/rock-paper-scissor/style.css @@ -0,0 +1,144 @@ +@import url('https://fonts.googleapis.com/css?family=Lato:400,700,900'); + +html{ + height: 100%; +} + +body { + margin: 0; + padding: 0; + font-family: 'Lato', sans-serif; + text-align: center; + font-size: 1.2rem; + background-image: linear-gradient(180deg , #70c6e3, #19c045); +} + +.container { + padding: 2vh 0; +} + +#inside { + margin: auto; + width: 45%; + height: 50%; + border-radius: 25px; + padding: 2vh 0; +} + +h1 { + font-size: 3.2rem; + margin: 1vh 0; +} + +p { + color: #000000; +} + +hr { + width: 50%; +} + +#instruction { + font-size: 1.5rem; + margin-bottom: 0; +} + +.img-weapon { + max-width: 120px; + height: auto +} + +.choice { + margin: auto; +} + +.select-choice { + display: inline-block; + border: 5px solid #000000; + border-radius: 80px; + margin: 1rem; + transition: all 0.6s ease; +} + +#rock:hover, #paper:hover, #scissors:hover { + background-color: #cf6807d0; + cursor: pointer; + box-shadow: 5px 7px 8px #888888; + +} + +#rock { + background-color: #FFEE88; +} + +#paper { + background-color: #F40076; +} + +#scissors { + background-color: #75C9C8; +} + +.result { + font-size: 1.4rem; + font-weight: 600; +} + +.win-border { + border: 5px solid #3bff00; + box-shadow: 2px 2px 12px #3e3e3e; +} + +.lose-border { + border: 5px solid #ff0000; + box-shadow: 2px 2px 12px #3e3e3e; +} + +.tie-border { + border: 5px solid #4545a3; + box-shadow: 2px 2px 12px #3e3e3e; +} + +.scores { + background-color: #2eadfe; + border-radius: 25px; + opacity:0.5; + border: 1px groove black; +} + +.scores>p { + color: #FFFFFF; + font-size: 1.7rem; + font-weight: 600; + padding: 0.5rem; + margin: 0; +} + +#reset-button { + border-radius: 10px; + display: inline-block; + cursor: pointer; + color: #000000; + font-size: 0.8rem; + font-weight: 600; + padding: 0.5vh 0.5vw; + text-decoration: none; + margin: .2rem; + outline: none; +} + +#reset-button:active { + position: relative; + top: 1px; +} + +footer { + font-size: 0.7rem; + line-height: 0.3rem; + padding-top: 2vh; +} + +.fab { + color: #000000; + margin: 0 .5%; +} diff --git a/space-drifter/LICENSE b/space-drifter/LICENSE new file mode 100644 index 0000000..6861266 --- /dev/null +++ b/space-drifter/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Bence A. TΓ³th + +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: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. diff --git a/space-drifter/README.md b/space-drifter/README.md new file mode 100644 index 0000000..dfd3938 --- /dev/null +++ b/space-drifter/README.md @@ -0,0 +1,13 @@ +# Space Drifter :rocket: + +A pretty darn difficult asteroid shooter game with realistic inertia and unconventional controls. + +## Play the game + +You can [play the game here](https://bence-toth.github.io/space-drifter/). + +Have fun! + +## License + +[MIT](LICENSE). Do what you will. diff --git a/space-drifter/assets/asteroid-big.svg b/space-drifter/assets/asteroid-big.svg new file mode 100644 index 0000000..9e5a194 --- /dev/null +++ b/space-drifter/assets/asteroid-big.svg @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/space-drifter/assets/asteroid-medium.svg b/space-drifter/assets/asteroid-medium.svg new file mode 100644 index 0000000..eb74945 --- /dev/null +++ b/space-drifter/assets/asteroid-medium.svg @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/space-drifter/assets/asteroid-small.svg b/space-drifter/assets/asteroid-small.svg new file mode 100644 index 0000000..3d66e9f --- /dev/null +++ b/space-drifter/assets/asteroid-small.svg @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/space-drifter/assets/space-drifter-cover.jpg b/space-drifter/assets/space-drifter-cover.jpg new file mode 100644 index 0000000..7405d51 Binary files /dev/null and b/space-drifter/assets/space-drifter-cover.jpg differ diff --git a/space-drifter/assets/stars.png b/space-drifter/assets/stars.png new file mode 100644 index 0000000..fac54bd Binary files /dev/null and b/space-drifter/assets/stars.png differ diff --git a/space-drifter/assets/starship.svg b/space-drifter/assets/starship.svg new file mode 100644 index 0000000..b0048f0 --- /dev/null +++ b/space-drifter/assets/starship.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/space-drifter/assets/torpedo.svg b/space-drifter/assets/torpedo.svg new file mode 100644 index 0000000..3506fd0 --- /dev/null +++ b/space-drifter/assets/torpedo.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/space-drifter/game.js b/space-drifter/game.js new file mode 100644 index 0000000..521ec79 --- /dev/null +++ b/space-drifter/game.js @@ -0,0 +1,964 @@ +// Parameters +const rotationSpeedChange = 0.1; +const movementSpeedChange = 0.01; +const torpedoLaunchSpeed = 3; +const asteroidSpeedCoefficient = 1.5; +const updateFrequency = 1000 / 60; +const dangerousTorpedoTimeout = 1000; +const explosionDuration = 1000; +const explosionMaxRadius = 100; +const explosionMaxWidth = 20; + +let score = 0; + +let isGameRunning = false; +let isGamePaused = false; +let gameOver = false; + +const canvas = document.getElementById("game-canvas"); +const ctx = canvas.getContext("2d"); +ctx.canvas.width = 1920; +ctx.canvas.height = 1080; + +const getDegToRad = (degrees) => degrees * (Math.PI / 180); + +const getRadToDeg = (radians) => radians * (180 / Math.PI); + +const getDistance = ( + { position: { x: x1, y: y1 } }, + { position: { x: x2, y: y2 } } +) => ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5; + +const getRandomDirection = () => Math.random() * 360; + +const getRandomAsteroidPosition = (starship) => { + const distanceFromStarship = ctx.canvas.height / 2; + const randomDirection = getRandomDirection(); + let x = + starship.position.x + + Math.cos(getDegToRad(randomDirection)) * distanceFromStarship; + let y = + starship.position.y + + Math.sin(getDegToRad(randomDirection)) * distanceFromStarship; + if (x < 0) { + x += ctx.canvas.width; + } + if (x > ctx.canvas.width) { + x -= ctx.canvas.width; + } + if (y < 0) { + y += ctx.canvas.height; + } + if (y > ctx.canvas.height) { + y -= ctx.canvas.height; + } + return { x, y }; +}; + +let starship; +let torpedoes; +let asteroids; +let explosions; + +const starshipImage = new Image(); +starshipImage.src = "./assets/starship.svg"; + +const torpedoImage = new Image(); +torpedoImage.src = "./assets/torpedo.svg"; + +const asteroidBigImage = new Image(); +asteroidBigImage.src = "./assets/asteroid-big.svg"; + +const asteroidMediumImage = new Image(); +asteroidMediumImage.src = "./assets/asteroid-medium.svg"; + +const asteroidSmallImage = new Image(); +asteroidSmallImage.src = "./assets/asteroid-small.svg"; + +const draw = () => { + // Clear the canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + // Draw the starship + if (!starship.exploded) { + ctx.save(); + ctx.translate(starship.position.x, starship.position.y); + ctx.rotate(-1 * getDegToRad(starship.rotation - 90)); + ctx.translate(-starship.position.x, -starship.position.y); + ctx.drawImage( + starshipImage, + starship.position.x - starshipImage.naturalWidth / 2, + starship.position.y - starshipImage.naturalHeight / 2, + starshipImage.naturalWidth, + starshipImage.naturalHeight + ); + ctx.restore(); + + // Left edge + if (starship.position.x <= starshipImage.naturalWidth) { + ctx.save(); + ctx.translate( + starship.position.x + ctx.canvas.width, + starship.position.y + ); + ctx.rotate(-1 * getDegToRad(starship.rotation - 90)); + ctx.translate(-starship.position.x, -starship.position.y); + ctx.drawImage( + starshipImage, + starship.position.x - starshipImage.naturalWidth / 2, + starship.position.y - starshipImage.naturalHeight / 2, + starshipImage.naturalWidth, + starshipImage.naturalHeight + ); + ctx.restore(); + } + + // Right edge + if (starship.position.x >= ctx.canvas.width - starshipImage.naturalWidth) { + ctx.save(); + ctx.translate( + starship.position.x - ctx.canvas.width, + starship.position.y + ); + ctx.rotate(-1 * getDegToRad(starship.rotation - 90)); + ctx.translate(-starship.position.x, -starship.position.y); + ctx.drawImage( + starshipImage, + starship.position.x - starshipImage.naturalWidth / 2, + starship.position.y - starshipImage.naturalHeight / 2, + starshipImage.naturalWidth, + starshipImage.naturalHeight + ); + ctx.restore(); + } + + // Top edge + if (starship.position.y <= starshipImage.naturalHeight) { + ctx.save(); + ctx.translate( + starship.position.x, + starship.position.y + ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(starship.rotation - 90)); + ctx.translate(-starship.position.x, -starship.position.y); + ctx.drawImage( + starshipImage, + starship.position.x - starshipImage.naturalWidth / 2, + starship.position.y - starshipImage.naturalHeight / 2, + starshipImage.naturalWidth, + starshipImage.naturalHeight + ); + ctx.restore(); + } + + // Bottom edge + if ( + starship.position.y >= + ctx.canvas.height - starshipImage.naturalHeight + ) { + ctx.save(); + ctx.translate( + starship.position.x, + starship.position.y - ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(starship.rotation - 90)); + ctx.translate(-starship.position.x, -starship.position.y); + ctx.drawImage( + starshipImage, + starship.position.x - starshipImage.naturalWidth / 2, + starship.position.y - starshipImage.naturalHeight / 2, + starshipImage.naturalWidth, + starshipImage.naturalHeight + ); + ctx.restore(); + } + + // Top left corner + if ( + starship.position.x <= starshipImage.naturalWidth && + starship.position.y <= starshipImage.naturalHeight + ) { + ctx.save(); + ctx.translate( + starship.position.x + ctx.canvas.width, + starship.position.y + ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(starship.rotation - 90)); + ctx.translate(-starship.position.x, -starship.position.y); + ctx.drawImage( + starshipImage, + starship.position.x - starshipImage.naturalWidth / 2, + starship.position.y - starshipImage.naturalHeight / 2, + starshipImage.naturalWidth, + starshipImage.naturalHeight + ); + ctx.restore(); + } + + // Bottom left corner + if ( + starship.position.x <= starshipImage.naturalWidth && + starship.position.y >= ctx.canvas.height - starshipImage.naturalHeight + ) { + ctx.save(); + ctx.translate( + starship.position.x + ctx.canvas.width, + starship.position.y - ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(starship.rotation - 90)); + ctx.translate(-starship.position.x, -starship.position.y); + ctx.drawImage( + starshipImage, + starship.position.x - starshipImage.naturalWidth / 2, + starship.position.y - starshipImage.naturalHeight / 2, + starshipImage.naturalWidth, + starshipImage.naturalHeight + ); + ctx.restore(); + } + + // Top right corner + if ( + starship.position.x >= ctx.canvas.width - starshipImage.naturalWidth && + starship.position.y <= starshipImage.naturalHeight + ) { + ctx.save(); + ctx.translate( + starship.position.x - ctx.canvas.width, + starship.position.y + ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(starship.rotation - 90)); + ctx.translate(-starship.position.x, -starship.position.y); + ctx.drawImage( + starshipImage, + starship.position.x - starshipImage.naturalWidth / 2, + starship.position.y - starshipImage.naturalHeight / 2, + starshipImage.naturalWidth, + starshipImage.naturalHeight + ); + ctx.restore(); + } + + // Bottom right corner + if ( + starship.position.y >= ctx.canvas.height - starshipImage.naturalHeight && + starship.position.x >= ctx.canvas.width - starshipImage.naturalWidth + ) { + ctx.save(); + ctx.translate( + starship.position.x - ctx.canvas.width, + starship.position.y - ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(starship.rotation - 90)); + ctx.translate(-starship.position.x, -starship.position.y); + ctx.drawImage( + starshipImage, + starship.position.x - starshipImage.naturalWidth / 2, + starship.position.y - starshipImage.naturalHeight / 2, + starshipImage.naturalWidth, + starshipImage.naturalHeight + ); + ctx.restore(); + } + } + + // Draw the torpedoes + torpedoes.forEach((torpedo) => { + ctx.drawImage( + torpedoImage, + torpedo.position.x - torpedoImage.naturalWidth / 2, + torpedo.position.y - torpedoImage.naturalHeight / 2, + torpedoImage.naturalWidth, + torpedoImage.naturalHeight + ); + }); + + // Draw the asteroids + asteroids.forEach((asteroid) => { + let asteroidImage; + if (asteroid.size === 2) { + asteroidImage = asteroidBigImage; + } + if (asteroid.size === 1) { + asteroidImage = asteroidMediumImage; + } + if (asteroid.size === 0) { + asteroidImage = asteroidSmallImage; + } + ctx.save(); + ctx.translate(asteroid.position.x, asteroid.position.y); + ctx.rotate(-1 * getDegToRad(asteroid.rotation - 90)); + ctx.translate(-asteroid.position.x, -asteroid.position.y); + ctx.drawImage( + asteroidImage, + asteroid.position.x - asteroidImage.naturalWidth / 2, + asteroid.position.y - asteroidImage.naturalHeight / 2, + asteroidImage.naturalWidth, + asteroidImage.naturalHeight + ); + ctx.restore(); + + // Left edge + if (asteroid.position.x <= asteroidImage.naturalWidth) { + ctx.save(); + ctx.translate( + asteroid.position.x + ctx.canvas.width, + asteroid.position.y + ); + ctx.rotate(-1 * getDegToRad(asteroid.rotation - 90)); + ctx.translate(-asteroid.position.x, -asteroid.position.y); + ctx.drawImage( + asteroidImage, + asteroid.position.x - asteroidImage.naturalWidth / 2, + asteroid.position.y - asteroidImage.naturalHeight / 2, + asteroidImage.naturalWidth, + asteroidImage.naturalHeight + ); + ctx.restore(); + } + + // Right edge + if (asteroid.position.x >= ctx.canvas.width - asteroidImage.naturalWidth) { + ctx.save(); + ctx.translate( + asteroid.position.x - ctx.canvas.width, + asteroid.position.y + ); + ctx.rotate(-1 * getDegToRad(asteroid.rotation - 90)); + ctx.translate(-asteroid.position.x, -asteroid.position.y); + ctx.drawImage( + asteroidImage, + asteroid.position.x - asteroidImage.naturalWidth / 2, + asteroid.position.y - asteroidImage.naturalHeight / 2, + asteroidImage.naturalWidth, + asteroidImage.naturalHeight + ); + ctx.restore(); + } + + // Top edge + if (asteroid.position.y <= asteroidImage.naturalHeight) { + ctx.save(); + ctx.translate( + asteroid.position.x, + asteroid.position.y + ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(asteroid.rotation - 90)); + ctx.translate(-asteroid.position.x, -asteroid.position.y); + ctx.drawImage( + asteroidImage, + asteroid.position.x - asteroidImage.naturalWidth / 2, + asteroid.position.y - asteroidImage.naturalHeight / 2, + asteroidImage.naturalWidth, + asteroidImage.naturalHeight + ); + ctx.restore(); + } + + // Bottom edge + if ( + asteroid.position.y >= + ctx.canvas.height - asteroidImage.naturalHeight + ) { + ctx.save(); + ctx.translate( + asteroid.position.x, + asteroid.position.y - ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(asteroid.rotation - 90)); + ctx.translate(-asteroid.position.x, -asteroid.position.y); + ctx.drawImage( + asteroidImage, + asteroid.position.x - asteroidImage.naturalWidth / 2, + asteroid.position.y - asteroidImage.naturalHeight / 2, + asteroidImage.naturalWidth, + asteroidImage.naturalHeight + ); + ctx.restore(); + } + + // Top left corner + if ( + asteroid.position.x <= asteroidImage.naturalWidth && + asteroid.position.y <= asteroidImage.naturalHeight + ) { + ctx.save(); + ctx.translate( + asteroid.position.x + ctx.canvas.width, + asteroid.position.y + ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(asteroid.rotation - 90)); + ctx.translate(-asteroid.position.x, -asteroid.position.y); + ctx.drawImage( + asteroidImage, + asteroid.position.x - asteroidImage.naturalWidth / 2, + asteroid.position.y - asteroidImage.naturalHeight / 2, + asteroidImage.naturalWidth, + asteroidImage.naturalHeight + ); + ctx.restore(); + } + + // Bottom left corner + if ( + asteroid.position.x <= asteroidImage.naturalWidth && + asteroid.position.y >= ctx.canvas.height - asteroidImage.naturalHeight + ) { + ctx.save(); + ctx.translate( + asteroid.position.x + ctx.canvas.width, + asteroid.position.y - ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(asteroid.rotation - 90)); + ctx.translate(-asteroid.position.x, -asteroid.position.y); + ctx.drawImage( + asteroidImage, + asteroid.position.x - asteroidImage.naturalWidth / 2, + asteroid.position.y - asteroidImage.naturalHeight / 2, + asteroidImage.naturalWidth, + asteroidImage.naturalHeight + ); + ctx.restore(); + } + + // Top right corner + if ( + asteroid.position.x >= ctx.canvas.width - asteroidImage.naturalWidth && + asteroid.position.y <= asteroidImage.naturalHeight + ) { + ctx.save(); + ctx.translate( + asteroid.position.x - ctx.canvas.width, + asteroid.position.y + ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(asteroid.rotation - 90)); + ctx.translate(-asteroid.position.x, -asteroid.position.y); + ctx.drawImage( + asteroidImage, + asteroid.position.x - asteroidImage.naturalWidth / 2, + asteroid.position.y - asteroidImage.naturalHeight / 2, + asteroidImage.naturalWidth, + asteroidImage.naturalHeight + ); + ctx.restore(); + } + + // Bottom right corner + if ( + asteroid.position.x >= ctx.canvas.width - asteroidImage.naturalWidth && + asteroid.position.y >= ctx.canvas.height - asteroidImage.naturalHeight + ) { + ctx.save(); + ctx.translate( + asteroid.position.x - ctx.canvas.width, + asteroid.position.y - ctx.canvas.height + ); + ctx.rotate(-1 * getDegToRad(asteroid.rotation - 90)); + ctx.translate(-asteroid.position.x, -asteroid.position.y); + ctx.drawImage( + asteroidImage, + asteroid.position.x - asteroidImage.naturalWidth / 2, + asteroid.position.y - asteroidImage.naturalHeight / 2, + asteroidImage.naturalWidth, + asteroidImage.naturalHeight + ); + ctx.restore(); + } + }); + + // Draw the explosions + const now = Date.now(); + explosions.forEach((explosion) => { + const explosionProgress = (now - explosion.startedAt) / explosionDuration; + const explosionRadius = + torpedoImage.naturalWidth + explosionProgress * explosionMaxRadius; + ctx.beginPath(); + ctx.arc( + explosion.position.x, + explosion.position.y, + explosionRadius, + 0, + 2 * Math.PI + ); + ctx.strokeStyle = `hsla(0, 0%, 100%, ${Math.max( + 0.75 * 1 - explosionProgress, + 0 + )})`; + ctx.lineWidth = 1 + explosionProgress * explosionMaxWidth; + ctx.stroke(); + }); + + // Request next frame + if (isGameRunning && !isGamePaused) { + requestAnimationFrame(draw); + } +}; + +let rotationMomentumChangeInterval = null; +let forwardSpeedChangeInterval = null; + +const fireTorpedo = () => { + starship.canFire = false; + setTimeout(() => { + starship.canFire = true; + }, 500); + const moveVector = { + x: + (Math.cos(getDegToRad(starship.rotation)) || 0) * + (starship.forwardSpeed + torpedoLaunchSpeed), + y: + (Math.sin(getDegToRad(starship.rotation)) || 0) * + (starship.forwardSpeed + torpedoLaunchSpeed), + }; + const driftVector = { + x: + (Math.cos(getDegToRad(starship.driftDirection)) || 0) * + starship.driftSpeed, + y: + (Math.sin(getDegToRad(starship.driftDirection)) || 0) * + starship.driftSpeed, + }; + const deltaXDrift = driftVector.x + moveVector.x; + const deltaYDrift = driftVector.y + moveVector.y; + let direction; + if (starship.driftSpeed === 0) { + direction = starship.rotation; + } else { + direction = + getRadToDeg(Math.atan(deltaYDrift / deltaXDrift || 0)) + + (deltaXDrift < 0 ? 180 : 0); + } + const speed = (deltaXDrift ** 2 + deltaYDrift ** 2) ** 0.5; + torpedoes.push({ + position: { + x: starship.position.x, + y: starship.position.y, + }, + direction, + speed, + detonated: false, + launchedAt: Date.now(), + }); +}; + +window.addEventListener("keydown", (event) => { + if (!isGameRunning) { + return; + } + if (event.key === "p" || event.key === "P") { + if (isGamePaused) { + document.getElementById("paused").classList.add("hidden"); + isGamePaused = false; + clock = setInterval(tick, updateFrequency); + requestAnimationFrame(draw); + } else { + if (gameOver) { + return; + } + document.getElementById("paused").classList.remove("hidden"); + isGamePaused = true; + clearInterval(clock); + } + } + if (isGamePaused) { + return; + } + if (event.key === "ArrowLeft" || event.key === "a" || event.key === "A") { + starship.rotationMomentum += rotationSpeedChange; + clearInterval(rotationMomentumChangeInterval); + rotationMomentumChangeInterval = setInterval(() => { + starship.rotationMomentum += rotationSpeedChange; + }, 50); + } + if (event.key === "ArrowRight" || event.key === "d" || event.key === "D") { + starship.rotationMomentum -= rotationSpeedChange; + clearInterval(rotationMomentumChangeInterval); + rotationMomentumChangeInterval = setInterval(() => { + starship.rotationMomentum -= rotationSpeedChange; + }, 50); + } + if (event.key === "ArrowUp" || event.key === "w" || event.key === "W") { + if (starship.forwardSpeed < 0) { + starship.forwardSpeed = 0; + } + starship.forwardSpeed += movementSpeedChange; + clearInterval(forwardSpeedChangeInterval); + forwardSpeedChangeInterval = setInterval(() => { + starship.forwardSpeed += movementSpeedChange; + }, 50); + } + if (event.key === "ArrowDown" || event.key === "s" || event.key === "S") { + if (starship.forwardSpeed > 0) { + starship.forwardSpeed = 0; + } + starship.forwardSpeed -= movementSpeedChange; + clearInterval(forwardSpeedChangeInterval); + forwardSpeedChangeInterval = setInterval(() => { + starship.forwardSpeed -= movementSpeedChange; + }, 50); + } + if (event.key === " " && starship.canFire) { + fireTorpedo(); + } +}); + +document.addEventListener("click", () => { + if (!isGameRunning) { + return; + } + if (starship.canFire) { + fireTorpedo(); + } +}); + +window.addEventListener("keyup", (event) => { + if (!isGameRunning) { + return; + } + if (event.key === "ArrowLeft" || event.key === "a" || event.key === "A") { + clearInterval(rotationMomentumChangeInterval); + } + if (event.key === "ArrowRight" || event.key === "d" || event.key === "D") { + clearInterval(rotationMomentumChangeInterval); + } + if (event.key === "ArrowUp" || event.key === "w" || event.key === "W") { + clearInterval(forwardSpeedChangeInterval); + starship.forwardSpeed = 0; + } + if (event.key === "ArrowDown" || event.key === "s" || event.key === "S") { + clearInterval(forwardSpeedChangeInterval); + starship.forwardSpeed = 0; + } +}); + +const tick = () => { + // Move starship + starship.rotation += starship.rotationMomentum; + const moveVector = { + x: (Math.cos(getDegToRad(starship.rotation)) || 0) * starship.forwardSpeed, + y: (Math.sin(getDegToRad(starship.rotation)) || 0) * starship.forwardSpeed, + }; + const driftVector = { + x: + (Math.cos(getDegToRad(starship.driftDirection)) || 0) * + starship.driftSpeed, + y: + (Math.sin(getDegToRad(starship.driftDirection)) || 0) * + starship.driftSpeed, + }; + const deltaXDrift = driftVector.x + moveVector.x; + const deltaYDrift = driftVector.y + moveVector.y; + if (starship.driftSpeed === 0) { + starship.driftDirection = starship.rotation; + } else { + starship.driftDirection = + getRadToDeg(Math.atan(deltaYDrift / deltaXDrift || 0)) + + (deltaXDrift < 0 ? 180 : 0); + } + starship.driftSpeed = (deltaXDrift ** 2 + deltaYDrift ** 2) ** 0.5; + starship.position.x += + starship.driftSpeed * Math.cos(getDegToRad(starship.driftDirection)) || 0; + if (starship.position.x < 0) { + starship.position.x += ctx.canvas.width; + } + if (starship.position.x > ctx.canvas.width) { + starship.position.x -= ctx.canvas.width; + } + starship.position.y -= + starship.driftSpeed * Math.sin(getDegToRad(starship.driftDirection)) || 0; + if (starship.position.y < 0) { + starship.position.y += ctx.canvas.height; + } + if (starship.position.y > ctx.canvas.height) { + starship.position.y -= ctx.canvas.height; + } + + // Move torpedoes + torpedoes.forEach((torpedo) => { + torpedo.position.x += + torpedo.speed * Math.cos(getDegToRad(torpedo.direction)) || 0; + if (torpedo.position.x < 0) { + torpedo.position.x += ctx.canvas.width; + } + if (torpedo.position.x > ctx.canvas.width) { + torpedo.position.x -= ctx.canvas.width; + } + torpedo.position.y -= + torpedo.speed * Math.sin(getDegToRad(torpedo.direction)) || 0; + if (torpedo.position.y < 0) { + torpedo.position.y += ctx.canvas.height; + } + if (torpedo.position.y > ctx.canvas.height) { + torpedo.position.y -= ctx.canvas.height; + } + }); + + // Move asteroids + asteroids.forEach((asteroid) => { + const asteroidSpeed = (3 - asteroid.size) * asteroidSpeedCoefficient; + const deltaPosition = { + x: asteroidSpeed * Math.cos(getDegToRad(asteroid.direction)) || 0, + y: asteroidSpeed * Math.sin(getDegToRad(asteroid.direction)) || 0, + }; + asteroid.position.x += deltaPosition.x; + if (asteroid.position.x < 0) { + asteroid.position.x += ctx.canvas.width; + } + if (asteroid.position.x > ctx.canvas.width) { + asteroid.position.x -= ctx.canvas.width; + } + asteroid.position.y -= deltaPosition.y; + if (asteroid.position.y < 0) { + asteroid.position.y += ctx.canvas.height; + } + if (asteroid.position.y > ctx.canvas.height) { + asteroid.position.y -= ctx.canvas.height; + } + asteroid.rotation += asteroidSpeed; + if (asteroid.rotation > 360) { + asteroid.rotation -= 360; + } + }); + + const now = Date.now(); + + // Detect torpedo collisions + torpedoes.forEach((torpedo, torpedoIndex) => { + // Torpedo hitting asteroid + asteroids.forEach((asteroid) => { + let asteroidImage; + if (asteroid.size === 2) { + asteroidImage = asteroidBigImage; + } + if (asteroid.size === 1) { + asteroidImage = asteroidMediumImage; + } + if (asteroid.size === 0) { + asteroidImage = asteroidSmallImage; + } + if (getDistance(torpedo, asteroid) <= asteroidImage.naturalWidth / 2) { + torpedo.detonated = true; + asteroid.exploded = true; + explosions.push({ + position: { + x: torpedo.position.x, + y: torpedo.position.y, + }, + startedAt: now, + }); + if (!starship.exploded) { + score++; + } + document.getElementById("score").innerHTML = score; + } + }); + + // Torpedo hitting another torpedo + torpedoes.forEach((otherTorpedo, otherTorpedoIndex) => { + if (torpedoIndex !== otherTorpedoIndex) { + if ( + getDistance(torpedo, otherTorpedo) <= + torpedoImage.naturalWidth / 2 + ) { + torpedo.detonated = true; + otherTorpedo.detonated = true; + explosions.push({ + position: { + x: torpedo.position.x, + y: torpedo.position.y, + }, + startedAt: now, + }); + explosions.push({ + position: { + x: otherTorpedo.position.x, + y: otherTorpedo.position.y, + }, + startedAt: now, + }); + } + } + }); + + // Torpedo hitting starship + if ( + !torpedo.detonated && + !starship.exploded && + now - torpedo.launchedAt > dangerousTorpedoTimeout + ) { + if (getDistance(torpedo, starship) <= starshipImage.naturalWidth / 2) { + starship.exploded = true; + torpedo.detonated = true; + explosions.push({ + position: { + x: starship.position.x, + y: starship.position.y, + }, + startedAt: now, + }); + } + } + }); + + asteroids.forEach((asteroid) => { + if (!asteroid.exploded && !starship.exploded) { + // Asteroid hitting starship + let asteroidImage; + if (asteroid.size === 2) { + asteroidImage = asteroidBigImage; + } + if (asteroid.size === 1) { + asteroidImage = asteroidMediumImage; + } + if (asteroid.size === 0) { + asteroidImage = asteroidSmallImage; + } + if ( + getDistance(asteroid, starship) <= + asteroidImage.naturalWidth / 2 + starshipImage.naturalWidth / 2 + ) { + starship.exploded = true; + explosions.push({ + position: { + x: starship.position.x, + y: starship.position.y, + }, + startedAt: now, + }); + } + } + }); + + // Get rid of detonated torpedoes + torpedoes = torpedoes.filter((torpedo) => !torpedo.detonated); + + // Get rid of invisible explosions + explosions = explosions.filter( + (explosion) => now - explosion.startedAt <= explosionDuration + ); + + asteroids = asteroids + .map((asteroid) => { + if (!asteroid.exploded) { + return asteroid; + } + + // Remove exploded small asteroids + if (asteroid.size === 0) { + return []; + } + + // Split exploded asteroids + return [ + { + size: asteroid.size - 1, + position: { x: asteroid.position.x, y: asteroid.position.y }, + direction: getRandomDirection(), + rotation: getRandomDirection(), + exploded: false, + }, + { + size: asteroid.size - 1, + position: { x: asteroid.position.x, y: asteroid.position.y }, + direction: getRandomDirection(), + rotation: getRandomDirection(), + exploded: false, + }, + ]; + }) + .flat(); + + // Create new asteroid if the last one has exploded + if (asteroids.length === 0) { + asteroids = [ + { + size: 2, + position: getRandomAsteroidPosition(starship), + direction: getRandomDirection(), + rotation: getRandomDirection(), + exploded: false, + }, + ]; + } + + // Game over when starship has exploded + if (starship.exploded && !gameOver) { + gameOver = true; + clearInterval(rotationMomentumChangeInterval); + clearInterval(rotationMomentumChangeInterval); + clearInterval(forwardSpeedChangeInterval); + clearInterval(forwardSpeedChangeInterval); + setTimeout(() => { + isGameRunning = false; + clearInterval(clock); + document.getElementById("gameOver").classList.remove("hidden"); + document.getElementById("finalScore").innerHTML = score; + document.getElementById("restart").tabIndex = 0; + document.getElementById("restart").focus(); + }, explosionDuration * 2); + } +}; + +const startGame = () => { + // Hide splash screen + document.getElementById("splash").classList.add("hidden"); + document.getElementById("start").tabIndex = -1; + document.getElementById("start").blur(); + document.getElementById("gameOver").classList.add("hidden"); + document.getElementById("restart").tabIndex = -1; + document.getElementById("restart").blur(); + + // Reset score + score = 0; + document.getElementById("score").innerHTML = "0"; + + // Reset ship + starship = { + position: { + x: ctx.canvas.width / 2, + y: ctx.canvas.height / 2, + }, + rotation: 90, + driftDirection: 0, + driftSpeed: 0, + rotationMomentum: 0, + forwardSpeed: 0, + canFire: true, + exploded: false, + }; + + // Reset torpedoes + torpedoes = []; + + // Reset asteroids + asteroids = [ + { + size: 2, + position: getRandomAsteroidPosition(starship), + direction: getRandomDirection(), + rotation: getRandomDirection(), + exploded: false, + }, + ]; + explosions = []; + + // Start clock + isGameRunning = true; + isGamePaused = false; + gameOver = false; + clock = setInterval(tick, updateFrequency); + requestAnimationFrame(draw); +}; + +// Set up splash screen +document.getElementById("start").focus(); +document.getElementById("start").addEventListener("click", (event) => { + event.stopPropagation(); + startGame(); +}); + +// Set up game over screen +document.getElementById("restart").addEventListener("click", (event) => { + event.stopPropagation(); + startGame(); +}); diff --git a/space-drifter/index.html b/space-drifter/index.html new file mode 100644 index 0000000..529c025 --- /dev/null +++ b/space-drifter/index.html @@ -0,0 +1,112 @@ + + + + + + + Space Drifter + + + + + + + + + + + + + + + +
+
+

Space Drifter

+ +
+

Controls

+
+
Fire thrusters
+
+
+ W + A + S + D +
+
+ ↑ + ← + ↓ + β†’ +
+
+
Launch torpedo
+
+ Space + Mouse click +
+
Pause/Resume
+
+ P +
+
+
+ +
+
+ + +
+ +
0
+
+ + + diff --git a/space-drifter/styles.css b/space-drifter/styles.css new file mode 100644 index 0000000..ffa6a32 --- /dev/null +++ b/space-drifter/styles.css @@ -0,0 +1,297 @@ +@import url("https://fonts.googleapis.com/css2?family=Audiowide&display=swap"); + +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: "Audiowide", serif; + line-height: 1; +} + +html, +body { + width: 100%; + height: 100%; +} + +body { + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + background-color: hsl(0, 0%, 5%); + color: hsl(0, 0%, 95%); + user-select: none; +} + +.canvasWrapper { + max-width: 95%; + max-height: 95%; + aspect-ratio: 16 / 9; + border: 2px solid hsl(0, 0%, 10%); + background-color: black; + position: relative; + display: flex; + background-image: url(assets/stars.png); + background-position: center center; + background-size: 50vmin; +} + +canvas { + width: 100%; + height: 100%; +} + +#score { + position: absolute; + top: 0; + right: 0; + color: white; + padding: 1.5vmin; + font-size: 3vmin; + line-height: 1; +} + +#splash, +#gameOver, +#paused { + position: fixed; + width: 100%; + height: 100%; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + background-image: url(assets/stars.png); + background-position: center center; + background-size: 50vmin; + z-index: 1; + transition: opacity 0.5s; +} + +#splash.hidden, +#gameOver.hidden, +#paused.hidden { + opacity: 0; + pointer-events: none; +} + +.innerWrapper { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 3vmin; +} + +#splash h1, +#gameOver h2, +#paused h2 { + font-size: 10vmin; +} + +#paused h2 { + animation: twinkle 2s linear infinite; +} + +@keyframes twinkle { + from { + opacity: 1; + } + 45% { + opacity: 0.3333; + } + 90% { + opacity: 1; + } + to { + opacity: 1; + } +} + +#gameOver h3 { + font-size: 3vmin; +} + +#paused p { + font-size: 3vmin; +} + +button { + padding: 1.5vmin; + background-color: transparent; + color: inherit; + font-size: 1.5vmin; + outline: 0; + border: 2px solid hsl(0, 0%, 25%); + cursor: pointer; + position: relative; + margin-top: 1em; +} + +button span { + opacity: 0.5; + transition: opacity 0.5s; + text-transform: uppercase; +} + +button .line { + position: absolute; + background-color: white; + transition: transform 1s; +} + +button .top, +button .bottom { + width: calc(100% + 4px); + height: 2px; + transform: scaleX(0); +} + +button .left, +button .right { + width: 2px; + height: calc(100% + 4px); + transform: scaleY(0); +} + +button .top { + top: -2px; + left: -2px; + transform-origin: left; +} + +button .bottom { + bottom: -2px; + right: -2px; + transform-origin: right; +} + +button .left { + left: -2px; + bottom: -2px; + transform-origin: bottom; +} + +button .right { + right: -2px; + top: -2px; + transform-origin: top; +} + +button:is(:hover, :focus, :active) .top, +button:is(:hover, :focus, :active) .bottom { + transform: scaleX(1); +} + +button:is(:hover, :focus, :active) .left, +button:is(:hover, :focus, :active) .right { + transform: scaleY(1); +} + +button:is(:hover, :focus, :active) span { + opacity: 1; +} + +button:is(:hover, :focus, :active) span, +button:is(:hover, :focus, :active) .line { + transition-delay: 0.25s; +} + +.controls { + margin-top: 5vmin; + border: 1px solid hsl(0, 0%, 50%); + background-color: hsl(0, 0%, 7.5%); + padding: 2vmin 4vmin 3vmin; +} + +.controls h3 { + margin-bottom: 3vmin; + text-align: center; + font-size: 3vmin; +} + +dl { + display: grid; + grid-template-columns: 1fr auto; + font-size: 2vmin; + gap: 3vmin 1.5vmin; +} + +dt, +dd { + display: flex; + align-items: center; + gap: 1.5vmin; +} + +dt { + justify-content: flex-start; +} + +dd { + justify-content: center; +} + +.wasd { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-template-rows: 1fr 1fr; + gap: 0.5vmin; + grid-template-areas: + ". w ." + "a s d"; +} + +.wasd kbd:nth-child(1) { + grid-area: w; +} + +.wasd kbd:nth-child(2) { + grid-area: a; +} + +.wasd kbd:nth-child(3) { + grid-area: s; +} + +.wasd kbd:nth-child(4) { + grid-area: d; +} + +kbd { + display: inline-block; + vertical-align: middle; + white-space: nowrap; + line-height: 1; + padding: 0.2em 0.4em; + font-size: 0.9em; + color: hsl(0, 0%, 20%); + background-color: hsl(0, 0%, 90%); + border: 1px solid hsl(0, 0%, 80%); + border-radius: 0.25em; + box-shadow: 0 0.05em 0 hsla(0, 0%, 0%, 20%), + 0 0.1em 0 hsla(0, 0%, 100%, 50%) inset; +} + +#splash footer { + position: absolute; + bottom: 0; + left: 0; + right: 0; + text-align: center; + padding: 2vmin; + color: hsl(0, 0%, 60%); +} + +a { + color: inherit; + outline: 0; + transition: color 0.5s; +} + +a:hover, +a:active, +a:focus { + color: hsl(0, 0%, 100%); +} diff --git a/storage/bg1.jpg b/storage/bg1.jpg new file mode 100644 index 0000000..b85d533 Binary files /dev/null and b/storage/bg1.jpg differ diff --git a/storage/car.png b/storage/car.png new file mode 100644 index 0000000..71d7d5f Binary files /dev/null and b/storage/car.png differ diff --git a/storage/flappybird.png b/storage/flappybird.png new file mode 100644 index 0000000..d6f7068 Binary files /dev/null and b/storage/flappybird.png differ diff --git a/storage/o.png b/storage/o.png new file mode 100644 index 0000000..8fb671f Binary files /dev/null and b/storage/o.png differ diff --git a/storage/paper1.png b/storage/paper1.png new file mode 100644 index 0000000..52a46fd Binary files /dev/null and b/storage/paper1.png differ diff --git a/storage/rock1.png b/storage/rock1.png new file mode 100644 index 0000000..c229e43 Binary files /dev/null and b/storage/rock1.png differ diff --git a/storage/scissor1.png b/storage/scissor1.png new file mode 100644 index 0000000..2396f09 Binary files /dev/null and b/storage/scissor1.png differ diff --git a/storage/starship.svg b/storage/starship.svg new file mode 100644 index 0000000..5dd464e --- /dev/null +++ b/storage/starship.svg @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + diff --git a/storage/x.png b/storage/x.png new file mode 100644 index 0000000..a4fd800 Binary files /dev/null and b/storage/x.png differ diff --git a/style.css b/style.css new file mode 100644 index 0000000..35249ad --- /dev/null +++ b/style.css @@ -0,0 +1,73 @@ +body { + font-family: 'Arial', sans-serif; + margin: 0; + padding: 0; +} + +header { + background-color: #ff99cc; /* Light pink background */ + color: #00CBF6; /* Light blue text */ + text-align: center; + padding: 1em; + position: relative; +} + +nav { + background-color: #ff99cc; /* Light pink background */ + color: #00CBF6; /* Light blue text */ + padding: 0.5em; +} + +nav ul { + list-style: none; + margin: 0; + padding: 0; +} + +nav ul li { + display: inline; + margin-right: 10px; +} + +nav a { + text-decoration: none; + color: #00CBF6; /* Light blue text */ +} + +main { + padding: 20px; +} + +.game { + border: 1px solid #ff99cc; /* Light pink border */ + background-color: #ACE9F6; /* Light blue background */ + padding: 20px; + margin-bottom: 20px; +} + +.game img { + max-width: 100%; +} + +footer { + background-color: #ff99cc; /* Light pink background */ + color: #00CBF6; /* Light blue text */ + text-align: center; + padding: 1em; + position: fixed; + bottom: 0; + width: 100%; +} + +/* Girly font for headings and paragraphs */ +h1, h2, p { + font-family: 'Pacifico', cursive; +} + +.popcorn { + max-width: 6rem; +} + +.game-video { + max-width: 100%; +} diff --git a/tik-tak-toe/img/bg.jpg b/tik-tak-toe/img/bg.jpg new file mode 100644 index 0000000..0e087d5 Binary files /dev/null and b/tik-tak-toe/img/bg.jpg differ diff --git a/tik-tak-toe/img/bg1.jpg b/tik-tak-toe/img/bg1.jpg new file mode 100644 index 0000000..3a76c31 Binary files /dev/null and b/tik-tak-toe/img/bg1.jpg differ diff --git a/tik-tak-toe/img/gameover.png b/tik-tak-toe/img/gameover.png new file mode 100644 index 0000000..0325de3 Binary files /dev/null and b/tik-tak-toe/img/gameover.png differ diff --git a/tik-tak-toe/img/o.png b/tik-tak-toe/img/o.png new file mode 100644 index 0000000..da61a3e Binary files /dev/null and b/tik-tak-toe/img/o.png differ diff --git a/tik-tak-toe/img/x.png b/tik-tak-toe/img/x.png new file mode 100644 index 0000000..7b18bce Binary files /dev/null and b/tik-tak-toe/img/x.png differ diff --git a/tik-tak-toe/index.htm b/tik-tak-toe/index.htm new file mode 100644 index 0000000..257145b --- /dev/null +++ b/tik-tak-toe/index.htm @@ -0,0 +1,219 @@ + + + + JS + + + + +
+ +
+ + + + +
+
+ +
+

user1

+

+
+
+

user1

+

+
+ + + +
+ +
+
+ + +
+ + + + + + \ No newline at end of file diff --git a/tik-tak-toe/style.css b/tik-tak-toe/style.css new file mode 100644 index 0000000..cb84f7a --- /dev/null +++ b/tik-tak-toe/style.css @@ -0,0 +1,164 @@ +@import url('https://fonts.googleapis.com/css?family=Lobster&display=swap&subset=cyrillic,cyrillic-ext,latin-ext,vietnamese'); + * + { + margin: 0; + padding: 0; + } + body { + margin: 0; + background: url(img/bg1.jpg); + background-repeat: no-repeat; + + background-size: cover; + display: flex; + + } + + section { + display: flex; + justify-content: space-around; + background-color: #0e1f27; + height: 60px; + + + } + + div { + display: none; + margin: auto; + } + + #say1 { + background-color: #0e1f27; + color: blanchedalmond; + font-size: 15px; + width: 100px; + height: 30px; + font-family: 'Lobster', cursive; + } + + #say2 { + background-color: #0e1f27; + color: blanchedalmond; + font-size: 15px; + width: 100px; + height: 30px; + font-family: 'Lobster', cursive; + } + + table, + td { + border: 5px solid black; + border-collapse: collapse; + background-color: #fa2f4d; + } + + #Tbl label { + font-size: 45px; + font-family: 'Lobster', cursive; + margin-top: 50x; + color: lightcyan; + display: block; + text-align: center; + } + + #Tbl p { + background-color: #0e1f27; + color: blanchedalmond; + font-size: 25px; + font-family: 'Lobster', cursive; + } + + img { + height: 80px; + width: 80px; + } + + td { + height: 100px; + width: 100px; + text-align: center; + user-select: none; + cursor: pointer; + } + #Finish + { + display: none; + margin: auto; + + + + } + #Finish img + { + width: 400px; + height: 400px; + } + #Finish button{ + text-align: center; + font-size: 30px; + height: 40px; + width: 250px; + border: none; + border-radius: 15px; + outline: none; + background-color: firebrick; + margin-top: 20px; + cursor: pointer; + font-family: 'Lobster', cursive; + margin: auto; + + } + + form { + width: 500px; + height: 300px; + background-color: firebrick; + margin: auto; + text-align: center; + padding-top: 0px; + border-radius: 10px; + } + + form label { + font-family: 'Lobster', cursive; + font-size: 30px; + text-align: center; + } + + form input { + width: 200px; + margin-top: 50px; + height: 30px; + border: none; + border-radius: 15px; + background-color: white; + color: black; + text-align: center; + outline: none; + font-family: 'Lobster', cursive; + padding: 5px; + + } + + form input::placeholder { + color: black; + text-align: center; + font-family: 'Lobster', cursive; + padding: 5px; + + } + + form button { + text-align: center; + height: 30px; + width: 150px; + border: none; + border-radius: 15px; + outline: none; + color: firebrick; + margin-top: 20px; + cursor: pointer; + font-family: 'Lobster', cursive; + + } diff --git a/videos/flappy-bird.mp4 b/videos/flappy-bird.mp4 new file mode 100644 index 0000000..05944cc Binary files /dev/null and b/videos/flappy-bird.mp4 differ diff --git a/videos/need-for-speed.mp4 b/videos/need-for-speed.mp4 new file mode 100644 index 0000000..01963c9 Binary files /dev/null and b/videos/need-for-speed.mp4 differ diff --git a/videos/rock-paper-scissor.mp4 b/videos/rock-paper-scissor.mp4 new file mode 100644 index 0000000..add1a52 Binary files /dev/null and b/videos/rock-paper-scissor.mp4 differ diff --git a/videos/space-drifter.mp4 b/videos/space-drifter.mp4 new file mode 100644 index 0000000..474457b Binary files /dev/null and b/videos/space-drifter.mp4 differ diff --git a/videos/tik-tak-toe.mp4 b/videos/tik-tak-toe.mp4 new file mode 100644 index 0000000..b9544fc Binary files /dev/null and b/videos/tik-tak-toe.mp4 differ