diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..6dbf6e0
Binary files /dev/null and b/.DS_Store differ
diff --git a/Frogger/.DS_Store b/Frogger/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/Frogger/.DS_Store differ
diff --git a/Frogger/README.md b/Frogger/README.md
index 8b15aae..cfc7a42 100644
--- a/Frogger/README.md
+++ b/Frogger/README.md
@@ -1 +1,6 @@
-Use this folder for the final project code from the Udacity course
+frontend-nanodegree-arcade-game
+===============================
+
+Students should use this [rubric](https://review.udacity.com/#!/projects/2696458597/rubric) for self-checking their submission. Make sure the functions you write are **object-oriented** - either class functions (like Player and Enemy) or class prototype functions such as Enemy.prototype.checkCollisions, and that the keyword 'this' is used appropriately within your class and class prototype functions to refer to the object the function is called upon. Also be sure that the **readme.md** file is updated with your instructions on both how to 1. Run and 2. Play your arcade game.
+
+For detailed instructions on how to get started, check out this [guide](https://docs.google.com/document/d/1v01aScPjSWCCWQLIpFqvg3-vXLH2e8_SZQKC8jNO0Dc/pub?embedded=true).
diff --git a/Frogger/css/style.css b/Frogger/css/style.css
new file mode 100644
index 0000000..e28c912
--- /dev/null
+++ b/Frogger/css/style.css
@@ -0,0 +1,3 @@
+body {
+ text-align: center;
+}
diff --git a/Frogger/images/Gem Blue.png b/Frogger/images/Gem Blue.png
new file mode 100755
index 0000000..5808a7d
Binary files /dev/null and b/Frogger/images/Gem Blue.png differ
diff --git a/Frogger/images/Gem Green.png b/Frogger/images/Gem Green.png
new file mode 100755
index 0000000..e971d14
Binary files /dev/null and b/Frogger/images/Gem Green.png differ
diff --git a/Frogger/images/Gem Orange.png b/Frogger/images/Gem Orange.png
new file mode 100755
index 0000000..f8faf7b
Binary files /dev/null and b/Frogger/images/Gem Orange.png differ
diff --git a/Frogger/images/Heart.png b/Frogger/images/Heart.png
new file mode 100755
index 0000000..aa49b5c
Binary files /dev/null and b/Frogger/images/Heart.png differ
diff --git a/Frogger/images/Key.png b/Frogger/images/Key.png
new file mode 100755
index 0000000..7602326
Binary files /dev/null and b/Frogger/images/Key.png differ
diff --git a/Frogger/images/Rock.png b/Frogger/images/Rock.png
new file mode 100755
index 0000000..29c4e20
Binary files /dev/null and b/Frogger/images/Rock.png differ
diff --git a/Frogger/images/Selector.png b/Frogger/images/Selector.png
new file mode 100755
index 0000000..e7c5475
Binary files /dev/null and b/Frogger/images/Selector.png differ
diff --git a/Frogger/images/Star.png b/Frogger/images/Star.png
new file mode 100755
index 0000000..17c0af5
Binary files /dev/null and b/Frogger/images/Star.png differ
diff --git a/Frogger/images/char-boy.png b/Frogger/images/char-boy.png
new file mode 100755
index 0000000..3dc7c29
Binary files /dev/null and b/Frogger/images/char-boy.png differ
diff --git a/Frogger/images/char-cat-girl.png b/Frogger/images/char-cat-girl.png
new file mode 100755
index 0000000..dc0538b
Binary files /dev/null and b/Frogger/images/char-cat-girl.png differ
diff --git a/Frogger/images/char-horn-girl.png b/Frogger/images/char-horn-girl.png
new file mode 100755
index 0000000..90f2278
Binary files /dev/null and b/Frogger/images/char-horn-girl.png differ
diff --git a/Frogger/images/char-pink-girl.png b/Frogger/images/char-pink-girl.png
new file mode 100755
index 0000000..baef177
Binary files /dev/null and b/Frogger/images/char-pink-girl.png differ
diff --git a/Frogger/images/char-princess-girl.png b/Frogger/images/char-princess-girl.png
new file mode 100755
index 0000000..9d9f958
Binary files /dev/null and b/Frogger/images/char-princess-girl.png differ
diff --git a/Frogger/images/enemy-bug.png b/Frogger/images/enemy-bug.png
new file mode 100755
index 0000000..191587b
Binary files /dev/null and b/Frogger/images/enemy-bug.png differ
diff --git a/Frogger/images/grass-block.png b/Frogger/images/grass-block.png
new file mode 100755
index 0000000..eb04ba9
Binary files /dev/null and b/Frogger/images/grass-block.png differ
diff --git a/Frogger/images/stone-block.png b/Frogger/images/stone-block.png
new file mode 100755
index 0000000..01113cf
Binary files /dev/null and b/Frogger/images/stone-block.png differ
diff --git a/Frogger/images/water-block.png b/Frogger/images/water-block.png
new file mode 100755
index 0000000..0383ed8
Binary files /dev/null and b/Frogger/images/water-block.png differ
diff --git a/Frogger/index.html b/Frogger/index.html
new file mode 100644
index 0000000..c9a3b8e
--- /dev/null
+++ b/Frogger/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+ Effective JavaScript: Frogger
+
+
+
+
+
+
+
+
diff --git a/Frogger/js/app.js b/Frogger/js/app.js
new file mode 100644
index 0000000..d31cf43
--- /dev/null
+++ b/Frogger/js/app.js
@@ -0,0 +1,103 @@
+var Enemy = function(x, y) {
+ this.sprite = 'images/enemy-bug.png';
+ this.x = x;
+ this.y = y;
+ this.enemySpeed = Math.floor((Math.random() * 200) + 100);
+};
+
+Enemy.prototype.update = function(dt) {
+ if (this.x <= 600) {
+ this.x += this.enemySpeed * dt
+ } else {
+ this.x = -100
+ }
+};
+
+
+Object.prototype.render = function() {
+ ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
+ ctx.font = "30px Verdana";
+ ctx.fillStyle = 'purple';
+ ctx.fillText("Points: " + player.points,55,575)
+ ctx.fillText("Lives: " + player.lives,340,575)
+ if (player.lives === 0) {
+ ctx.font = "60px Verdana";
+ ctx.fillStyle = 'black';
+ ctx.fillText("Womp womp",50,275);
+ setTimeout(function() {
+ window.location.reload()
+ }, 2000);
+ }
+ if (player.points === 5) {
+ ctx.font = "60px Verdana";
+ ctx.fillStyle = 'red';
+ ctx.fillText("Yay! You win!",50,275);
+ setTimeout(function() {
+ window.location.reload()
+ }, 2000);
+ }
+};
+
+
+var Player = function(x, y) {
+ this.sprite = 'images/char-boy.png';
+ this.x = x;
+ this.y = y;
+ this.lives = 3;
+ this.points = 0;
+};
+
+Player.prototype.update = function() {
+ if (this.y <= -15) {
+ this.reset();
+ this.points++;
+ }
+ for (i = 0; i < allEnemies.length; i++) {
+ if (Math.abs(this.x - allEnemies[i].x) < 30) {
+ if (Math.abs(this.y - allEnemies[i].y) < 30) {
+ this.reset();
+ this.lives--;
+ }
+ }
+ }
+};
+
+Player.prototype.handleInput = function(e) {
+ if (e === 'left' && this.x > 0) {
+ this.x -= 101;
+ } else if (e === 'right' && this.x < 400) {
+ this.x += 101;
+ } else if (e === 'down' && this.y < 350) {
+ this.y += 80;
+ } else if (e === 'up') {
+ this.y -= 80;
+ }
+};
+
+Player.prototype.reset = function() {
+ this.y = 390;
+ this.x = 200;
+}
+
+
+var allEnemies = [];
+allEnemies.push(new Enemy(-300, 215));
+allEnemies.push(new Enemy(-300, 135));
+allEnemies.push(new Enemy(-300, 60));
+allEnemies.push(new Enemy(-300, 215));
+allEnemies.push(new Enemy(-300, 135));
+allEnemies.push(new Enemy(-300, 60));
+
+var player = new Player(200, 390);
+
+
+document.addEventListener('keyup', function(e) {
+ var allowedKeys = {
+ 37: 'left',
+ 38: 'up',
+ 39: 'right',
+ 40: 'down'
+ };
+
+ player.handleInput(allowedKeys[e.keyCode]);
+});
diff --git a/Frogger/js/engine.js b/Frogger/js/engine.js
new file mode 100644
index 0000000..3c44055
--- /dev/null
+++ b/Frogger/js/engine.js
@@ -0,0 +1,183 @@
+/* Engine.js
+ * This file provides the game loop functionality (update entities and render),
+ * draws the initial game board on the screen, and then calls the update and
+ * render methods on your player and enemy objects (defined in your app.js).
+ *
+ * A game engine works by drawing the entire game screen over and over, kind of
+ * like a flipbook you may have created as a kid. When your player moves across
+ * the screen, it may look like just that image/character is moving or being
+ * drawn but that is not the case. What's really happening is the entire "scene"
+ * is being drawn over and over, presenting the illusion of animation.
+ *
+ * This engine is available globally via the Engine variable and it also makes
+ * the canvas' context (ctx) object globally available to make writing app.js
+ * a little simpler to work with.
+ */
+
+var Engine = (function(global) {
+ /* Predefine the variables we'll be using within this scope,
+ * create the canvas element, grab the 2D context for that canvas
+ * set the canvas elements height/width and add it to the DOM.
+ */
+ var doc = global.document,
+ win = global.window,
+ canvas = doc.createElement('canvas'),
+ ctx = canvas.getContext('2d'),
+ lastTime;
+
+ canvas.width = 505;
+ canvas.height = 606;
+ doc.body.appendChild(canvas);
+
+ /* This function serves as the kickoff point for the game loop itself
+ * and handles properly calling the update and render methods.
+ */
+ function main() {
+ /* Get our time delta information which is required if your game
+ * requires smooth animation. Because everyone's computer processes
+ * instructions at different speeds we need a constant value that
+ * would be the same for everyone (regardless of how fast their
+ * computer is) - hurray time!
+ */
+ var now = Date.now(),
+ dt = (now - lastTime) / 1000.0;
+
+ /* Call our update/render functions, pass along the time delta to
+ * our update function since it may be used for smooth animation.
+ */
+ update(dt);
+ render();
+
+ /* Set our lastTime variable which is used to determine the time delta
+ * for the next time this function is called.
+ */
+ lastTime = now;
+
+ /* Use the browser's requestAnimationFrame function to call this
+ * function again as soon as the browser is able to draw another frame.
+ */
+ win.requestAnimationFrame(main);
+ }
+
+ /* This function does some initial setup that should only occur once,
+ * particularly setting the lastTime variable that is required for the
+ * game loop.
+ */
+ function init() {
+ reset();
+ lastTime = Date.now();
+ main();
+ }
+
+ /* This function is called by main (our game loop) and itself calls all
+ * of the functions which may need to update entity's data. Based on how
+ * you implement your collision detection (when two entities occupy the
+ * same space, for instance when your character should die), you may find
+ * the need to add an additional function call here. For now, we've left
+ * it commented out - you may or may not want to implement this
+ * functionality this way (you could just implement collision detection
+ * on the entities themselves within your app.js file).
+ */
+ function update(dt) {
+ updateEntities(dt);
+ // checkCollisions();
+ }
+
+ /* This is called by the update function and loops through all of the
+ * objects within your allEnemies array as defined in app.js and calls
+ * their update() methods. It will then call the update function for your
+ * player object. These update methods should focus purely on updating
+ * the data/properties related to the object. Do your drawing in your
+ * render methods.
+ */
+ function updateEntities(dt) {
+ allEnemies.forEach(function(enemy) {
+ enemy.update(dt);
+ });
+ player.update();
+ }
+
+ /* This function initially draws the "game level", it will then call
+ * the renderEntities function. Remember, this function is called every
+ * game tick (or loop of the game engine) because that's how games work -
+ * they are flipbooks creating the illusion of animation but in reality
+ * they are just drawing the entire screen over and over.
+ */
+ function render() {
+ /* This array holds the relative URL to the image used
+ * for that particular row of the game level.
+ */
+ var rowImages = [
+ 'images/water-block.png', // Top row is water
+ 'images/stone-block.png', // Row 1 of 3 of stone
+ 'images/stone-block.png', // Row 2 of 3 of stone
+ 'images/stone-block.png', // Row 3 of 3 of stone
+ 'images/grass-block.png', // Row 1 of 2 of grass
+ 'images/grass-block.png' // Row 2 of 2 of grass
+ ],
+ numRows = 6,
+ numCols = 5,
+ row, col;
+
+ /* Loop through the number of rows and columns we've defined above
+ * and, using the rowImages array, draw the correct image for that
+ * portion of the "grid"
+ */
+ for (row = 0; row < numRows; row++) {
+ for (col = 0; col < numCols; col++) {
+ /* The drawImage function of the canvas' context element
+ * requires 3 parameters: the image to draw, the x coordinate
+ * to start drawing and the y coordinate to start drawing.
+ * We're using our Resources helpers to refer to our images
+ * so that we get the benefits of caching these images, since
+ * we're using them over and over.
+ */
+ ctx.drawImage(Resources.get(rowImages[row]), col * 101, row * 83);
+ }
+ }
+
+ renderEntities();
+ }
+
+ /* This function is called by the render function and is called on each game
+ * tick. Its purpose is to then call the render functions you have defined
+ * on your enemy and player entities within app.js
+ */
+ function renderEntities() {
+ /* Loop through all of the objects within the allEnemies array and call
+ * the render function you have defined.
+ */
+ allEnemies.forEach(function(enemy) {
+ enemy.render();
+ });
+
+ player.render();
+ }
+
+ /* This function does nothing but it could have been a good place to
+ * handle game reset states - maybe a new game menu or a game over screen
+ * those sorts of things. It's only called once by the init() method.
+ */
+ function reset() {
+ // noop
+ }
+
+ /* Go ahead and load all of the images we know we're going to need to
+ * draw our game level. Then set init as the callback method, so that when
+ * all of these images are properly loaded our game will start.
+ */
+ Resources.load([
+ 'images/stone-block.png',
+ 'images/water-block.png',
+ 'images/grass-block.png',
+ 'images/enemy-bug.png',
+ 'images/char-boy.png'
+ ]);
+ Resources.onReady(init);
+
+ /* Assign the canvas' context object to the global variable (the window
+ * object when run in a browser) so that developers can use it more easily
+ * from within their app.js files.
+ */
+ global.ctx = ctx;
+})(this);
diff --git a/Frogger/js/resources.js b/Frogger/js/resources.js
new file mode 100644
index 0000000..c49baff
--- /dev/null
+++ b/Frogger/js/resources.js
@@ -0,0 +1,111 @@
+/* Resources.js
+ * This is simply an image loading utility. It eases the process of loading
+ * image files so that they can be used within your game. It also includes
+ * a simple "caching" layer so it will reuse cached images if you attempt
+ * to load the same image multiple times.
+ */
+(function() {
+ var resourceCache = {};
+ var loading = [];
+ var readyCallbacks = [];
+
+ /* This is the publicly accessible image loading function. It accepts
+ * an array of strings pointing to image files or a string for a single
+ * image. It will then call our private image loading function accordingly.
+ */
+ function load(urlOrArr) {
+ if(urlOrArr instanceof Array) {
+ /* If the developer passed in an array of images
+ * loop through each value and call our image
+ * loader on that image file
+ */
+ urlOrArr.forEach(function(url) {
+ _load(url);
+ });
+ } else {
+ /* The developer did not pass an array to this function,
+ * assume the value is a string and call our image loader
+ * directly.
+ */
+ _load(urlOrArr);
+ }
+ }
+
+ /* This is our private image loader function, it is
+ * called by the public image loader function.
+ */
+ function _load(url) {
+ if(resourceCache[url]) {
+ /* If this URL has been previously loaded it will exist within
+ * our resourceCache array. Just return that image rather
+ * re-loading the image.
+ */
+ return resourceCache[url];
+ } else {
+ /* This URL has not been previously loaded and is not present
+ * within our cache; we'll need to load this image.
+ */
+ var img = new Image();
+ img.onload = function() {
+ /* Once our image has properly loaded, add it to our cache
+ * so that we can simply return this image if the developer
+ * attempts to load this file in the future.
+ */
+ resourceCache[url] = img;
+
+ /* Once the image is actually loaded and properly cached,
+ * call all of the onReady() callbacks we have defined.
+ */
+ if(isReady()) {
+ readyCallbacks.forEach(function(func) { func(); });
+ }
+ };
+
+ /* Set the initial cache value to false, this will change when
+ * the image's onload event handler is called. Finally, point
+ * the image's src attribute to the passed in URL.
+ */
+ resourceCache[url] = false;
+ img.src = url;
+ }
+ }
+
+ /* This is used by developers to grab references to images they know
+ * have been previously loaded. If an image is cached, this functions
+ * the same as calling load() on that URL.
+ */
+ function get(url) {
+ return resourceCache[url];
+ }
+
+ /* This function determines if all of the images that have been requested
+ * for loading have in fact been properly loaded.
+ */
+ function isReady() {
+ var ready = true;
+ for(var k in resourceCache) {
+ if(resourceCache.hasOwnProperty(k) &&
+ !resourceCache[k]) {
+ ready = false;
+ }
+ }
+ return ready;
+ }
+
+ /* This function will add a function to the callback stack that is called
+ * when all requested images are properly loaded.
+ */
+ function onReady(func) {
+ readyCallbacks.push(func);
+ }
+
+ /* This object defines the publicly accessible functions available to
+ * developers by creating a global Resources object.
+ */
+ window.Resources = {
+ load: load,
+ get: get,
+ onReady: onReady,
+ isReady: isReady
+ };
+})();
diff --git a/README.md b/README.md
index 384313e..bbdbca1 100644
--- a/README.md
+++ b/README.md
@@ -13,51 +13,51 @@ Your objectives for the day is to:
### Scopes
-- [ ] Watch these videos on Type and Scope
+- [X] Watch these videos on Type and Scope
- https://shereef.wistia.com/medias/mlnjxm9z9s
- https://shereef.wistia.com/medias/hn99v12lkr
- https://shereef.wistia.com/medias/6snmj6es7v
- https://shereef.wistia.com/medias/5bva01dxbw
-- [ ] Signup for [Udacity Object Oriented Javascript][udacity]
-- [ ] Complete the [Scopes lesson][udacity]
+- [X] Signup for [Udacity Object Oriented Javascript][udacity]
+- [X] Complete the [Scopes lesson][udacity]
### Closures
-- [ ] Complete the [Closures lesson][udacity]
+- [X] Complete the [Closures lesson][udacity]
## Day 2: Objects and "this"
### Objects
-- [ ] Watch [Video introduction to Object Oriented Javascript](https://www.youtube.com/watch?v=O8wwnhdkPE4) (1 Hour)
-- [ ] Read [Javascript Objects in Detail](http://javascriptissexy.com/javascript-objects-in-detail/)
-- [ ] Read pages 173 to 184 in [Professional JS for Web Developers][projs]
-- [ ] Signup for a free Team Treehouse trial and complete their [Object Oriented Javascript Course] (https://teamtreehouse.com/library/objectoriented-javascript)
-- [ ] Skim this [cheat sheet][cheat]
+- [X] Watch [Video introduction to Object Oriented Javascript](https://www.youtube.com/watch?v=O8wwnhdkPE4) (1 Hour)
+- [X] Read [Javascript Objects in Detail](http://javascriptissexy.com/javascript-objects-in-detail/)
+- [X] Read pages 173 to 184 in [Professional JS for Web Developers][projs]
+- [X] Signup for a free Team Treehouse trial and complete their [Object Oriented Javascript Course] (https://teamtreehouse.com/library/objectoriented-javascript)
+- [X] Skim this [cheat sheet][cheat]
### This
-- [ ] Watch these videos:
+- [X] Watch these videos:
- https://shereef.wistia.com/medias/wfybhl2nmr
- https://shereef.wistia.com/medias/kqbedkmm13
-- [ ] Read [Undrestanding Javascrpt's This with Clarity and Mastery](http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/)
-- [ ] Read [What is this in Javascript](http://www.code-sample.com/2015/06/what-is-this-in-javascript.html)
-- [ ] Complete the [Keyword "this" lesson][udacity]
+- [X] Read [Undrestanding Javascrpt's This with Clarity and Mastery](http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/)
+- [X] Read [What is this in Javascript](http://www.code-sample.com/2015/06/what-is-this-in-javascript.html)
+- [X] Complete the [Keyword "this" lesson][udacity]
### Stretch
-- [ ] Do exercises for Chapter 4 of [Object Oriented Javascript][book-oojs] (and maybe read it)
-- [ ] Study these [top 50 OOPs interview questions](http://career.guru99.com/top-50-oops-interview-questions/)
+- [] Do exercises for Chapter 4 of [Object Oriented Javascript][book-oojs] (and maybe read it)
+- [] Study these [top 50 OOPs interview questions](http://career.guru99.com/top-50-oops-interview-questions/)
## Day 3: Prototype and Inheritance
-- [ ] Watch these videos on Prototypes:
+- [X] Watch these videos on Prototypes:
- https://shereef.wistia.com/medias/a5m8nwq4su
- https://shereef.wistia.com/medias/ednchu35gz
- https://shereef.wistia.com/medias/yejzrin760
- https://shereef.wistia.com/medias/372u07ybvu
- https://shereef.wistia.com/medias/xxj6323pk9
-- [ ] Read [Prototype in Plain English](http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/)
+- [] Read [Prototype in Plain English](http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/)
- [ ] Read [OOP in Javascript](http://javascriptissexy.com/oop-in-javascript-what-you-need-to-know/)
- [ ] Complete the [Prototype Chains][udacity] Lesson on Udacity
- [ ] Complete the [Prototypal Classes][udacity] Lesson on Udacity
@@ -72,16 +72,16 @@ Your objectives for the day is to:
## Day 4: Deeper Dive and Final Project
-- [ ] Complete the [Object Decorator Pattern][udacity] Lesson on Udacity
-- [ ] Complete the [Functional Classes][udacity] Lesson on Udacity
-- [ ] Complete the [Pseudoclassical Patterns][udacity] Lesson on Udacity
-- [ ] Complete the [Superclass and Subclass Patterns][udacity] Lesson on Udacity
-- [ ] Complete the [Pseudoclassical Sublasses][udacity] Lesson on Udacity
-- [ ] Start (and maybe finish) the [Final Project][udacity] Lesson on Udacity
+- [X] Complete the [Object Decorator Pattern][udacity] Lesson on Udacity
+- [X] Complete the [Functional Classes][udacity] Lesson on Udacity
+- [X] Complete the [Pseudoclassical Patterns][udacity] Lesson on Udacity
+- [X] Complete the [Superclass and Subclass Patterns][udacity] Lesson on Udacity
+- [X] Complete the [Pseudoclassical Sublasses][udacity] Lesson on Udacity
+- [X] Start (and maybe finish) the [Final Project][udacity] Lesson on Udacity
## Day 5: Final Project and check your understanding
-- [ ] Complete the [Final Project][udacity] Lesson on Udacity
+- [X] Complete the [Final Project][udacity] Lesson on Udacity
Do you know/understand: