├── sizzle.wav ├── favicon.ico ├── og-image.jpg ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── mstile-150x150.png ├── android-chrome-96x96.png ├── browserconfig.xml ├── site.webmanifest ├── README.md ├── twitter.svg ├── volume-high.svg ├── question-circle.svg ├── volume-no.svg ├── index.html ├── game.js └── main.css /sizzle.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cassidoo/flapjack-fwop/HEAD/sizzle.wav -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cassidoo/flapjack-fwop/HEAD/favicon.ico -------------------------------------------------------------------------------- /og-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cassidoo/flapjack-fwop/HEAD/og-image.jpg -------------------------------------------------------------------------------- /favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cassidoo/flapjack-fwop/HEAD/favicon-16x16.png -------------------------------------------------------------------------------- /favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cassidoo/flapjack-fwop/HEAD/favicon-32x32.png -------------------------------------------------------------------------------- /apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cassidoo/flapjack-fwop/HEAD/apple-touch-icon.png -------------------------------------------------------------------------------- /mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cassidoo/flapjack-fwop/HEAD/mstile-150x150.png -------------------------------------------------------------------------------- /android-chrome-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cassidoo/flapjack-fwop/HEAD/android-chrome-96x96.png -------------------------------------------------------------------------------- /browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #00aba9 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Flapjack Fwop", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-96x96.png", 7 | "sizes": "96x96", 8 | "type": "image/png" 9 | } 10 | ], 11 | "theme_color": "#F53635", 12 | "background_color": "#272039", 13 | "display": "standalone" 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flapjack-fwop 2 | A game where you have to get butter on all of the pancakes. 3 | 4 | [Play the game here](https://cassidoo.github.io/flapjack-fwop/)! 5 | 6 | ## How to play 7 | 8 | Click a pancake to remove or add butter to it, as well as the pancake's neighbors. Click around and try to get butter on all of them! 9 | 10 | ## How to run 11 | 12 | This is built with plain ol' HTML, CSS, and JavaScript, so there's no need to build anything fancy to make in run on your machine. If you clone the repository and open up `index.html` in your browser, you'll be all set! 13 | -------------------------------------------------------------------------------- /twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /volume-high.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /question-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /volume-no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Flapjack Fwop 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 29 | 30 | 34 | 35 | 36 | 37 | 41 | 42 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 60 |
61 |
62 | 0 63 | Clicks 64 |
65 |
66 |
Best Score
67 |
68 |
69 |
70 | how to play 71 |
72 |

How to Play

73 |

74 | Click on the pancakes to add or remove butter from them, plus the ones 75 | on the top, left, bottom, and right of the pancake you clicked. 76 |
Get butter on all of the pancakes to win! 77 |

78 |
79 |
80 | 83 | 97 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /game.js: -------------------------------------------------------------------------------- 1 | let grid = []; 2 | let clicks = 0; 3 | let snd; 4 | let audio = true; 5 | 6 | function audioSetup() { 7 | snd = new Audio("sizzle.wav"); 8 | let volumeButton = document.getElementById('vol'); 9 | 10 | if (localStorage.getItem('volume') !== null) { 11 | audio = localStorage.getItem('volume') == 'true'; 12 | if (audio) { 13 | volumeButton.src = 'volume-high.svg' 14 | } else { 15 | volumeButton.src = 'volume-no.svg' 16 | } 17 | } 18 | volumeButton.addEventListener('click', () => { 19 | if (audio) { 20 | volumeButton.src = 'volume-no.svg' 21 | audio = false; 22 | } else { 23 | volumeButton.src = 'volume-high.svg' 24 | audio = true; 25 | } 26 | localStorage.setItem('volume', audio); 27 | }); 28 | } 29 | 30 | function randomGrid() { 31 | for (let i = 0; i < 5; i++) { 32 | let row = []; 33 | for (let j = 0; j < 5; j++) { 34 | row.push(0); 35 | } 36 | grid.push(row); 37 | } 38 | 39 | return grid; 40 | } 41 | 42 | function getRandomInt(max) { 43 | return Math.floor(Math.random() * Math.floor(max)); 44 | } 45 | 46 | function generateGrid(grid) { 47 | let board = document.getElementById('board'); 48 | board.innerHTML = ''; 49 | for (let i = 0; i < grid.length; i++) { 50 | for (let j = 0; j < grid[0].length; j++) { 51 | let button = ``; 55 | button = htmlToElement(button); 56 | board.appendChild(button); 57 | } 58 | } 59 | 60 | for (let k = 0; k < 30; k++) { 61 | handleClick(getRandomInt(4), getRandomInt(4), true); 62 | } 63 | } 64 | 65 | function handleClick(x, y, init) { 66 | let g = grid; 67 | 68 | g[x][y] = flip(g[x][y]); 69 | document.getElementById(`flapjack-${x}-${y}`).innerHTML = 70 | `${grid[x][y] === 0 ? '
' : ''}`; 71 | 72 | if (x < g[0].length - 1) { 73 | g[x + 1][y] = flip(g[x + 1][y]); 74 | document.getElementById(`flapjack-${x+1}-${y}`).innerHTML = 75 | `${grid[x+1][y] === 0 ? '
' : ''}`; 76 | } 77 | if (x > 0) { 78 | g[x - 1][y] = flip(g[x - 1][y]); 79 | document.getElementById(`flapjack-${x-1}-${y}`).innerHTML = 80 | `${grid[x-1][y] === 0 ? '
' : ''}`; 81 | } 82 | if (y < g.length - 1) { 83 | g[x][y + 1] = flip(g[x][y + 1]); 84 | document.getElementById(`flapjack-${x}-${y+1}`).innerHTML = 85 | `${grid[x][y+1] === 0 ? '
' : ''}`; 86 | } 87 | if (y > 0) { 88 | g[x][y - 1] = flip(g[x][y - 1]); 89 | document.getElementById(`flapjack-${x}-${y-1}`).innerHTML = 90 | `${grid[x][y-1] === 0 ? '
' : ''}`; 91 | } 92 | grid = g; 93 | 94 | if (!init) { 95 | if (audio) { 96 | snd.play(); 97 | snd.currentTime = 0; 98 | } 99 | 100 | if (checkWin()) { 101 | win(); 102 | } else { 103 | addClick(); 104 | } 105 | } 106 | } 107 | 108 | function win() { 109 | let tweetString = `I just scored ${clicks} in %23FlapjackFwop! Can you beat me?`; 110 | const website = `http://cassidoo.github.io/flapjack-fwop`; 111 | let win = `
` 112 | + `

You win!

` 113 | + `
It took you ${clicks} clicks!
` 114 | + `` 115 | + `
`; 116 | win = htmlToElement(win); 117 | document.getElementById('board').appendChild(win); 118 | 119 | if (localStorage.getItem('ffbestscore') === null || clicks < localStorage.getItem('ffbestscore')) { 120 | localStorage.setItem('ffbestscore', clicks); 121 | } 122 | } 123 | 124 | function checkWin() { 125 | let check = [ 126 | [0,0,0,0,0], 127 | [0,0,0,0,0], 128 | [0,0,0,0,0], 129 | [0,0,0,0,0], 130 | [0,0,0,0,0] 131 | ]; 132 | return JSON.stringify(check) === JSON.stringify(grid); 133 | } 134 | 135 | function addClick() { 136 | clicks = clicks += 1; 137 | document.getElementById('clicks').innerHTML = clicks; 138 | } 139 | 140 | function flip(val) { 141 | return val === 0 ? 1 : 0; 142 | } 143 | 144 | function htmlToElement(html) { 145 | let template = document.createElement('template'); 146 | html = html.trim(); 147 | template.innerHTML = html; 148 | return template.content.firstChild; 149 | } 150 | 151 | -------------------------------------------------------------------------------- /main.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Baloo Chettan', cursive; 3 | background: #272039; 4 | color: #fff; 5 | } 6 | 7 | .banner { 8 | position: absolute; 9 | top: 60px; 10 | left: -10px; 11 | z-index: 1; 12 | width: 400px; 13 | } 14 | 15 | .banner .line { 16 | width: 100%; 17 | height: 78px; 18 | text-align: center; 19 | text-transform: uppercase; 20 | font-size: 3em; 21 | line-height: 78px; 22 | transform: skew(0, -15deg) scale(.8, 1); 23 | } 24 | 25 | .banner .line:after, 26 | .banner .line:first-child:before { 27 | position: absolute; 28 | top: 44px; 29 | left: 0; 30 | z-index: -1; 31 | display: block; 32 | width: 330px; 33 | height: 78px; 34 | border-radius: 4px; 35 | background: linear-gradient(105deg, #fed816 0%,#fc860b 21%,#f88f83 49%,#ff838a 58%,#ff53bd 84%,#ff3175 100%); 36 | content: ''; 37 | transform: skew(0, 15deg); 38 | } 39 | 40 | .banner .line:first-child:before { 41 | top: -10px; 42 | right: 0; 43 | left: auto; 44 | } 45 | 46 | .banner .line:first-child:before, 47 | .banner .line:after { 48 | width: 0; 49 | height: 0; 50 | border-width: 38px; 51 | border-style: solid; 52 | border-color: #F53635 #F53635 transparent transparent; 53 | background: linear-gradient(105deg, #fed816 0%,#fc860b 21%,#f88f83 49%,#ff838a 58%,#ff53bd 84%,#ff3175 100%); 54 | } 55 | 56 | .banner .line:last-child:after { 57 | top: 12px; 58 | border-color: transparent transparent #B10072 #B10072; 59 | } 60 | 61 | .banner span { 62 | display: block; 63 | width: 100%; 64 | height: 100%; 65 | border-radius: 4px; 66 | background: linear-gradient(280deg, #fed816 0%,#fc860b 21%,#f88f83 49%,#ff838a 58%,#ff53bd 84%,#ff3175 100%); 67 | } 68 | 69 | .score { 70 | position: absolute; 71 | top: 40px; 72 | right: 40px; 73 | padding: 0 20px 20px; 74 | background: #211931; 75 | border-radius: 20px; 76 | font-size: 2em; 77 | text-align: center; 78 | } 79 | 80 | .score #clicks { 81 | display: block; 82 | font-size: 2em; 83 | } 84 | 85 | .score .scored { 86 | font-size: .8em; 87 | } 88 | 89 | .score .line { 90 | width: 100%; 91 | height: 5px; 92 | margin: 5px 0; 93 | background: linear-gradient(to right, #f88f83 0%, #f56fe5 100%); 94 | } 95 | 96 | .help { 97 | position: absolute; 98 | bottom: 20px; 99 | left: 20px; 100 | width: 100px; 101 | background: transparent; 102 | border: none; 103 | } 104 | 105 | .volume { 106 | position: absolute; 107 | bottom: 20px; 108 | right: 20px; 109 | width: 100px; 110 | background: transparent; 111 | border: none; 112 | } 113 | 114 | .help img, .volume img { 115 | width: 80px; 116 | } 117 | 118 | .helptext { 119 | display: none; 120 | position: absolute; 121 | bottom: 20px; 122 | left: 110px; 123 | width: 600px; 124 | padding: 15px; 125 | background: #272039; 126 | border-radius: 20px; 127 | box-shadow: 0 5px 0 10px #211931; 128 | box-sizing: border-box; 129 | z-index: 10; 130 | } 131 | 132 | .helptext h3, .helptext p { 133 | margin: 0; 134 | } 135 | 136 | .help:focus .helptext, 137 | .help:hover .helptext { 138 | display: block; 139 | } 140 | 141 | .board { 142 | position: absolute; 143 | top: 50%; 144 | left: 50%; 145 | transform: translate(-50%, -50%); 146 | display: inline-grid; 147 | grid-template-columns: 1fr 1fr 1fr 1fr 1fr; 148 | grid-template-rows: auto; 149 | grid-column-gap: 30px; 150 | grid-row-gap: 30px; 151 | justify-items: center; 152 | padding: 20px 30px 35px; 153 | background: linear-gradient(135deg, #f88f83 0%,#ff838a 24%,#ff53bd 76%,#f56fe5 100%); 154 | border: 4px solid #D6217F; 155 | border-radius: 20px; 156 | box-shadow: 0 10px 0 20px #211931; 157 | } 158 | 159 | .win { 160 | position: absolute; 161 | top: 0; 162 | width: 100%; 163 | height: 100%; 164 | display: flex; 165 | justify-content: center; 166 | align-items: center; 167 | background: rgba(214, 33, 127, .5); 168 | border: 4px solid #D6217F; 169 | border-radius: 20px; 170 | text-align: center; 171 | animation: .5s winner; 172 | } 173 | 174 | .win h1 { 175 | font-size: 4em; 176 | margin: 0; 177 | } 178 | 179 | .result { 180 | font-size: 2em; 181 | } 182 | 183 | .twitter-button { 184 | display: inline-block; 185 | height: 20px; 186 | padding: 0 5px 5px; 187 | background: #1CA1F3; 188 | border-radius: 4px; 189 | color: #fff; 190 | text-decoration: none; 191 | } 192 | 193 | .twitter-button img { 194 | margin-right: 5px; 195 | vertical-align: middle; 196 | } 197 | 198 | .fj { 199 | position: relative; 200 | width: 100px; 201 | height: 60px; 202 | background: radial-gradient(ellipse at center, #bf642f 0%,#bf642f 28%,#f0a653 61%,#f0a653 85%,#ec903c 100%); 203 | border: none; 204 | border-radius: 100%; 205 | box-shadow: 0 2px 2px 3px #f0dda6, 0px 9px 0px 6px #B10072; 206 | cursor: pointer; 207 | } 208 | 209 | .fj:focus { 210 | outline-color: rgba(177,0,114,.5); 211 | outline-offset: 10px; 212 | outline-style: dashed; 213 | } 214 | 215 | .fj:before { 216 | display: block; 217 | content: ''; 218 | position: absolute; 219 | top: 50%; 220 | left: 0; 221 | z-index: -1; 222 | width: 100%; 223 | height: 5px; 224 | background: #eec368; 225 | } 226 | 227 | .fj:after { 228 | display: block; 229 | content: ''; 230 | position: absolute; 231 | top: 5px; 232 | left: -2px; 233 | z-index: -1; 234 | width: 104%; 235 | height: 104%; 236 | background: #eec368; 237 | border-radius: 100%; 238 | } 239 | 240 | .butter { 241 | position: absolute; 242 | top: 50%; 243 | left: 50%; 244 | transform: translate(-50%, -50%); 245 | width: 25%; 246 | height: 25%; 247 | background: linear-gradient(to bottom, #f6f1d2 0%,#fbd457 100%); 248 | border-bottom: 3px solid #DB9526; 249 | border-radius: 2px; 250 | animation: .5s butterdrop; 251 | } 252 | 253 | .hide { 254 | display: none !important; 255 | } 256 | 257 | @keyframes butterdrop { 258 | 0% { 259 | top: 0; 260 | opacity: 0; 261 | box-shadow: 0 20px 5px rgba(135, 64, 24, 0.8); 262 | } 263 | 100% { 264 | opacity: 1; 265 | box-shadow: 0 1px 5px #874018; 266 | } 267 | } 268 | 269 | @keyframes winner { 270 | 0% { 271 | top: -20px; 272 | background: #FED314; 273 | opacity: 0; 274 | } 275 | 100% { 276 | background: rgba(214, 33, 127, .5); 277 | opacity: 1; 278 | } 279 | } 280 | 281 | @media (max-width: 1400px) { 282 | .banner { 283 | position: relative; 284 | margin: 80px auto; 285 | left: auto; 286 | top: auto; 287 | transform: none; 288 | } 289 | 290 | .banner .line { 291 | transform: skew(0, -5deg) scale(.8, 1); 292 | } 293 | 294 | .board { 295 | position: relative; 296 | top: auto; 297 | left: auto; 298 | transform: none; 299 | display: grid; 300 | width: 688px; 301 | margin: auto; 302 | } 303 | } 304 | 305 | @media (max-width: 1000px) { 306 | .banner { 307 | margin: 60px auto 20px; 308 | } 309 | .score { 310 | position: relative; 311 | top: auto; 312 | right: auto; 313 | margin: 35px auto 10px; 314 | padding: 20px; 315 | width: 80%; 316 | display: flex; 317 | flex-direction: row; 318 | align-items: center; 319 | justify-content: space-around; 320 | } 321 | .score #clicks, .score #best { 322 | display: inline; 323 | font-size: 1.5em; 324 | } 325 | .score .line { 326 | display: inline-block; 327 | content: ''; 328 | width: 4px; 329 | height: 50px; 330 | margin: 0 5px; 331 | background: linear-gradient(to bottom, #f88f83 0%, #f56fe5 100%); 332 | } 333 | .board { 334 | grid-column-gap: 20px; 335 | grid-row-gap: 25px; 336 | padding: 10px 10px 20px; 337 | width: 580px; 338 | } 339 | .fj { 340 | width: 80px; 341 | height: 48px; 342 | } 343 | } 344 | 345 | @media (max-width: 800px) { 346 | .board { 347 | width: 460px; 348 | box-shadow: 0 5px 0 10px #211931; 349 | } 350 | .score { 351 | padding: 10px; 352 | } 353 | .fj { 354 | width: 60px; 355 | height: 36px; 356 | } 357 | .help, .volume { 358 | position: absolute; 359 | bottom: auto; 360 | right: auto; 361 | top: 5px; 362 | left: 5px; 363 | width: 60px; 364 | } 365 | .help { 366 | left: 70px; 367 | } 368 | .help img, .volume img { 369 | width: 50px; 370 | } 371 | .helptext { 372 | position: fixed; 373 | top: 70px; 374 | left: 0; 375 | min-width: 300px; 376 | width: 100%; 377 | max-height: 180px; 378 | } 379 | } 380 | 381 | @media (max-width: 500px) { 382 | .banner { 383 | width: auto; 384 | } 385 | .banner .line { 386 | height: 68px; 387 | font-size: 2.5em; 388 | line-height: 68px; 389 | } 390 | .banner .line:last-child:after { 391 | top: 18px; 392 | } 393 | .banner .line:first-child:before, .banner .line:after { 394 | border-width: 30px; 395 | } 396 | .score { 397 | width: auto; 398 | } 399 | .board { 400 | width: 90%; 401 | grid-column-gap: 15px; 402 | } 403 | .fj { 404 | width: 50px; 405 | } 406 | } 407 | --------------------------------------------------------------------------------