From c0f79397dd75e03a7a40303f82926e8187697d07 Mon Sep 17 00:00:00 2001
From: M.Gergo
Date: Fri, 8 Mar 2019 23:32:47 +0100
Subject: Rev: 4455
---
.../www/include/alert/hu_HU/module-jatek.php | 0
.../include/menu/private/hu_HU/module-jatek.php | 14 +
.../www/include/modules/jatek/base/base.php | 58 ++
.../www/include/modules/jatek/base/query.php | 36 ++
.../www/lang/hu_HU/module-jatek/egyszam.php | 10 +
.../www/lang/hu_HU/module-jatek/jatek.php | 7 +
.../www/policy/private/jatek/2048-pre.php | 0
.../mayor-jatek/www/policy/private/jatek/2048.php | 5 +
.../www/policy/private/jatek/egyszam-pre.php | 18 +
.../www/policy/private/jatek/egyszam.php | 7 +
.../www/policy/private/jatek/jatek-pre.php | 6 +
.../mayor-jatek/www/policy/private/jatek/jatek.php | 7 +
.../www/skin/classic/module-jatek/css/2048.css | 499 +++++++++++++++
.../www/skin/classic/module-jatek/css/egyszam.css | 2 +
.../css/fonts/ClearSans-Bold-webfont.eot | Bin 0 -> 23821 bytes
.../css/fonts/ClearSans-Bold-webfont.svg | 640 ++++++++++++++++++++
.../css/fonts/ClearSans-Bold-webfont.woff | Bin 0 -> 27120 bytes
.../css/fonts/ClearSans-Light-webfont.eot | Bin 0 -> 25570 bytes
.../css/fonts/ClearSans-Light-webfont.svg | 670 +++++++++++++++++++++
.../css/fonts/ClearSans-Light-webfont.woff | Bin 0 -> 28700 bytes
.../css/fonts/ClearSans-Regular-webfont.eot | Bin 0 -> 23490 bytes
.../css/fonts/ClearSans-Regular-webfont.svg | 669 ++++++++++++++++++++
.../css/fonts/ClearSans-Regular-webfont.woff | Bin 0 -> 26764 bytes
.../classic/module-jatek/css/fonts/clear-sans.css | 29 +
.../www/skin/classic/module-jatek/css/jatek.css | 12 +
.../www/skin/classic/module-jatek/html/2048.phtml | 77 +++
.../www/skin/classic/module-jatek/html/base.phtml | 51 ++
.../www/skin/classic/module-jatek/img/2048.png | Bin 0 -> 21371 bytes
.../classic/module-jatek/js/animframe_polyfill.js | 28 +
.../skin/classic/module-jatek/js/application.js | 4 +
.../skin/classic/module-jatek/js/bind_polyfill.js | 9 +
.../classic/module-jatek/js/classlist_polyfill.js | 71 +++
.../skin/classic/module-jatek/js/game_manager.js | 276 +++++++++
.../www/skin/classic/module-jatek/js/grid.js | 117 ++++
.../skin/classic/module-jatek/js/html_actuator.js | 139 +++++
.../module-jatek/js/keyboard_input_manager.js | 144 +++++
.../module-jatek/js/local_storage_manager.js | 63 ++
.../www/skin/classic/module-jatek/js/tile.js | 27 +
38 files changed, 3695 insertions(+)
create mode 100644 mayor-orig/mayor-jatek/www/include/alert/hu_HU/module-jatek.php
create mode 100644 mayor-orig/mayor-jatek/www/include/menu/private/hu_HU/module-jatek.php
create mode 100644 mayor-orig/mayor-jatek/www/include/modules/jatek/base/base.php
create mode 100644 mayor-orig/mayor-jatek/www/include/modules/jatek/base/query.php
create mode 100644 mayor-orig/mayor-jatek/www/lang/hu_HU/module-jatek/egyszam.php
create mode 100644 mayor-orig/mayor-jatek/www/lang/hu_HU/module-jatek/jatek.php
create mode 100644 mayor-orig/mayor-jatek/www/policy/private/jatek/2048-pre.php
create mode 100644 mayor-orig/mayor-jatek/www/policy/private/jatek/2048.php
create mode 100644 mayor-orig/mayor-jatek/www/policy/private/jatek/egyszam-pre.php
create mode 100644 mayor-orig/mayor-jatek/www/policy/private/jatek/egyszam.php
create mode 100644 mayor-orig/mayor-jatek/www/policy/private/jatek/jatek-pre.php
create mode 100644 mayor-orig/mayor-jatek/www/policy/private/jatek/jatek.php
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/2048.css
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/egyszam.css
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.eot
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.svg
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.woff
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.eot
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.svg
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.woff
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.eot
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.svg
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.woff
create mode 100755 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/clear-sans.css
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/jatek.css
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/html/2048.phtml
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/html/base.phtml
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/img/2048.png
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/animframe_polyfill.js
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/application.js
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/bind_polyfill.js
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/classlist_polyfill.js
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/game_manager.js
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/grid.js
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/html_actuator.js
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/keyboard_input_manager.js
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/local_storage_manager.js
create mode 100644 mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/tile.js
(limited to 'mayor-orig/mayor-jatek/www')
diff --git a/mayor-orig/mayor-jatek/www/include/alert/hu_HU/module-jatek.php b/mayor-orig/mayor-jatek/www/include/alert/hu_HU/module-jatek.php
new file mode 100644
index 00000000..e69de29b
diff --git a/mayor-orig/mayor-jatek/www/include/menu/private/hu_HU/module-jatek.php b/mayor-orig/mayor-jatek/www/include/menu/private/hu_HU/module-jatek.php
new file mode 100644
index 00000000..d96d14e3
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/include/menu/private/hu_HU/module-jatek.php
@@ -0,0 +1,14 @@
+ 'Játék', 'url' => 'index.php?page=jatek&f=2048')
+ );
+
+ $MENU['modules']['jatek'][''] = array(
+ array('txt' => '2048', 'url' => 'index.php?page=jatek&f=2048'),
+ array('txt' => 'Egyszámjáték szavazó', 'url' => 'index.php?page=jatek&f=egyszam'),
+ array('txt' => 'Egyszámjáték eredmény', 'url' => 'index.php?page=jatek&f=jatek')
+ );
+
+
+?>
diff --git a/mayor-orig/mayor-jatek/www/include/modules/jatek/base/base.php b/mayor-orig/mayor-jatek/www/include/modules/jatek/base/base.php
new file mode 100644
index 00000000..0cbc0821
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/include/modules/jatek/base/base.php
@@ -0,0 +1,58 @@
+=200) return false;
+ if (!is_numeric($het) || $het==0) $het = getEgyszamHet();
+
+ /* a kulcs ellenőrzés miatt nem szavazhat 2* */
+ $q = "INSERT INTO egyszam (ev,het,szam,userAccount) VALUES (year(now()),$het,$szam,'"._USERACCOUNT."')";
+
+ _my_query($q,array('db'=>'jatek'));
+
+ }
+
+ function getEgyszamHet() {
+ return date('W');
+ }
+
+ function egyszamSzavazott($het='') { //:bool
+
+ if (!is_numeric($het) || $het==0) $het = getEgyszamHet();
+
+ /* a kulcs ellenőrzés miatt nem szavazhat 2* */
+ $q = "SELECT count(*) AS db FROM egyszam WHERE ev=year(now()) AND het=$het AND userAccount='"._USERACCOUNT."'";
+
+ $db = _my_value_query($q,array('db'=>'jatek'));
+
+ return ($db==1)?true:false;
+
+ }
+
+ function getEgyszamEredmeny($het) {
+
+ if (!is_numeric($het) || $het==0) $het = getEgyszamHet()-1; // évváltás!
+ if ($het==0) {
+ //kérdezd le a year-1 max(het)
+ $q = "SELECT max(het) FROM egyszam WHERE ev = year(now())-1";
+ $het = _my_value_query($q,array('db'=>'jatek'));
+ }
+
+ /* a kulcs ellenőrzés miatt nem szavazhat 2* */
+ $q = "SELECT count(*) AS db,szam FROM egyszam WHERE ev=year(now()) AND het=$het GROUP BY szam ORDER BY szam";
+ return _my_assoc_query($q,'szam',array('db'=>'jatek'));
+
+ }
+
+ function getEgyszamNyertes($het) {
+
+ if (!is_numeric($het) || $het==0) $het = getEgyszamHet(); // évváltás!
+
+ /* a kulcs ellenőrzés miatt nem szavazhat 2* */
+ $q = "SELECT szam,count(*) AS db,userAccount FROM egyszam WHERE ev=year(now()) AND het=$het GROUP BY szam HAVING db=1 ORDER BY szam LIMIT 1";
+ $RET = _my_query($q,array('db'=>'jatek'));
+ return $RET[0];
+
+ }
+
+?>
diff --git a/mayor-orig/mayor-jatek/www/include/modules/jatek/base/query.php b/mayor-orig/mayor-jatek/www/include/modules/jatek/base/query.php
new file mode 100644
index 00000000..2351f682
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/include/modules/jatek/base/query.php
@@ -0,0 +1,36 @@
+
diff --git a/mayor-orig/mayor-jatek/www/lang/hu_HU/module-jatek/egyszam.php b/mayor-orig/mayor-jatek/www/lang/hu_HU/module-jatek/egyszam.php
new file mode 100644
index 00000000..9f3fb04a
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/lang/hu_HU/module-jatek/egyszam.php
@@ -0,0 +1,10 @@
+
diff --git a/mayor-orig/mayor-jatek/www/lang/hu_HU/module-jatek/jatek.php b/mayor-orig/mayor-jatek/www/lang/hu_HU/module-jatek/jatek.php
new file mode 100644
index 00000000..2ffb3060
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/lang/hu_HU/module-jatek/jatek.php
@@ -0,0 +1,7 @@
+
diff --git a/mayor-orig/mayor-jatek/www/policy/private/jatek/2048-pre.php b/mayor-orig/mayor-jatek/www/policy/private/jatek/2048-pre.php
new file mode 100644
index 00000000..e69de29b
diff --git a/mayor-orig/mayor-jatek/www/policy/private/jatek/2048.php b/mayor-orig/mayor-jatek/www/policy/private/jatek/2048.php
new file mode 100644
index 00000000..e9524d55
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/policy/private/jatek/2048.php
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/mayor-orig/mayor-jatek/www/policy/private/jatek/egyszam-pre.php b/mayor-orig/mayor-jatek/www/policy/private/jatek/egyszam-pre.php
new file mode 100644
index 00000000..67f52d59
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/policy/private/jatek/egyszam-pre.php
@@ -0,0 +1,18 @@
+0 && $szam<200) {
+ egyszamszavaz($het,$szam);
+ } // különben hibás számra akart szavazni. XSS??
+ $ADAT['szavazott'] = true;
+
+ }
+
+ $ADAT['db'] = count(getEgyszamEredmeny(getegyszamHet()));
+ $ADAT['elozoNyertes'] = getEgyszamNyertes(getegyszamHet()-1);
+
+?>
diff --git a/mayor-orig/mayor-jatek/www/policy/private/jatek/egyszam.php b/mayor-orig/mayor-jatek/www/policy/private/jatek/egyszam.php
new file mode 100644
index 00000000..91b217e7
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/policy/private/jatek/egyszam.php
@@ -0,0 +1,7 @@
+
diff --git a/mayor-orig/mayor-jatek/www/policy/private/jatek/jatek-pre.php b/mayor-orig/mayor-jatek/www/policy/private/jatek/jatek-pre.php
new file mode 100644
index 00000000..3a66e3ef
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/policy/private/jatek/jatek-pre.php
@@ -0,0 +1,6 @@
+
diff --git a/mayor-orig/mayor-jatek/www/policy/private/jatek/jatek.php b/mayor-orig/mayor-jatek/www/policy/private/jatek/jatek.php
new file mode 100644
index 00000000..d7cc96a0
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/policy/private/jatek/jatek.php
@@ -0,0 +1,7 @@
+
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/2048.css b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/2048.css
new file mode 100644
index 00000000..50125755
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/2048.css
@@ -0,0 +1,499 @@
+@import url(fonts/clear-sans.css);
+div.mayorbody {
+ font-family: "Clear Sans", "Helvetica Neue", Arial, sans-serif;
+ font-size: 18px; }
+*/
+/*body {
+ margin: 80px 0; }*/
+
+div.mayorbody .heading:after {
+ content: "";
+ display: block;
+ clear: both; }
+
+div.mayorbody h1.title {
+ font-size: 80px;
+ font-weight: bold;
+ margin: 0;
+ display: block;
+ float: left; }
+
+@-webkit-keyframes move-up {
+ 0% {
+ top: 25px;
+ opacity: 1; }
+
+ 100% {
+ top: -50px;
+ opacity: 0; } }
+@-moz-keyframes move-up {
+ 0% {
+ top: 25px;
+ opacity: 1; }
+
+ 100% {
+ top: -50px;
+ opacity: 0; } }
+@keyframes move-up {
+ 0% {
+ top: 25px;
+ opacity: 1; }
+
+ 100% {
+ top: -50px;
+ opacity: 0; } }
+.scores-container {
+ float: right;
+ text-align: right; }
+
+.score-container, .best-container {
+ position: relative;
+ display: inline-block;
+ background: #bbada0;
+ padding: 15px 25px;
+ font-size: 25px;
+ height: 25px;
+ line-height: 47px;
+ font-weight: bold;
+ border-radius: 3px;
+ color: white;
+ margin-top: 8px;
+ text-align: center; }
+ .score-container:after, .best-container:after {
+ position: absolute;
+ width: 100%;
+ top: 10px;
+ left: 0;
+ text-transform: uppercase;
+ font-size: 13px;
+ line-height: 13px;
+ text-align: center;
+ color: #eee4da; }
+ .score-container .score-addition, .best-container .score-addition {
+ position: absolute;
+ right: 30px;
+ color: red;
+ font-size: 25px;
+ line-height: 25px;
+ font-weight: bold;
+ color: rgba(119, 110, 101, 0.9);
+ z-index: 100;
+ -webkit-animation: move-up 600ms ease-in;
+ -moz-animation: move-up 600ms ease-in;
+ animation: move-up 600ms ease-in;
+ -webkit-animation-fill-mode: both;
+ -moz-animation-fill-mode: both;
+ animation-fill-mode: both; }
+
+.score-container:after {
+ content: "Score"; }
+
+.best-container:after {
+ content: "Best"; }
+
+div.mayorbody p {
+ margin-top: 0;
+ margin-bottom: 10px;
+ line-height: 1.65; }
+
+div.mayorbody a {
+ color: #776e65;
+ font-weight: bold;
+ text-decoration: underline;
+ cursor: pointer; }
+
+div.mayorbody strong.important {
+ text-transform: uppercase; }
+
+div.mayorbody hr {
+ border: none;
+ border-bottom: 1px solid #d8d4d0;
+ margin-top: 20px;
+ margin-bottom: 30px; }
+
+.container {
+ width: 500px;
+ margin: 0 auto; }
+
+@-webkit-keyframes fade-in {
+ 0% {
+ opacity: 0; }
+
+ 100% {
+ opacity: 1; } }
+@-moz-keyframes fade-in {
+ 0% {
+ opacity: 0; }
+
+ 100% {
+ opacity: 1; } }
+@keyframes fade-in {
+ 0% {
+ opacity: 0; }
+
+ 100% {
+ opacity: 1; } }
+.game-container {
+ margin-top: 40px;
+ position: relative;
+ padding: 15px;
+ cursor: default;
+ -webkit-touch-callout: none;
+ -ms-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -ms-touch-action: none;
+ touch-action: none;
+ background: #bbada0;
+ 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 {
+ 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; }
+
+.grid-container {
+ position: absolute;
+ z-index: 1; }
+
+.grid-row {
+ margin-bottom: 15px; }
+ .grid-row:last-child {
+ margin-bottom: 0; }
+ .grid-row:after {
+ content: "";
+ display: block;
+ clear: both; }
+
+.grid-cell {
+ width: 106.25px;
+ height: 106.25px;
+ margin-right: 15px;
+ float: left;
+ border-radius: 3px;
+ background: rgba(238, 228, 218, 0.35); }
+ .grid-cell:last-child {
+ margin-right: 0; }
+
+.tile-container {
+ position: absolute;
+ z-index: 2; }
+
+.tile, .tile .tile-inner {
+ width: 107px;
+ height: 107px;
+ line-height: 116.25px; }
+.tile.tile-position-1-1 {
+ -webkit-transform: translate(0px, 0px);
+ -moz-transform: translate(0px, 0px);
+ transform: translate(0px, 0px); }
+.tile.tile-position-1-2 {
+ -webkit-transform: translate(0px, 121px);
+ -moz-transform: translate(0px, 121px);
+ transform: translate(0px, 121px); }
+.tile.tile-position-1-3 {
+ -webkit-transform: translate(0px, 242px);
+ -moz-transform: translate(0px, 242px);
+ transform: translate(0px, 242px); }
+.tile.tile-position-1-4 {
+ -webkit-transform: translate(0px, 363px);
+ -moz-transform: translate(0px, 363px);
+ transform: translate(0px, 363px); }
+.tile.tile-position-2-1 {
+ -webkit-transform: translate(121px, 0px);
+ -moz-transform: translate(121px, 0px);
+ transform: translate(121px, 0px); }
+.tile.tile-position-2-2 {
+ -webkit-transform: translate(121px, 121px);
+ -moz-transform: translate(121px, 121px);
+ transform: translate(121px, 121px); }
+.tile.tile-position-2-3 {
+ -webkit-transform: translate(121px, 242px);
+ -moz-transform: translate(121px, 242px);
+ transform: translate(121px, 242px); }
+.tile.tile-position-2-4 {
+ -webkit-transform: translate(121px, 363px);
+ -moz-transform: translate(121px, 363px);
+ transform: translate(121px, 363px); }
+.tile.tile-position-3-1 {
+ -webkit-transform: translate(242px, 0px);
+ -moz-transform: translate(242px, 0px);
+ transform: translate(242px, 0px); }
+.tile.tile-position-3-2 {
+ -webkit-transform: translate(242px, 121px);
+ -moz-transform: translate(242px, 121px);
+ transform: translate(242px, 121px); }
+.tile.tile-position-3-3 {
+ -webkit-transform: translate(242px, 242px);
+ -moz-transform: translate(242px, 242px);
+ transform: translate(242px, 242px); }
+.tile.tile-position-3-4 {
+ -webkit-transform: translate(242px, 363px);
+ -moz-transform: translate(242px, 363px);
+ transform: translate(242px, 363px); }
+.tile.tile-position-4-1 {
+ -webkit-transform: translate(363px, 0px);
+ -moz-transform: translate(363px, 0px);
+ transform: translate(363px, 0px); }
+.tile.tile-position-4-2 {
+ -webkit-transform: translate(363px, 121px);
+ -moz-transform: translate(363px, 121px);
+ transform: translate(363px, 121px); }
+.tile.tile-position-4-3 {
+ -webkit-transform: translate(363px, 242px);
+ -moz-transform: translate(363px, 242px);
+ transform: translate(363px, 242px); }
+.tile.tile-position-4-4 {
+ -webkit-transform: translate(363px, 363px);
+ -moz-transform: translate(363px, 363px);
+ transform: translate(363px, 363px); }
+
+.tile {
+ position: absolute;
+ -webkit-transition: 100ms ease-in-out;
+ -moz-transition: 100ms ease-in-out;
+ transition: 100ms ease-in-out;
+ -webkit-transition-property: -webkit-transform;
+ -moz-transition-property: -moz-transform;
+ transition-property: transform; }
+ .tile .tile-inner {
+ border-radius: 3px;
+ background: #eee4da;
+ text-align: center;
+ font-weight: bold;
+ z-index: 10;
+ font-size: 55px; }
+ .tile.tile-2 .tile-inner {
+ background: #eee4da;
+ 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;
+ 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: #f2b179; }
+ .tile.tile-16 .tile-inner {
+ color: #f9f6f2;
+ background: #f59563; }
+ .tile.tile-32 .tile-inner {
+ color: #f9f6f2;
+ background: #f67c5f; }
+ .tile.tile-64 .tile-inner {
+ color: #f9f6f2;
+ background: #f65e3b; }
+ .tile.tile-128 .tile-inner {
+ color: #f9f6f2;
+ background: #edcf72;
+ 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; }
+ @media screen and (max-width: 520px) {
+ .tile.tile-128 .tile-inner {
+ font-size: 25px; } }
+ .tile.tile-256 .tile-inner {
+ color: #f9f6f2;
+ background: #edcc61;
+ 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; }
+ @media screen and (max-width: 520px) {
+ .tile.tile-256 .tile-inner {
+ font-size: 25px; } }
+ .tile.tile-512 .tile-inner {
+ color: #f9f6f2;
+ 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; }
+ @media screen and (max-width: 520px) {
+ .tile.tile-512 .tile-inner {
+ font-size: 25px; } }
+ .tile.tile-1024 .tile-inner {
+ color: #f9f6f2;
+ 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; }
+ @media screen and (max-width: 520px) {
+ .tile.tile-1024 .tile-inner {
+ font-size: 15px; } }
+ .tile.tile-2048 .tile-inner {
+ color: #f9f6f2;
+ 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; }
+ @media screen and (max-width: 520px) {
+ .tile.tile-2048 .tile-inner {
+ font-size: 15px; } }
+ .tile.tile-super .tile-inner {
+ color: #f9f6f2;
+ background: #3c3a32;
+ font-size: 30px; }
+ @media screen and (max-width: 520px) {
+ .tile.tile-super .tile-inner {
+ font-size: 10px; } }
+
+@-webkit-keyframes appear {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0);
+ -moz-transform: scale(0);
+ transform: scale(0); }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: scale(1);
+ -moz-transform: scale(1);
+ transform: scale(1); } }
+@-moz-keyframes appear {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0);
+ -moz-transform: scale(0);
+ transform: scale(0); }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: scale(1);
+ -moz-transform: scale(1);
+ transform: scale(1); } }
+@keyframes appear {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0);
+ -moz-transform: scale(0);
+ transform: scale(0); }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: scale(1);
+ -moz-transform: scale(1);
+ transform: scale(1); } }
+.tile-new .tile-inner {
+ -webkit-animation: appear 200ms ease 100ms;
+ -moz-animation: appear 200ms ease 100ms;
+ animation: appear 200ms ease 100ms;
+ -webkit-animation-fill-mode: backwards;
+ -moz-animation-fill-mode: backwards;
+ animation-fill-mode: backwards; }
+
+@-webkit-keyframes pop {
+ 0% {
+ -webkit-transform: scale(0);
+ -moz-transform: scale(0);
+ transform: scale(0); }
+
+ 50% {
+ -webkit-transform: scale(1.2);
+ -moz-transform: scale(1.2);
+ transform: scale(1.2); }
+
+ 100% {
+ -webkit-transform: scale(1);
+ -moz-transform: scale(1);
+ transform: scale(1); } }
+@-moz-keyframes pop {
+ 0% {
+ -webkit-transform: scale(0);
+ -moz-transform: scale(0);
+ transform: scale(0); }
+
+ 50% {
+ -webkit-transform: scale(1.2);
+ -moz-transform: scale(1.2);
+ transform: scale(1.2); }
+
+ 100% {
+ -webkit-transform: scale(1);
+ -moz-transform: scale(1);
+ transform: scale(1); } }
+@keyframes pop {
+ 0% {
+ -webkit-transform: scale(0);
+ -moz-transform: scale(0);
+ transform: scale(0); }
+
+ 50% {
+ -webkit-transform: scale(1.2);
+ -moz-transform: scale(1.2);
+ transform: scale(1.2); }
+
+ 100% {
+ -webkit-transform: scale(1);
+ -moz-transform: scale(1);
+ transform: scale(1); } }
+.tile-merged .tile-inner {
+ z-index: 20;
+ -webkit-animation: pop 200ms ease 100ms;
+ -moz-animation: pop 200ms ease 100ms;
+ animation: pop 200ms ease 100ms;
+ -webkit-animation-fill-mode: backwards;
+ -moz-animation-fill-mode: backwards;
+ animation-fill-mode: backwards; }
+
+.above-game:after {
+ content: "";
+ display: block;
+ clear: both; }
+
+.game-intro {
+ float: left;
+ line-height: 42px;
+ 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; }
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/egyszam.css b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/egyszam.css
new file mode 100644
index 00000000..b0dac656
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/egyszam.css
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.eot b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.eot
new file mode 100755
index 00000000..3678ef2a
Binary files /dev/null and b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.eot differ
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.svg b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.svg
new file mode 100755
index 00000000..aa985aeb
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.svg
@@ -0,0 +1,640 @@
+
+
+
\ No newline at end of file
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.woff b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.woff
new file mode 100755
index 00000000..184a945d
Binary files /dev/null and b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Bold-webfont.woff differ
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.eot b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.eot
new file mode 100755
index 00000000..0dc609d1
Binary files /dev/null and b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.eot differ
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.svg b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.svg
new file mode 100755
index 00000000..1d5d2ece
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.svg
@@ -0,0 +1,670 @@
+
+
+
\ No newline at end of file
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.woff b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.woff
new file mode 100755
index 00000000..44555e04
Binary files /dev/null and b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Light-webfont.woff differ
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.eot b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.eot
new file mode 100755
index 00000000..b020e058
Binary files /dev/null and b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.eot differ
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.svg b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.svg
new file mode 100755
index 00000000..1e2cffdc
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.svg
@@ -0,0 +1,669 @@
+
+
+
\ No newline at end of file
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.woff b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.woff
new file mode 100755
index 00000000..9d58858d
Binary files /dev/null and b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/ClearSans-Regular-webfont.woff differ
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/clear-sans.css b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/clear-sans.css
new file mode 100755
index 00000000..d6d0521f
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/fonts/clear-sans.css
@@ -0,0 +1,29 @@
+@font-face {
+ font-family: "Clear Sans";
+ src: url("ClearSans-Light-webfont.eot");
+ src: url("ClearSans-Light-webfont.eot?#iefix") format("embedded-opentype"),
+ url("ClearSans-Light-webfont.svg#clear_sans_lightregular") format("svg"),
+ url("ClearSans-Light-webfont.woff") format("woff");
+ font-weight: 200;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: "Clear Sans";
+ src: url("ClearSans-Regular-webfont.eot");
+ src: url("ClearSans-Regular-webfont.eot?#iefix") format("embedded-opentype"),
+ url("ClearSans-Regular-webfont.svg#clear_sansregular") format("svg"),
+ url("ClearSans-Regular-webfont.woff") format("woff");
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: "Clear Sans";
+ src: url("ClearSans-Bold-webfont.eot");
+ src: url("ClearSans-Bold-webfont.eot?#iefix") format("embedded-opentype"),
+ url("ClearSans-Bold-webfont.svg#clear_sansbold") format("svg"),
+ url("ClearSans-Bold-webfont.woff") format("woff");
+ font-weight: 700;
+ font-style: normal;
+}
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/jatek.css b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/jatek.css
new file mode 100644
index 00000000..4fb1d074
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/css/jatek.css
@@ -0,0 +1,12 @@
+
+ div.egyszam { width:140px; margin-left: auto; margin-right: auto; margin-bottom: 50px;}
+ h1.egyszam { text-align: center }
+
+ table.egyszam {
+ background-color: #dddddd;
+ width:200px;
+ }
+ table.egyszam thead th { background-color: magenta; border-bottom: solid 2px lightblue; height:2em; }
+ table.egyszam tfoot th { background-color: lightblue; border-bottom: solid 1px white; }
+ table.egyszam td { background-color: #eeeeee; text-align:right; padding-right:4px; }
+
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/html/2048.phtml b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/html/2048.phtml
new file mode 100644
index 00000000..fa330967
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/html/2048.phtml
@@ -0,0 +1,77 @@
+
+
+echo '
+
+
+
+
+
Join the numbers and get to the 2048 tile!
+
New Game
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+';
+}
+
+?>
\ No newline at end of file
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/html/base.phtml b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/html/base.phtml
new file mode 100644
index 00000000..ed555187
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/html/base.phtml
@@ -0,0 +1,51 @@
+'._EGYSZAMJATEK.'';
+
+ echo '';
+
+ echo _EDDIG.': '.$ADAT['db'].' '._SZAVAZAT.'
';
+ echo _NYERTES.': '.$ADAT['elozoNyertes']['szam'].' ('.$ADAT['elozoNyertes']['userAccount'].')
';
+
+ if ($ADAT['szavazott']==false) {
+
+ //echo '
';
+
+ }
+
+ function putEgyszamTablazat($ADAT) {
+
+ foreach($ADAT as $het => $D) {
+ echo '';
+ echo ''.$het.'. '._JATEKHET.' |
'."\n";
+ echo ''._SZAM.' | '._DB.' |
'."\n";
+ echo '';
+ foreach ($D as $szam => $T) {
+ echo '';
+ echo ''.$szam.' | ';
+ echo ''.$T['db'].' | ';
+ echo '
';
+ }
+ echo '';
+ }
+ echo '
';
+ }
+
+?>
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/img/2048.png b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/img/2048.png
new file mode 100644
index 00000000..5d85963a
Binary files /dev/null and b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/img/2048.png differ
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/animframe_polyfill.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/animframe_polyfill.js
new file mode 100644
index 00000000..c524a994
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/animframe_polyfill.js
@@ -0,0 +1,28 @@
+(function () {
+ var lastTime = 0;
+ var vendors = ['webkit', 'moz'];
+ for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
+ window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
+ window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||
+ window[vendors[x] + 'CancelRequestAnimationFrame'];
+ }
+
+ if (!window.requestAnimationFrame) {
+ window.requestAnimationFrame = function (callback) {
+ var currTime = new Date().getTime();
+ var timeToCall = Math.max(0, 16 - (currTime - lastTime));
+ var id = window.setTimeout(function () {
+ callback(currTime + timeToCall);
+ },
+ timeToCall);
+ lastTime = currTime + timeToCall;
+ return id;
+ };
+ }
+
+ if (!window.cancelAnimationFrame) {
+ window.cancelAnimationFrame = function (id) {
+ clearTimeout(id);
+ };
+ }
+}());
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/application.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/application.js
new file mode 100644
index 00000000..2c1108e7
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/application.js
@@ -0,0 +1,4 @@
+// Wait till the browser is ready to render the game (avoids glitches)
+window.requestAnimationFrame(function () {
+ new GameManager(4, KeyboardInputManager, HTMLActuator, LocalStorageManager);
+});
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/bind_polyfill.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/bind_polyfill.js
new file mode 100644
index 00000000..8d9c4a48
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/bind_polyfill.js
@@ -0,0 +1,9 @@
+Function.prototype.bind = Function.prototype.bind || function (target) {
+ var self = this;
+ return function (args) {
+ if (!(args instanceof Array)) {
+ args = [args];
+ }
+ self.apply(target, args);
+ };
+};
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/classlist_polyfill.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/classlist_polyfill.js
new file mode 100644
index 00000000..1789ae78
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/classlist_polyfill.js
@@ -0,0 +1,71 @@
+(function () {
+ if (typeof window.Element === "undefined" ||
+ "classList" in document.documentElement) {
+ return;
+ }
+
+ var prototype = Array.prototype,
+ push = prototype.push,
+ splice = prototype.splice,
+ join = prototype.join;
+
+ function DOMTokenList(el) {
+ this.el = el;
+ // The className needs to be trimmed and split on whitespace
+ // to retrieve a list of classes.
+ var classes = el.className.replace(/^\s+|\s+$/g, '').split(/\s+/);
+ for (var i = 0; i < classes.length; i++) {
+ push.call(this, classes[i]);
+ }
+ }
+
+ DOMTokenList.prototype = {
+ add: function (token) {
+ if (this.contains(token)) return;
+ push.call(this, token);
+ this.el.className = this.toString();
+ },
+ contains: function (token) {
+ return this.el.className.indexOf(token) != -1;
+ },
+ item: function (index) {
+ return this[index] || null;
+ },
+ remove: function (token) {
+ if (!this.contains(token)) return;
+ for (var i = 0; i < this.length; i++) {
+ if (this[i] == token) break;
+ }
+ splice.call(this, i, 1);
+ this.el.className = this.toString();
+ },
+ toString: function () {
+ return join.call(this, ' ');
+ },
+ toggle: function (token) {
+ if (!this.contains(token)) {
+ this.add(token);
+ } else {
+ this.remove(token);
+ }
+
+ return this.contains(token);
+ }
+ };
+
+ window.DOMTokenList = DOMTokenList;
+
+ function defineElementGetter(obj, prop, getter) {
+ if (Object.defineProperty) {
+ Object.defineProperty(obj, prop, {
+ get: getter
+ });
+ } else {
+ obj.__defineGetter__(prop, getter);
+ }
+ }
+
+ defineElementGetter(HTMLElement.prototype, 'classList', function () {
+ return new DOMTokenList(this);
+ });
+})();
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/game_manager.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/game_manager.js
new file mode 100644
index 00000000..aea99f33
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/game_manager.js
@@ -0,0 +1,276 @@
+function GameManager(size, InputManager, Actuator, StorageManager) {
+ this.size = size; // Size of the grid
+ this.inputManager = new InputManager;
+ this.storageManager = new StorageManager;
+ this.actuator = new Actuator;
+
+ this.startTiles = 2;
+
+ 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.setup();
+}
+
+// Restart the game
+GameManager.prototype.restart = function () {
+ this.storageManager.clearGameState();
+ this.actuator.continueGame(); // Clear the game won/lost message
+ this.setup();
+};
+
+// Keep playing after winning (allows going over 2048)
+GameManager.prototype.keepPlaying = function () {
+ this.keepPlaying = true;
+ this.actuator.continueGame(); // Clear the game won/lost message
+};
+
+// 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)) {
+ return true;
+ } else {
+ return false;
+ }
+};
+
+// Set up the game
+GameManager.prototype.setup = function () {
+ var previousState = this.storageManager.getGameState();
+
+ // Reload the game from a previous game if present
+ if (previousState) {
+ this.grid = new Grid(previousState.grid.size,
+ previousState.grid.cells); // Reload grid
+ this.score = previousState.score;
+ this.over = previousState.over;
+ this.won = previousState.won;
+ this.keepPlaying = previousState.keepPlaying;
+ } else {
+ this.grid = new Grid(this.size);
+ this.score = 0;
+ this.over = false;
+ this.won = false;
+ this.keepPlaying = false;
+
+ // Add the initial tiles
+ this.addStartTiles();
+ }
+
+ // Update the actuator
+ this.actuate();
+};
+
+// Set up the initial tiles to start the game with
+GameManager.prototype.addStartTiles = function () {
+ for (var i = 0; i < this.startTiles; i++) {
+ this.addRandomTile();
+ }
+};
+
+// Adds a tile in a random position
+GameManager.prototype.addRandomTile = function () {
+ if (this.grid.cellsAvailable()) {
+ var value = Math.random() < 0.9 ? 2 : 4;
+ var tile = new Tile(this.grid.randomAvailableCell(), value);
+
+ this.grid.insertTile(tile);
+ }
+};
+
+// Sends the updated grid to the actuator
+GameManager.prototype.actuate = function () {
+ if (this.storageManager.getBestScore() < this.score) {
+ this.storageManager.setBestScore(this.score);
+ }
+
+ // Clear the state when the game is over (game over only, not win)
+ if (this.over) {
+ this.storageManager.clearGameState();
+ } else {
+ this.storageManager.setGameState(this.serialize());
+ }
+
+ this.actuator.actuate(this.grid, {
+ score: this.score,
+ over: this.over,
+ won: this.won,
+ bestScore: this.storageManager.getBestScore(),
+ terminated: this.isGameTerminated()
+ });
+
+};
+
+// Represent the current game as an object
+GameManager.prototype.serialize = function () {
+ return {
+ grid: this.grid.serialize(),
+ score: this.score,
+ over: this.over,
+ won: this.won,
+ keepPlaying: this.keepPlaying
+ };
+};
+
+// Save all tile positions and remove merger info
+GameManager.prototype.prepareTiles = function () {
+ this.grid.eachCell(function (x, y, tile) {
+ if (tile) {
+ tile.mergedFrom = null;
+ tile.savePosition();
+ }
+ });
+};
+
+// Move a tile and its representation
+GameManager.prototype.moveTile = function (tile, cell) {
+ this.grid.cells[tile.x][tile.y] = null;
+ this.grid.cells[cell.x][cell.y] = tile;
+ tile.updatePosition(cell);
+};
+
+// Move tiles on the grid in the specified direction
+GameManager.prototype.move = function (direction) {
+ // 0: up, 1: right, 2: down, 3: left
+ var self = this;
+
+ if (this.isGameTerminated()) return; // Don't do anything if the game's over
+
+ var cell, tile;
+
+ var vector = this.getVector(direction);
+ var traversals = this.buildTraversals(vector);
+ var moved = false;
+
+ // Save the current tile positions and remove merger information
+ this.prepareTiles();
+
+ // Traverse the grid in the right direction and move tiles
+ traversals.x.forEach(function (x) {
+ traversals.y.forEach(function (y) {
+ cell = { x: x, y: y };
+ tile = self.grid.cellContent(cell);
+
+ if (tile) {
+ var positions = self.findFarthestPosition(cell, vector);
+ var next = self.grid.cellContent(positions.next);
+
+ // Only one merger per row traversal?
+ if (next && next.value === tile.value && !next.mergedFrom) {
+ var merged = new Tile(positions.next, tile.value * 2);
+ merged.mergedFrom = [tile, next];
+
+ self.grid.insertTile(merged);
+ self.grid.removeTile(tile);
+
+ // Converge the two tiles' positions
+ tile.updatePosition(positions.next);
+
+ // Update the score
+ self.score += merged.value;
+
+ // The mighty 2048 tile
+ if (merged.value === 2048) self.won = true;
+ } else {
+ self.moveTile(tile, positions.farthest);
+ }
+
+ if (!self.positionsEqual(cell, tile)) {
+ moved = true; // The tile moved from its original cell!
+ }
+ }
+ });
+ });
+
+ if (moved) {
+ this.addRandomTile();
+
+ if (!this.movesAvailable()) {
+ this.over = true; // Game over!
+ }
+
+ this.actuate();
+ }
+};
+
+// Get the vector representing the chosen direction
+GameManager.prototype.getVector = function (direction) {
+ // Vectors representing tile movement
+ var map = {
+ 0: { x: 0, y: -1 }, // Up
+ 1: { x: 1, y: 0 }, // Right
+ 2: { x: 0, y: 1 }, // Down
+ 3: { x: -1, y: 0 } // Left
+ };
+
+ return map[direction];
+};
+
+// Build a list of positions to traverse in the right order
+GameManager.prototype.buildTraversals = function (vector) {
+ var traversals = { x: [], y: [] };
+
+ for (var pos = 0; pos < this.size; pos++) {
+ traversals.x.push(pos);
+ traversals.y.push(pos);
+ }
+
+ // Always traverse from the farthest cell in the chosen direction
+ if (vector.x === 1) traversals.x = traversals.x.reverse();
+ if (vector.y === 1) traversals.y = traversals.y.reverse();
+
+ return traversals;
+};
+
+GameManager.prototype.findFarthestPosition = function (cell, vector) {
+ var previous;
+
+ // Progress towards the vector direction until an obstacle is found
+ do {
+ previous = cell;
+ cell = { x: previous.x + vector.x, y: previous.y + vector.y };
+ } while (this.grid.withinBounds(cell) &&
+ this.grid.cellAvailable(cell));
+
+ return {
+ farthest: previous,
+ next: cell // Used to check if a merge is required
+ };
+};
+
+GameManager.prototype.movesAvailable = function () {
+ return this.grid.cellsAvailable() || this.tileMatchesAvailable();
+};
+
+// Check for available matches between tiles (more expensive check)
+GameManager.prototype.tileMatchesAvailable = function () {
+ var self = this;
+
+ var tile;
+
+ for (var x = 0; x < this.size; x++) {
+ for (var y = 0; y < this.size; y++) {
+ tile = this.grid.cellContent({ x: x, y: y });
+
+ if (tile) {
+ for (var direction = 0; direction < 4; direction++) {
+ var vector = self.getVector(direction);
+ var cell = { x: x + vector.x, y: y + vector.y };
+
+ var other = self.grid.cellContent(cell);
+
+ if (other && other.value === tile.value) {
+ return true; // These two tiles can be merged
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+};
+
+GameManager.prototype.positionsEqual = function (first, second) {
+ return first.x === second.x && first.y === second.y;
+};
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/grid.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/grid.js
new file mode 100644
index 00000000..29f0821e
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/grid.js
@@ -0,0 +1,117 @@
+function Grid(size, previousState) {
+ this.size = size;
+ this.cells = previousState ? this.fromState(previousState) : this.empty();
+}
+
+// Build a grid of the specified size
+Grid.prototype.empty = function () {
+ var cells = [];
+
+ for (var x = 0; x < this.size; x++) {
+ var row = cells[x] = [];
+
+ for (var y = 0; y < this.size; y++) {
+ row.push(null);
+ }
+ }
+
+ return cells;
+};
+
+Grid.prototype.fromState = function (state) {
+ var cells = [];
+
+ for (var x = 0; x < this.size; x++) {
+ var row = cells[x] = [];
+
+ for (var y = 0; y < this.size; y++) {
+ var tile = state[x][y];
+ row.push(tile ? new Tile(tile.position, tile.value) : null);
+ }
+ }
+
+ return cells;
+};
+
+// Find the first available random position
+Grid.prototype.randomAvailableCell = function () {
+ var cells = this.availableCells();
+
+ if (cells.length) {
+ return cells[Math.floor(Math.random() * cells.length)];
+ }
+};
+
+Grid.prototype.availableCells = function () {
+ var cells = [];
+
+ this.eachCell(function (x, y, tile) {
+ if (!tile) {
+ cells.push({ x: x, y: y });
+ }
+ });
+
+ return cells;
+};
+
+// Call callback for every cell
+Grid.prototype.eachCell = function (callback) {
+ for (var x = 0; x < this.size; x++) {
+ for (var y = 0; y < this.size; y++) {
+ callback(x, y, this.cells[x][y]);
+ }
+ }
+};
+
+// Check if there are any cells available
+Grid.prototype.cellsAvailable = function () {
+ return !!this.availableCells().length;
+};
+
+// Check if the specified cell is taken
+Grid.prototype.cellAvailable = function (cell) {
+ return !this.cellOccupied(cell);
+};
+
+Grid.prototype.cellOccupied = function (cell) {
+ return !!this.cellContent(cell);
+};
+
+Grid.prototype.cellContent = function (cell) {
+ if (this.withinBounds(cell)) {
+ return this.cells[cell.x][cell.y];
+ } else {
+ return null;
+ }
+};
+
+// Inserts a tile at its position
+Grid.prototype.insertTile = function (tile) {
+ this.cells[tile.x][tile.y] = tile;
+};
+
+Grid.prototype.removeTile = function (tile) {
+ this.cells[tile.x][tile.y] = null;
+};
+
+Grid.prototype.withinBounds = function (position) {
+ return position.x >= 0 && position.x < this.size &&
+ position.y >= 0 && position.y < this.size;
+};
+
+Grid.prototype.serialize = function () {
+ var cellState = [];
+
+ for (var x = 0; x < this.size; x++) {
+ var row = cellState[x] = [];
+
+ for (var y = 0; y < this.size; y++) {
+ row.push(this.cells[x][y] ? this.cells[x][y].serialize() : null);
+ }
+ }
+
+ return {
+ size: this.size,
+ cells: cellState
+ };
+};
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/html_actuator.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/html_actuator.js
new file mode 100644
index 00000000..6b31f2d1
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/html_actuator.js
@@ -0,0 +1,139 @@
+function HTMLActuator() {
+ this.tileContainer = document.querySelector(".tile-container");
+ this.scoreContainer = document.querySelector(".score-container");
+ this.bestContainer = document.querySelector(".best-container");
+ this.messageContainer = document.querySelector(".game-message");
+
+ this.score = 0;
+}
+
+HTMLActuator.prototype.actuate = function (grid, metadata) {
+ var self = this;
+
+ window.requestAnimationFrame(function () {
+ self.clearContainer(self.tileContainer);
+
+ grid.cells.forEach(function (column) {
+ column.forEach(function (cell) {
+ if (cell) {
+ self.addTile(cell);
+ }
+ });
+ });
+
+ self.updateScore(metadata.score);
+ self.updateBestScore(metadata.bestScore);
+
+ if (metadata.terminated) {
+ if (metadata.over) {
+ self.message(false); // You lose
+ } else if (metadata.won) {
+ self.message(true); // You win!
+ }
+ }
+
+ });
+};
+
+// Continues the game (both restart and keep playing)
+HTMLActuator.prototype.continueGame = function () {
+ this.clearMessage();
+};
+
+HTMLActuator.prototype.clearContainer = function (container) {
+ while (container.firstChild) {
+ container.removeChild(container.firstChild);
+ }
+};
+
+HTMLActuator.prototype.addTile = function (tile) {
+ 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);
+
+ // We can't use classlist because it somehow glitches when replacing classes
+ var classes = ["tile", "tile-" + tile.value, positionClass];
+
+ if (tile.value > 2048) classes.push("tile-super");
+
+ this.applyClasses(wrapper, classes);
+
+ inner.classList.add("tile-inner");
+ inner.textContent = tile.value;
+
+ if (tile.previousPosition) {
+ // Make sure that the tile gets rendered in the previous position first
+ window.requestAnimationFrame(function () {
+ classes[2] = self.positionClass({ x: tile.x, y: tile.y });
+ self.applyClasses(wrapper, classes); // Update the position
+ });
+ } else if (tile.mergedFrom) {
+ classes.push("tile-merged");
+ this.applyClasses(wrapper, classes);
+
+ // Render the tiles that merged
+ tile.mergedFrom.forEach(function (merged) {
+ self.addTile(merged);
+ });
+ } else {
+ classes.push("tile-new");
+ this.applyClasses(wrapper, classes);
+ }
+
+ // Add the inner part of the tile to the wrapper
+ wrapper.appendChild(inner);
+
+ // Put the tile on the board
+ this.tileContainer.appendChild(wrapper);
+};
+
+HTMLActuator.prototype.applyClasses = function (element, classes) {
+ element.setAttribute("class", classes.join(" "));
+};
+
+HTMLActuator.prototype.normalizePosition = function (position) {
+ return { x: position.x + 1, y: position.y + 1 };
+};
+
+HTMLActuator.prototype.positionClass = function (position) {
+ position = this.normalizePosition(position);
+ return "tile-position-" + position.x + "-" + position.y;
+};
+
+HTMLActuator.prototype.updateScore = function (score) {
+ this.clearContainer(this.scoreContainer);
+
+ var difference = score - this.score;
+ this.score = score;
+
+ this.scoreContainer.textContent = this.score;
+
+ if (difference > 0) {
+ var addition = document.createElement("div");
+ addition.classList.add("score-addition");
+ addition.textContent = "+" + difference;
+
+ this.scoreContainer.appendChild(addition);
+ }
+};
+
+HTMLActuator.prototype.updateBestScore = function (bestScore) {
+ this.bestContainer.textContent = bestScore;
+};
+
+HTMLActuator.prototype.message = function (won) {
+ var type = won ? "game-won" : "game-over";
+ var message = won ? "You win!" : "Game over!";
+
+ this.messageContainer.classList.add(type);
+ this.messageContainer.getElementsByTagName("p")[0].textContent = message;
+};
+
+HTMLActuator.prototype.clearMessage = function () {
+ // IE only takes one value to remove at a time.
+ this.messageContainer.classList.remove("game-won");
+ this.messageContainer.classList.remove("game-over");
+};
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/keyboard_input_manager.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/keyboard_input_manager.js
new file mode 100644
index 00000000..32a177a4
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/keyboard_input_manager.js
@@ -0,0 +1,144 @@
+function KeyboardInputManager() {
+ this.events = {};
+
+ if (window.navigator.msPointerEnabled) {
+ //Internet Explorer 10 style
+ this.eventTouchstart = "MSPointerDown";
+ this.eventTouchmove = "MSPointerMove";
+ this.eventTouchend = "MSPointerUp";
+ } else {
+ this.eventTouchstart = "touchstart";
+ this.eventTouchmove = "touchmove";
+ this.eventTouchend = "touchend";
+ }
+
+ this.listen();
+}
+
+KeyboardInputManager.prototype.on = function (event, callback) {
+ if (!this.events[event]) {
+ this.events[event] = [];
+ }
+ this.events[event].push(callback);
+};
+
+KeyboardInputManager.prototype.emit = function (event, data) {
+ var callbacks = this.events[event];
+ if (callbacks) {
+ callbacks.forEach(function (callback) {
+ callback(data);
+ });
+ }
+};
+
+KeyboardInputManager.prototype.listen = function () {
+ var self = this;
+
+ var map = {
+ 38: 0, // Up
+ 39: 1, // Right
+ 40: 2, // Down
+ 37: 3, // Left
+ 75: 0, // Vim up
+ 76: 1, // Vim right
+ 74: 2, // Vim down
+ 72: 3, // Vim left
+ 87: 0, // W
+ 68: 1, // D
+ 83: 2, // S
+ 65: 3 // A
+ };
+
+ // Respond to direction keys
+ document.addEventListener("keydown", function (event) {
+ var modifiers = event.altKey || event.ctrlKey || event.metaKey ||
+ event.shiftKey;
+ var mapped = map[event.which];
+
+ if (!modifiers) {
+ if (mapped !== undefined) {
+ event.preventDefault();
+ self.emit("move", mapped);
+ }
+ }
+
+ // R key restarts the game
+ if (!modifiers && event.which === 82) {
+ self.restart.call(self, event);
+ }
+ });
+
+ // Respond to button presses
+ this.bindButtonPress(".retry-button", this.restart);
+ this.bindButtonPress(".restart-button", this.restart);
+ this.bindButtonPress(".keep-playing-button", this.keepPlaying);
+
+ // Respond to swipe events
+ var touchStartClientX, touchStartClientY;
+ var gameContainer = document.getElementsByClassName("game-container")[0];
+
+ 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
+ }
+
+ if (window.navigator.msPointerEnabled) {
+ touchStartClientX = event.pageX;
+ touchStartClientY = event.pageY;
+ } else {
+ touchStartClientX = event.touches[0].clientX;
+ touchStartClientY = event.touches[0].clientY;
+ }
+
+ event.preventDefault();
+ });
+
+ gameContainer.addEventListener(this.eventTouchmove, function (event) {
+ event.preventDefault();
+ });
+
+ 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
+ }
+
+ var touchEndClientX, touchEndClientY;
+
+ if (window.navigator.msPointerEnabled) {
+ touchEndClientX = event.pageX;
+ touchEndClientY = event.pageY;
+ } else {
+ touchEndClientX = event.changedTouches[0].clientX;
+ touchEndClientY = event.changedTouches[0].clientY;
+ }
+
+ var dx = touchEndClientX - touchStartClientX;
+ var absDx = Math.abs(dx);
+
+ var dy = touchEndClientY - touchStartClientY;
+ var absDy = Math.abs(dy);
+
+ if (Math.max(absDx, absDy) > 10) {
+ // (right : left) : (down : up)
+ self.emit("move", absDx > absDy ? (dx > 0 ? 1 : 3) : (dy > 0 ? 2 : 0));
+ }
+ });
+};
+
+KeyboardInputManager.prototype.restart = function (event) {
+ event.preventDefault();
+ this.emit("restart");
+};
+
+KeyboardInputManager.prototype.keepPlaying = function (event) {
+ event.preventDefault();
+ this.emit("keepPlaying");
+};
+
+KeyboardInputManager.prototype.bindButtonPress = function (selector, fn) {
+ var button = document.querySelector(selector);
+ button.addEventListener("click", fn.bind(this));
+ button.addEventListener(this.eventTouchend, fn.bind(this));
+};
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/local_storage_manager.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/local_storage_manager.js
new file mode 100644
index 00000000..776e94b1
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/local_storage_manager.js
@@ -0,0 +1,63 @@
+window.fakeStorage = {
+ _data: {},
+
+ setItem: function (id, val) {
+ return this._data[id] = String(val);
+ },
+
+ getItem: function (id) {
+ return this._data.hasOwnProperty(id) ? this._data[id] : undefined;
+ },
+
+ removeItem: function (id) {
+ return delete this._data[id];
+ },
+
+ clear: function () {
+ return this._data = {};
+ }
+};
+
+function LocalStorageManager() {
+ this.bestScoreKey = "bestScore";
+ this.gameStateKey = "gameState";
+
+ var supported = this.localStorageSupported();
+ this.storage = supported ? window.localStorage : window.fakeStorage;
+}
+
+LocalStorageManager.prototype.localStorageSupported = function () {
+ var testKey = "test";
+ var storage = window.localStorage;
+
+ try {
+ storage.setItem(testKey, "1");
+ storage.removeItem(testKey);
+ return true;
+ } catch (error) {
+ return false;
+ }
+};
+
+// Best score getters/setters
+LocalStorageManager.prototype.getBestScore = function () {
+ return this.storage.getItem(this.bestScoreKey) || 0;
+};
+
+LocalStorageManager.prototype.setBestScore = function (score) {
+ this.storage.setItem(this.bestScoreKey, score);
+};
+
+// Game state getters/setters and clearing
+LocalStorageManager.prototype.getGameState = function () {
+ var stateJSON = this.storage.getItem(this.gameStateKey);
+ return stateJSON ? JSON.parse(stateJSON) : null;
+};
+
+LocalStorageManager.prototype.setGameState = function (gameState) {
+ this.storage.setItem(this.gameStateKey, JSON.stringify(gameState));
+};
+
+LocalStorageManager.prototype.clearGameState = function () {
+ this.storage.removeItem(this.gameStateKey);
+};
diff --git a/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/tile.js b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/tile.js
new file mode 100644
index 00000000..92a670a5
--- /dev/null
+++ b/mayor-orig/mayor-jatek/www/skin/classic/module-jatek/js/tile.js
@@ -0,0 +1,27 @@
+function Tile(position, value) {
+ this.x = position.x;
+ this.y = position.y;
+ this.value = value || 2;
+
+ this.previousPosition = null;
+ this.mergedFrom = null; // Tracks tiles that merged together
+}
+
+Tile.prototype.savePosition = function () {
+ this.previousPosition = { x: this.x, y: this.y };
+};
+
+Tile.prototype.updatePosition = function (position) {
+ this.x = position.x;
+ this.y = position.y;
+};
+
+Tile.prototype.serialize = function () {
+ return {
+ position: {
+ x: this.x,
+ y: this.y
+ },
+ value: this.value
+ };
+};
--
cgit v1.2.3