diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..c4190194 Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md index 317a3e58..691f036f 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,192 @@ -# Project Name (Start editing here) - +# Yuki Tsuboniwa: "Project #1" + -#  Project #1: The Game +#  Project #1: My Space Invader -### Overview - -Let's start out with something fun - **a game!** - -Everyone will get a chance to **be creative**, and work through some really **tough programming challenges** – since you've already gotten your feet wet with Tic Tac Toe, it's up to you to come up with a fun and interesting game to build. - -**You will be working individually for this project**, but we'll be guiding you along the process and helping as you go. Show us what you've got! - - ---- - -### Technical Requirements - -Your app must: - -* **Render a game in the browser** -* **Any number of players** will be okay, switch turns will be great -* **Design logic for winning** & **visually display which player won** -* **Include separate HTML / CSS / JavaScript files** -* Stick with **KISS (Keep It Simple Stupid)** and **DRY (Don't Repeat Yourself)** principles -* Use **Javascript** for **DOM manipulation**, jQuery is not compulsory -* **Deploy your game online**, where the rest of the world can access it -* Use **semantic markup** for HTML and CSS (adhere to best practices) -* **No canvas** project will be accepted, only HTML5 + CSS3 + JS please - ---- - -### Necessary Deliverables - -* A **working game, built by you**, hosted somewhere on the internet -* A **link to your hosted working game** in the URL section of your GitHub repo -* A **git repository hosted on GitHub**, with a link to your hosted game, and frequent commits dating back to the very beginning of the project -* **A ``readme.md`` file** with explanations of the technologies used, the approach taken, installation instructions, unsolved problems, etc. - ---- - -### Suggested Ways to Get Started +https://yukitsuboniwa.github.io/project-1/ -* **Break the project down into different components** (data, presentation, views, style, DOM manipulation) and brainstorm each component individually. Use whiteboards! -* **Use your Development Tools** (console.log, inspector, alert statements, etc) to debug and solve problems -* Work through the lessons in class & ask questions when you need to! Think about adding relevant code to your game each night, instead of, you know... _procrastinating_. -* **Commit early, commit often.** Don’t be afraid to break something because you can always go back in time to a previous version. -* **Consult documentation resources** (MDN, jQuery, etc.) at home to better understand what you’ll be getting into. -* **Don’t be afraid to write code that you know you will have to remove later.** Create temporary elements (buttons, links, etc) that trigger events if real data is not available. For example, if you’re trying to figure out how to change some text when the game is over but you haven’t solved the win/lose game logic, you can create a button to simulate that until then. - ---- - -### Potential Project Ideas - -##### Blackjack -Make a one player game where people down on their luck can lose all their money by guessing which card the computer will deal next! - -##### Self-scoring Trivia -Test your wits & knowledge with whatever-the-heck you know about (so you can actually win). Guess answers, have the computer tell you how right you are! - ---- - -### Useful Resources - -* **[MDN Javascript Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** _(a great reference for all things Vanilla Javascript)_ -* **[jQuery Docs](http://api.jquery.com)** _(if you're using jQuery)_ -* **[GitHub Pages](https://pages.github.com)** _(for hosting your game)_ -* **[How to write readme - Markdown CheatSheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)** _(for editing this readme)_ -* **[How to write a good readme for github repo!](https://gist.github.com/PurpleBooth/109311bb0361f32d87a2)** _(to make it better)_ - ---- - -### Project Feedback + Evaluation - -* __Project Workflow__: Did you complete the user stories, wireframes, task tracking, and/or ERDs, as specified above? Did you use source control as expected for the phase of the program you’re in (detailed above)? - -* __Technical Requirements__: Did you deliver a project that met all the technical requirements? Given what the class has covered so far, did you build something that was reasonably complex? - -* __Creativity__: Did you add a personal spin or creative element into your project submission? Did you deliver something of value to the end user (not just a login button and an index page)? - -* __Code Quality__: Did you follow code style guidance and best practices covered in class, such as spacing, modularity, and semantic naming? Did you comment your code as your instructors have in class? +### Overview -* __Deployment__: Did you deploy your application to a public url using GitHub Pages? + My Space Invader Game is designed for players who likes to play a never ending game where you rack up points until the player dies. The key to the game is to survive as long as possible while getting points by shooting enemies. The longer you survive more enemies will spawn and the faster they will get. It's game over if one of the enemy sprite touches the player sprite. Player wins by beating the high score. It is a game that is inspired by the classic Space Invader game with a slight difference in gameplay. -* __Total__: Your instructors will give you a total score on your project between: +### Game Instructions - Score | Expectations - ----- | ------------ - **0** | _Incomplete._ - **1** | _Does not meet expectations._ - **2** | _Meets expectations, good job!_ - **3** | _Exceeds expectations, you wonderful creature, you!_ +Move Player = Arrow keys (← ↑ ↓ →) - This will serve as a helpful overall gauge of whether you met the project goals, but __the more important scores are the individual ones__ above, which can help you identify where to focus your efforts for the next project! +Fire Laser = Spacebar + +Click the "Instructions" to view the instructions of the game once your ready click Start to begin playing! + +### Game Flowchart + + + + +### Assets + +1. Game Layout + +  + +2. Characters + +  = PLAYER + +  = LASER + +  = ENEMY + + +### Code Snippets + +* For the player's movement/control I used the keyCodes of the keyboard to move by pressing the arrow keys and fire lasers when pressing the Spacebar + +``` +var leftKey = 37 +var upKey = 38 +var rightKey = 39 +var downKey = 40 +var spaceKey = 32 + +function pressKey(keyCode, isPressed) { + // console.log(keyCode) + if (keyCode == leftKey) { + controller.left = isPressed + } + if (keyCode == upKey) { + controller.up = isPressed + } + if (keyCode == rightKey) { + controller.right = isPressed + } + if (keyCode == downKey) { + controller.down = isPressed + } + if (keyCode == spaceKey) { + controller.space = isPressed + } +} + +document.onkeydown = function(event) { + pressKey(event.keyCode, true) +} + +document.onkeyup = function(event) { + pressKey(event.keyCode, false) +} + +var controller = new Object() +var playerMovement = 10 + +function handleControls() { + + if (controller.left) { + player.x -= playerMovement + } + if (controller.up) { + player.y -= playerMovement + } + if (controller.right) { + player.x += playerMovement + } + if (controller.down) { + player.y += playerMovement + } + if (controller.space && laser.y <= 0) { + laser.x = player.x + 15 + laser.y = player.y - laser.h + laserSound() + } +} +``` +* To create and spawn my enemies I created an array to place all my enemies and I also created a random number function to add some randomness to how the enemy will behave and spawn the iteration is where the difficulty of the game is changed over time + +``` +var enemies = new Array() +var iterations = 0 +function addEnemy() { + var interval = 50 + for (var i = 0; i < enemies.length; i++) { + if (iterations > 2000) { + interval = 5 + enemies[i].y += getRandom(50) + enemies[i].x += getRandom(7) - 3 + } else if (iterations > 1500) { + interval = 5 + enemies[i].y += getRandom(25) + enemies[i].x += getRandom(7) - 3 + } else if (iterations > 1000) { + interval = 15 + enemies[i].y += getRandom(18) + enemies[i].x += getRandom(7) - 3 + } else if (iterations > 500) { + interval = 35 + enemies[i].y += getRandom(12) + enemies[i].x += getRandom(7) - 3 + } + iterations++ + } + if (getRandom(interval) == 0) { + var elementName = 'enemy' + getRandom(100000000) + var enemy = new Object() + enemy.element = elementName + enemy.x = getRandom(480) + enemy.y = 0 + enemy.w = 40 + enemy.h = 40 + + var createEnemy = document.createElement('div') + createEnemy.id = enemy.element + createEnemy.className = 'enemy' + document.getElementById('background').appendChild(createEnemy) + enemies[enemies.length] = enemy + } +} + +function getRandom(max) { + return parseInt(Math.random() * max) +} + ``` + +* My collision function is how my characters interacts with each other and other elements of the game I used an intersect function by using the dimension and axis of the objects that when a > b and b > a the collision happens. + +``` +function intersect(a,b) { + return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y +} + +function checkCollision() { + for (var i = 0; i < enemies.length; i++) { + if (intersect(laser, enemies[i])) { + var element = document.getElementById(enemies[i].element); + element.style.visibility = 'hidden'; + element.parentNode.removeChild(element); + enemies.splice(i, 1); + i--; + laser.y = -laser.h + $('#laser').css('visibility', 'hidden') + collideSound() + score += 100 + + } else if (intersect(player, enemies[i])) { + collideSound() + gameOver() + + } else if (enemies[i].y + enemies[i].h >= 495) { + var element = document.getElementById(enemies[i].element); + element.style.visibility = 'hidden'; + element.parentNode.removeChild(element); + enemies.splice(i, 1); + i--; + + } else if (laser.y + laser.h <= 5) { + $('#laser').css('visibility', 'hidden') + } +} +``` + +### Reference + +1.[Space Invader Tutorial](https://sites.google.com/site/wecanprogramcom/html-and-javascript/web-development-level2/lesson-1-setting-up-the-first-sprite) + +2.[Additional Infos and Sources "Copyright (C) 2012 Steven Lambert"](https://github.com/straker/galaxian-canvas-game) diff --git a/assets/.DS_Store b/assets/.DS_Store new file mode 100644 index 00000000..6790dd41 Binary files /dev/null and b/assets/.DS_Store differ diff --git a/assets/css/style.css b/assets/css/style.css new file mode 100644 index 00000000..32b921df --- /dev/null +++ b/assets/css/style.css @@ -0,0 +1,93 @@ +body { + background: url('../img/spacebg.jpg') +} + +h1, h3 { + display: flex; + justify-content: center; + color: #ffffff; + font-family: Desdemona; +} + +p { + color: #ffffff; + font-family: Papyrus; + +} + +#container { + width: 500px; + margin: 0 auto; +} + +#background { + background: url('../img/bg2.png'); + width: 500px; + height: 500px; + position: absolute; + border: 5px solid orange; +} + +#player { + background: url('../img/ship.png') no-repeat; + width: 38px; + height: 38px; + position: absolute; + visibility: hidden; +} + +#laser { + background: url('../img/bullet.png') no-repeat; + width: 12px; + height: 15px; + position: absolute; + visibility: hidden; +} +.enemy { + background: url('../img/enemy1.png'); + width: 50px; + height: 50px; + position: absolute; +} +#score { + color: #ffffff; + font-size: 18pt; + position: absolute; + left: 20px; + top: 20px; +} + +#highscore { + color: #ffffff; + font-size: 18pt; + position: absolute; + left: 270px; + top: 20px; +} + +#gameover { + color: purple; + font-size: 20px; + position: absolute; + left: 190px; + top: 190px; + visibility: hidden; +} + +#start { + color: #ffffff; + font-size: 20px; + position: absolute; + left: 220px; + top: 200px; +} + +span { + cursor: pointer; + display: flex; + justify-content: center; +} + +span:hover { + color: pink; +} diff --git a/assets/css/stylesheet.css b/assets/css/stylesheet.css deleted file mode 100644 index e69de29b..00000000 diff --git a/assets/img/.DS_Store b/assets/img/.DS_Store new file mode 100644 index 00000000..088cc10e Binary files /dev/null and b/assets/img/.DS_Store differ diff --git a/assets/img/bg2.png b/assets/img/bg2.png new file mode 100755 index 00000000..c5ad05b0 Binary files /dev/null and b/assets/img/bg2.png differ diff --git a/assets/img/bullet.png b/assets/img/bullet.png new file mode 100755 index 00000000..627d3ce7 Binary files /dev/null and b/assets/img/bullet.png differ diff --git a/assets/img/enemy1.png b/assets/img/enemy1.png new file mode 100755 index 00000000..f73c0ca1 Binary files /dev/null and b/assets/img/enemy1.png differ diff --git a/assets/img/gamemap.png b/assets/img/gamemap.png new file mode 100644 index 00000000..a0e50257 Binary files /dev/null and b/assets/img/gamemap.png differ diff --git a/assets/img/ship.png b/assets/img/ship.png new file mode 100755 index 00000000..1807f727 Binary files /dev/null and b/assets/img/ship.png differ diff --git a/assets/img/spacebg.jpg b/assets/img/spacebg.jpg new file mode 100644 index 00000000..f4e51aaa Binary files /dev/null and b/assets/img/spacebg.jpg differ diff --git a/assets/img/spaceinvaderflowchart.jpg b/assets/img/spaceinvaderflowchart.jpg new file mode 100644 index 00000000..e08cc3e9 Binary files /dev/null and b/assets/img/spaceinvaderflowchart.jpg differ diff --git a/assets/img/spaceinvaderflowchartupdated.png b/assets/img/spaceinvaderflowchartupdated.png new file mode 100644 index 00000000..b9053541 Binary files /dev/null and b/assets/img/spaceinvaderflowchartupdated.png differ diff --git a/assets/img/starsbackground.jpg b/assets/img/starsbackground.jpg new file mode 100644 index 00000000..823cfdc6 Binary files /dev/null and b/assets/img/starsbackground.jpg differ diff --git a/assets/js/script.js b/assets/js/script.js index e69de29b..8607991b 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -0,0 +1,357 @@ +// start the game +function start() { + init() + $('#start').css('visibility', 'hidden') +} + +function init() { + +// create objects here +var player = new Object() +player.element = 'player' +player.x = 250 +player.y = 450 +player.w = 38 +player.h = 38 +$('#player').css('visibility', 'visible') + +var laser = new Object() +laser.element = 'laser' +laser.x = 0 +laser.y = 0 +laser.w = 12 +laser.h = 15 + +// create an object for the controls +var controller = new Object() + +//create an enemy Array +var enemies = new Array() + + +// keycode of controller +var leftKey = 37 +var upKey = 38 +var rightKey = 39 +var downKey = 40 +var spaceKey = 32 + +// player movement speed +var playerMovement = 10 + + +// set up our control keys +function pressKey(keyCode, isPressed) { + // console.log(keyCode) + if (keyCode == leftKey) { + controller.left = isPressed + } + if (keyCode == upKey) { + controller.up = isPressed + } + if (keyCode == rightKey) { + controller.right = isPressed + } + if (keyCode == downKey) { + controller.down = isPressed + } + if (keyCode == spaceKey) { + controller.space = isPressed + } +} + +document.onkeydown = function(event) { + pressKey(event.keyCode, true) +} + +document.onkeyup = function(event) { + pressKey(event.keyCode, false) +} + +// input controls to player +function handleControls() { + + if (controller.left) { + player.x -= playerMovement + } + if (controller.up) { + player.y -= playerMovement + } + if (controller.right) { + player.x += playerMovement + } + if (controller.down) { + player.y += playerMovement + } + if (controller.space && laser.y <= 0) { + laser.x = player.x + 15 + laser.y = player.y - laser.h + $('#laser').css('visibility', 'visible') + laserSound() + } +// it ensures that my character will not go out of the game map + ensureBounds(player) +} + +// set the position of our objects +function setPosition(sprite) { + var e = document.getElementById(sprite.element) + e.style.left = sprite.x + 'px' + e.style.top = sprite.y + 'px' +} + +var score = 0 + +var highscore = localStorage.getItem("highscore") + +// to reset highscore +// localStorage.setItem("highscore", score); + +// load the elements to the game layout +function showSprites() { + setPosition(player) + setPosition(laser) + + for (var i = 0; i < enemies.length; i++) { + setPosition(enemies[i]) + } + + var scoreElement = document.getElementById('score'); + scoreElement.innerHTML = 'SCORE: ' + score; + + // create a highscore function to keep track player highest score + var highScoreElement = document.getElementById('highscore'); + highScoreElement.innerHTML = 'HIGH SCORE: ' + localStorage.getItem("highscore"); + + if (score > localStorage.getItem("highscore")) { + localStorage.setItem("highscore", score); + } +} + +// to update the position of object that player cannot control +function updatePosition() { + // update position of enemy + for (var i = 0; i < enemies.length; i++) { + enemies[i].y += getRandom(7) + enemies[i].x += getRandom(7) - 3 + ensureBounds(enemies[i]) + } + // adjust for the rate of speed of laser + laser.y -= 25 +} + +// to keep the objects inside of the game map +function ensureBounds(sprite) { + if (sprite.x < 5) { + sprite.x = 5 + } + if (sprite.y < 5) { + sprite.y = 5 + } + if (sprite.x + sprite.w > 495) { + sprite.x = 495 - sprite.w + } + if (sprite.y + sprite.h > 495) { + sprite.y = 495 - sprite.h + } +} + +var iterations = 0 +// add enemy to the game map +function addEnemy() { + // how to add more enemy when time passes by + var interval = 50 + for (var i = 0; i < enemies.length; i++) { + if (iterations > 2000) { + interval = 5 + enemies[i].y += getRandom(35) + enemies[i].x += getRandom(7) - 3 + } else if (iterations > 1500) { + interval = 5 + enemies[i].y += getRandom(25) + enemies[i].x += getRandom(7) - 3 + } else if (iterations > 1000) { + interval = 15 + enemies[i].y += getRandom(18) + enemies[i].x += getRandom(7) - 3 + } else if (iterations > 500) { + interval = 30 + enemies[i].y += getRandom(12) + enemies[i].x += getRandom(7) - 3 + } + ensureBounds(enemies[i]) + // console.log(iterations) +} + // this will create the random enemies that will be placed in an array + if (getRandom(interval) == 0) { + var elementName = 'enemy' + getRandom(100000000) + var enemy = new Object() + enemy.element = elementName + enemy.x = getRandom(480) + enemy.y = 0 + enemy.w = 40 + enemy.h = 40 + + var createEnemy = document.createElement('div') + createEnemy.id = enemy.element + createEnemy.className = 'enemy' + document.getElementById('background').appendChild(createEnemy) + // $("#background").append(createEnemy) + enemies[enemies.length] = enemy + } + } + + +// get random number for enemies function +function getRandom(max) { + return parseInt(Math.random() * max) +} + + +// now to check for collision when element intersect with each other +function intersect(a,b) { + return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y +} + +// check for collision function +function checkCollision() { + // laser collide with enemies + for (var i = 0; i < enemies.length; i++) { + if (intersect(laser, enemies[i])) { + var element = document.getElementById(enemies[i].element); + element.style.visibility = 'hidden'; + element.parentNode.removeChild(element); + enemies.splice(i, 1); + i--; + // console.log(element) + laser.y = -laser.h // this ensures that it also gets deleted after hitting an enemy + $('#laser').css('visibility', 'hidden') + collideSound() + score += 100 + + // hero collide with enemies + } else if (intersect(player, enemies[i])) { + collideSound() + gameOver() + + // and if uncontrollable object collide with edge of game map + } else if (enemies[i].y + enemies[i].h >= 495) { + var element = document.getElementById(enemies[i].element); + element.style.visibility = 'hidden'; + element.parentNode.removeChild(element); + enemies.splice(i, 1); + i--; + } + } + if (laser.y + laser.h <= 5) { + $('#laser').css('visibility', 'hidden') + // console.log($('#laser').position()) + // console.log($('#background').position()) + } + +} + +// this will run the events in our game to keep the gameplay smooth +// var lastLoopRun = 0 +// if (new Date().getTime() - lastLoopRun > 40) {} +// lastLoopRun = new Date().getTime() +function gameLoop() { + + updatePosition() + + handleControls() + + checkCollision() + + addEnemy() + + showSprites() + + iterations++ // it creates the difficulty component by increasing speed & number of enemies as it increases + console.log(iterations) +} + +var game = setInterval(function() { + gameLoop() +}, 40) // can also put 40 milliseconds to run the same without if statement in gameLoop + + + +function gameOver() { + // var element = document.getElementById(player.element); + // element.style.visibility = 'hidden'; + // element = document.getElementById('gameover'); + // element.style.visibility = 'visible'; + $('#gameover').css('visibility', 'visible') + $('#player').css('visibility', 'hidden') + $('.enemy').css('visibility', 'hidden') + $('#laser').css('visibility', 'hidden') + + gameOverSound() + + // stop game music to let game over music play + stop() + + // this stops all functions in the gameLoop + clearInterval(game) + +// alert player if he gets new High Score + // if (score > highscore) + // alert("Good Job!!! NEW HIGH SCORE!!!") + // else + // alert("Try Again!") +} + + + + +// Add sounds to the game + +var gameAudio = document.createElement('audio') + gameAudio.src = './assets/sounds/kick_shock.wav' + gameAudio.autoplay = true + gameAudio.loop = true + gameAudio.volume = 0.3 + document.body.appendChild(gameAudio) + +function play() { + gameAudio.play() +} +play() + +function stop() { + gameAudio.pause() +} + +function laserSound() { + var audio = document.createElement('audio') + audio.src = './assets/sounds/shot.mp3' + audio.autoplay = true + audio.play() + audio.volume = 0.3 +} + +function collideSound() { + var audio = document.createElement('audio') + audio.src = './assets/sounds/explo.mp3' + audio.autoplay = true + audio.play() + audio.volume = 0.3 +} + +function gameOverSound() { + var audio = document.createElement('audio') + audio.src = './assets/sounds/game_over.wav' + audio.autoplay = true + audio.loop = true + audio.play() + audio.volume = 0.5 +} + + +} + +// reload the game +function reload() { + location.reload() +} diff --git a/assets/sounds/explo.mp3 b/assets/sounds/explo.mp3 new file mode 100755 index 00000000..b5e804a4 Binary files /dev/null and b/assets/sounds/explo.mp3 differ diff --git a/assets/sounds/explosion.wav b/assets/sounds/explosion.wav new file mode 100644 index 00000000..ae6c7294 Binary files /dev/null and b/assets/sounds/explosion.wav differ diff --git a/assets/sounds/game_over.wav b/assets/sounds/game_over.wav new file mode 100644 index 00000000..0c8bc695 Binary files /dev/null and b/assets/sounds/game_over.wav differ diff --git a/assets/sounds/kick_shock.wav b/assets/sounds/kick_shock.wav new file mode 100644 index 00000000..2297af7e Binary files /dev/null and b/assets/sounds/kick_shock.wav differ diff --git a/assets/sounds/shot.mp3 b/assets/sounds/shot.mp3 new file mode 100755 index 00000000..1ac12fad Binary files /dev/null and b/assets/sounds/shot.mp3 differ diff --git a/index.html b/index.html index 5b002212..7ad8e39f 100644 --- a/index.html +++ b/index.html @@ -2,10 +2,44 @@
-START
Restart