diff --git a/README.md b/README.md index 317a3e58..55ff7c67 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,176 @@ -# Project Name (Start editing here) - - -# ![](https://ga-dash.s3.amazonaws.com/production/assets/logo-9f88ae6c9c3871690e33280fcf557f33.png) Project #1: The Game - +# Project 1: Maplestory XII ### 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 - -* **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. +Game is based on **Maplestory**, a Mass Multiplayer Online Role Playing Game (MMORPG) + +[Online Version](https://josephpung.github.io/project-1/) +## Controls +- Left and Right arrow keys to move horizontally +- Space to jump +- "C" to attack +- "D" for skill 1 +- "X" for skill 2 +- "Z" for skill 3 + +### Instructions + +Control your character and avoid dying to the mobs spawned, your character has a mana pool as well as a hitpoint pool. If your mana pool is depleted, you will not be able to use any skills till it regenerates. Once your hitpoint pool reaches zero, you die and the game ends. + +Kill enough mobs and the boss awaits you! + + +### Idea Path +Drafting of idea and concept came about as I wanted to try and challenge myself to duplicate the play area and game code of Maplestory. I wanted to recreate a single map with all platforms as well as logical functions ( projectiles, knock-back, jump) + +###### Phase 1 +Drafted a playing field and added the necessary main elements of the game. Tested linking of movement to key presses and automation of Mob path. + +##### Phase 2 +Testing and added the projectile logic, idea starts to seem a bit far fetched due to the fact that it will be difficult to control so many mobs and bullets at the same time since the mobs are continuously moving and had individual hit points. + +###### Phase 3 +Reduced idea to just spawning mobs on a single map and using one bullet to minimize coding load. Decided to add hitpoints and mana tracking for the player to make things more interactive. + +Recoded the spawning function with help from soe min and solved the issue surrounding the different mob's with different and varying hit points. + +Added player skills as well. + +###### Final Phase +Added CSS styling as well as boss functions and restart functions. Game is stable but still buggy. + +## Game Logic +Mob and Boss spawns are controlled by classes pre set to contain the necessary information like their damage and hit points. Boss is spawned and linked to the DOM via a jquery target. That on its own allows me to control the object that is spawned to the smallest of changes. +``` +class Boss { // Class to spawn boss + + constructor (id) { + this.id = id + this.hitPoints = 500 + this.damage = 3 + this.bosscheck = true + this.jTarget = $('body').find(`#${this.id}`) + this.width = this.jTarget.css('width') + this.height = this.jTarget.css('height') + + setInterval(() => { + this.positionCheck() + }, 1000) + } + + positionCheck () { + var speed = Math.floor(Math.random() * 30) + var mobPosition = this.jTarget.position() + if (mobPosition.left < 400) { + *** + }) + } + } + + addBoss () { + var location = Math.floor(Math.random() * 380) + var spawnMob = $('
') + spawnMob.attr('id', this.id) + + $('.topContainer').append(spawnMob) + this.jTarget = $('body').find(`#${this.id}`) + **** + }) + } + +} +``` + +- The bullet is set to travel across the screen and check for collisions along the way and reduce the mob's hitpoints if a collision is detected, any changes in the amount of mobs is also registered and the game is ended/ moved on to the next level as necessary. +``` + + function bulletCollisionCheck (obj1, obj2) { //bullet collision check + if (blueX < redX + obj1.width() && + blueX + obj2.jTarget.width() > redX && + blueY < redX + obj1.height() && + obj2.jTarget.height() + blueY > redY) { + obj2.hitPoints -= 1 + $bullet.css('left', $playPos.left) + $bullet.css('top', '620px') + if (obj2.hitPoints === 0) { + obj2.jTarget.remove() + ////// + } + } + if (mobsOnScreen === 0 && levelOneMobCount === 0) { //if mobs are dead, spawn boss + bossLevel = true + } + if (bossLevel === true && bossDead === true) { //if boss is dead, end game + gameEnd = true + } + return true + } else { return false } + } +``` +- Skills are also added to add variety to the playstyle as per the original game. Each skills has different damage results as well as mana costs. The mama required to cast each skill is set to regenerate automatically. +``` +function skillOne () { // small damage skill + if (mana >= 10) { + mana -= 10 + $mpBar.text(`${mana}/200`) + $mpBar.css('width', `${$mpBar.width() - 10}px`) + $firstSkillDiv.css('visibility', 'visible') // show skill animation and hide after 800 ms + setTimeout(function () { + $firstSkillDiv.css('visibility', 'hidden') + }, 800) + + for (key in mobArray) { // test for mobs +///////////////- + } + } + for (key in bossArray) { // test for boss + bossArray[key].hitPoints -= 10 + if (bossArray[key].hitPoints < 0) { + ////////// + } + } +////////// + } +} +``` + +The game ends when either the player dies or all the mobs are killed as well as the boss. + +### Log +Currently working on making the initial base fighting area and the main player +* 1/10/17 - Added jump capability and changed mob movement to follow player instead of preset axis +* 2/10/17 - Changed CSS styles and edit to fix axis differences +* 3/10/17 - Added health bar and player hit points +* 4/10/17 - Added mana regen and mana bar, replaced manual spawn with class based spawning and added various functions to check for game status. +* 5/10/17 - Added boss and 2 more skills to character, edited main skill and attack functions to accomodate to boss feature + +### Image Log +**29/10/17 (Initial Draft Frame)** +![](/assets/images/old.gif) +**4/10/17** +![](/assets/images/v2.png) +**Final Product [5/10/17]** +![](/assets/images/v3.png) + +### **BUG REPORT** + * Jump is still choppy, unable to remove 1 sec delay from continuous button pressing. + * Collision detection for far left side of the map working properly (0-200px) + * Mobs occasionally not dying, pressing skill button kills them and ends bug + + +### Flowchart + +![](/assets/images/flowchart.jpg) + +## Features To Be Added +1) Proper Jump function +2) More bosses with damage on impact, allowing them to jump to do the damage when they land +3) Adding platforms and ladders for players to climb onto +4) Multi level spawning once platform is available. +5) Improve accuracy and recode collision detection --- - -### 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? - -* __Deployment__: Did you deploy your application to a public url using GitHub Pages? - -* __Total__: Your instructors will give you a total score on your project between: - - Score | Expectations - ----- | ------------ - **0** | _Incomplete._ - **1** | _Does not meet expectations._ - **2** | _Meets expectations, good job!_ - **3** | _Exceeds expectations, you wonderful creature, you!_ - - 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! +## References +* Stackoverflow +* Logo and Text Images - https://textcraft.net/ +* Sprites - Google Images +* Many thanks to the TA's for debugging and Soe Min for his explanation on linking the dom to my object diff --git a/assets/css/style.css b/assets/css/style.css new file mode 100644 index 00000000..d0248354 --- /dev/null +++ b/assets/css/style.css @@ -0,0 +1,269 @@ +body{ + background-color: black; + color: white; + max-width: 1700px; + max-height: 840px; +} +.container{ + /*border: 3px solid red;*/ + height:840px; +} +.topContainer{ + /*border: 2px solid lightblue;*/ + height: 88%; + background-image: url(../images/background.png); + background-size: contain; +} +#restart{ + background-image: url(../images/buttons.png); + width: 170px; + height: 87px; + background-position: 31% 46.5%; + border: none; + position: relative; + top: 40px; + border-radius: 10px; +} +.levelOneGameEnd{ + position: absolute; + text-align: center; + left: 560px; + top:200px; + background-image: url(../images/bossLevel.png); + width: 435px; + height: 100px; + visibility: hidden; +} +.maplestoryImage{ + background-image: url(../images/maplestory.png); + width: 500px; + height: 100px; + position: relative; + top: 80px; + left: 540px; +} +.instructions{ + font-family: 'Lekton'; + text-align: center; + position: relative; + top: 150px; + left: 400px; + width: 800px; +} +.won{ + background-image: url(../images/congratulations.png); + width: 830px; + height: 80px; + position: absolute; + left: 400px; + top: 50px; + /*visibility: hidden;*/ +} +.bottomContainer{ + border: 0px; + height: 12%; + background-image: url(../images/healthBarTest.png); + background-size: contain; + position: relative; +} + +.landingScreen{ + z-index: 9; + background-image: url(../images/landingPage.jpg); + height: 700px; + width: 1550px; + margin: 50px; + background-size: cover; + background-position: bottom; + float: left; + position: relative; + visibility: visible; + border-radius: 20px; +} +.projectile{ + height: 20px; + width: 20px; + position: absolute; + top: 620px; + left:150px; + transition: 0.5s; + background-image: url(../images/bullet.png); + background-position: 16% 15%; + /*visibility: hidden;*/ +} +.miniMap{ + position: absolute; + width: 440px; + height: 200px; + background-image: url(../images/minimap.png); + border-radius: 10px; +} +.skillOne{ + + background-image: url(../images/skill1.gif); + width: 657px; + height: 346px; + position: absolute; + left: 400px; + top: 400px; + visibility: hidden; +} +.skillTwo{ + background-image: url(../images/skill2.gif); + width: 575px; + height: 346px; + position: absolute; + left: 450px; + top: 400px; + visibility: hidden; +} +.skillThree{ + background-image: url(../images/skill4.gif); + width: 600px; + height: 306px; + position: absolute; + left: 450px; + top: 360px; + visibility: hidden; +} +.player{ + z-index: 1; + height: 80px; + width: 60px; + /*border: 2px solid green;*/ + position: absolute; + top: 590px; + left:50px; + transition: 0.8s; + background: url(../images/playerModel.png); + animation: playerPlay 1s steps(4) infinite; + animation-play-state: paused; +} +.playerRight{ + z-index: 1; + height: 80px; + width: 57px; + /*border: 2px solid green;*/ + position: absolute; + top: 560px; + left:50px; + transition: 0.8s; + background: url(../images/playerModelRight.png); + animation: playerPlayRight 1s steps(4) infinite; + animation-play-state: paused; +} +.mob{ + /*border: 1px solid yellow;*/ + position: absolute; + top: 505px; + width: 180px; + height: 170px; + transition: 20s; + background: url(../images/stoneGolem.png); + animation: mobPlay 2s steps(4) infinite; + +} +.mobRight{ + /*border: 1px solid yellow;*/ + position: absolute; + top: 505px; + width: 180px; + height: 170px; + transition: 20s; + background: url(../images/stoneGolemRight.png); + animation: mobPlayRight 4s steps(4) infinite; + +} +.hpBar{ + position: absolute; + text-align: center; + color: white; + left: 747px; + top: 39px; + width: 200px; + height: 14px; + border-radius: 4px; + background-color: red; +} +.mpBar{ + position: absolute; + text-align: center; + color: white; + left: 747px; + top: 59px; + width: 202px; + height: 14px; + border-radius: 4px; + background-color: #4AC9DD; + border-color: white; + border: 1px; +} + +.boss{ + width: 250px; + height: 320px; + position: absolute; + top: 390px; + left: 100px; + transition: 20s; + background: url(../images/boss.png); + animation: bossOne 1s steps(8) infinite; +} +.bossRight{ + width: 250px; + height: 320px; + position: absolute; + top: 390px; + left: 100px; + transition: 20s; + background: url(../images/bossRight.png); + animation: bossRight 1s steps(8) infinite; +} + +@keyframes bossOne { + 0% { + background-position: 0% 0%; + } + 100% { + background-position: 34% 0%; + } } + @keyframes bossRight { + 0% { + background-position: 66% 0%; + } + 100% { + background-position: 100% 0%; + } } + +@keyframes mobPlayRight { + 0% { + background-position: 100% 22%; + } + 100% { + background-position: 54% 22%; + } } +@keyframes mobPlay { + 0% { + background-position: 0% 22%; + } + 100% { + background-position: 46% 22%; + } } + + +@keyframes playerPlay { + 0% { + background-position: 55% 37%; + } + 100% { + background-position: 85.1% 37%; + } +} +@keyframes playerPlayRight { + 0% { + background-position: 22.5% 37%; + } + 100% { + background-position: 52% 37%; + } +} diff --git a/assets/css/stylesheet.css b/assets/css/stylesheet.css deleted file mode 100644 index e69de29b..00000000 diff --git a/assets/images/MapleStory-Screen-233751-1.png b/assets/images/MapleStory-Screen-233751-1.png new file mode 100644 index 00000000..e5625dba Binary files /dev/null and b/assets/images/MapleStory-Screen-233751-1.png differ diff --git a/assets/images/background.png b/assets/images/background.png new file mode 100644 index 00000000..90b29b83 Binary files /dev/null and b/assets/images/background.png differ diff --git a/assets/images/boss copy.png b/assets/images/boss copy.png new file mode 100644 index 00000000..ef0c78ab Binary files /dev/null and b/assets/images/boss copy.png differ diff --git a/assets/images/boss.png b/assets/images/boss.png new file mode 100644 index 00000000..ef0c78ab Binary files /dev/null and b/assets/images/boss.png differ diff --git a/assets/images/boss2.png b/assets/images/boss2.png new file mode 100644 index 00000000..f8ca53bd Binary files /dev/null and b/assets/images/boss2.png differ diff --git a/assets/images/bossLevel.png b/assets/images/bossLevel.png new file mode 100644 index 00000000..fca3b2aa Binary files /dev/null and b/assets/images/bossLevel.png differ diff --git a/assets/images/bossRight.png b/assets/images/bossRight.png new file mode 100644 index 00000000..a92ba0c5 Binary files /dev/null and b/assets/images/bossRight.png differ diff --git a/assets/images/bullet.png b/assets/images/bullet.png new file mode 100644 index 00000000..25a1e3e5 Binary files /dev/null and b/assets/images/bullet.png differ diff --git a/assets/images/buttons.png b/assets/images/buttons.png new file mode 100644 index 00000000..87a8bfc9 Binary files /dev/null and b/assets/images/buttons.png differ diff --git a/assets/images/congratulations.png b/assets/images/congratulations.png new file mode 100644 index 00000000..d87bda2d Binary files /dev/null and b/assets/images/congratulations.png differ diff --git a/assets/images/flowchart.jpg b/assets/images/flowchart.jpg new file mode 100644 index 00000000..c196a23f Binary files /dev/null and b/assets/images/flowchart.jpg differ diff --git a/assets/images/gameOver.png b/assets/images/gameOver.png new file mode 100644 index 00000000..51a8fbb2 Binary files /dev/null and b/assets/images/gameOver.png differ diff --git a/assets/images/healthBar.png b/assets/images/healthBar.png new file mode 100644 index 00000000..fda115b5 Binary files /dev/null and b/assets/images/healthBar.png differ diff --git a/assets/images/healthBarTest.png b/assets/images/healthBarTest.png new file mode 100644 index 00000000..d2b1d854 Binary files /dev/null and b/assets/images/healthBarTest.png differ diff --git a/assets/images/landingPage.jpg b/assets/images/landingPage.jpg new file mode 100644 index 00000000..99be411d Binary files /dev/null and b/assets/images/landingPage.jpg differ diff --git a/assets/images/loginScreen.jpg b/assets/images/loginScreen.jpg new file mode 100644 index 00000000..10c54107 Binary files /dev/null and b/assets/images/loginScreen.jpg differ diff --git a/assets/images/maplestory.png b/assets/images/maplestory.png new file mode 100644 index 00000000..ddfadaba Binary files /dev/null and b/assets/images/maplestory.png differ diff --git a/assets/images/minimap.png b/assets/images/minimap.png new file mode 100644 index 00000000..28a449e4 Binary files /dev/null and b/assets/images/minimap.png differ diff --git a/assets/images/old.gif b/assets/images/old.gif new file mode 100644 index 00000000..2e405506 Binary files /dev/null and b/assets/images/old.gif differ diff --git a/assets/images/playerModel.png b/assets/images/playerModel.png new file mode 100644 index 00000000..8735ced9 Binary files /dev/null and b/assets/images/playerModel.png differ diff --git a/assets/images/playerModelRight.png b/assets/images/playerModelRight.png new file mode 100644 index 00000000..37f381fa Binary files /dev/null and b/assets/images/playerModelRight.png differ diff --git a/assets/images/skill1.gif b/assets/images/skill1.gif new file mode 100644 index 00000000..0a7855d2 Binary files /dev/null and b/assets/images/skill1.gif differ diff --git a/assets/images/skill2.gif b/assets/images/skill2.gif new file mode 100644 index 00000000..43774950 Binary files /dev/null and b/assets/images/skill2.gif differ diff --git a/assets/images/skill3.gif b/assets/images/skill3.gif new file mode 100644 index 00000000..f220d2f5 Binary files /dev/null and b/assets/images/skill3.gif differ diff --git a/assets/images/skill4.gif b/assets/images/skill4.gif new file mode 100644 index 00000000..fcf4d43a Binary files /dev/null and b/assets/images/skill4.gif differ diff --git a/assets/images/source.gif b/assets/images/source.gif new file mode 100644 index 00000000..3ba402d5 Binary files /dev/null and b/assets/images/source.gif differ diff --git a/assets/images/stoneGolem.png b/assets/images/stoneGolem.png new file mode 100644 index 00000000..5e8ef761 Binary files /dev/null and b/assets/images/stoneGolem.png differ diff --git a/assets/images/stoneGolemRight.png b/assets/images/stoneGolemRight.png new file mode 100644 index 00000000..0ae655c9 Binary files /dev/null and b/assets/images/stoneGolemRight.png differ diff --git a/assets/images/throwingStar.gif b/assets/images/throwingStar.gif new file mode 100644 index 00000000..02add4c4 Binary files /dev/null and b/assets/images/throwingStar.gif differ diff --git a/assets/images/v2.png b/assets/images/v2.png new file mode 100644 index 00000000..e80544a3 Binary files /dev/null and b/assets/images/v2.png differ diff --git a/assets/images/v3.png b/assets/images/v3.png new file mode 100644 index 00000000..87af451e Binary files /dev/null and b/assets/images/v3.png differ diff --git a/assets/js/script.js b/assets/js/script.js index e69de29b..bcb64aa2 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -0,0 +1,190 @@ +$(function () { + + console.log('Dom is ready') + + var $container = $('.container') + var $topContainer = $('.topContainer') + var $mob = $('.mob') + var $player = $('.player') + var $bullet = $('.projectile') + var $body = $('body') + var $mobHP = $("#mobHP") + var $playerHP = $("#healthPoints") + var $hpBar = $(".hpBar") + var $startButton = $("#restart") + var fireDirection = "" + var keys = {37: false, 32: false, 39: false} + var playerHealth = 100 + var mobHealth = 50 + var currentMobsOnScreen = 0 + var gameEnd = false + $bullet.hide() + $mob.css("left","205px") + + + // setInterval(checkHeight,300) + + setInterval(function(){ + if (gameEnd) { $(".landingScreen").show()} + },1000) + + $startButton.on("click",restartGame) + + + + function restartGame(){ + $(".landingScreen").hide() + setInterval(startMob, 1000) + setInterval(bulletCollisionCheck, 10) + setInterval(playerMobCollisionCheck,300) + playerHealth = 100 + mobHealth = 50 + $mob.css("left","205px") + gameEnd = false + } + + + function checkHeight(){ // check player height and drop if he is floating + var $player = $('.player') + var $playPos = $player.position() + if ($playPos.top !== 560) {$player.css('top', `560px`)} + } + + $body.on('keydown', function (e) { + var $player = $('.player') + var $playPos = $player.position() + keys[e.keyCode] = true + $player.css("webkitAnimationPlayState","running") + + if (keys[32] && keys[39] && $playPos.top === 560 && $playPos.left < 1240){ //right and up + $player.css('top', `${$playPos.top -= 200}px`) + $player.css('left', `${$playPos.left += 200}px`) + $player.css("transform","scaleX(-1)") + fireDirection = "right" + } + if(keys[37] && keys[32] && $playPos.top === 560 && $playPos.left >201){ //left and up + $player.css('top', `${$playPos.top -= 200}px`) + $player.css('left', `${$playPos.left -= 200}px`) + $player.css("transform","scaleX(1)") + fireDirection = "left" + } + if (keys[37] && $playPos.left >151) { + $player.css('left', `${$playPos.left -= 150}px`) + $player.css("transform","scaleX(1)") + fireDirection = "left" + } //left + if (keys[32] && $playPos.top === 560) {$player.css('top', `${$playPos.top -= 300}px`)} //up + if (keys[39] && $playPos.left < 1480) { + $player.css('left', `${$playPos.left += 150}px`) + $player.css("transform","scaleX(-1)") + fireDirection = "right"} //right + if (keys[67]) {fireBullet()} + e.preventDefault() // prevent the default action (scroll / move caret) + }) + + $body.on('keyup', function (e) { + keys[e.which] = false + var $player = $('.player') + var $playPos = $player.position() + $player.css("webkitAnimationPlayState","paused") + // console.log(` current position ${$playPos.top}`) + if ($playPos.top !== 560) { $player.css('top', `560px`) } + }) + + function startMob () { + $mobPosition = $mob.position() + $playPos = $player.position() + mobPosLeft = $mobPosition.left + if (mobPosLeft === 205) { + $mob.css('left', "1490px") + $mob.removeClass("mob") + $mob.addClass("mobRight") + } else if (mobPosLeft === 1490) { + $mob.css('left', "205px") + $mob.removeClass("mobRight") + $mob.addClass("mob") + } + + } + + + + + function fireBullet () { + $playPos = $player.position() + $mobPos = $mob.position() + $bullet.show() + $bulletLoc = $bullet.position() + $bulletExact = $bulletLoc.left + $bulletTop = $playPos.top + $bulletLeft= $playPos.left + $bullet.css('left',$playPos.left) + if(fireDirection === "right"){ + $bullet.css('left', `${$bulletExact + (1600-$bulletExact)}px`) + }else if(fireDirection === "left"){ + $bullet.css('left', `${$bulletExact - (1600-$bulletExact)}px`) + } + if ($bulletExact <= 50 || $bulletExact >= 1400) { + $bullet.css('left',$playPos.left) + $bullet.hide() + console.log('bullet', $bulletExact); + } + + } + + + + + function bulletCollisionCheck () { + var red = $bullet.position() + var redX = red.left + var blue = $mob.position() + var blueX = blue.left + var redY = red.top + var blueY = blue.top + + if (blueX < redX + $bullet.width() && + blueX + $mob.width() > redX && + blueY < redX + $bullet.height() && + $mob.height() + blueY > redY) { + mobHealth -=1 + $mobHP.text(`Current MOB HP: ${mobHealth}`) + $bullet.css('left',$playPos.left) + $bullet.css("top","620px") + if(mobHealth === 0) { + $mob.remove() + gameEnd = true + } + console.log('CRASH') + $bullet.hide() + } else { + return false + } + } + + function playerMobCollisionCheck () { + var red = $player.position() + var redX = red.left + var blue = $mob.position() + var blueX = blue.left + var redY = red.top + var blueY = blue.top + + if (blueX < redX + $player.width() && + blueX + $mob.width() > redX && + blueY < redX + $player.height() && + $mob.height() + blueY > redY) { + console.log('PLAYER HEALTH REDUCED') + playerHealth -=1 + var currentHpWidth = $(".hpBar").width() + $(".hpBar").css("width",`${currentHpWidth-2}px`) + $hpBar.text(`${playerHealth}/100`) + if(playerHealth === 0){ + gameEnd = true + } + } else { + return false + } + } + +}) diff --git a/assets/js/testScript.js b/assets/js/testScript.js new file mode 100644 index 00000000..58de4e27 --- /dev/null +++ b/assets/js/testScript.js @@ -0,0 +1,488 @@ +class Mob { // class to spawn mobs + + constructor (id) { + this.id = id + this.hitPoints = 20 + this.damage = 1 // mob damage per second + this.bosscheck = false // check to allow DOM to check whether its a boss or a mob spawn + this.jTarget = $('body').find(`#${this.id}`) + this.width = this.jTarget.css('width') + this.height = this.jTarget.css('height') + + setInterval(() => { + this.positionCheck() + }, 1000) + } + + positionCheck () { + var speed = Math.floor(Math.random() * 30) + var mobPosition = this.jTarget.position() // get position of current mob + if (mobPosition.left < 500) { + this.jTarget.css({ + width: '180px', + height: '170px', + position: 'absolute', + top: '505px', + left: '1460px', + transition: `${speed}s`, + background: 'url(./assets/images/stoneGolemRight.png)', // assign right facing image when mob turns + animation: 'mobPlayRight 2s steps(4) infinite' // run animation + }) + } else if (mobPosition.left > 1400) { + this.jTarget.css({ + left: '1px', + transition: `${speed}s`, + background: 'url(./assets/images/stoneGolem.png)', // assign left facing image when mob turns + animation: 'mobPlay 2s steps(4) infinite' + }) + } + } + + addChar () { + var location = Math.floor(Math.random() * 480) + var spawnMob = $('
') + spawnMob.attr('id', this.id) + + $('.topContainer').append(spawnMob) + this.jTarget = $('body').find(`#${this.id}`) + this.jTarget.css({ + width: '180px', + height: '170px', + position: 'absolute', + top: '505px', + left: `${location}px`, + transition: '20s', + background: 'url(./assets/images/stoneGolemRight.png)', + animation: 'mobPlayRight 2s steps(4) infinite' + }) + } + +} + +class Boss { // Class to spawn boss + + constructor (id) { + this.id = id + this.hitPoints = 500 + this.damage = 3 + this.bosscheck = true + this.jTarget = $('body').find(`#${this.id}`) + this.width = this.jTarget.css('width') + this.height = this.jTarget.css('height') + + setInterval(() => { + this.positionCheck() + }, 1000) + } + + positionCheck () { + var speed = Math.floor(Math.random() * 30) + var mobPosition = this.jTarget.position() + if (mobPosition.left < 400) { + this.jTarget.css({ + left: '1460px', + transition: `${speed}s`, + background: 'url(./assets/images/bossRight.png)', + animation: ' bossRight 1s steps(8) infinite' + }) + } else if (mobPosition.left > 1400) { + this.jTarget.css({ + left: '1px', + transition: `${speed}s`, + background: 'url(./assets/images/boss.png)', + animation: ' bossOne 1s steps(8) infinite' + }) + } + } + + addBoss () { + var location = Math.floor(Math.random() * 380) + var spawnMob = $('
') + spawnMob.attr('id', this.id) + + $('.topContainer').append(spawnMob) + this.jTarget = $('body').find(`#${this.id}`) + this.jTarget.css({ + width: '250px', + height: '320px', + position: 'absolute', + top: '390px', + left: `${location}px`, + transition: '16s', + background: 'url(./assets/images/boss.png)', + animation: ' bossOne 1s steps(8) infinite' + }) + } + +} +$(function () { + var $container = $('.container') + var $topContainer = $('.topContainer') + var $mob = $('.mob') + var $player = $('.player') + var $bullet = $('.projectile') + var $body = $('body') + var $playerHP = $('#healthPoints') + var $hpBar = $('.hpBar') + var $startButton = $('#restart') + var $firstSkillDiv = $('.skillOne') + var $mpBar = $('.mpBar') + var $bossSign = $('.levelOneGameEnd') + var mobArray = [] + var bossArray = [] + var fireDirection = '' + var keys = {37: false, 32: false, 39: false} + var playerHealth = 1000 + var mobsOnScreen = 0 + var levelOneMobCount = 20 + var gameEnd = false + var bossDead = false + var bossLevel = false + var mana = 202 + $bullet.hide() + + $startButton.on('click', restartGame) + + setInterval(function () { // if game has ended show the landing screen + if (gameEnd === true && playerHealth > 0) { + $('.landingScreen').show() + $(".maplestoryImage").css({ + background: "url(./assets/images/congratulations.png)", + width: "830px", + height: "80px", + position: "absolute", + left: "400px", + top: "50px" + }) + + }else if (gameEnd === true && playerHealth < 0){ + $('.landingScreen').show() + $(".maplestoryImage").css({ + background: "url(./assets/images/gameOver.png)", + width: "570px", + height: "80px", + position: "absolute", + left: "520px", + top: "50px" + }) + } + }, 1000) + + + setInterval(function () { // check whether boss is to be spawned, if yes set image to visible and spawn boss + if (bossLevel) { + $bossSign.css('visibility', 'visible') + if (mobsOnScreen < 1 && bossDead === false) { generateBoss() } // ensure no other bosses are on screen prior to spawning + } + }, 1000) + + function restartGame () { // function to reset all fields when game restarts + $('.landingScreen').hide() + playerHealth = 1000 + $hpBar.text(`${playerHealth}/1000`) + $bossSign.css('visibility', 'hidden') + $hpBar.css('width', `200px`) + mana = 202 + $mpBar.text(`${mana}/202`) + $mpBar.css('width', `202px`) + mobsOnScreen = 0 + gameEnd = false + bossLevel = false + levelOneMobCount = 10 + bossDead = false + runSpawner() + for (key in mobArray) { + mobArray[key].jTarget.remove() + } + mobArray = [] + for (key in bossArray) { + bossArray[key].jTarget.remove() + } + bossArray = [] + } + + function runSpawner () { // spawn mobs based on limit set per level + var mobSpawn = setInterval(function () { + if (mobsOnScreen < levelOneMobCount) { + generateMob() + } + }, 3000) + } + + function generateMob () { //run mob spawn class + var id = Math.floor(Math.random() * 1000) + mobArray[id] = new Mob(id) + mobArray[id].addChar() + mobsOnScreen += 1 + } + function generateBoss () { // run boss spawn class + var id = Math.floor(Math.random() * 1000) + bossArray[id] = new Boss(id) + bossArray[id].addBoss() + mobsOnScreen += 1 + } + + var manaRegen = setInterval(function () { //mana regeneration function + if (mana < 200) { + mana += 4 + $mpBar.text(`${mana}/200`) + $mpBar.css('width', `${$mpBar.width() + 4}px`) + } + }, 1000) + + setInterval(function () { // collision check for bullets and player contact against mobs + for (key in mobArray) { + bulletCollisionCheck($bullet, mobArray[key]) + playerMobCollisionCheck($player, mobArray[key]) + } + }, 30) + + setInterval(function () { // collision check for bullets and player contact against boss + for (key in bossArray) { + bulletCollisionCheck($bullet, bossArray[key]) + playerMobCollisionCheck($player, bossArray[key]) + } + }, 30) + + $body.on('keydown', function (e) { //player keyboard press detection + var $player = $('.player') + var $playPos = $player.position() + keys[e.keyCode] = true + $player.css('webkitAnimationPlayState', 'running') + + if (keys[32] && keys[39] && $playPos.top === 590 && $playPos.left < 1240) { // right and up + $player.css('top', `${$playPos.top -= 200}px`) + $player.css('left', `${$playPos.left += 200}px`) + $player.css({ + background: "url(./assets/images/playerModelRight.png)", + animation: "playerPlayRight 1s steps(4) infinite" + }) + fireDirection = 'right' + } + if (keys[37] && keys[32] && $playPos.top === 590 && $playPos.left > 201) { // left and up + $player.css('top', `${$playPos.top -= 200}px`) + $player.css('left', `${$playPos.left -= 200}px`) + $player.css({ + background: "url(./assets/images/playerModel.png)", + animation: "playerPlay 1s steps(4) infinite" + }) + fireDirection = 'left' + } + if (keys[37] && $playPos.left > 151) { // left + $player.css('left', `${$playPos.left -= 150}px`) + $player.css({ + background: "url(./assets/images/playerModel.png)", + animation: "playerPlay 1s steps(4) infinite" + }) + fireDirection = 'left' + } + if (keys[32] && $playPos.top === 590) { $player.css('top', `${$playPos.top -= 300}px`) } // up + if (keys[39] && $playPos.left < 1480) { + $player.css('left', `${$playPos.left += 150}px`) + $player.css({ + background: "url(./assets/images/playerModelRight.png)", + animation: "playerPlayRight 1s steps(4) infinite" + }) + fireDirection = 'right' + } // right + if (keys[67]) { fireBullet() } //default attack + if (keys[68]) { skillOne() } // purple wave (D) + if (keys[90]) { skillTwo() } // giant panda (X) + if (keys[88]) { skillThree() }// giant hammer(Z) + e.preventDefault() // prevent the default action (scroll / move caret) + }) + $body.on('keyup', function (e) { // stop player sprite animation when not moving or attacking and reset player Y-axis to counteract jump + keys[e.which] = false + var $player = $('.player') + var $playPos = $player.position() + $player.css('webkitAnimationPlayState', 'paused') + // console.log(` current position ${$playPos.top}`) + if ($playPos.top !== 590) { $player.css('top', `590px`) } + }) + + function bulletCollisionCheck (obj1, obj2) { //bullet collision check + var red = obj1.position() + var redX = red.left + var blue = obj2.jTarget.position() + var blueX = blue.left + var redY = red.top + var blueY = blue.top + if (blueX < redX + obj1.width() && + blueX + obj2.jTarget.width() > redX && + blueY < redX + obj1.height() && + obj2.jTarget.height() + blueY > redY) { + obj2.hitPoints -= 1 + $bullet.css('left', $playPos.left) + $bullet.css('top', '620px') + if (obj2.hitPoints === 0) { + obj2.jTarget.remove() + if (obj2.bosscheck === false) { + mobArray.splice(key, 1) + mobsOnScreen-- + levelOneMobCount-- + } else if (obj2.bosscheck) { + bossArray.splice(key, 1) + bossDead = true + } + } + if (mobsOnScreen === 0 && levelOneMobCount === 0) { //if mobs are dead, spawn boss + bossLevel = true + } + if (bossLevel === true && bossDead === true) { //if boss is dead, end game + gameEnd = true + } + return true + } else { return false } + } + + function playerMobCollisionCheck (obj1, obj2) { //player - mob collision check + var red = obj1.position() + var redX = red.left + var blue = obj2.jTarget.position() + var blueX = blue.left + var redY = red.top + var blueY = blue.top + + if (blueX < redX + $player.width() && + blueX + obj2.jTarget.width() > redX && + blueY < redX + $player.height() && + obj2.jTarget.height() + blueY > redY) { + console.log('PLAYER HEALTH REDUCED') + playerHealth -= obj2.damage + var currentHpWidth = $('.hpBar').width() + $('.hpBar').css('width', `${currentHpWidth - obj2.damage / 5}px`) + $hpBar.text(`${playerHealth}/1000`) + if (playerHealth === 0) { + gameEnd = true + } + } else { + return false + } + } + + function fireBullet () { //bullet control functiom + $playPos = $player.position() + $mobPos = $mob.position() + $bullet.show() + $bulletLoc = $bullet.position() + $bulletExact = $bulletLoc.left + $bulletTop = $playPos.top + $bulletLeft = $playPos.left + $bullet.css('left', $playPos.left) + if (fireDirection === 'right') { + $bullet.css('left', `${$bulletExact + (1600 - $bulletExact)}px`) + } else if (fireDirection === 'left') { + $bullet.css('left', `${$bulletExact - (1600 - $bulletExact)}px`) + } + if ($bulletExact <= 200 || $bulletExact >= 1600) { //reset when it moves out of screen + $bullet.css('left', $playPos.left) + console.log('bullet', $bulletExact) + } + setTimeout(function(){$bullet.hide()},1000) + } + function skillOne () { // small damage skill + if (mana >= 10) { + mana -= 10 + $mpBar.text(`${mana}/200`) + $mpBar.css('width', `${$mpBar.width() - 10}px`) + $firstSkillDiv.css('visibility', 'visible') // show skill animation and hide after 800 ms + setTimeout(function () { + $firstSkillDiv.css('visibility', 'hidden') + }, 800) + + for (key in mobArray) { // test for mobs + mobArray[key].hitPoints -= 10 + if (mobArray[key].hitPoints < 0) { + mobArray[key].jTarget.remove() + mobArray.splice(key, 1) + mobsOnScreen-- //deduct 1 from total mobs on screen + levelOneMobCount-- + } + } + for (key in bossArray) { // test for boss + bossArray[key].hitPoints -= 10 + if (bossArray[key].hitPoints < 0) { + bossArray[key].jTarget.remove() + bossArray.splice(key, 1) + mobsOnScreen-- + bossDead = true + } + } + + if (mobsOnScreen === 0 && levelOneMobCount === 0) { bossLevel = true } + if (bossLevel === true && bossDead === true) { gameEnd = true } + } else { + return false + } + } + function skillTwo () { //medium damage skill + if (mana >= 20) { + mana -= 20 + $mpBar.text(`${mana}/200`) + $mpBar.css('width', `${$mpBar.width() - 20}px`) + $('.skillTwo').css('visibility', 'visible') + setTimeout(function () { + $('.skillTwo').css('visibility', 'hidden') + }, 800) + for (key in mobArray) { + mobArray[key].hitPoints -= 20 + if (mobArray[key].hitPoints < 0) { + mobArray[key].jTarget.remove() + mobArray.splice(key, 1) + mobsOnScreen-- + levelOneMobCount-- + } + } + for (key in bossArray) { + bossArray[key].hitPoints -= 20 + if (bossArray[key].hitPoints < 0) { + bossArray[key].jTarget.remove() + bossArray.splice(key, 1) + mobsOnScreen-- + bossDead = true + } + } + + if (mobsOnScreen === 0 && levelOneMobCount === 0) { bossLevel = true } + if (bossLevel === true && bossDead === true) { gameEnd = true } + } else { + return false + } + } + function skillThree () { + if (mana >= 50) { + mana -= 50 + $mpBar.text(`${mana}/200`) + $mpBar.css('width', `${$mpBar.width() - 50}px`) + $('.skillThree').css('visibility', 'visible') + setTimeout(function () { + $('.skillThree').css('visibility', 'hidden') + }, 800) + + for (key in mobArray) { + mobArray[key].hitPoints -= 100 + if (mobArray[key].hitPoints < 0) { + mobArray[key].jTarget.remove() + mobArray.splice(key, 1) + mobsOnScreen-- + levelOneMobCount-- + } + } + + for (key in bossArray) { + bossArray[key].hitPoints -= 100 + if (bossArray[key].hitPoints < 0) { + bossArray[key].jTarget.remove() + bossArray.splice(key, 1) + mobsOnScreen-- + bossDead = true + } + } + + if (mobsOnScreen === 0 && levelOneMobCount === 0) { bossLevel = true } + if (bossLevel === true && bossDead === true) { gameEnd = true } + } else { + return false + } + } +}) diff --git a/index.html b/index.html index 5b002212..4f77d739 100644 --- a/index.html +++ b/index.html @@ -3,9 +3,51 @@ - + + - +
+
+
+
+

Use left and right arrow keys to move, space bar to jump and "C" to attack

+ Kill all mobs and avoid dying to reach the boss stage! Defeat the boss and the win is yours!
+
Skill Keys:
+ D - Does small amount of damage to one mob
+ X - Does moderate amount of damage to one mob
+ Z - Does large amount of damage to one mob
+ + + +
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
1000/1000
+
200/200
+
+ +
+ + +
+ + diff --git a/old.md b/old.md new file mode 100644 index 00000000..317a3e58 --- /dev/null +++ b/old.md @@ -0,0 +1,96 @@ +# Project Name (Start editing here) + + +# ![](https://ga-dash.s3.amazonaws.com/production/assets/logo-9f88ae6c9c3871690e33280fcf557f33.png) Project #1: The Game + +### 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 + +* **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? + +* __Deployment__: Did you deploy your application to a public url using GitHub Pages? + +* __Total__: Your instructors will give you a total score on your project between: + + Score | Expectations + ----- | ------------ + **0** | _Incomplete._ + **1** | _Does not meet expectations._ + **2** | _Meets expectations, good job!_ + **3** | _Exceeds expectations, you wonderful creature, you!_ + + 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!