Skip to content

issue-2 #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions 3-typing-game/SOLUTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Assignment

I got the idea and then I searched Google for images so that I can take inspiration from. This was how I made the resources. Keyboard game preview:
![A game involving keyboard](image.png)

## Challenge

- To implement highscore, I used localStorage.get and set item to a current score if it is less than the stored highscore.
- To remove the event listener, I simply removed the event listener from the typedValueElement and re-added it after button press.
- To display the modal dialog box, I simply used the alert function as we don't need any other custom UI or styles.
- To disable the text box, I changed the disabled attribute to true;
18 changes: 18 additions & 0 deletions 3-typing-game/beats/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>Beats</title>
<link rel="stylesheet" href="style.css">
<script src="script.js" defer></script>
</head>

<body>
<div id="game-area">

<div class="block" id="key-area"></div>
<div id="floor-top"></div>
<div id="floor-bottom"></div>
<button id="play"><img src="play.svg"></button>
</div>
</body>
</html>
3 changes: 3 additions & 0 deletions 3-typing-game/beats/play.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions 3-typing-game/beats/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@

const game = document.getElementById('game-area');
const keyArea = document.getElementById('key-area');
const play = document.getElementById('play');

let characters = ['a', 's', 'd', 'j', 'k'];
let blocks = [];

document.getElementById('floor-top').style.display = 'none';
document.getElementById('floor-bottom').style.display = 'none';
keyArea.style.display = 'none';

var delta = 0;
var difficulty = 1;

function exit() {
play.style.display = '';
}

function animate() {

if (Math.random() < (delta**0.8)*difficulty/10000) {
const block = document.createElement('div');
block.classList.add('block');
block.lane = Math.round(Math.random()*4);
block.style.top = '-20%';
game.appendChild(block);
blocks.push(block);
block.offsetTop = 0;
block.innerHTML = characters[block.lane];


for (let i = 0; i < blocks.length; i++) {
let b = blocks[i];
if (b === block) continue;

let bTop = parseFloat(b.style.top);

const computedStyle = window.getComputedStyle(block);

const width = parseFloat(computedStyle.width);
const height = parseFloat(computedStyle.height);
let blockTop = parseFloat(block.style.top);

if (b.lane === block.lane && bTop < blockTop + height) {
blockTop -= height;
block.style.top = blockTop + "px";
i = -1;
}
}

delta = 0;
}

for (let i=0; i<blocks.length; i++) {
let block = blocks[i];
block.style.top = block.offsetTop + 3 + 'px';
block.style.left = block.lane*block.clientWidth + game.offsetLeft + 'px';

const computedStyle = window.getComputedStyle(block);
const height = parseFloat(computedStyle.height);

if (block.offsetTop + height> game.clientHeight) {
exit();
return;
}

if (block.offsetTop > keyArea.offsetTop && block.offsetTop < keyArea.offsetTop + keyArea.clientHeight) {
if(keyArea.innerHTML === '') {
continue;
}
if (keyArea.innerHTML === block.innerHTML) {
keyArea.innerHTML = '';
blocks.splice(i, 1);
block.remove();
i--;
} else {
exit();
return;
}
}
}

delta++;
difficulty += 0.0001;

requestAnimationFrame(animate);
}

play.addEventListener("click", function() {
requestAnimationFrame(animate);
blocks.forEach(block => block.remove());
blocks = [];
this.style.display = 'none';
keyArea.style.display = '';
document.getElementById('floor-top').style.display = '';
document.getElementById('floor-bottom').style.display = '';
keyArea.innerHTML = '';
});

document.addEventListener('keydown', function(event) {
if (characters.includes(event.key)) {
keyArea.innerHTML = event.key;
}
});

exit();
83 changes: 83 additions & 0 deletions 3-typing-game/beats/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* GAME AREA */
#game-area {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 95vh;
width: 25vw; /* Use vw instead of fixed width */
background-color: skyblue;
margin: 2vh auto; /* Margin with vh */
border-radius: 1.5vw; /* Responsive border-radius */
}

/* FLOORS */
#floor-top {
position: absolute;
bottom: 5vh; /* Use vh for vertical spacing */
width: 25vw;
height: 4vh;
background-color: #739eec;
z-index: 10;
}

#floor-bottom {
position: absolute;
bottom: 1vh;
width: 25vw;
height: 5vh;
background-color: #3d5a91;
z-index: 10;
border-radius: 0 0 1.5vw 1.5vw;
}

/* BLOCKS */
.block {
width: 5vw; /* Make block size relative */
aspect-ratio: 1/2;
position: absolute;
border-radius: 1vw;
background-image: linear-gradient(orange, yellow);
box-shadow: inset 0 0 0 0.3vw maroon, 0.2vw 0.5vw 1vw rgba(0, 0, 0, 0.3);
font-size: 3vw;
text-align: center;
}

#key-area {
display: flex;
height: 25%;
bottom: 9%;
justify-content: center;
width: 25vw;
background-color: rgba(255, 0, 0, 0.3);
background-image: none;
border-radius: 0%;
box-shadow: none;
border-top: maroon 0.2vw solid;
z-index: 20;
}

/* BODY */
body {
overflow: hidden;
padding: 0;
margin: 0;
background-color: darkcyan;
}


#play {
position: absolute;
border-radius: 0.5vw;
padding: 1vh;
/* bottom: 0.0vh; */

display: flex;
flex-wrap: wrap;
justify-content: center;
/* width: vw; */
z-index: 100;
background-color: #5da16c;

box-shadow: 0.2vw 0.2vw 0.5vw rgba(0, 0, 0, 0.3);
}
Binary file added 3-typing-game/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions 3-typing-game/typing-game/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>Typing game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Typing game!</h1>
<div id="highscore"></div>
<p>Practice your typing skills with a quote from Sherlock Holmes. Click **start** to begin!</p>
<p id="quote"></p>
<p id="message"></p>
<div>
<input type="text" aria-label="current word" id="typed-value" />
<button type="button" id="start">Start</button>
</div>
<script src="script.js"></script>
</body>
</html>
94 changes: 94 additions & 0 deletions 3-typing-game/typing-game/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
var quotes = [
'When you have eliminated the impossible, whatever remains, however improbable, must be the truth.',
'There is nothing more deceptive than an obvious fact.',
'I ought to know by this time that when a fact appears to be opposed to a long train of deductions it invariably proves to be capable of bearing some other interpretation.',
'I never make exceptions. An exception disproves the rule.',
'What one man can invent another can discover.',
'Nothing clears up a case so much as stating it to another person.',
'Education never ends, Watson. It is a series of lessons, with the greatest for the last.',
];

let words = [];
let wordIndex = 0;

let startTime = Date.now();

const quoteElement = document.getElementById('quote');
const messageElement = document.getElementById('message');
const typedValueElement = document.getElementById('typed-value');
const highscore = document.getElementById('highscore');

typedValueElement.disabled = true;

if (localStorage.getItem('highscore') === null) {
localStorage.setItem('highscore', 0);
} else {
highscore.innerText = `Highscore: ${localStorage.getItem('highscore') / 1000} seconds`;
}

document.getElementById('start').addEventListener('click', () => {
const quoteIndex = Math.floor(Math.random() * quotes.length);
const quote = quotes[quoteIndex];
words = quote.split(' ');
wordIndex = 0;

const spanWords = words.map(function(word) { return `<span>${word} </span>`});
quoteElement.innerHTML = spanWords.join('');
quoteElement.childNodes[0].className = 'highlight';
messageElement.innerText = '';

typedValueElement.value = '';
typedValueElement.disabled = false;
typedValueElement.focus();

startTime = new Date().getTime();
typedValueElement.addEventListener('input', input);
});

function input() {
const currentWord = words[wordIndex];
const typedValue = typedValueElement.value;

if (typedValue === currentWord && wordIndex === words.length - 1) {

const elapsedTime = new Date().getTime() - startTime;
const message = `CONGRATULATIONS! You finished in ${elapsedTime / 1000} seconds.`;
messageElement.innerText = message;
typedValueElement.disabled = true;
messageElement.innerText = '';
typedValueElement.value = '';

let HighScoreTime = parseInt(localStorage.getItem('highscore'));
if (HighScoreTime === 0) {
HighScoreTime = elapsedTime;
}
if (HighScoreTime > elapsedTime || HighScoreTime === 0 || isNaN(HighScoreTime)) {
HighScoreTime = elapsedTime;
}

alert(message+'\nHighscore: '+HighScoreTime / 1000+' seconds');
highscore.innerText = `Highscore: ${HighScoreTime / 1000} seconds`;

localStorage.setItem('highscore', HighScoreTime);


typedValueElement.removeEventListener('input', input);

} else if (typedValue.endsWith(' ') && typedValue.trim() === currentWord) {

typedValueElement.value = '';
wordIndex++;

for (const wordElement of quoteElement.childNodes) {
wordElement.className = '';
}

quoteElement.childNodes[wordIndex].className = 'highlight';

} else if (currentWord.startsWith(typedValue)) {
typedValueElement.className = '';

} else {
typedValueElement.className = 'error';
}
}
9 changes: 9 additions & 0 deletions 3-typing-game/typing-game/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

.highlight {
background-color: yellow;
}

.error {
background-color: lightcoral;
border: red;
}