diff --git a/README.md b/README.md index dac8af33f5..4368102967 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,13 @@ -# 2048 -A small clone of [1024](https://play.google.com/store/apps/details?id=com.veewo.a1024), based on [Saming's 2048](http://saming.fr/p/2048/) (also a clone). +# Make 2048 +A Udacity version of Gabriele Cirulli's [original 2048](http://gabrielecirulli.github.io/2048/). -Made just for fun. [Play it here!](http://gabrielecirulli.github.io/2048/) +The original version is a small clone of [1024](https://play.google.com/store/apps/details?id=com.veewo.a1024), based on [Saming's 2048](http://saming.fr/p/2048/) (also a clone). -### Contributions - - - [TimPetricola](https://github.com/TimPetricola) added best score storage - - [chrisprice](https://github.com/chrisprice) added custom code for swipe handling on mobile - - [elektryk](https://github.com/elektryk) made swipes work on Windows Phone - - [mgarciaisaia](https://github.com/mgarciaisaia) addes support for Android 2.3 - -Many thanks to [rayhaanj](https://github.com/rayhaanj), [Mechazawa](https://github.com/Mechazawa), [grant](https://github.com/grant), [remram44](https://github.com/remram44) and [ghoullier](https://github.com/ghoullier) for the many other good contributions. - -### Screenshot - -

- Screenshot -

- -That screenshot is fake, by the way. I never reached 2048 :smile: - -## Contributing -Changes and improvements are more than welcome! Feel free to fork and open a pull request. Please make your changes in a specific branch and request to pull into `master`! If you can, please make sure the game fully works before sending the PR, as that will help speed up the process. - -You can find the same information in the [contributing guide.](https://github.com/gabrielecirulli/2048/blob/master/CONTRIBUTING.md) +### Notes for the Udacity verssion +We're using this version as the recommended fork to avoid potential learning issues as the original source changes (and the Udacity videos don't update). You can [fork the original repo as well](https://github.com/gabrielecirulli/2048) ## License 2048 is licensed under the [MIT license.](https://github.com/gabrielecirulli/2048/blob/master/LICENSE.txt) ## Donations -I made this in my spare time, and it's hosted on GitHub (which means I don't have any hosting costs), but if you enjoyed the game and feel like buying me coffee, you can donate at my BTC address: `1Ec6onfsQmoP9kkL3zkpB6c5sA4PVcXU2i`. Thank you very much! +Gabriele made this in his spare time, and it's hosted on GitHub (which means I don't have any hosting costs), but if you enjoyed the game and feel like buying him coffee, you can donate at his BTC address: `1Ec6onfsQmoP9kkL3zkpB6c5sA4PVcXU2i`. diff --git a/cache.appcache b/cache.appcache new file mode 100644 index 0000000000..b307f60b0c --- /dev/null +++ b/cache.appcache @@ -0,0 +1,47 @@ +CACHE MANIFEST + +# Adds the ability to play the game online. +# The following comment needs to be updated whenever a change is made. +# Run `rake appcache:update` to do so +# Updated: 2014-03-27T17:09:22+01:00 + +# Main page +index.html + +# CSS +style/main.css + +# Fonts +style/fonts/clear-sans.css +style/fonts/ClearSans-Bold-webfont.eot +style/fonts/ClearSans-Bold-webfont.svg +style/fonts/ClearSans-Bold-webfont.woff +style/fonts/ClearSans-Light-webfont.eot +style/fonts/ClearSans-Light-webfont.svg +style/fonts/ClearSans-Light-webfont.woff +style/fonts/ClearSans-Regular-webfont.eot +style/fonts/ClearSans-Regular-webfont.svg +style/fonts/ClearSans-Regular-webfont.woff + +# Other resources +meta/apple-touch-icon.png +meta/icon_bitcoin.svg +meta/icon_pp.svg +meta/og_image.png + +# JavaScript +js/animframe_polyfill.js +js/application.js +js/bind_polyfill.js +js/classlist_polyfill.js +js/game_manager.js +js/grid.js +js/html_actuator.js +js/keyboard_input_manager.js +js/local_storage_manager.js +js/tile.js + +favicon.ico + +NETWORK: +* diff --git a/favicon.ico b/favicon.ico index 22109e04a9..b3c28ed631 100644 Binary files a/favicon.ico and b/favicon.ico differ diff --git a/index.html b/index.html index 8d188c160b..fe1fe8a931 100644 --- a/index.html +++ b/index.html @@ -1,22 +1,31 @@ - + - 2048 + Make and Play Udacity 2048 + + + + + + + + +
-

2048

+

Make 2048

0
0
@@ -24,16 +33,24 @@

2048

-

Join the numbers and get to the 2048 tile!

+

New Game + Use the arrow keys to slide tiles. Combine similar tiles to create new ones.

+ +
+ +
+

Learn to make your own version of 2048 in 30 minutes in Udacity's mini online class for beginners.

Take the Class!
+
@@ -69,16 +86,17 @@

2048

+

- How to play: Use your arrow keys to move the tiles. When two tiles with the same number touch, they merge into one! + Make your own version: If you'd like to make your own version of this game, check out Udacity's newest course for beginners Make your own 2048. No programming experience is required and in less than half an hour you'll dig into the source code, make some changes, and have your own version of the game to share.


-

- Note: This site is the official version of 2048. You can play it on your phone via http://git.io/2048. All other apps or sites are derivatives or fakes, and should be used with caution. +

+ How to play: Use your arrow keys to move the tiles. When two tiles with the same value touch, they merge into one!


- Created by Gabriele Cirulli. Based on 1024 by Veewo Studio and conceptually similar to Threes by Asher Vollmer. + This is a modified version of the original game created by Gabriele Cirulli.

@@ -92,5 +110,7 @@

2048

+ + diff --git a/js/game_manager.js b/js/game_manager.js index aea99f335a..2f01aa1805 100644 --- a/js/game_manager.js +++ b/js/game_manager.js @@ -9,6 +9,7 @@ function GameManager(size, InputManager, Actuator, StorageManager) { this.inputManager.on("move", this.move.bind(this)); this.inputManager.on("restart", this.restart.bind(this)); this.inputManager.on("keepPlaying", this.keepPlaying.bind(this)); + this.inputManager.on("clearAll", this.clearAll.bind(this)) this.setup(); } @@ -26,6 +27,10 @@ GameManager.prototype.keepPlaying = function () { this.actuator.continueGame(); // Clear the game won/lost message }; +GameManager.prototype.clearAll = function () { + this.storageManager.clearHistory(); +} + // Return true if the game is lost, or has won and the user hasn't kept playing GameManager.prototype.isGameTerminated = function () { if (this.over || (this.won && !this.keepPlaying)) { diff --git a/js/html_actuator.js b/js/html_actuator.js index 6b31f2d107..5d0106847f 100644 --- a/js/html_actuator.js +++ b/js/html_actuator.js @@ -3,6 +3,7 @@ function HTMLActuator() { this.scoreContainer = document.querySelector(".score-container"); this.bestContainer = document.querySelector(".best-container"); this.messageContainer = document.querySelector(".game-message"); + this.sharingContainer = document.querySelector(".score-sharing"); this.score = 0; } @@ -37,6 +38,9 @@ HTMLActuator.prototype.actuate = function (grid, metadata) { // Continues the game (both restart and keep playing) HTMLActuator.prototype.continueGame = function () { + if (typeof ga !== "undefined") { + ga("send", "event", "game", "restart"); + } this.clearMessage(); }; @@ -47,10 +51,25 @@ HTMLActuator.prototype.clearContainer = function (container) { }; HTMLActuator.prototype.addTile = function (tile) { + var valueMap = { + 2 : '', + 4 : '', + 8 : "skills=['code']", + 16 : "skills.add('CSS')", + 32 : '', + 64 : '', + 128 : 'getJob(skills)', + 256 : '', + 512 : 'if Udacious:', + 1024 : 'skills.increase()', + 2048 : 'myJob.advance()', + 4096 : 'myCareer=myJob' + } var self = this; var wrapper = document.createElement("div"); var inner = document.createElement("div"); + var position = tile.previousPosition || { x: tile.x, y: tile.y }; var positionClass = this.positionClass(position); @@ -62,7 +81,8 @@ HTMLActuator.prototype.addTile = function (tile) { this.applyClasses(wrapper, classes); inner.classList.add("tile-inner"); - inner.textContent = tile.value; + //inner.textContent = tile.value; + inner.textContent = valueMap[tile.value]; if (tile.previousPosition) { // Make sure that the tile gets rendered in the previous position first @@ -128,8 +148,16 @@ HTMLActuator.prototype.message = function (won) { var type = won ? "game-won" : "game-over"; var message = won ? "You win!" : "Game over!"; + if (typeof ga !== "undefined") { + ga("send", "event", "game", "end", type, this.score); + } + this.messageContainer.classList.add(type); this.messageContainer.getElementsByTagName("p")[0].textContent = message; + + this.clearContainer(this.sharingContainer); + this.sharingContainer.appendChild(this.scoreTweetButton()); + twttr.widgets.load(); }; HTMLActuator.prototype.clearMessage = function () { @@ -137,3 +165,15 @@ HTMLActuator.prototype.clearMessage = function () { this.messageContainer.classList.remove("game-won"); this.messageContainer.classList.remove("game-over"); }; + +HTMLActuator.prototype.scoreTweetButton = function () { + var tweet = document.createElement("a"); + tweet.classList.add("twitter-share-button"); + tweet.setAttribute("href", "https://twitter.com/share"); + tweet.textContent = "Tweet"; + + var text = "" + this.score + " points in Udacity2048! http://ow.ly/vpoFS Code your own game in their new mini course http://ow.ly/vpaLY #2048game" + tweet.setAttribute("data-text", text); + + return tweet; +}; diff --git a/js/keyboard_input_manager.js b/js/keyboard_input_manager.js index 32a177a47d..8056055aee 100644 --- a/js/keyboard_input_manager.js +++ b/js/keyboard_input_manager.js @@ -55,6 +55,9 @@ KeyboardInputManager.prototype.listen = function () { event.shiftKey; var mapped = map[event.which]; + // Ignore the event if it's happening in a text field + if (self.targetIsInput(event)) return; + if (!modifiers) { if (mapped !== undefined) { event.preventDefault(); @@ -71,7 +74,7 @@ KeyboardInputManager.prototype.listen = function () { // Respond to button presses this.bindButtonPress(".retry-button", this.restart); this.bindButtonPress(".restart-button", this.restart); - this.bindButtonPress(".keep-playing-button", this.keepPlaying); + //this.bindButtonPress(".keep-playing-button", this.keepPlaying); // Respond to swipe events var touchStartClientX, touchStartClientY; @@ -79,8 +82,9 @@ KeyboardInputManager.prototype.listen = function () { gameContainer.addEventListener(this.eventTouchstart, function (event) { if ((!window.navigator.msPointerEnabled && event.touches.length > 1) || - event.targetTouches > 1) { - return; // Ignore if touching with more than 1 finger + event.targetTouches > 1 || + self.targetIsInput(event)) { + return; // Ignore if touching with more than 1 finger or touching input } if (window.navigator.msPointerEnabled) { @@ -100,8 +104,9 @@ KeyboardInputManager.prototype.listen = function () { gameContainer.addEventListener(this.eventTouchend, function (event) { if ((!window.navigator.msPointerEnabled && event.touches.length > 0) || - event.targetTouches > 0) { - return; // Ignore if still touching with one or more fingers + event.targetTouches > 0 || + self.targetIsInput(event)) { + return; // Ignore if still touching with one or more fingers or input } var touchEndClientX, touchEndClientY; @@ -142,3 +147,7 @@ KeyboardInputManager.prototype.bindButtonPress = function (selector, fn) { button.addEventListener("click", fn.bind(this)); button.addEventListener(this.eventTouchend, fn.bind(this)); }; + +KeyboardInputManager.prototype.targetIsInput = function (event) { + return event.target.tagName.toLowerCase() === "input"; +}; diff --git a/js/local_storage_manager.js b/js/local_storage_manager.js index 776e94b1ab..1d5b5580c8 100644 --- a/js/local_storage_manager.js +++ b/js/local_storage_manager.js @@ -61,3 +61,7 @@ LocalStorageManager.prototype.setGameState = function (gameState) { LocalStorageManager.prototype.clearGameState = function () { this.storage.removeItem(this.gameStateKey); }; + +LocalStorageManager.prototype.clearHistory = function () { + this.storage.clear(); +} diff --git a/meta/icon_bitcoin.svg b/meta/icon_bitcoin.svg new file mode 100644 index 0000000000..944d65d063 --- /dev/null +++ b/meta/icon_bitcoin.svg @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/meta/icon_pp.svg b/meta/icon_pp.svg new file mode 100644 index 0000000000..50f2e2cd52 --- /dev/null +++ b/meta/icon_pp.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/meta/og_image.png b/meta/og_image.png new file mode 100644 index 0000000000..b3c6827ccb Binary files /dev/null and b/meta/og_image.png differ diff --git a/style/helpers.scss b/style/helpers.scss index 7b4445b37b..3786bc09ae 100644 --- a/style/helpers.scss +++ b/style/helpers.scss @@ -71,6 +71,13 @@ } } +// Appearance +@mixin appearance($args...) { + -webkit-appearance: $args; + -moz-appearance: $args; + appearance: $args; +} + // Clearfix @mixin clearfix { &:after { diff --git a/style/main.css b/style/main.css index aeca8ed14e..d019f67a80 100644 --- a/style/main.css +++ b/style/main.css @@ -1,23 +1,67 @@ @import url(fonts/clear-sans.css); +@import url("http://fonts.googleapis.com/css?family=Source+Code+Pro:400,600,700"); html, body { margin: 0; padding: 0; - background: #faf8ef; - color: #776e65; + background: #9cc2d2; + color: #354b59; font-family: "Clear Sans", "Helvetica Neue", Arial, sans-serif; + font-family: "Whitney SSm A","Whitney SSm B","Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 18px; } body { margin: 80px 0; } +p.learn { + margin-top: 20px; +} + +span.tile-text { + line-height: 1.25; +} + + + +input { + display: inline-block; + background: #8f7a66; + border-radius: 3px; + padding: 0 20px; + text-decoration: none; + color: #f9f6f2; + height: 40px; + line-height: 42px; + cursor: pointer; + font: inherit; + border: none; + outline: none; + box-sizing: border-box; + font-weight: bold; + margin: 0; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; } + input[type="text"], input[type="email"] { + cursor: auto; + background: #fcfbf9; + font-weight: normal; + color: #776e65; + padding: 0 15px; } + input[type="text"]::-webkit-input-placeholder, input[type="email"]::-webkit-input-placeholder { + color: #9d948c; } + input[type="text"]::-moz-placeholder, input[type="email"]::-moz-placeholder { + color: #9d948c; } + input[type="text"]:-ms-input-placeholder, input[type="email"]:-ms-input-placeholder { + color: #9d948c; } + .heading:after { content: ""; display: block; clear: both; } h1.title { - font-size: 80px; - font-weight: bold; + font-size: 55px; + font-weight: medium; margin: 0; display: block; float: left; } @@ -53,7 +97,7 @@ h1.title { .score-container, .best-container { position: relative; display: inline-block; - background: #bbada0; + background: #0c92bf; padding: 15px 25px; font-size: 25px; height: 25px; @@ -101,8 +145,7 @@ p { line-height: 1.65; } a { - color: #776e65; - font-weight: bold; + font-weight: medium; text-decoration: underline; cursor: pointer; } @@ -137,8 +180,26 @@ hr { 100% { opacity: 1; } } +@-webkit-keyframes slide-up { + 0% { + margin-top: 32%; } + + 100% { + margin-top: 20%; } } +@-moz-keyframes slide-up { + 0% { + margin-top: 32%; } + + 100% { + margin-top: 20%; } } +@keyframes slide-up { + 0% { + margin-top: 32%; } + + 100% { + margin-top: 20%; } } .game-container { - margin-top: 40px; + margin-top: 20px; position: relative; padding: 15px; cursor: default; @@ -149,57 +210,86 @@ hr { -ms-user-select: none; -ms-touch-action: none; touch-action: none; - background: #bbada0; + background: #1e6477; border-radius: 6px; width: 500px; height: 500px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } - .game-container .game-message { - display: none; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - background: rgba(238, 228, 218, 0.5); - z-index: 100; - text-align: center; - -webkit-animation: fade-in 800ms ease 1200ms; - -moz-animation: fade-in 800ms ease 1200ms; - animation: fade-in 800ms ease 1200ms; - -webkit-animation-fill-mode: both; - -moz-animation-fill-mode: both; - animation-fill-mode: both; } - .game-container .game-message p { - font-size: 60px; - font-weight: bold; - height: 60px; - line-height: 60px; - margin-top: 222px; } - .game-container .game-message .lower { + +.game-message { + display: none; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(150, 150, 150, 0.83); + z-index: 100; + padding-top: 40px; + text-align: center; + -webkit-animation: fade-in 800ms ease 1200ms; + -moz-animation: fade-in 800ms ease 1200ms; + animation: fade-in 800ms ease 1200ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + .game-message p { + font-size: 60px; + font-weight: bold; + height: 60px; + line-height: 60px; + margin-top: 222px; } + .game-message .lower { + display: block; + margin-top: 29px; } + .game-message .mailing-list { + margin-top: 52px; } + .game-message .mailing-list strong { display: block; - margin-top: 59px; } - .game-container .game-message a { - display: inline-block; - background: #8f7a66; - border-radius: 3px; - padding: 0 20px; - text-decoration: none; - color: #f9f6f2; - height: 40px; - line-height: 42px; - margin-left: 9px; } - .game-container .game-message a.keep-playing-button { - display: none; } - .game-container .game-message.game-won { - background: rgba(237, 194, 46, 0.5); - color: #f9f6f2; } - .game-container .game-message.game-won a.keep-playing-button { - display: inline-block; } - .game-container .game-message.game-won, .game-container .game-message.game-over { - display: block; } + margin-bottom: 10px; } + .game-message .mailing-list .mailing-list-email-field { + width: 230px; + margin-right: 5px; } + .game-message a { + display: inline-block; + background: #8f7a66; + border-radius: 3px; + padding: 0 20px; + text-decoration: none; + color: #f9f6f2; + height: 40px; + line-height: 42px; + cursor: pointer; + margin-left: 9px; } + .game-message a.keep-playing-button { + display: none; } + .game-message .score-sharing { + display: inline-block; + vertical-align: middle; + margin-left: 10px; } + .game-message.game-won { + background: rgba(237, 194, 46, 0.5); + color: #f9f6f2; } + .game-message.game-won a.keep-playing-button { + display: inline-block; } + .game-message.game-won, .game-message.game-over { + display: block; } + .game-message.game-won p, .game-message.game-over p { + -webkit-animation: slide-up 1.5s ease-in-out 2500ms; + -moz-animation: slide-up 1.5s ease-in-out 2500ms; + animation: slide-up 1.5s ease-in-out 2500ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + .game-message.game-won .mailing-list, .game-message.game-over .mailing-list { + -webkit-animation: fade-in 1.5s ease-in-out 2500ms; + -moz-animation: fade-in 1.5s ease-in-out 2500ms; + animation: fade-in 1.5s ease-in-out 2500ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } .grid-container { position: absolute; @@ -307,91 +397,101 @@ hr { transition-property: transform; } .tile .tile-inner { border-radius: 3px; - background: #eee4da; + background: #f5f5f5; text-align: center; font-weight: bold; z-index: 10; - font-size: 55px; - color: rgba(0,0,0,0);} + font-family: 'Source Code Pro', Courier; + font-size: 16px; + color: #354b59;} .tile.tile-2 .tile-inner { - background: #eee4da; - background: url('../tile-sets/presidents/2.jpg'); + background: url('../tile-sets/udacity/2.png'); + background-size: 100%; + color: rgba(0,0,0,0); box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0), inset 0 0 0 1px rgba(255, 255, 255, 0); } .tile.tile-4 .tile-inner { - background: #ede0c8; - background: url('../tile-sets/presidents/4.jpg'); + background: url('../tile-sets/udacity/4.png'); + background-size: 100%; + color: rgba(0,0,0,0); box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0), inset 0 0 0 1px rgba(255, 255, 255, 0); } .tile.tile-8 .tile-inner { - color: #f9f6f2; + background: url('../tile-sets/udacity/8.png'); + background-size: 100%; color: rgba(0,0,0,0); - background: #f2b179; - background: url('../tile-sets/presidents/8.jpg'); } + font-weight: medium; + font-size: 11px; + } .tile.tile-16 .tile-inner { - color: #f9f6f2; + background: url('../tile-sets/udacity/16.png'); + background-size: 100%; color: rgba(0,0,0,0); - background: #f59563; - background: url('../tile-sets/presidents/16.jpg'); } + font-weight: medium; + font-size: 10px; + } .tile.tile-32 .tile-inner { - color: #f9f6f2; + background: url('../tile-sets/udacity/32.png'); + background-size: 100%; color: rgba(0,0,0,0); - background: #f67c5f; - background: url('../tile-sets/presidents/32.jpg'); } + font-size: 14px; + } .tile.tile-64 .tile-inner { - color: #f9f6f2; + background: url('../tile-sets/udacity/64.png'); + background-size: 100%; color: rgba(0,0,0,0); - background: #f65e3b; - background: url('../tile-sets/presidents/64.jpg'); } + font-size: 14px; + + } .tile.tile-128 .tile-inner { - color: #f9f6f2; + font-weight: medium; + background: url('../tile-sets/udacity/128.png'); + background-size: 100%; color: rgba(0,0,0,0); - background: #edcf72; - background: url('../tile-sets/presidents/128.jpg'); box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.2381), inset 0 0 0 1px rgba(255, 255, 255, 0.14286); - font-size: 45px; } + font-size: 12px; } @media screen and (max-width: 520px) { .tile.tile-128 .tile-inner { - font-size: 25px; } } + font-size: 12px; } } .tile.tile-256 .tile-inner { - color: #f9f6f2; + background: url('../tile-sets/udacity/256.png'); + background-size: 100%; color: rgba(0,0,0,0); - background: #edcc61; - background: url('/tile-sets/presidents/256.jpg'); box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.31746), inset 0 0 0 1px rgba(255, 255, 255, 0.19048); - font-size: 45px; } + font-size: 14px; } @media screen and (max-width: 520px) { .tile.tile-256 .tile-inner { - font-size: 25px; } } + font-size: 16px; } } .tile.tile-512 .tile-inner { - color: #f9f6f2; + background: url('../tile-sets/udacity/512.png'); + background-size: 100%; color: rgba(0,0,0,0); - background: #edc850; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.39683), inset 0 0 0 1px rgba(255, 255, 255, 0.2381); - font-size: 45px; } + font-size: 13px; } @media screen and (max-width: 520px) { .tile.tile-512 .tile-inner { - font-size: 25px; } } + font-size: 13px; } } .tile.tile-1024 .tile-inner { - color: #f9f6f2; + background: url('../tile-sets/udacity/1024.png'); + background-size: 100%; color: rgba(0,0,0,0); - background: #edc53f; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.47619), inset 0 0 0 1px rgba(255, 255, 255, 0.28571); - font-size: 35px; } + font-size: 10px; } @media screen and (max-width: 520px) { .tile.tile-1024 .tile-inner { - font-size: 15px; } } + font-size: 10px; } } .tile.tile-2048 .tile-inner { - color: #f9f6f2; + background: url('../tile-sets/udacity/2048.png'); + background-size: 100%; color: rgba(0,0,0,0); - background: #edc22e; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.55556), inset 0 0 0 1px rgba(255, 255, 255, 0.33333); - font-size: 35px; } + font-size: 10px; } @media screen and (max-width: 520px) { .tile.tile-2048 .tile-inner { - font-size: 15px; } } + font-size: 10px; } } .tile.tile-super .tile-inner { color: #f9f6f2; background: #3c3a32; - font-size: 30px; } + font-weight: medium; + font-size: 12px; } @media screen and (max-width: 520px) { .tile.tile-super .tile-inner { font-size: 10px; } } @@ -494,32 +594,31 @@ hr { -moz-animation-fill-mode: backwards; animation-fill-mode: backwards; } +.above-game { + margin-top: 10px; +} + .above-game:after { content: ""; display: block; clear: both; } .game-intro { + margin-top: 5px; float: left; - line-height: 42px; + line-height: 30px; margin-bottom: 0; } -.restart-button { - display: inline-block; - background: #8f7a66; - border-radius: 3px; - padding: 0 20px; - text-decoration: none; - color: #f9f6f2; - height: 40px; - line-height: 42px; - display: block; - text-align: center; - float: right; } - .game-explanation { margin-top: 50px; } +.sharing { + margin-top: 20px; + text-align: center; } + .sharing > iframe, .sharing > span, .sharing > form { + display: inline-block; + vertical-align: middle; } + @media screen and (max-width: 520px) { html, body { font-size: 15px; } @@ -545,12 +644,12 @@ hr { margin-bottom: 10px; } .game-intro { - width: 55%; + width: 100%; display: block; box-sizing: border-box; line-height: 1.65; } - .restart-button { + .restart-button, .retry-button { width: 42%; padding: 0; display: block; @@ -569,57 +668,86 @@ hr { -ms-user-select: none; -ms-touch-action: none; touch-action: none; - background: #bbada0; + background: #1e6477; border-radius: 6px; width: 280px; height: 280px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } - .game-container .game-message { - display: none; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - background: rgba(238, 228, 218, 0.5); - z-index: 100; - text-align: center; - -webkit-animation: fade-in 800ms ease 1200ms; - -moz-animation: fade-in 800ms ease 1200ms; - animation: fade-in 800ms ease 1200ms; - -webkit-animation-fill-mode: both; - -moz-animation-fill-mode: both; - animation-fill-mode: both; } - .game-container .game-message p { - font-size: 60px; - font-weight: bold; - height: 60px; - line-height: 60px; - margin-top: 222px; } - .game-container .game-message .lower { + + .game-message { + display: none; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(238, 228, 218, 0.73); + z-index: 100; + padding-top: 40px; + text-align: center; + -webkit-animation: fade-in 800ms ease 1200ms; + -moz-animation: fade-in 800ms ease 1200ms; + animation: fade-in 800ms ease 1200ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + .game-message p { + font-size: 60px; + font-weight: bold; + height: 60px; + line-height: 60px; + margin-top: 222px; } + .game-message .lower { + display: block; + margin-top: 29px; } + .game-message .mailing-list { + margin-top: 52px; } + .game-message .mailing-list strong { display: block; - margin-top: 59px; } - .game-container .game-message a { - display: inline-block; - background: #8f7a66; - border-radius: 3px; - padding: 0 20px; - text-decoration: none; - color: #f9f6f2; - height: 40px; - line-height: 42px; - margin-left: 9px; } - .game-container .game-message a.keep-playing-button { - display: none; } - .game-container .game-message.game-won { - background: rgba(237, 194, 46, 0.5); - color: #f9f6f2; } - .game-container .game-message.game-won a.keep-playing-button { - display: inline-block; } - .game-container .game-message.game-won, .game-container .game-message.game-over { - display: block; } + margin-bottom: 10px; } + .game-message .mailing-list .mailing-list-email-field { + width: 230px; + margin-right: 5px; } + .game-message a { + display: inline-block; + background: #8f7a66; + border-radius: 3px; + padding: 0 20px; + text-decoration: none; + color: #f9f6f2; + height: 40px; + line-height: 42px; + cursor: pointer; + margin-left: 9px; } + .game-message a.keep-playing-button { + display: none; } + .game-message .score-sharing { + display: inline-block; + vertical-align: middle; + margin-left: 10px; } + .game-message.game-won { + background: rgba(237, 194, 46, 0.5); + color: #f9f6f2; } + .game-message.game-won a.keep-playing-button { + display: inline-block; } + .game-message.game-won, .game-message.game-over { + display: block; } + .game-message.game-won p, .game-message.game-over p { + -webkit-animation: slide-up 1.5s ease-in-out 2500ms; + -moz-animation: slide-up 1.5s ease-in-out 2500ms; + animation: slide-up 1.5s ease-in-out 2500ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + .game-message.game-won .mailing-list, .game-message.game-over .mailing-list { + -webkit-animation: fade-in 1.5s ease-in-out 2500ms; + -moz-animation: fade-in 1.5s ease-in-out 2500ms; + animation: fade-in 1.5s ease-in-out 2500ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } .grid-container { position: absolute; @@ -720,10 +848,169 @@ hr { .tile .tile-inner { font-size: 35px; } - .game-message p { - font-size: 30px !important; - height: 30px !important; - line-height: 30px !important; - margin-top: 90px !important; } - .game-message .lower { - margin-top: 30px !important; } } + .game-message { + padding-top: 0; } + .game-message p { + font-size: 30px !important; + height: 30px !important; + line-height: 30px !important; + margin-top: 32% !important; + margin-bottom: 0 !important; } + .game-message .lower { + margin-top: 10px !important; } + .game-message.game-won .score-sharing { + margin-top: 10px; } + .game-message.game-over .mailing-list { + margin-top: 25px; } + .game-message .mailing-list { + margin-top: 10px; } + .game-message .mailing-list .mailing-list-email-field { + width: 180px; } + + .sharing > iframe, .sharing > span, .sharing > form { + display: block; + margin: 0 auto; + margin-bottom: 20px; } } +.pp-donate button { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border: none; + font: inherit; + color: inherit; + display: inline-block; + background: #8f7a66; + border-radius: 3px; + padding: 0 20px; + text-decoration: none; + color: #f9f6f2; + height: 40px; + line-height: 42px; + cursor: pointer; } + .pp-donate button img { + vertical-align: -4px; + margin-right: 8px; } + +.btc-donate { + position: relative; + margin-left: 10px; + display: inline-block; + background: #8f7a66; + border-radius: 3px; + padding: 0 20px; + text-decoration: none; + color: #f9f6f2; + height: 40px; + line-height: 42px; + cursor: pointer; } + .btc-donate img { + vertical-align: -4px; + margin-right: 8px; } + .btc-donate a { + color: #f9f6f2; + text-decoration: none; + font-weight: normal; } + .btc-donate .address { + cursor: auto; + position: absolute; + width: 340px; + right: 50%; + margin-right: -170px; + padding-bottom: 7px; + top: -30px; + opacity: 0; + pointer-events: none; + -webkit-transition: 400ms ease; + -moz-transition: 400ms ease; + transition: 400ms ease; + -webkit-transition-property: top, opacity; + -moz-transition-property: top, opacity; + transition-property: top, opacity; } + .btc-donate .address:after { + position: absolute; + border-top: 10px solid #bbada0; + border-right: 7px solid transparent; + border-left: 7px solid transparent; + content: ""; + bottom: 0px; + left: 50%; + margin-left: -7px; } + .btc-donate .address code { + background-color: #bbada0; + padding: 10px 15px; + width: 100%; + border-radius: 3px; + line-height: 1; + font-weight: normal; + font-size: 15px; + font-family: Consolas, "Liberation Mono", Courier, monospace; + text-align: center; } + .btc-donate:hover .address, .btc-donate .address:hover .address { + opacity: 1; + top: -45px; + pointer-events: auto; } + @media screen and (max-width: 480px) { + .btc-donate { + width: 120px; } + .btc-donate .address { + margin-right: -150px; + width: 300px; } + .btc-donate .address code { + font-size: 13px; } + .btc-donate .address:after { + left: 50%; + bottom: 2px; } } +a.learn, a.keep-playing-button { + background-color: #de8b3e; + text-decoration: none; + border: 1px solid; + border-color: #c7640b; + color: white; + border-radius: 0; + margin: 0 auto; + margin-top: 5px; + display: block; + width: 200px; + padding: 10px; + text-align: center; +} +a.learn:visited, a.keep-playing-button { + } +a.learn:hover, a.keep-playing-button:hover, a.learn-low:hover { + background-image: linear-gradient(to bottom,#f59a18 0,#f27d13 100%); + background-repeat: repeat-x; +} +.restart-button, a.retry-button { + display: inline-block; + background: #1e6477; + border-radius: 3px; + padding: 0 20px; + text-decoration: none; + color: #f9f6f2; + line-height: 42px; + cursor: pointer; + display: block; + text-align: center; + float: right; + margin-top: 7px; +} + +a.retry-button, a.learn-low { + width: 150px; + height: 40px; + padding: 0; + border-radius: 0; + background-color:black; + display: inline-block; + margin: 0; + line-height: 42px; +} + +a.learn-low { + margin-right: 10px; +} + +a.retry-button { + margin-left: 10px; + float: center; +} \ No newline at end of file diff --git a/style/main.scss b/style/main.scss index cce393fa78..40ddf1c1a6 100644 --- a/style/main.scss +++ b/style/main.scss @@ -35,6 +35,56 @@ body { margin: 80px 0; } +// Styles for buttons +@mixin button { + display: inline-block; + background: darken($game-container-background, 20%); + border-radius: 3px; + padding: 0 20px; + text-decoration: none; + color: $bright-text-color; + height: 40px; + line-height: 42px; + cursor: pointer; +} + +input { + @include button; + font: inherit; + border: none; + outline: none; + box-sizing: border-box; + font-weight: bold; + margin: 0; + @include appearance(none); + + &[type="text"], &[type="email"] { + cursor: auto; + background: lighten($tile-color, 9%); + font-weight: normal; + color: $text-color; + + padding: 0 15px; + + @mixin placeholder { + color: lighten($text-color, 15%); + } + + // Included separately so that browsers don't refuse mixed rules + &::-webkit-input-placeholder { + @include placeholder; + } + + &::-moz-placeholder { + @include placeholder; + } + + &:-ms-input-placeholder { + @include placeholder; + } + } +} + .heading { @include clearfix; } @@ -155,16 +205,16 @@ hr { } } -// Styles for buttons -@mixin button { - display: inline-block; - background: darken($game-container-background, 20%); - border-radius: 3px; - padding: 0 20px; - text-decoration: none; - color: $bright-text-color; - height: 40px; - line-height: 42px; +@include keyframes(slide-up) { + 0% { + margin-top: 32%; + // margin-top: 222px; + } + + 100% { + margin-top: 20%; + // margin-top: 150px; + } } // Game field mixin used to render CSS at different width @@ -192,59 +242,91 @@ hr { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; + } - .game-message { - display: none; + .game-message { + display: none; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - background: rgba($tile-color, .5); - z-index: 100; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba($tile-color, .73); + z-index: 100; - text-align: center; + padding-top: 40px; // Pushes content down in desktop version (removed on mobile) - p { - font-size: 60px; - font-weight: bold; - height: 60px; - line-height: 60px; - margin-top: 222px; - // height: $field-width; - // line-height: $field-width; - } + text-align: center; - .lower { + p { + font-size: 60px; + font-weight: bold; + height: 60px; + line-height: 60px; + margin-top: 222px; + // height: $field-width; + // line-height: $field-width; + } + + .lower { + display: block; + margin-top: 29px; + } + + .mailing-list { + margin-top: 52px; + + strong { display: block; - margin-top: 59px; + margin-bottom: 10px; + } + + .mailing-list-email-field { + width: 230px; + margin-right: 5px; } + } - a { - @include button; - margin-left: 9px; - // margin-top: 59px; + a { + @include button; + margin-left: 9px; + // margin-top: 59px; - &.keep-playing-button { - display: none; - } + &.keep-playing-button { + display: none; } + } + + .score-sharing { + display: inline-block; + vertical-align: middle; + margin-left: 10px; + } - @include animation(fade-in 800ms ease $transition-speed * 12); - @include animation-fill-mode(both); + @include animation(fade-in 800ms ease $transition-speed * 12); + @include animation-fill-mode(both); - &.game-won { - background: rgba($tile-gold-color, .5); - color: $bright-text-color; + &.game-won { + background: rgba($tile-gold-color, .5); + color: $bright-text-color; - a.keep-playing-button { - display: inline-block; - } + a.keep-playing-button { + display: inline-block; } + } - &.game-won, &.game-over { - display: block; + &.game-won, &.game-over { + display: block; + + p { + @include animation(slide-up 1.5s ease-in-out $transition-speed * 25); + @include animation-fill-mode(both); + } + + .mailing-list { + @include animation(fade-in 1.5s ease-in-out $transition-speed * 25); + @include animation-fill-mode(both); } } } @@ -472,6 +554,16 @@ hr { margin-top: 50px; } +.sharing { + margin-top: 20px; + text-align: center; + + > iframe, > span, > form { + display: inline-block; + vertical-align: middle; + } +} + @include smaller($mobile-threshold) { // Redefine variables for smaller screens $field-width: 280px; @@ -535,15 +627,147 @@ hr { } .game-message { + padding-top: 0; + p { font-size: 30px !important; height: 30px !important; line-height: 30px !important; - margin-top: 90px !important; + margin-top: 32% !important; + margin-bottom: 0 !important; } .lower { - margin-top: 30px !important; + margin-top: 10px !important; + } + + &.game-won .score-sharing { + margin-top: 10px; + } + + &.game-over .mailing-list { + margin-top: 25px; + } + + .mailing-list { + margin-top: 10px; + + .mailing-list-email-field { + width: 180px; + } + } + } + + .sharing { + > iframe, > span, > form { + display: block; + margin: 0 auto; + margin-bottom: 20px; + } + } +} + +// PP Donate button +.pp-donate { + button { + @include appearance(none); + border: none; + font: inherit; + color: inherit; + @include button; + + img { + vertical-align: -4px; + margin-right: 8px; + } + } +} + +// Bitcoin donate button +.btc-donate { + // font-size: 14px; + position: relative; + margin-left: 10px; + @include button; + + img { + vertical-align: -4px; + margin-right: 8px; + } + + a { + color: $bright-text-color; + text-decoration: none; + font-weight: normal; + } + + .address { + // display: none; + cursor: auto; + position: absolute; + // background: red; + width: 340px; + right: 50%; + margin-right: -170px; + + padding-bottom: 7px; + + top: -30px; + opacity: 0; + pointer-events: none; + @include transition(400ms ease); + @include transition-property(top, opacity); + + &:after { + position: absolute; + border-top: 10px solid $game-container-background; + border-right: 7px solid transparent; + border-left: 7px solid transparent; + content: ""; + bottom: 0px; + left: 50%; + margin-left: -7px; + } + + code { + background-color: $game-container-background; + padding: 10px 15px; + width: 100%; + border-radius: 3px; + line-height: 1; + font-weight: normal; + font-size: 15px; + font-family: Consolas, "Liberation Mono", Courier, monospace; + text-align: center; + + } + } + + &:hover, .address:hover { + .address { + opacity: 1; + top: -45px; + pointer-events: auto; + } + } + + // Styles for small screens + @include smaller(480px) { + width: 120px; + + .address { + margin-right: -150px; + // background: red; + width: 300px; + + code { + font-size: 13px; + } + + &:after { + left: 50%; + bottom: 2px; + } } } } diff --git a/tile-sets/udacity/1024.png b/tile-sets/udacity/1024.png new file mode 100644 index 0000000000..2a85797a83 Binary files /dev/null and b/tile-sets/udacity/1024.png differ diff --git a/tile-sets/udacity/128.png b/tile-sets/udacity/128.png old mode 100755 new mode 100644 index 7e31d27455..d14cfc4a15 Binary files a/tile-sets/udacity/128.png and b/tile-sets/udacity/128.png differ diff --git a/tile-sets/udacity/16.png b/tile-sets/udacity/16.png old mode 100755 new mode 100644 index 9adf22d1f2..56482b268c Binary files a/tile-sets/udacity/16.png and b/tile-sets/udacity/16.png differ diff --git a/tile-sets/udacity/2.png b/tile-sets/udacity/2.png old mode 100755 new mode 100644 index e7eac747f0..e1dc3f9d09 Binary files a/tile-sets/udacity/2.png and b/tile-sets/udacity/2.png differ diff --git a/tile-sets/udacity/2048.png b/tile-sets/udacity/2048.png new file mode 100644 index 0000000000..83b5647d14 Binary files /dev/null and b/tile-sets/udacity/2048.png differ diff --git a/tile-sets/udacity/256.png b/tile-sets/udacity/256.png old mode 100755 new mode 100644 index 8d9f348116..51f4359fae Binary files a/tile-sets/udacity/256.png and b/tile-sets/udacity/256.png differ diff --git a/tile-sets/udacity/32.png b/tile-sets/udacity/32.png old mode 100755 new mode 100644 index b471b2fd13..0b376138cd Binary files a/tile-sets/udacity/32.png and b/tile-sets/udacity/32.png differ diff --git a/tile-sets/udacity/4.png b/tile-sets/udacity/4.png old mode 100755 new mode 100644 index a924c8bc6f..12d9c63466 Binary files a/tile-sets/udacity/4.png and b/tile-sets/udacity/4.png differ diff --git a/tile-sets/udacity/512.png b/tile-sets/udacity/512.png new file mode 100644 index 0000000000..7bb1eef5d6 Binary files /dev/null and b/tile-sets/udacity/512.png differ diff --git a/tile-sets/udacity/64.png b/tile-sets/udacity/64.png old mode 100755 new mode 100644 index 1c090c5da7..e8215e035e Binary files a/tile-sets/udacity/64.png and b/tile-sets/udacity/64.png differ diff --git a/tile-sets/udacity/8.png b/tile-sets/udacity/8.png old mode 100755 new mode 100644 index aa1b09878f..76f0d84552 Binary files a/tile-sets/udacity/8.png and b/tile-sets/udacity/8.png differ