added win popup
This commit is contained in:
		
							parent
							
								
									76f1765be7
								
							
						
					
					
						commit
						3997e94a68
					
				
					 4 changed files with 192 additions and 12 deletions
				
			
		| 
						 | 
					@ -2,6 +2,9 @@
 | 
				
			||||||
	location.hash='';
 | 
						location.hash='';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const assets=require('assets');
 | 
						const assets=require('assets');
 | 
				
			||||||
 | 
						const Popup=require('popup');
 | 
				
			||||||
 | 
						const SnekGame=require('snek');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	await new Promise(ok => assets.onReady(ok));
 | 
						await new Promise(ok => assets.onReady(ok));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const main=document.querySelector('main');
 | 
						const main=document.querySelector('main');
 | 
				
			||||||
| 
						 | 
					@ -73,6 +76,10 @@
 | 
				
			||||||
		if(!config.gamepad.buffer) inputs.clearBuffer=true;
 | 
							if(!config.gamepad.buffer) inputs.clearBuffer=true;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const startGame=async (category, filename) => {
 | 
				
			||||||
 | 
							//TODO migrate relevant code here
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	window.addEventListener('hashchange', async () => {
 | 
						window.addEventListener('hashchange', async () => {
 | 
				
			||||||
		nav.classList.add('hidden');
 | 
							nav.classList.add('hidden');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,7 +90,6 @@
 | 
				
			||||||
			return await resp.json();
 | 
								return await resp.json();
 | 
				
			||||||
		})();
 | 
							})();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const SnekGame=require('snek');
 | 
					 | 
				
			||||||
		const snek=new SnekGame(level, canvas, rules);
 | 
							const snek=new SnekGame(level, canvas, rules);
 | 
				
			||||||
		canvas.classList.remove('hidden');
 | 
							canvas.classList.remove('hidden');
 | 
				
			||||||
		snek.start();
 | 
							snek.start();
 | 
				
			||||||
| 
						 | 
					@ -91,6 +97,21 @@
 | 
				
			||||||
			if(evt=='tick') {
 | 
								if(evt=='tick') {
 | 
				
			||||||
				if(navigator.getGamepads) handleGamepads();
 | 
									if(navigator.getGamepads) handleGamepads();
 | 
				
			||||||
				snek.handleInputs(currentInputs);
 | 
									snek.handleInputs(currentInputs);
 | 
				
			||||||
 | 
								} else if(evt=='win') {
 | 
				
			||||||
 | 
									let popup=new Popup("Finished!");
 | 
				
			||||||
 | 
									popup.addStrong("You won!");
 | 
				
			||||||
 | 
									popup.addContent({
 | 
				
			||||||
 | 
										"Time": snek.playTime/1000+'s',
 | 
				
			||||||
 | 
										"Score": snek.score,
 | 
				
			||||||
 | 
										"Final length": snek.snake.length
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
									popup.buttons={
 | 
				
			||||||
 | 
										retry: "Retry",
 | 
				
			||||||
 | 
										next: "Next level",
 | 
				
			||||||
 | 
										menu: "Main menu"
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
									popup.display();
 | 
				
			||||||
 | 
									//TODO do something with the result
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		currentGame=snek;
 | 
							currentGame=snek;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										87
									
								
								src/js/popup.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/js/popup.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,87 @@
 | 
				
			||||||
 | 
					const objToDom=obj => {
 | 
				
			||||||
 | 
						if(obj[Popup.EM]) {
 | 
				
			||||||
 | 
							let em=document.createElement('em');
 | 
				
			||||||
 | 
							em.appendChild(document.createTextNode(obj[Popup.EM]));
 | 
				
			||||||
 | 
							return em;
 | 
				
			||||||
 | 
						} else if(obj[Popup.STRONG]) {
 | 
				
			||||||
 | 
							let em=document.createElement('strong');
 | 
				
			||||||
 | 
							em.appendChild(document.createTextNode(obj[Popup.STRONG]));
 | 
				
			||||||
 | 
							return em;
 | 
				
			||||||
 | 
						} else if(typeof obj=='string' || typeof obj=='number') {
 | 
				
			||||||
 | 
							return document.createTextNode(obj+'');
 | 
				
			||||||
 | 
						} else if(Array.isArray(obj)) {
 | 
				
			||||||
 | 
							let ul=document.createElement('ul');
 | 
				
			||||||
 | 
							obj.forEach(elem => ul.appendChild(objToDom(elem)));
 | 
				
			||||||
 | 
							return ul;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							let table=document.createElement('table');
 | 
				
			||||||
 | 
							Object
 | 
				
			||||||
 | 
								.keys(obj)
 | 
				
			||||||
 | 
								.forEach(key => {
 | 
				
			||||||
 | 
									let tr=table.appendChild(document.createElement('tr'));
 | 
				
			||||||
 | 
									tr.appendChild(document.createElement('th')).appendChild(document.createTextNode(key));
 | 
				
			||||||
 | 
									tr.appendChild(document.createElement('td')).appendChild(objToDom(obj[key]));
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							return table;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Popup {
 | 
				
			||||||
 | 
						constructor(title, content=[], buttons={}) {
 | 
				
			||||||
 | 
							this.title=title;
 | 
				
			||||||
 | 
							this.content=content.map(objToDom);
 | 
				
			||||||
 | 
							this.buttons={...buttons};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addContent(cnt) {
 | 
				
			||||||
 | 
							this.content.push(objToDom(cnt));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						addText(cnt) {
 | 
				
			||||||
 | 
							this.content.push(document.createTextNode(cnt));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						addEm(cnt) {
 | 
				
			||||||
 | 
							this.content.push(objToDom({[Popup.EM]: cnt}));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						addStrong(cnt) {
 | 
				
			||||||
 | 
							this.content.push(objToDom({[Popup.STRONG]: cnt}));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						async display() {
 | 
				
			||||||
 | 
							let outer=document.createElement('div');
 | 
				
			||||||
 | 
							outer.classList.add('popup');
 | 
				
			||||||
 | 
							let popup=outer.appendChild(document.createElement('div'));
 | 
				
			||||||
 | 
							popup.classList.add('content');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let title=popup.appendChild(document.createElement('h1'));
 | 
				
			||||||
 | 
							title.innerText=this.title;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let contentSection=popup.appendChild(document.createElement('section'));
 | 
				
			||||||
 | 
							this.content.forEach(elem => contentSection.appendChild(elem));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let buttonSection=popup.appendChild(document.createElement('section'));
 | 
				
			||||||
 | 
							let buttons=Object.keys(this.buttons).map(btn => {
 | 
				
			||||||
 | 
								let button=document.createElement('button');
 | 
				
			||||||
 | 
								button.innerText=this.buttons[btn];
 | 
				
			||||||
 | 
								button.dataset.code=btn;
 | 
				
			||||||
 | 
								return button;
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							buttons.forEach(btn => buttonSection.appendChild(btn));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							document.body.appendChild(outer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const code=await Promise.race(buttons.map(btn => new Promise(ok => {
 | 
				
			||||||
 | 
								btn.addEventListener('click', e => {
 | 
				
			||||||
 | 
									e.preventDefault();
 | 
				
			||||||
 | 
									return ok(btn.dataset.code);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							})));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							document.body.removeChild(outer);
 | 
				
			||||||
 | 
							return code;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Popup.EM=Symbol('EM');
 | 
				
			||||||
 | 
					Popup.STRONG=Symbol('STRONG');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return module.exports=Popup;
 | 
				
			||||||
| 
						 | 
					@ -293,6 +293,9 @@ class SnekGame {
 | 
				
			||||||
					([x, y]) => !(x==head[0] && y==head[1])
 | 
										([x, y]) => !(x==head[0] && y==head[1])
 | 
				
			||||||
				);
 | 
									);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// increase score
 | 
				
			||||||
 | 
									this.score++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// custom rules
 | 
									// custom rules
 | 
				
			||||||
				if(this.rules.fruitRegrow) {
 | 
									if(this.rules.fruitRegrow) {
 | 
				
			||||||
					const emptyCells=this.world
 | 
										const emptyCells=this.world
 | 
				
			||||||
| 
						 | 
					@ -409,9 +412,9 @@ class SnekGame {
 | 
				
			||||||
		this.firstStep=Date.now();
 | 
							this.firstStep=Date.now();
 | 
				
			||||||
		this.tickId=0;
 | 
							this.tickId=0;
 | 
				
			||||||
		this.playing=true;
 | 
							this.playing=true;
 | 
				
			||||||
 | 
							this.score=0;
 | 
				
			||||||
		requestAnimationFrame(() => this.tick());
 | 
							requestAnimationFrame(() => this.tick());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports=SnekGame;
 | 
					return module.exports=SnekGame;
 | 
				
			||||||
return SnekGame;
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,14 +1,15 @@
 | 
				
			||||||
@keyframes popupAppear {
 | 
					@keyframes popupAppear {
 | 
				
			||||||
	0% {
 | 
						0% {
 | 
				
			||||||
		background: transparent;
 | 
							background: rgba(0, 0, 0, 0%);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	100% {
 | 
						100% {
 | 
				
			||||||
		background: black;
 | 
							background: rgba(0, 0, 0, 90%);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.popup {
 | 
					.popup {
 | 
				
			||||||
	animation: popupAppear 1s linear no-repeat;
 | 
						animation: popupAppear 1s linear;
 | 
				
			||||||
 | 
						background: rgba(0, 0, 0, 90%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	position: absolute;
 | 
						position: absolute;
 | 
				
			||||||
	top: 0;
 | 
						top: 0;
 | 
				
			||||||
| 
						 | 
					@ -18,12 +19,80 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.content {
 | 
						.content {
 | 
				
			||||||
		border-radius: 2rem;
 | 
							border-radius: 2rem;
 | 
				
			||||||
		background: @accentbg;
 | 
							background: @bg;
 | 
				
			||||||
		text-align: center;
 | 
							text-align: center;
 | 
				
			||||||
 | 
							box-shadow: black 0 0 1rem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		postion: absolute;
 | 
							position: absolute;
 | 
				
			||||||
		top: 50%;
 | 
							top: 50%;
 | 
				
			||||||
		left: 50%;
 | 
							left: 50%;
 | 
				
			||||||
		transform: translate(-50%, -50%);
 | 
							transform: translate(-50%, -50%);
 | 
				
			||||||
 | 
							box-sizing: border-box;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							max-width: 50vw;
 | 
				
			||||||
 | 
							max-height: 50vh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							padding: 2rem;
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							font-size: 1.4rem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							& > section {
 | 
				
			||||||
 | 
								margin: 1rem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&:first-of-type {
 | 
				
			||||||
 | 
									display: flex;
 | 
				
			||||||
 | 
									flex-direction: column;
 | 
				
			||||||
 | 
									align-items: center;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									& > * {
 | 
				
			||||||
 | 
										margin: .5rem;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&:last-of-type {
 | 
				
			||||||
 | 
									display: flex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									& > * {
 | 
				
			||||||
 | 
										flex: 1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							table {
 | 
				
			||||||
 | 
								display: flex;
 | 
				
			||||||
 | 
								flex-direction: column;
 | 
				
			||||||
 | 
								width: 100%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								tr {
 | 
				
			||||||
 | 
									display: flex;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								th {
 | 
				
			||||||
 | 
									text-align: right;
 | 
				
			||||||
 | 
									&::after {
 | 
				
			||||||
 | 
										content: ':';
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								td {
 | 
				
			||||||
 | 
									text-align: left;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								th, td {
 | 
				
			||||||
 | 
									padding: 0 .5rem;
 | 
				
			||||||
 | 
									flex: 1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							button {
 | 
				
			||||||
 | 
								display: inline;
 | 
				
			||||||
 | 
								color: @accentfg;
 | 
				
			||||||
 | 
								background: @accentbg;
 | 
				
			||||||
 | 
								font-weight: bold;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								border-radius: 1rem;
 | 
				
			||||||
 | 
								border: 0;
 | 
				
			||||||
 | 
								padding: 2rem;
 | 
				
			||||||
 | 
								margin: 1rem;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue