Skip to content
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
46 changes: 22 additions & 24 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="styles/styles.css" />
<title>Hangman</title>
</head>
<body>
<div style="text-align:center; margin: 50px 0px;">
<img
src="http://www.firstcomicsnews.com/wp-content/uploads/2016/09/Hangman-Logo-600x253.png"
alt="hangman image"
class="game-logo"
/>
</div>
<div style="text-align:center; margin: 50px 0px;">
<button id="start-game-button">START GAME</button>
</div>
<div style="text-align:center;">
<canvas id="hangman" height="800px" width="1200px"></canvas>
</div>
<script type="text/javascript" src="javascript/canvas.js"></script>
<script type="text/javascript" src="javascript/hangman.js"></script>
</body>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="styles/styles.css" />
<title>Hangman</title>
<img src="images/hangman-logo.png">
<style>
body { text-align: center; font-family: Arial, sans-serif; }
#start-game-button { margin-top: 20px; padding: 10px 20px; font-size: 18px; }
</style>
</head>
<body>
<button id="start-game-button">Start Game</button>
<canvas id="hangman" width="1200" height="800"></canvas>
<br>

<!-- JS files -->
<script src="javascript/canvas.js"></script>
<script src="javascript/hangman.js"></script>

</body>
</html>
65 changes: 56 additions & 9 deletions javascript/canvas.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,81 @@
class HangmanCanvas {
constructor(secretWord) {
this.context = document.getElementById('hangman').getContext('2d');
// ... your code goes here
this.secretWord = secretWord;
this.canvas = document.getElementById('hangman');
this.context = this.canvas.getContext('2d');
}

createBoard() {
// ... your code goes here
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.drawLines();
}

drawLines() {
// ... your code goes here
const ctx = this.context;
const startX = 200;
const startY = 500;
const lineWidth = 50;
const gap = 15;
ctx.lineWidth = 3;

for (let i = 0; i < this.secretWord.length; i++) {
const x = startX + i * (lineWidth + gap);
ctx.beginPath();
ctx.moveTo(x, startY);
ctx.lineTo(x + lineWidth, startY);
ctx.stroke();
ctx.closePath();
}
}

writeCorrectLetter(index) {
// ... your code goes here
const ctx = this.context;
const letter = this.secretWord[index].toUpperCase();
const startX = 200;
const startY = 495;
const lineWidth = 50;
const gap = 15;
ctx.font = "40px Arial";
ctx.fillStyle = "black";
const x = startX + index * (lineWidth + gap) + 12;
ctx.fillText(letter, x, startY - 20);
}

writeWrongLetter(letter, errorsLeft) {
// ... your code goes here
const ctx = this.context;
ctx.font = "40px Arial";
ctx.fillStyle = "red";
const x = 700;
const y = 100 + (10 - errorsLeft) * 45;
ctx.fillText(letter.toUpperCase(), x, y);
}

drawHangman(errorsLeft) {
// ... your code goes here
const ctx = this.context;
ctx.lineWidth = 4;
switch (errorsLeft) {
case 9: ctx.beginPath(); ctx.moveTo(100, 500); ctx.lineTo(300, 500); ctx.stroke(); break;
case 8: ctx.beginPath(); ctx.moveTo(150, 500); ctx.lineTo(150, 100); ctx.stroke(); break;
case 7: ctx.beginPath(); ctx.moveTo(150, 100); ctx.lineTo(350, 100); ctx.stroke(); break;
case 6: ctx.beginPath(); ctx.moveTo(350, 100); ctx.lineTo(350, 150); ctx.stroke(); break;
case 5: ctx.beginPath(); ctx.arc(350, 190, 40, 0, Math.PI * 2); ctx.stroke(); break;
case 4: ctx.beginPath(); ctx.moveTo(350, 230); ctx.lineTo(350, 350); ctx.stroke(); break;
case 3: ctx.beginPath(); ctx.moveTo(350, 260); ctx.lineTo(300, 310); ctx.stroke(); break;
case 2: ctx.beginPath(); ctx.moveTo(350, 260); ctx.lineTo(400, 310); ctx.stroke(); break;
case 1: ctx.beginPath(); ctx.moveTo(350, 350); ctx.lineTo(300, 430); ctx.stroke(); break;
case 0: ctx.beginPath(); ctx.moveTo(350, 350); ctx.lineTo(400, 430); ctx.stroke(); break;
}
}

gameOver() {
// ... your code goes here
const img = new Image();
img.src = './images/gameover.png';
img.onload = () => this.context.drawImage(img, 100, 50, 400, 400);
}

winner() {
// ... your code goes here
const img = new Image();
img.src = './images/awesome.png';
img.onload = () => this.context.drawImage(img, 100, 50, 400, 400);
}
}
71 changes: 48 additions & 23 deletions javascript/hangman.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,80 @@
let hangman;
let hangmanCanvas;

const startGameButton = document.getElementById('start-game-button');

class Hangman {
constructor(words) {
this.words = words;
// ... your code goes here
this.secretWord = this.pickWord();
this.letters = [];
this.guessedLetters = "";
this.errorsLeft = 10;
}

pickWord() {
// ... your code goes here
return this.words[Math.floor(Math.random() * this.words.length)];
}

checkIfLetter(keyCode) {
// ... your code goes here
return keyCode >= 65 && keyCode <= 90;
}

checkClickedLetters(letter) {
// ... your code goes here
return !this.letters.includes(letter);
}

addCorrectLetter(letter) {
// ... your code goes here
if (!this.letters.includes(letter)) this.letters.push(letter);
this.guessedLetters += letter;
return this.checkWinner();
}

addWrongLetter(letter) {
// ... your code goes here
if (!this.letters.includes(letter)) this.letters.push(letter);
this.errorsLeft -= 1;
}

checkGameOver() {
// ... your code goes here
return this.errorsLeft <= 0;
}

checkWinner() {
// ... your code goes here
return [...this.secretWord].every(char => this.guessedLetters.includes(char));
}
}

let hangman;

const startGameButton = document.getElementById('start-game-button');

// START BUTTON
if (startGameButton) {
startGameButton.addEventListener('click', event => {
hangman = new Hangman(['node', 'javascript', 'react', 'miami', 'paris', 'amsterdam', 'lisboa']);

// HINT (uncomment when start working on the canvas portion of the lab)
// hangman.secretWord = hangman.pickWord();
// hangmanCanvas = new HangmanCanvas(hangman.secretWord);

// ... your code goes here
startGameButton.addEventListener('click', () => {
hangman = new Hangman([
'node','javascript','react','miami','paris','amsterdam','lisboa'
]);
hangman.secretWord = hangman.pickWord();
hangmanCanvas = new HangmanCanvas(hangman.secretWord);
hangmanCanvas.createBoard();
});
}

document.addEventListener('keydown', event => {
// React to user pressing a key
// ... your code goes here
// KEYDOWN HANDLER
document.addEventListener('keydown', (event) => {
if (!hangman) return;

const letter = event.key.toLowerCase();

if (!hangman.checkIfLetter(event.keyCode)) return;
if (!hangman.checkClickedLetters(letter)) return;

if (hangman.secretWord.includes(letter)) {
hangman.addCorrectLetter(letter);
[...hangman.secretWord].forEach((char, idx) => {
if (char === letter) hangmanCanvas.writeCorrectLetter(idx);
});
if (hangman.checkWinner()) hangmanCanvas.winner();
} else {
hangman.addWrongLetter(letter);
hangmanCanvas.writeWrongLetter(letter, hangman.errorsLeft);
hangmanCanvas.drawHangman(hangman.errorsLeft);
if (hangman.checkGameOver()) hangmanCanvas.gameOver();
}
});
4 changes: 3 additions & 1 deletion styles/styles.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.game-logo {

text-align: center;
}

#start-game-button {
Expand All @@ -10,6 +10,8 @@
padding: 20px 40px;
font-size: 30px;
border-radius: 5px;
display: block;
margin: auto;
}

#hangman {
Expand Down