diff --git a/CONTRACT.md b/CONTRACT.md new file mode 100644 index 0000000..d114776 --- /dev/null +++ b/CONTRACT.md @@ -0,0 +1,86 @@ +--- +authors: +- "shereefb" +- "tannerwelsh" +team_size: 1 +goal_id: 83 +title: 'Browser Games [Basic]' +created_at: '2016-10-05T21:34:11Z' +labels: +- foundational +published: true +level: '1' +redirect_from: "/goals/83" +--- + +# Browser Games [Basic] + +## Challenge Rating + +This goal will likely be within your ZPD if you... + +- Can build basic web sites with HTML & CSS +- Can add behavior to a web site with JavaScript +- Are familiar with DOM manipulation +- Are familiar with games like tic-tac-toe and Simon +- Are interested in making more complex interactive web pages + +## Description + +Build simple graphical games for the browser. + +Fork the the [browser-games repository][browser-games] and use the fork as your project artifact. + +Implement the games **Tic-Tac-Toe** and **Simon** from the list in the [games.md][games-list] file. As a stretch, implement the **Connect Four** game. + +You will be using FreeCodeCamp challenges as guides and tutorials for building these games. + +## Context + +This goal will challenge your ability to take a _formal, defined system_ from the real world and replicate it in code. You will start with all of the logic of the system (the rules of the game) and most of the UI already designed. + +Your work will be mainly in deciding how to replicate that formal logic and user interface using JavaScript, HTML, and CSS. + +## Specifications + +#### General + +- [x] Artifact produced is a fork of the [browser-games][browser-games] repo. +- [x] Variables, functions, files, etc. have appropriate and meaningful names. +- [x] HTML, CSS, and JS files are well formatted with proper spacing and indentation. +- [ ] All major features are added via pull requests with a clear description and concise commit messages. +- [x] Every pull request has been reviewed by at least one other person. +- [x] The artifact produced is properly licensed, preferably with the [MIT license][mit-license]. + +#### Tic-Tac-Toe + +- [x] Tic-Tac-Toe game can be found at `public/ticTacToe.html` +- [ ] Tic-Tac-Toe game is playable by two people +- [x] Tic-Tac-Toe game page is linked from `public/index.html` + +#### Simon + +- [x] Simon game can be found at `public/ticTacToe.html` +- [ ] Simon game is playable +- [x] Simon game page is linked from `public/index.html` + +### Stretch + +- [x] Tic-Tac-Toe has a player-vs-computer version +- [ ] Tic-Tac-Toe AI will always win or tie +- [x] Simon plays sounds +- Implement Connect Four game + - [ ] Connect Four game can be found at `public/connectFour.html` + - [ ] Connect Four game is playable by two people (human v human) + - [ ] Connect Four game page is linked from `public/index.html` + +## Resources + +- MDN: [Introduction to the DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction) #html #dom #js +- MDN: [Guide to Event Handlers](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers) #dom #js +- Shay Howe: [Learn to Code HTML & CSS](http://learn.shayhowe.com/html-css/) #html #css + +[browser-games]: https://github.com/GuildCrafts/browser-games +[games-list]: https://github.com/GuildCrafts/browser-games/blob/master/games.md +[basic-games]: https://github.com/GuildCrafts/browser-games/blob/master/games.md#basic-graphical-games +[mit-license]: https://opensource.org/licenses/MIT diff --git a/CONTRACT_Platform-Game.md b/CONTRACT_Platform-Game.md new file mode 100644 index 0000000..3f8359f --- /dev/null +++ b/CONTRACT_Platform-Game.md @@ -0,0 +1,71 @@ +#bitter-steenbok +## Somaya Bounouar +#363 Browser Games: Generic Platform Game +http://jsdev.learnersguild.org/goals/363-Browser_Games-Platform.html + +# Browser Games: Generic Platform Game + +## Challenge Rating + +This goal will likely be within your ZPD if you... + +- Can build basic web sites with HTML & CSS +- Can add behavior to a web site with JavaScript +- Are familiar with DOM manipulation +- Are familiar with platform-based games +- Are interested in making more complex interactive web pages + +## Description + +Implement a simple [platform](https://en.wikipedia.org/wiki/Platform_game) ("run and jump") game with HTML, CSS, and JavaScript. + +Follow [this tutorial](http://eloquentjavascript.net/15_game.html) from [Eloquent JavaScript](http://eloquentjavascript.net/). + +Fork the the [browser-games repository][browser-games] and use the fork as your project artifact. + +Implement the **Platform** game from the list in the [games.md][games-list] file. + + + +## Context + +This goal will challenge your ability to take a _formal, defined system_ from the real world and replicate it in code. You will start with all of the logic of the system (the rules of the game) and most of the UI already designed. + +Your work will be mainly in deciding how to replicate that formal logic and user interface using only JavaScript, HTML, and CSS. + +## Specifications + +#### General + +- [x] Artifact produced is a fork of the [browser-games][browser-games] repo. +- [ ] Variables, functions, files, etc. have appropriate and meaningful names. +- [ ] HTML, CSS, and JS files are well formatted with proper spacing and indentation. +- [ ] There is a clear separation of game logic code from view/rendering code. +- [ ] All major features are added via pull requests with a clear description and concise commit messages. +- [ ] The artifact produced is properly licensed, preferably with the [MIT license][mit-license]. + +#### Generic Platform Game + +- [ ] Game can be found at `public/platform.html` +- [ ] Game is playable by one player +- [ ] Game follows rules established in [tutorial](http://eloquentjavascript.net/15_game.html) +- [ ] Game page is linked from `public/index.html` + +### Stretch + +Design and build your own platform-like game. What else can you build with the techniques you came up with in building the Generic Platform Game? + +- [ ] Game has its own HTML, CSS, and JS +- [ ] Game is playable +- [ ] Game page is linked from `public/index.html` + +## Resources + +- MDN: [Introduction to the DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction) #html #dom #js +- MDN: [Guide to Event Handlers](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers) #dom #js +- Shay Howe: [Learn to Code HTML & CSS](http://learn.shayhowe.com/html-css/) #html #css +- Tutorial: [Project: A Platform Game](http://eloquentjavascript.net/15_game.html) #js #html #dom + +[browser-games]: https://github.com/GuildCrafts/browser-games +[games-list]: https://github.com/GuildCrafts/browser-games/blob/master/games.md +[mit-license]: https://opensource.org/licenses/MIT diff --git a/README.md b/README.md index 09a972f..b38c1a4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +#diminutive-rat +Somaya Bounouar +http://jsdev.learnersguild.org/goals/83-Browser_Games-Basic.html + # Browser Games A collection of games to play in a web browser. See the full list of games in the [games.md](games.md) file. diff --git a/public/css/simon.css b/public/css/simon.css new file mode 100644 index 0000000..b2b1fcd --- /dev/null +++ b/public/css/simon.css @@ -0,0 +1,116 @@ +body { + font-family: Arial, serif; + color: black; + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ + -o-user-select: none; + user-select: none; + background: white; +} + +ul { + list-style: none; +} + +ul, li { + padding: 0; + margin: 0; +} + +p[data-action="lose"] { + display: none; +} + +.active { + opacity: 1 !important; +} + +.wrapper { + width: 540px; + margin: 0 auto; + margin-top: 90px; +} + +/*.container { + width: 305px; +}*/ + +.simon { + /*background: white;*/ + position: relative; + float: left; + margin-right: 3em; + width: 295px; + height: 290px; + /*-webkit-border-radius: 150px 150px 150px 150px; + border-radius: 150px 150px 150px 150px;*/ + /*-moz-box-shadow: 2px 1px 12px #aaa; + -webkit-box-shadow: 2px 1px 12px #aaa; + -o-box-shadow: 2px 1px 12px #aaa; + box-shadow: 2px 1px 12px #aaa;*/ +} + +.tile { + opacity: 0.7; + -webkit-transition: opacity 250ms ease; + -moz-transition: opacity 250ms ease; + -ms-transition: opacity 250ms ease; + -o-transition: opacity 250ms ease; + transition: opacity 250ms ease; +} + +.tile.lit { + opacity: 1; +} + +.red, .blue, .yellow, .green { + height: 290px; + -webkit-border-radius: 150px 150px 150px 150px; + border-radius: 150px 150px 150px 150px; + position: absolute; + text-indent: 10000px; +} + +.red:hover, .blue:hover, .yellow:hover, .green:hover { + border: 2px solid black; +} + +.red { + background: #b00101; + clip: rect(0px, 300px, 150px, 150px); + width: 296px; +} + +.blue { + background: #000fd9; + clip: rect(0px, 150px, 150px, 0px); + width: 300px; +} + +.yellow { + background: #deb502; + clip: rect(150px, 150px, 300px, 0px); + width: 300px; +} + +.green { + background: #00850d; + clip: rect(150px,300px, 300px, 150px); + width: 296px; +} + +.game-info button { + width: 5em; + box-sizing: border-box; + font-size: 1.4em; + -webkit-border-radius: 10px 10px 10px 10px; + border-radius: 10px 10px 10px 10px; + background: #6DABE8; + border: none; + padding: 0.3em 0.6em; +} + +.game-info button:hover { + background: #78BCFF; +} diff --git a/public/css/ticTacToe.css b/public/css/ticTacToe.css new file mode 100644 index 0000000..b4ac4cc --- /dev/null +++ b/public/css/ticTacToe.css @@ -0,0 +1,44 @@ +* { + padding: 0px; + margin: 0px; +} + +h1 { + color: white; + margin: 20px; + font-size: 50px; +} +body { + background: #AA3939; + text-align: center; +} + +canvas { + background: #FFAAAA; + transition: transform 1s; + -webkit-transition: -webkit-transform 1s; + -moz-transition: -moz-transform 1s; + -ms-transition: -ms-transform 1s; + -o-transition: -o-transform 1s; + +} + +canvas:hover { + width: 101px; + height: 99px; +} + +#canvasDiv { + margin: 80px auto 40px; + padding-top: -50px; +} + +#reloadButton { + text-decoration: none; + color: white; + font-size: 20px; +} + +#reloadButton:hover { + font-size: 22px; +} diff --git a/public/index.html b/public/index.html index 278d291..1f91f20 100644 --- a/public/index.html +++ b/public/index.html @@ -13,9 +13,8 @@
Sorry, you lost. Try again!
+diff --git a/public/js/simon.js b/public/js/simon.js new file mode 100644 index 0000000..c63ce3b --- /dev/null +++ b/public/js/simon.js @@ -0,0 +1,104 @@ + +var sequence = [] +var copy = [] +var round = 0 +var active = true + +var startGame = function() { + document.querySelector('[data-action="lose"]').style.visibility = "hidden" + sequence = [] + copy = [] + round = 0 + active = true + newRound() +} + +var newRound = function() { + document.querySelector('[data-round]').innerHTML = ++round + sequence.push(randomNumber()) + copy = sequence.slice(0) + animate(sequence) +} + +var randomNumber = function() { + return Math.floor((Math.random()*4)+1) +} + +var animate = function(sequence) { + var i = 0 + var interval = setInterval(function() { + playSound(sequence[i]) + lightUp(sequence[i]) + + i++ + if (i >= sequence.length) { + clearInterval(interval) + activateSimonBoard() + } + }, 600) +} + +var playSound = function(tile) { + let audio = document.createElement('audio') + audio.setAttribute('autoplay', true) + let source1 = document.createElement('source') + source1.src = 'js/simonSounds/' + tile + '.ogg' + source1.type = 'audio/ogg' + let source2 = document.createElement('source') + source2.src = 'js/simonSounds/' + tile + '.mp3' + source2.type = 'audio/mp3' + audio.appendChild(source1) + audio.appendChild(source2) + document.querySelector('[data-action="sound"]').appendChild(audio) +} + +var lightUp = function(tile) { + var tileDom = document.querySelector('[data-tile="' + tile + '"]') + tileDom.className += ' lit' + window.setTimeout(function() { + tileDom.classList.remove('lit') + }, 300) +} + +var activateSimonBoard = function() { + document.querySelector('.simon').addEventListener('click', function(event) { + let num = event.target.getAttribute('data-tile') + registerClick(num) + }) + document.querySelector('[data-tile]').className += ' hoverable' +} + +var registerClick = function(num) { + var desiredResponse = copy.shift() + var actualResponse = num + active = (desiredResponse == actualResponse) + checkLose() +} + +var checkLose = function() { + if (copy.length === 0 && active) { + deactivateSimonBoard() + newRound() + } else if (!active) { + deactivateSimonBoard() + endGame() + } +} + +var deactivateSimonBoard = function() { + document.querySelector('.tile').removeEventListener('click', function() { + }) + document.querySelector('[data-tile]').classList.remove('hoverable') +} + +var endGame = function() { + document.querySelector('[data-action="lose"]').style.visibility = "visible" +} + + + +window.onload = function() { + document.querySelector('[data-action=start]').addEventListener('click', function() { + startGame() + }) +} diff --git a/public/js/simonSounds/1.mp3 b/public/js/simonSounds/1.mp3 new file mode 100644 index 0000000..17a585e Binary files /dev/null and b/public/js/simonSounds/1.mp3 differ diff --git a/public/js/simonSounds/1.ogg b/public/js/simonSounds/1.ogg new file mode 100755 index 0000000..531699d Binary files /dev/null and b/public/js/simonSounds/1.ogg differ diff --git a/public/js/simonSounds/2.mp3 b/public/js/simonSounds/2.mp3 new file mode 100644 index 0000000..f42b0e2 Binary files /dev/null and b/public/js/simonSounds/2.mp3 differ diff --git a/public/js/simonSounds/2.ogg b/public/js/simonSounds/2.ogg new file mode 100755 index 0000000..7408422 Binary files /dev/null and b/public/js/simonSounds/2.ogg differ diff --git a/public/js/simonSounds/3.mp3 b/public/js/simonSounds/3.mp3 new file mode 100644 index 0000000..d1e7688 Binary files /dev/null and b/public/js/simonSounds/3.mp3 differ diff --git a/public/js/simonSounds/3.ogg b/public/js/simonSounds/3.ogg new file mode 100755 index 0000000..127a0b2 Binary files /dev/null and b/public/js/simonSounds/3.ogg differ diff --git a/public/js/simonSounds/4.mp3 b/public/js/simonSounds/4.mp3 new file mode 100644 index 0000000..0bb7c86 Binary files /dev/null and b/public/js/simonSounds/4.mp3 differ diff --git a/public/js/simonSounds/4.ogg b/public/js/simonSounds/4.ogg new file mode 100755 index 0000000..4734d3b Binary files /dev/null and b/public/js/simonSounds/4.ogg differ diff --git a/public/js/ticTacToe.js b/public/js/ticTacToe.js new file mode 100644 index 0000000..37257ee --- /dev/null +++ b/public/js/ticTacToe.js @@ -0,0 +1,134 @@ +var button = [] +for(var i = 1; i < 10; i++) { + button[i] = document.getElementById('canvas'+ i) +} + +var canvasContext = [] +for(var i = 1; i < 10; i++) { + canvasContext[i] = button[i].getContext('2d') +} + +var buttonDisabled = [] +for(var i = 1; i < 10; i++) { + buttonDisabled[i] = false +} + +var isGameOver = false +var btnContent = [] +var isComputerTurn = false + + +function loop(currentButton) { //Need help giving this function a better name + if (isGameOver || isComputerTurn) return + if(!buttonDisabled[currentButton]) { + buttonDisabled[currentButton] = true + button[currentButton].style.opacity = 0.7 + btnContent[currentButton] = 'x' + + button[currentButton].style.Transform = 'rotateY(180deg)' + button[currentButton].style.webkitTransform = 'rotateY(180deg)' + button[currentButton].style.mozTransform = 'rotateY(180deg)' + button[currentButton].style.msTransform = 'rotateY(180deg)' + button[currentButton].style.oTransform = 'rotateY(180deg)' + + isComputerTurn = true + checkWinner() + + setTimeout(function(){ + canvasContext[currentButton].lineWidth = 3 + canvasContext[currentButton].beginPath() + canvasContext[currentButton].moveTo(10,10) + canvasContext[currentButton].lineTo(90,90) + canvasContext[currentButton].moveTo(90,10) + canvasContext[currentButton].lineTo(10,90) + canvasContext[currentButton].stroke() + canvasContext[currentButton].closePath() + + computerTurn() + }, 300) + } +} + +function computerTurn() { + if(isGameOver) return + var random = Math.random() + + if(random < 0.1 && !buttonDisabled[1]) { + draw0(1) + } else if(random < 0.2 && !buttonDisabled[2]) { + draw0(2) + } else if(random < 0.3 && !buttonDisabled[3]) { + draw0(3) + } else if(random < 0.4 && !buttonDisabled[4]) { + draw0(4) + } else if(random < 0.5 && !buttonDisabled[5]) { + draw0(5) + } else if(random < 0.6 && !buttonDisabled[6]) { + draw0(6) + } else if(random < 0.7 && !buttonDisabled[7]) { + draw0(7) + } else if(random < 0.8 && !buttonDisabled[8]) { + draw0(8) + } else if(random < 1 && !buttonDisabled[9]) { + draw0(9) + } + checkWinner() +} + +function draw0(x) { + buttonDisabled[x] = true + button[x].style.opacity = 0.7 + btnContent[x] = '0' + button[x].style.webkitTransform = "rotateX(180deg)" + + setTimeout(function(){ + canvasContext[x].beginPath() + canvasContext[x].lineWidth = 3 + canvasContext[x].arc(50,50,34,0,Math.PI*2,false) + canvasContext[x].stroke() + canvasContext[x].closePath() + isComputerTurn = false + }, 300) +} + +function checkWinner(){ + if(!isGameOver){ + if(btnContent[1] == 'x' && btnContent[2] == 'x' && btnContent[3] == 'x') showWinner('You won!') + else if(btnContent[4] == 'x' && btnContent[5] == 'x' && btnContent[6] == 'x') showWinner('You won!') + else if(btnContent[7] == 'x' && btnContent[8] == 'x' && btnContent[9] == 'x') showWinner('You won!') + else if(btnContent[1] == 'x' && btnContent[4] == 'x' && btnContent[7] == 'x') showWinner('You won!') + else if(btnContent[2] == 'x' && btnContent[5] == 'x' && btnContent[8] == 'x') showWinner('You won!') + else if(btnContent[3] == 'x' && btnContent[6] == 'x' && btnContent[9] == 'x') showWinner('You won!') + else if(btnContent[1] == 'x' && btnContent[5] == 'x' && btnContent[9] == 'x') showWinner('You won!') + else if(btnContent[3] == 'x' && btnContent[5] == 'x' && btnContent[7] == 'x') showWinner('You won!') + + else if(btnContent[1] == '0' && btnContent[2] == '0' && btnContent[3] == '0') showWinner('You lost!') + else if(btnContent[4] == '0' && btnContent[5] == '0' && btnContent[6] == '0') showWinner('You lost!') + else if(btnContent[7] == '0' && btnContent[8] == '0' && btnContent[9] == '0') showWinner('You lost!') + else if(btnContent[1] == '0' && btnContent[4] == '0' && btnContent[7] == '0') showWinner('You lost!') + else if(btnContent[2] == '0' && btnContent[5] == '0' && btnContent[8] == '0') showWinner('You lost!') + else if(btnContent[3] == '0' && btnContent[6] == '0' && btnContent[9] == '0') showWinner('You lost!') + else if(btnContent[1] == '0' && btnContent[5] == '0' && btnContent[9] == '0') showWinner('You lost!') + else if(btnContent[3] == '0' && btnContent[5] == '0' && btnContent[7] == '0') showWinner('You lost!') + + else if( + (btnContent[1] == 'x' || btnContent[1] == '0') && + (btnContent[2] == 'x' || btnContent[2] == '0') && + (btnContent[3] == 'x' || btnContent[3] == '0') && + (btnContent[4] == 'x' || btnContent[4] == '0') && + (btnContent[5] == 'x' || btnContent[5] == '0') && + (btnContent[6] == 'x' || btnContent[6] == '0') && + (btnContent[7] == 'x' || btnContent[7] == '0') && + (btnContent[8] == 'x' || btnContent[8] == '0') && + (btnContent[9] == 'x' || btnContent[9] == '0') + ) + showWinner("It's a draw. Play again!") + } +} + +function showWinner(message){ + isGameOver = true + setTimeout(function() { + alert(message) + }, 1000) +} diff --git a/public/simon.html b/public/simon.html new file mode 100644 index 0000000..0e992f9 --- /dev/null +++ b/public/simon.html @@ -0,0 +1,41 @@ + + +
+ +
+ + + + +
+