02/12/2023

This commit is contained in:
Jan-Niclas Loosen 2023-12-02 19:45:57 +01:00
commit b516324a8d
73 changed files with 3873 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -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

8
.idea/JS_Games.iml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/JS_Games.iml" filepath="$PROJECT_DIR$/.idea/JS_Games.iml" />
</modules>
</component>
</project>

19
.idea/php.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MessDetectorOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCSFixerOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCodeSnifferOptionsConfiguration">
<option name="highlightLevel" value="WARNING" />
<option name="transferred" value="true" />
</component>
<component name="PhpStanOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PsalmOptionsConfiguration">
<option name="transferred" value="true" />
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

54
flappy-bird/README.md Normal file
View File

@ -0,0 +1,54 @@
# Flappy Bird <img src="https://emojis.slackmojis.com/emojis/images/1481348711/1475/flappy_bird.png?1481348711" width="35" height="35" />
A 2D Flappy bird remake built using HTML, CSS &amp; 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
<a href="http://www.youtube.com/watch?feature=player_embedded&v=9rQIVyJJymk
" target="_blank"><img src="http://img.youtube.com/vi/9rQIVyJJymk/0.jpg"
alt="RoadFighter " width="240" height="180" border="10" /></a>
![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)

BIN
flappy-bird/back1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
flappy-bird/back2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
flappy-bird/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -0,0 +1,177 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
canvas {
border:1px solid #d3d3d3;
background-image: url("back2.png");
font-family: Impact, Charcoal, sans-serif;
align:center;
margin-top:100px;
margin-left:250px;
}
</style>
</head>
<body onload="startGame()">
<script>
var myGamePiece;
var myObstacles = [];
var myScore;
function startGame() {
myGamePiece = new component(60, 60, "flappybird.png", 100, 120, "image");
myGamePiece.gravity = 0.07;
myScore = new component("30px", "Impact", "white", 350, 40, "text");
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 800;
this.canvas.height = 400;
this.canvas.id="demo";
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
document.getElementById("demo").addEventListener("mousedown", mouseDown);
document.getElementById("demo").addEventListener("mouseup", mouseUp);
function mouseDown() {
accelerate(-0.2);
}
function mouseUp() {
accelerate(0.05);
}
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
stop : function() {
clearInterval(this.interval);
}
}
function component(width, height, color, x, y, type) {
this.type = type;
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.score = 0;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.gravity = 0;
this.gravitySpeed = 0;
this.update = function() {
ctx = myGameArea.context;
if (this.type == "text") {
ctx.font = this.width + " " + this.height;
ctx.fillStyle = color;
ctx.fillText(this.text, this.x, this.y);
}
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width, this.height);}
else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
//ctx.drawImage(myGamePiece,this.x,this.y,this.height,this.width);
}
}
this.newPos = function() {
this.gravitySpeed += this.gravity;
this.x += this.speedX;
this.y += this.speedY + this.gravitySpeed;
this.hitBottom();
}
this.hitBottom = function() {
var rockbottom = myGameArea.canvas.height - this.height;
if (this.y > rockbottom) {
this.y = rockbottom;
this.gravitySpeed = 0;
}
}
this.crashWith = function(otherobj) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = otherobj.x;
var otherright = otherobj.x + (otherobj.width);
var othertop = otherobj.y;
var otherbottom = otherobj.y + (otherobj.height);
var crash = true;
if ((mybottom-20< othertop) || (mytop+20> otherbottom) || (myright-20 < otherleft) || (myleft +20> otherright)) {
crash = false;
}
return crash;
}
}
function updateGameArea() {
var x, height, gap, minHeight, maxHeight, minGap, maxGap;
for (i = 0; i < myObstacles.length; i += 1) {
if (myGamePiece.crashWith(myObstacles[i])) {
return;
}
}
myGameArea.clear();
myGameArea.frameNo += 1;
if (myGameArea.frameNo == 1 || everyinterval(130)) {
x = myGameArea.canvas.width;
minHeight = 20;
maxHeight = 200;
height = Math.floor(Math.random()*(maxHeight-minHeight+1)+minHeight);
minGap = 50;
maxGap = 200;
gap = Math.floor(Math.random()*(maxGap-minGap+1)+minGap);
// myObstacles.push(new component(10, height, "green", x, 0));
//myObstacles.push(new component(10, x - height - gap, "green", x, height + gap));
myObstacles.push(new component(50, height, "rotatedpipe.png", x, 0, "image"));
myObstacles.push(new component(50, x - height - gap, "pipe.png", x, height + gap,"image"));
}
for (i = 0; i < myObstacles.length; i += 1) {
myObstacles[i].x += -2;
myObstacles[i].update();
}
myScore.text="SCORE: " + myGameArea.frameNo;
myScore.update();
myGamePiece.newPos();
myGamePiece.update();
}
function everyinterval(n) {
if ((myGameArea.frameNo / n) % 1 == 0) {return true;}
return false;
}
function accelerate(n) {
myGamePiece.gravity = n;
}
</script>
<br>
</body>
</html>

BIN
flappy-bird/flappybird.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

10
flappy-bird/index.html Normal file
View File

@ -0,0 +1,10 @@
<style>
.demo
{
margin-top:100px;
margin-left:250px;
}
</style>
<body><a href="modeselect.html">
<img src="menu.png" class="demo" onclick></a>
</body>

BIN
flappy-bird/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -0,0 +1,10 @@
<style>
.demo
{
margin-top:100px;
margin-left:250px;
}
</style>
<body><a href="daybackground.html">
<img src="modeselect.png" class="demo" onclick></a>
</body>

BIN
flappy-bird/modeselect.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -0,0 +1,177 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
canvas {
border:1px solid #d3d3d3;
background-image: url("back1.png");
font-family: Impact, Charcoal, sans-serif;
align:center;
margin-top:100px;
margin-left:250px;
}
</style>
</head>
<body onload="startGame()">
<script>
var myGamePiece;
var myObstacles = [];
var myScore;
function startGame() {
myGamePiece = new component(60, 60, "flappybird.png", 100, 120, "image");
myGamePiece.gravity = 0.05;
myScore = new component("30px", "Impact", "white", 350, 40, "text");
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 800;
this.canvas.height = 400;
this.canvas.id="demo";
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
document.getElementById("demo").addEventListener("mousedown", mouseDown);
document.getElementById("demo").addEventListener("mouseup", mouseUp);
function mouseDown() {
accelerate(-0.2);
}
function mouseUp() {
accelerate(0.05);
}
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
stop : function() {
clearInterval(this.interval);
}
}
function component(width, height, color, x, y, type) {
this.type = type;
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.score = 0;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.gravity = 0;
this.gravitySpeed = 0;
this.update = function() {
ctx = myGameArea.context;
if (this.type == "text") {
ctx.font = this.width + " " + this.height;
ctx.fillStyle = color;
ctx.fillText(this.text, this.x, this.y);
}
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width, this.height);}
else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
//ctx.drawImage(myGamePiece,this.x,this.y,this.height,this.width);
}
}
this.newPos = function() {
this.gravitySpeed += this.gravity;
this.x += this.speedX;
this.y += this.speedY + this.gravitySpeed;
this.hitBottom();
}
this.hitBottom = function() {
var rockbottom = myGameArea.canvas.height - this.height;
if (this.y > rockbottom) {
this.y = rockbottom;
this.gravitySpeed = 0;
}
}
this.crashWith = function(otherobj) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = otherobj.x;
var otherright = otherobj.x + (otherobj.width);
var othertop = otherobj.y;
var otherbottom = otherobj.y + (otherobj.height);
var crash = true;
if ((mybottom-20< othertop) || (mytop+20> otherbottom) || (myright-20 < otherleft) || (myleft +20> otherright)) {
crash = false;
}
return crash;
}
}
function updateGameArea() {
var x, height, gap, minHeight, maxHeight, minGap, maxGap;
for (i = 0; i < myObstacles.length; i += 1) {
if (myGamePiece.crashWith(myObstacles[i])) {
return;
}
}
myGameArea.clear();
myGameArea.frameNo += 1;
if (myGameArea.frameNo == 1 || everyinterval(130)) {
x = myGameArea.canvas.width;
minHeight = 20;
maxHeight = 200;
height = Math.floor(Math.random()*(maxHeight-minHeight+1)+minHeight);
minGap = 50;
maxGap = 200;
gap = Math.floor(Math.random()*(maxGap-minGap+1)+minGap);
// myObstacles.push(new component(10, height, "green", x, 0));
//myObstacles.push(new component(10, x - height - gap, "green", x, height + gap));
myObstacles.push(new component(50, height, "rotatedpipe.png", x, 0, "image"));
myObstacles.push(new component(50, x - height - gap, "pipe.png", x, height + gap,"image"));
}
for (i = 0; i < myObstacles.length; i += 1) {
myObstacles[i].x += -2;
myObstacles[i].update();
}
myScore.text="SCORE: " + myGameArea.frameNo;
myScore.update();
myGamePiece.newPos();
myGamePiece.update();
}
function everyinterval(n) {
if ((myGameArea.frameNo / n) % 1 == 0) {return true;}
return false;
}
function accelerate(n) {
myGamePiece.gravity = n;
}
</script>
<br>
</body>
</html>

BIN
flappy-bird/pipe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
flappy-bird/rotatedpipe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

27
images/popcorn.svg Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="-8.21 0 141.542 141.542" xmlns="http://www.w3.org/2000/svg">
<g id="popcorn_movie_cinema" data-name="popcorn movie cinema" transform="translate(-835.069 -127.481)">
<g id="Group_1920" data-name="Group 1920">
<path id="Path_4489" data-name="Path 4489" d="M959.4,173.13a14.516,14.516,0,1,1-14.747-14.281A14.515,14.515,0,0,1,959.4,173.13Z" fill="#fce4ab"/>
<path id="Path_4490" data-name="Path 4490" d="M878.922,166.5a17.867,17.867,0,1,1-18.152-17.576A17.867,17.867,0,0,1,878.922,166.5Z" fill="#fce4ab"/>
<path id="Path_4491" data-name="Path 4491" d="M940.9,145.059a17.867,17.867,0,1,1-18.154-17.576A17.869,17.869,0,0,1,940.9,145.059Z" fill="#fce4ab"/>
<path id="Path_4492" data-name="Path 4492" d="M920.546,150.414a22.558,22.558,0,1,1-22.918-22.19A22.559,22.559,0,0,1,920.546,150.414Z" fill="#facd7b"/>
<path id="Path_4493" data-name="Path 4493" d="M954.862,159.241a20.212,20.212,0,1,1-20.535-19.882A20.212,20.212,0,0,1,954.862,159.241Z" fill="#f9b968"/>
<path id="Path_4494" data-name="Path 4494" d="M928.547,168.712a15.523,15.523,0,1,1-15.77-15.269A15.523,15.523,0,0,1,928.547,168.712Z" fill="#ea8542"/>
<path id="Path_4495" data-name="Path 4495" d="M858.334,177.886a11.5,11.5,0,1,1-11.687-11.314A11.507,11.507,0,0,1,858.334,177.886Z" fill="#ea8542"/>
<path id="Path_4496" data-name="Path 4496" d="M908.135,170.381a15.522,15.522,0,1,1-15.771-15.267A15.524,15.524,0,0,1,908.135,170.381Z" fill="#fce4ab"/>
<path id="Path_4497" data-name="Path 4497" d="M887.07,173.067a14.517,14.517,0,1,1-14.75-14.28A14.515,14.515,0,0,1,887.07,173.067Z" fill="#f9b968"/>
</g>
<path id="Path_4498" data-name="Path 4498" d="M841.115,188.493l15.6,72.695,84.236-1.359L954.2,186.669Z" fill="#f39014"/>
<path id="Path_4499" data-name="Path 4499" d="M863.6,188.13l9.8,72.788,16.843-.272L886.2,187.765Z" fill="#e5eff3"/>
<path id="Path_4500" data-name="Path 4500" d="M841.115,188.493l15.6,72.695,16.69-.27-9.8-72.788Z" fill="#ed4d55"/>
<path id="Path_4501" data-name="Path 4501" d="M954.2,186.669l-22.816.367L923.935,260.1l17.017-.274Z" fill="#ed4d55"/>
<path id="Path_4502" data-name="Path 4502" d="M886.2,187.765l4.051,72.881,16.843-.272,1.7-72.974Z" fill="#ed4d55"/>
<path id="Path_4503" data-name="Path 4503" d="M908.789,187.4l-1.7,72.974,16.844-.271,7.446-73.066Z" fill="#e5eff3"/>
<path id="Path_4504" data-name="Path 4504" d="M847.933,220.261c20.267-9.988,55.611-22.533,104.131-21.8l2.133-11.788-113.082,1.824Z" fill="#c52c58" opacity="0.4"/>
<path id="Path_4505" data-name="Path 4505" d="M960.185,185.649a6.925,6.925,0,0,1-6.812,7.036l-111.238,1.794a6.925,6.925,0,0,1-7.036-6.811l-.029-1.847a6.925,6.925,0,0,1,6.811-7.036l111.238-1.793a6.925,6.925,0,0,1,7.036,6.811Z" fill="#ed4d55"/>
<path id="Path_4506" data-name="Path 4506" d="M945.535,234.511c-27.433,16.069-78.654,18.313-90.551,18.618l1.731,8.059,84.236-1.36Z" fill="#c52c58" opacity="0.4"/>
<path id="Path_4507" data-name="Path 4507" d="M945.235,260.684c.063,3.823-2.187,6.962-5.022,7.006l-82.507,1.332c-2.834.045-5.184-3.017-5.245-6.841l-.03-1.847c-.063-3.823,2.188-6.961,5.023-7.006L939.96,252c2.836-.046,5.184,3.016,5.246,6.841Z" fill="#ed4d55"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

71
index.php Normal file
View File

@ -0,0 +1,71 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Kergart Browser Games LTD</title>
</head>
<body>
<header>
<img src="images/popcorn.svg" alt="Popcorn Icon" class="header-icon popcorn">
<h1>Kergart Browser Games Ltd.</h1>
<h4>A premium amateur **** selection.<br>Only available on https://kergart.testgelaende.de!</h4>
</header>
<main>
<!-- Game sections with popcorn image -->
<section class="game">
<video src="videos/flappy-bird.mp4" class="game-video" controls autoplay loop></video>
<h2>Flappy Jan</h2>
<p>
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!
</p>
<a href="flappy-bird">Play Now</a>
</section>
<section class="game">
<video src="videos/need-for-speed.mp4" class="game-video" controls autoplay loop></video>
<h2>Need for Kergi</h2>
<p>
"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!
</p>
<a href="need-for-speed">Play Now</a>
</section>
<section class="game">
<video src="videos/rock-paper-scissor.mp4" class="game-video" controls autoplay loop></video>
<h2>Jan, Jan, Jan</h2>
<p>
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!
</p>
<a href="rock-paper-scissor">Play Now</a>
</section>
<section class="game">
<video src="videos/space-drifter.mp4" class="game-video" controls autoplay loop></video>
<h2>Space Kergi</h2>
<p>
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!
</p>
<a href="space-drifter">Play Now</a>
</section>
<section class="game" style="margin-bottom:10%">
<video src="videos/tik-tak-toe.mp4" class="game-video" controls autoplay loop></video>
<h2>Tik-Tok-Jan</h2>
<p>
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!
</p>
<a href="tik-tak-toe">Play Now</a>
</section>
</main>
<footer>
<p>&copy; 2023 Kergart Browser Games Ltd.<br>
and Hansi Enterprises GmbH and CoKG
</p>
</footer>
</body>
</html>

12
need-for-speed/README.md Normal file
View File

@ -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)

View File

@ -0,0 +1,4 @@
*{
margin: 0;
padding: 0;
}

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

32
need-for-speed/index.html Normal file
View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<title>Need for Kergi</title>
<link rel="stylesheet" type="text/css" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div class = "title">
<h1>Need for Kergi - Most Wanted</h1>
<span style="color: red">Spacebar fires bullets</span>
<br>
<span style="color: red">Press 'start' to begin</span>
<br>
<button id="toggle">Start</button>
</div>
<div class="wrapper">
<div class="container" id="container">
<div class="lane">
</div>
<div class="lane">
</div>
<div class="lane">
</div>
</div>
</div>
<script type="text/javascript" src="js/nfs.js"></script>
</body>
</html>

401
need-for-speed/js/nfs.js Normal file
View File

@ -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();

BIN
need-for-speed/sample.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@ -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.

View File

@ -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.

View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Jan, Jan, Jan</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">
</head>
<body>
<div class="container">
<header>
<h1>Jan, Jan, Jan</h1>
</header>
<div id="inside">
<p id="instruction">Select your ammo:</p>
<div class="choice">
<div class="select-choice" id="rock">
<img class="img-weapon" src="rock1.png" alt="rock">
</div>
<div class="select-choice" id="paper">
<img class="img-weapon" src="paper1.png" alt="paper">
</div>
<div class="select-choice" id="scissors">
<img class="img-weapon" src="scissor1.png" alt="scissors">
</div>
</div>
<div class="result">
<p id="message">Who will win the first game?</p>
<div class="scores">
<p class="total-score">Your score: <span id="user-score">0</span></p>
<p class="total-score">Computer's score: <span id="computer-score">0</span></p>
<p class="total-score">Draws: <span id="draws">0</span></p>
<button id="reset-button">Reset</button>
</div>
</div>
</div>
<footer>
<p>By Atharva Kulkarni</p>
<p>
<a
href="https://github.com/AtharvaKulkarniIT" target="_blank"><i class="fab fa-github-alt fa-2x" alt="Github icon"></i></a>
</p>
</footer>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

View File

@ -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();

View File

@ -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%;
}

21
space-drifter/LICENSE Normal file
View File

@ -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.

13
space-drifter/README.md Normal file
View File

@ -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.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -0,0 +1,4 @@
<svg height="10" width="10" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="5" cy="5" r="5" fill="#00ccff" />
<circle cx="5" cy="5" r="2.5" fill="#4ddbff" />
</svg>

After

Width:  |  Height:  |  Size: 182 B

964
space-drifter/game.js Normal file
View File

@ -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();
});

112
space-drifter/index.html Normal file
View File

@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Space Drifter</title>
<link rel="stylesheet" href="styles.css" />
<link rel="icon" href="assets/starship.svg" />
<meta property="og:title" content="Space Drifter" />
<meta property="og:type" content="article" />
<meta
property="og:image"
content="https://raw.githubusercontent.com/bence-toth/space-drifter/main/assets/space-drifter-cover.jpg"
/>
<meta
property="og:url"
content="https://bence-toth.github.io/space-drifter/"
/>
<meta name="twitter:card" content="summary_large_image" />
<meta
property="og:description"
content="A pretty darn difficult asteroid shooter game with realistic inertia and unconventional controls."
/>
<meta property="og:site_name" content="Space Drifter" />
<meta name="twitter:image:alt" content="Space Drifter" />
<meta
name="description"
content="A pretty darn difficult asteroid shooter game with realistic inertia and unconventional controls."
/>
<meta name="keywords" content="Space Shooter, Game" />
<meta name="author" content="Bence A. Tóth" />
</head>
<body>
<div id="splash">
<div class="innerWrapper">
<h1>Space Drifter</h1>
<button id="start">
<span>Start game</span>
<div class="line top"></div>
<div class="line right"></div>
<div class="line bottom"></div>
<div class="line left"></div>
</button>
<div class="controls">
<h3>Controls</h3>
<dl>
<dt>Fire thrusters</dt>
<dd>
<div class="wasd">
<kbd>W</kbd>
<kbd>A</kbd>
<kbd>S</kbd>
<kbd>D</kbd>
</div>
<div class="wasd">
<kbd></kbd>
<kbd></kbd>
<kbd></kbd>
<kbd></kbd>
</div>
</dd>
<dt>Launch torpedo</dt>
<dd>
<kbd>Space</kbd>
<kbd>Mouse click</kbd>
</dd>
<dt>Pause/Resume</dt>
<dd>
<kbd>P</kbd>
</dd>
</dl>
</div>
<footer>
<nav>
by
<a
href="https://github.com/bence-toth/space-drifter"
target="_blank"
rel="noopener"
>Bence A. Tóth</a
>
</nav>
</footer>
</div>
</div>
<div id="paused" class="hidden">
<div class="innerWrapper">
<h2>Game paused</h2>
<p>Press <kbd>P</kbd> to resume</p>
</div>
</div>
<div id="gameOver" class="hidden">
<div class="innerWrapper">
<h2>Game Over</h2>
<h3>Your score: <span id="finalScore"></span></h3>
<button id="restart" tabindex="-1">
<span>Restart game</span>
<div class="line top"></div>
<div class="line right"></div>
<div class="line bottom"></div>
<div class="line left"></div>
</button>
</div>
</div>
<div class="canvasWrapper">
<canvas id="game-canvas"></canvas>
<div id="score">0</div>
</div>
<script src="game.js"></script>
</body>
</html>

297
space-drifter/styles.css Normal file
View File

@ -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%);
}

BIN
storage/bg1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

BIN
storage/car.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
storage/flappybird.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
storage/o.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
storage/paper1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
storage/rock1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
storage/scissor1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

85
storage/starship.svg Normal file
View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="60"
height="60"
viewBox="0 0 15.875 15.875"
version="1.1"
id="svg5"
sodipodi:docname="starship-2.svg"
inkscape:version="1.1 (c4e8f9e, 2021-05-24)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
units="px"
showguides="false"
inkscape:zoom="10.732997"
inkscape:cx="22.966559"
inkscape:cy="37.035323"
inkscape:window-width="1792"
inkscape:window-height="1067"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="path846"
style="fill:#666666;stroke-width:0.268942"
d="M 9.8934528,0 C 10.30926,0.27469322 10.583333,0.75084753 10.583333,1.2943116 v 7.6629967 c 0,0.854741 -0.6777342,1.5430967 -1.519287,1.5430967 H 6.8109538 c -0.8415528,0 -1.5192872,-0.6883557 -1.5192872,-1.5430967 V 1.2943116 c 0,-0.54048587 0.2711849,-1.01420861 0.6831624,-1.28958784 A 7.9374999,8.0618925 0 0 0 0,7.8131075 7.9374999,8.0618925 0 0 0 7.9374999,15.875 7.9374999,8.0618925 0 0 0 15.875,7.8131075 7.9374999,8.0618925 0 0 0 9.8934528,0 Z" />
<path
id="path846-2"
style="fill:#4d4d4d;stroke-width:0.268941"
d="M 11.770341,0.75964356 V 9.7451414 c 0,1.0379226 -0.835865,1.8732706 -1.8737875,1.8732706 H 5.9784463 c -1.0379223,0 -1.8737873,-0.835348 -1.8737873,-1.8732706 V 0.76274413 A 7.9374999,8.0618924 0 0 0 0,7.8129597 7.9374999,8.0618924 0 0 0 7.9374999,15.875 7.9374999,8.0618924 0 0 0 15.875,7.8129597 7.9374999,8.0618924 0 0 0 11.770341,0.75964356 Z" />
<path
id="path846-6"
style="fill:#ffcc00;stroke-width:0.268941"
d="M 9.8934528,0 C 10.304222,0.27136505 10.576275,0.7396087 10.582816,1.2748576 A 7.9374999,8.0618924 0 0 1 15.855879,8.3343749 7.9374999,8.0618924 0 0 0 15.875,7.8129597 7.9374999,8.0618924 0 0 0 9.8934528,0 Z M 5.974829,0.00465088 A 7.9374999,8.0618924 0 0 0 0,7.8129597 7.9374999,8.0618924 0 0 0 0.01963704,8.3410929 7.9374999,8.0618924 0 0 1 5.2921833,1.2779581 C 5.2976761,0.74438496 5.5670775,0.27720546 5.974829,0.00465088 Z" />
<circle
style="fill:#00ccff;stroke:#ffcc00;stroke-width:0.279613;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1729"
cx="7.9375"
cy="13.49375"
r="0" />
<rect
style="fill:#4d4d4d;stroke:none;stroke-width:0.170662;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect3296"
width="1.6762948"
height="3.446121"
x="7.0993524"
y="7.5645933"
ry="0.55232006" />
<rect
style="fill:#333333;stroke:none;stroke-width:0.05941;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect3899"
width="1.3229166"
height="0.52916664"
x="7.2760415"
y="7.6729169"
ry="0.25653949" />
<ellipse
style="fill:#00ccff;stroke:#ffcc00;stroke-width:0.52916667;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4376"
cx="7.9375"
cy="13.747297"
rx="2.4966176"
ry="1.7028677" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
storage/x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

73
style.css Normal file
View File

@ -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%;
}

BIN
tik-tak-toe/img/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
tik-tak-toe/img/bg1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
tik-tak-toe/img/o.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

BIN
tik-tak-toe/img/x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

219
tik-tak-toe/index.htm Normal file
View File

@ -0,0 +1,219 @@
<html>
<head>
<meta charset="UTF-8" />
<title>JS</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<form id="Form" action="#">
<label>TIK TAK Jan</label>
<br />
<input class="p1" placeholder="Player-1" required="required" />
<input class="p2" placeholder="Player-2" required="required" />
<button onclick="Start()">Start</button>
</form>
<div id="Tbl">
<!--<label>Game</label>-->
<section>
<p id="p1">user1</p>
<p id="say1"></p>
</section>
<section>
<p id="p2">user1</p>
<p id="say2"></p>
</section>
<table>
</table>
</div>
<div id="Finish">
<img src="img/gameover.png"/>
<button onclick="Startt()">AGAIN</button>
</div>
<script>
let ply1;
let ply2;
let say1 = 0;
let say2 = 0;
let X = "<img src='img/x.png' >";
let O = "<img src='img/o.png' >";
/* let X="X";
let O="O";*/
let say = 1;
let M = [];
Massiv();
Qur();
function Start() {
document.getElementById("Tbl").style.display = "block";
document.getElementsByTagName("form")[0].style.display = "none";
ply1 = document.getElementsByTagName("input")[0].value;
ply2 = document.getElementsByTagName("input")[1].value;
document.getElementById("p1").innerHTML = `${ply1}`;
document.getElementById("p2").innerHTML = `${ply2}`;
document.getElementById("say1").innerHTML = say1;
document.getElementById("say2").innerHTML = say2;
}
function Startt(){
document.getElementById("Finish").style.display = "none";
document.getElementsByTagName("form")[0].style.display = "block";
}
function Massiv() {
for (let i = 0; i < 3; i++) {
M[i] = [];
}
}
function Qur() {
let tbl = "";
for (let i = 0; i < 3; i++) {
tbl += `<tr>`;
for (let j = 0; j < 3; j++) {
M[i][j] = M[i][j] == undefined ? "" : M[i][j];
tbl += `<td id="row_` + i + j + `" onclick="Tikla(${i},${j})">${M[i][j]}</td>`;
}
tbl += `</tr>`;
}
document.getElementsByTagName("table")[0].innerHTML = tbl;
}
function sil() {
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
M[i][j] = "";
document.getElementById("row_" + i + j).innerHTML = "";
}
}
say=1;
console.log(say);
}
function Tikla(i, j) {
if (M[i][j] == "") {
if (say % 2 == 1) {
M[i][j] = X;
} else {
M[i][j] = O;
}
say++;
setTimeout(Yoxla, 200);
Qur();
}
}
function Yoxla() {
for (let i = 0; i < 3; i++) {
if (M[i][0] == M[i][1] && M[i][1] == M[i][2] && M[i][0] != "") {
if (M[i][0] == X) {
alert(`${ply1} you get 1 point`);
say1++;
document.getElementById("say1").innerHTML=say1;
sil();
}
else {
alert(`${ply2} you get 1 point`);
say2++;
document.getElementById("say2").innerHTML=say2;
sil();
}
}
}
for (let i = 0; i < 3; i++) {
if (M[0][i] == M[1][i] && M[1][i] == M[2][i] && M[0][i] != "") {
if (M[0][i] == X) {
alert(`${ply1} you get 1 point`);
say1++;
document.getElementById("say1").innerHTML=say1;
sil();
}
else {
alert(`${ply2} you get 1 point`);
say2++;
document.getElementById("say2").innerHTML=say2;
sil();
}
}
}
if (M[0][0] == M[1][1] && M[1][1] == M[2][2] && M[0][0] != "") {
if (M[0][0] == X) {
alert(`${ply1} you get 1 point`);
say1++;
document.getElementById("say1").innerHTML=say1;
sil();
}
else {
alert(`${ply2} you get 1 point`);
say2++;
document.getElementById("say2").innerHTML=say2;
sil();
}
}
if (M[0][2] == M[1][1] && M[1][1] == M[2][0] && M[0][2] != "") {
if (M[0][2] == X) {
alert(`${ply1} you get 1 point`);
say1++;
document.getElementById("say1").innerHTML=say1;
sil();
}
else {
alert(`${ply2} you get 1 point`);
say2++;
document.getElementById("say2").innerHTML=say2;
sil();
}
}
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (M[0][0] != "" && M[0][1] != "" && M[0][2] != "" && M[1][0] != "" && M[1][1] != "" && M[1][2] != "" && M[2][0] != "" && M[2][1] != "" && M[2][2] != "") {
alert("None gets point!!");
sil();
}
}
}
if(say1==3 )
{
say1==3;
alert(`${ply1} you are winner!`);
setTimeout(200);
// setTimeout(alert("OYUN BITDI"), 400);
document.getElementById("Tbl").style.display="none";
document.getElementById("Finish").style.display="flex";
document.getElementById("Finish").style.flexDirection="column";
}
else if(say2==3)
{
say2==3;
alert(`${ply2} you are winner!`);
setTimeout(200);
// setTimeout(alert("OYUN BITDI"), 400);
document.getElementById("Tbl").style.display="none";
document.getElementById("Finish").style.display="flex";
document.getElementById("Finish").style.flexDirection="column";
}
}
</script>
</body>
</html>

164
tik-tak-toe/style.css Normal file
View File

@ -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;
}

BIN
videos/flappy-bird.mp4 Normal file

Binary file not shown.

BIN
videos/need-for-speed.mp4 Normal file

Binary file not shown.

Binary file not shown.

BIN
videos/space-drifter.mp4 Normal file

Binary file not shown.

BIN
videos/tik-tak-toe.mp4 Normal file

Binary file not shown.