|  |  | @ -25,7 +25,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	let currentGame=null; |  |  |  | 	let currentGame=null; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	// forward-declare functions
 |  |  |  | 	// forward-declare functions
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	let resizeCanvas, getLevel, startGame, handleWin, handleDeath, menu, help, restart; |  |  |  | 	let resizeCanvas, getLevel, startGame, stopGame, handleWin, handleDeath, menu, help, settings, restart; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	// handle window resize and fullscreen
 |  |  |  | 	// handle window resize and fullscreen
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	resizeCanvas=() => { |  |  |  | 	resizeCanvas=() => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -92,15 +92,31 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | 		}); |  |  |  | 		}); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	}); |  |  |  | 	}); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	// stop a running game
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	stopGame=() => { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if(currentGame) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			// stop the actual game
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			currentGame.playing=false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			// setup the DOM
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			nav.classList.remove('hidden'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			canvas.classList.add('hidden'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			hud.classList.add('hidden'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	}; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	// start a new game
 |  |  |  | 	// start a new game
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	startGame=async (category, levelId, filename) => { |  |  |  | 	startGame=async (category, levelId, filename) => { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// stop any running games
 |  |  |  | 		// stop any running games
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if(currentGame) currentGame.playing=false; |  |  |  | 		stopGame(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// load rules and level from cache or server
 |  |  |  | 		// load rules and level from cache or server
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		const rules=levelList[category].rules || {}; |  |  |  | 		const rules=levelList[category].rules || {}; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		const level=await levels.get(filename); |  |  |  | 		const level=await levels.get(filename); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		// stop any running games again
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		stopGame(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// create the game and attach the callbacks and config
 |  |  |  | 		// create the game and attach the callbacks and config
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		const snek=currentGame=new SnekGame(level, canvas, rules); |  |  |  | 		const snek=currentGame=new SnekGame(level, canvas, rules); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		snek.callback=evt => { |  |  |  | 		snek.callback=evt => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -135,13 +151,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	// return to the menu
 |  |  |  | 	// return to the menu
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	menu=() => { |  |  |  | 	menu=() => { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// stop any running games
 |  |  |  | 		stopGame(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if(currentGame) currentGame.playing=false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// setup the DOM
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		nav.classList.remove('hidden'); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		canvas.classList.add('hidden'); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		hud.classList.add('hidden'); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	}; |  |  |  | 	}; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	// display the win popup
 |  |  |  | 	// display the win popup
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -238,6 +248,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if(hash=='' || hash=='menu') return menu(); |  |  |  | 		if(hash=='' || hash=='menu') return menu(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		else if(hash=='help') return help(); |  |  |  | 		else if(hash=='help') return help(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		else if(hash=='settings') return settings(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		const [_, category, levelId, filename]=location.hash.match(/([a-zA-Z0-9_-]+?)\/([a-zA-Z0-9_-]+?)\/(.+)/); |  |  |  | 		const [_, category, levelId, filename]=location.hash.match(/([a-zA-Z0-9_-]+?)\/([a-zA-Z0-9_-]+?)\/(.+)/); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		startGame(category, levelId, filename); |  |  |  | 		startGame(category, levelId, filename); | 
			
		
	
	
		
		
			
				
					|  |  | 
 |