Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              $base-size: 12.5vmin;
$base-border-width: 0.07rem;
$base-border-color: #000000;
$base-border: solid $base-border-width $base-border-color;
$base-chars: ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ');

$before-move-pause-time: 500ms;

$screen-background-color: #a4fc20;
$screen-width: 8rem;
$screen-height: 8rem;

$turret-background-color: #1bad00;
$turret-width: 0.8rem;
$turret-height: 0.8rem;
$turret-border: $base-border;

$gun-width: 0.3rem;
$gun-height: 1rem;

$fire-background-image: radial-gradient(
	circle at 50% 50%,
	#ef7d00 0%,
	#f5b300 50%,
	transparent 100%
);
$fire-width: 0.25rem;
$fire-height: 0.25rem;

$zombie-width: 0.65rem;
$zombie-height: 1.2rem;
$zombie-border: solid $base-border-width $base-border-color;

$zombie-head-background-color: #0ddd63;

$zombie-head-width: $zombie-width;
$zombie-head-height: 0.55rem;

$zombie-eyes-width: 0.2rem;
$zombie-eyes-height: 0.2rem;

$zombie-eye-background-color: #ffffff;
$zombie-eye-width: $zombie-eyes-height;
$zombie-eye-height: $zombie-eyes-height;
$zombie-eye-border: solid 0.05rem $base-border-color;
$zombie-eye-top: 0.07rem;
$zombie-eye-left: 0.08rem;
$zombie-eye-right: 0.35rem;

$zombie-body-background-color: #b37500;
$zombie-body-width: 0.35rem;
$zombie-body-height: 0.35rem;
$zombie-body-transform: translate(0.09rem, -0.07rem);

$zombie-arm-width: 0.3rem;
$zombie-arm-height: 0.1rem;
$zombie-arm-top: 0.52rem;
$zombie-arm-left: 0.05rem;
$zombie-arm-right: 0.35rem;

$zombie-leg-background-color: #a2a2a2;
$zombie-leg-width: 0.23rem;
$zombie-leg-height: 0.32rem;
$zombie-leg-top: 0.75rem;
$zombie-leg-left: 0.09rem;
$zombie-leg-right: 0.21rem;

$zombie-foot-width: 0.1rem;
$zombie-foot-height: 0.2rem;
$zombie-foot-top: 0.19rem;

$zombie-hole-background-color: #000000;
$zombie-hole-width: $zombie-width;
$zombie-hole-height: $zombie-width;

$life-top: 0.4rem;
$life-left: 0.4rem;

$heart-background-color: #e41435;
$heart-width: 0.4rem;
$heart-height: 0.4rem;
$heart-border-color: #000000;
$heart-transition: background-color 500ms ease-out;

$score-top: 0.25rem;
$score-right: 0.25rem;

$title-background-color: #a4fc20;
$title-endln-margin: 0.2rem;

$zombie-dying-background-image: radial-gradient(
	circle at 50% 80%,
	rgba(#ef7d00, 0.8) 0%,
	rgba(#f5b300, 0.8) 50%,
	transparent 100%
);

@mixin render-character($i, $pixel-size) {
	$pixel-color: #000000;
	width: $pixel-size * 3;
	height: $pixel-size * 5;
	margin-left: $pixel-size / 2;
	&:before {
		content: '';
		width: $pixel-size;
		height: $pixel-size;
		display: block;
		transform: translate(-100%, -100%);
		@if ($i == "0" or $i == "o") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "1") {
			box-shadow: 
				($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 2) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "2") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "3") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "4") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "5" or $i == "s") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "6" or $i == "g") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "7") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "8") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "9") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "a") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "b") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "c") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "d") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "e") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "f") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "h") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "i") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 2) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "j") {
			box-shadow: ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "k") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "l") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "m") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 2) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "n") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 2) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "p") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color,
		}
		@elseif ($i == "q") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "r") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "t") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 2) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 4) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color,
		}
		@elseif ($i == "u") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "v") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color,
		}
		@elseif ($i == "w") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 1) ($pixel-size * 3) $pixel-color, ($pixel-size * 3) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 2) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "x") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 3) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@elseif ($i == "y") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 1) ($pixel-size * 2) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 2) ($pixel-size * 4) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color,
		}
		@elseif ($i == "z") {
			box-shadow: ($pixel-size * 1) ($pixel-size * 1) $pixel-color, ($pixel-size * 2) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 1) $pixel-color, ($pixel-size * 3) ($pixel-size * 2) $pixel-color, ($pixel-size * 2) ($pixel-size * 3) $pixel-color, ($pixel-size * 1) ($pixel-size * 4) $pixel-color, ($pixel-size * 1) ($pixel-size * 5) $pixel-color, ($pixel-size * 2) ($pixel-size * 5) $pixel-color, ($pixel-size * 3) ($pixel-size * 5) $pixel-color;
		}
		@else {
			// Nothing to do here... Maybe spaces?
		}
	}
}

html, body, #example_game {
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
}

html {
	// For responsive purposes
	font-size: $base-size;
}

#example_game {
	background-color: #000000;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: auto;
}

.screen {
	background-color: $screen-background-color;
	width: $screen-width;
	height: $screen-height;
	position: relative;
	overflow: hidden;
	flex-shrink: 0;
}

.debug {
	color: #00ff00;
	font-family: courier;
	font-size: 0.5rem;
	text-align: center;
	background-color: black;
	width: 2rem;
	height: 1rem;
	line-height: 1rem;
	display: none;
	position: absolute;
	top: 0;
	left: 0;
	&.shown {
		display: block;
	}
}

.turret {
	width: $turret-width;
	height: $turret-height;
	position: absolute;
	top: calc(50% - #{$turret-height / 2});
	left: calc(50% - #{$turret-width / 2});
	box-sizing: border-box;
	.gun {
		background-color: $turret-background-color;
		width: $gun-width;
		height: $gun-height;
		border: $turret-border;
		position: absolute;
		bottom: calc(100% - #{$gun-height / 2});
		left: calc(50% - #{$gun-width / 2});
		box-sizing: border-box;
	}
	.body {
		background-color: $turret-background-color;
		width: $turret-width;
		height: $turret-height;
		border: $turret-border;
		position: absolute;
		top: 0;
		left: 0;
		box-sizing: border-box;
		border-radius: 50%;
	}
}

.fire {
	background-image: $fire-background-image;
	width: $fire-width;
	height: $fire-height;
	border-radius: 50%;
	position: absolute;
	animation: animate-fire 100ms infinite;
}

.zombie {
	width: $zombie-width;
	height: $zombie-height;
	overflow: hidden;
	position: absolute;
	&:not(.zombie-dying):not(.zombie-hiding).zombie-walking .zombie-wrapper {
		transform: translateY(0%);
		.leg.left {
			animation: zombie-walk-left 1500ms linear infinite;
		}
		.leg.right {
			animation: zombie-walk-right 1500ms linear infinite;
		}
	}
	&:not(.zombie-walking):not(.zombie-dying):not(.zombie-hiding) .zombie-wrapper {
		animation: summon-zombie 500ms ease-out 1000ms forwards;
		.hole {
			animation: animate-zombie-hole 500ms forwards,
				animate-hole-at-bottom 500ms ease-out 1000ms forwards,
				clear-hole 300ms ease-out 1500ms forwards;
		}
	}
	&:not(.zombie-walking):not(.zombie-dying).zombie-hiding {
		.zombie-wrapper {
			transform: translateY(0%);
			animation: zombie-hiding 500ms ease-out forwards 500ms;
			.hole {
				display: none;
			}
		}
	}
	&.zombie-dying {
		animation: zombie-fade-out 500ms ease-out forwards 500ms;
	}
	&.flip {
		transform: scaleX(-1);
	}
	&.zombie-dying:after {
		content: '';
		background-image: $zombie-dying-background-image;
		width: 100%;
		height: 100%;
		display: block;
		position: absolute;
		top: 0;
		left: 0;
		border-radius: 50% / 50% 50% 20% 20%;
		animation: animate-fire 100ms infinite;
	}
	&.zombie-dying .zombie-wrapper {
		transform: translateY(0%);
	}
	.zombie-wrapper {
		width: 100%;
		height: 100%;
		position: relative;
		transform: translateY(100%);
	}
	.head {
		background-color: $zombie-head-background-color;
		width: $zombie-head-width;
		height: $zombie-head-height;
		border: $zombie-border;
		box-sizing: border-box;
		border-radius: 50% / 50% 50% 50% 30%;
		.eyes {
			width: $zombie-head-width;
			height: $zombie-eyes-height;
			position: relative;
			&:before, &:after {
				content: '';
				background-color: $zombie-eye-background-color;
				width: $zombie-eye-width;
				height: $zombie-eye-height;
				border: $zombie-eye-border;
				position: absolute;
				top: $zombie-eye-top;
				box-sizing: border-box;
				border-radius: 50%;
			}
			&:before {
				left: $zombie-eye-left;
			}
			&:after {
				left: $zombie-eye-right;
			}
		}
	}
	.body {
		background-color: $zombie-body-background-color;
		width: $zombie-body-width;
		height: $zombie-body-height;
		border: $zombie-border;
		box-sizing: border-box;
		transform: $zombie-body-transform;
	}
	.arm {
		width: $zombie-arm-width;
		height: $zombie-arm-height;
		border: $zombie-border;
		border-bottom: none;
		border-left: none;
		box-sizing: border-box;
		position: absolute;
		top: $zombie-arm-top;
		transform-origin: top left;
		transform: rotate(15deg);
		&.left {
			left: $zombie-arm-left;
		}
		&.right {
			left: $zombie-arm-right;
		}
	}
	.leg {
		background-color: $zombie-leg-background-color;
		width: $zombie-leg-width;
		height: $zombie-leg-height;
		border: $zombie-border;
		position: absolute;
		top: $zombie-leg-top;
		box-sizing: border-box;
		transform-origin: top left;
		&.left {
			left: $zombie-leg-left;
		}
		&.right {
			left: $zombie-leg-right;
		}
		&:after {
			content: '';
			width: $zombie-foot-width;
			height: $zombie-foot-height;
			border: $zombie-border;
			border-top: none;
			border-right: none;
			display: block;
			position: absolute;
			top: $zombie-foot-top;
			box-sizing: border-box;
		}
	}
	.hole {
		background-color: $zombie-hole-background-color;
		width: $zombie-hole-width;
		height: $zombie-hole-height;
		position: absolute;
		top: 0;
		left: 0;
		border-radius: 50%;
		transform-origin: bottom center;
		transform: translate(0%, -100%) rotateX(-55deg) scale(0);
	}
}

.life {
	position: absolute;
	top: $life-top;
	left: $life-left;
	display: flex;
	flex-direction: row-reverse;
}

.heart {
	width: $heart-width;
	height: $heart-height;
	margin-right: $heart-width;
	transform: rotate(45deg);
	border-radius: 0 0 30% 0;
	position: relative;
	transition: $heart-transition;
	&:before, &:after {
		content: '';
		width: 100%;
		height: 100%;
		border-radius: 50%;
		display: block;
		position: absolute;
		top: 0;
		left: 0;
		transition: $heart-transition;
	}
	&:before {
		transform: translateY(-50%);
	}
	&:after {
		transform: translateX(-50%);
	}
	&.empty {
		background-color: $heart-border-color;
		&:before, &:after {
			background-color: $heart-border-color;
		}
	}
	&.full {
		background-color: $heart-background-color;
		&:before, &:after {
			background-color: $heart-background-color;
		}
	}
}

@each $char in $base-chars {
	.char-small-#{$char} {
		@include render-character(#{$char}, 0.06rem);
	}
	.char-#{$char} {
		@include render-character(#{$char}, 0.12rem);
	}
	.char-large-#{$char} {
		@include render-character(#{$char}, 0.14rem);
	}
}

.score {
	display: flex;
	position: absolute;
	top: $score-top;
	right: $score-right;
}

.title {
	background-color: $title-background-color;
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	left: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction: column;
	&.hide {
		transform: scale(0);
	}
}

.game-title {
	display: flex;
	flex-direction: column;
	&:not(:last-child) {
		margin-bottom: ($title-endln-margin * 2.5);
	}
	.title-content {
		display: flex;
		justify-content: center;
		&:not(:last-child) {
			margin-bottom: $title-endln-margin;
		}
	}
}

@keyframes animate-fire {
	0%   { transform: scale(1); }
	50%  { transform: scale(1.5); }
	100% { transform: scale(1); }
}

@keyframes animate-zombie-hole {
	0%   { transform: translate(5%, -100%) rotateX(-55deg) scale(0); }
	20%  { transform: translate(-5%, -100%) rotateX(-55deg) scale(0.2); }
	40%  { transform: translate(5%, -100%) rotateX(-55deg) scale(0.4); }
	60%  { transform: translate(-5%, -100%) rotateX(-55deg) scale(0.6); }
	80%  { transform: translate(5%, -100%) rotateX(-55deg) scale(0.8); }
	100% { transform: translate(0%, -100%) rotateX(-55deg) scale(1); }
}

@keyframes animate-hole-at-bottom {
	from { transform: translate(0%, -100%) rotateX(-55deg); }
	to   { transform: translate(0%, calc(#{$zombie-height} - 100%)) rotateX(-55deg); }
}

@keyframes clear-hole {
	from { opacity: 1; }
	to   { opacity: 0; }
}

@keyframes summon-zombie {
	from { transform: translateY(100%); }
	to   { transform: translateY(0%); }
}

@keyframes zombie-walk-left {
	0%   { transform: skewX(0deg); }
	25%  { transform: skewX(10deg); }
	50%  { transform: skewX(0deg); }
	75%  { transform: skewX(-10deg); }
	100% { transform: skewX(0deg); }
}

@keyframes zombie-walk-right {
	0%   { transform: skewX(0deg); }
	25%  { transform: skewX(-10deg); }
	50%  { transform: skewX(0deg); }
	75%  { transform: skewX(10deg); }
	100% { transform: skewX(0deg); }
}

@keyframes zombie-fade-out {
	from { opacity: 1; }
	to   { opacity: 0; }
}

@keyframes zombie-hiding {
	from { transform: scale(1); }
	to   { transform: scale(0); }
}

            
          
!
            
              class ExampleGame extends React.Component {
	// ReactJS (or should I say Javascript) constructor
	// Basically, I declare variables and states here
	constructor(props) {
		super(props);

		// ----- Constants
		this.fps          = 1000 / 30;
		this.rotateSpd    = 4;
		this.fireInterval = 300;
		this.fireSpd      = 0.15;
		this.spdPerSummon = 250;
		this.minSummonSpd = 500;
		this.zombieSpd    = 0.025;
		this.zombieDelay  = 2000;
		this.lifeCount    = 3;
		this.center       = {x: 4, y: 4};
		this.screen       = {width: 8, height: 8};
		this.turret       = {width: 0.8, height: 0.8};
		this.fire         = {width: 0.25, height: 0.25};
		this.zombie       = {width: 0.65, height: 1.2};
		this.noSummonArea = {x1: 2, x2: 7, y1: 2, y2: 7};

		this.state = {
			// ----- Rendering/Animation
			time: performance.now(),
			// ----- Events/Controls
			holdLeft: false,
			holdRight: false,
			// ----- Movement
			rotation: 0,
			lastFire: 0,
			summonSpd: 5000,
			summonTime: 0,
			// ----- Game Objects
			turret: [],
			fires: [],
			// ^ Data structure: {a: angle, x: top, y: left}
			zombies: [],
			// ^ Data structure: {a: angle, x: top, y: left,
			// c: className, d: delay, s: stopFlag}
			life: this.lifeCount,
			score: 0,
			// ----- Game Option
			pause: true,
			showTitle: true,
			showTryAgain: false,
			// ----- Debug
			debugText: ''
		};
		
		// this.gameLoop;
	}

	// ReactJS componentDidMount() method to initialize event listeners
	componentDidMount() {
		// Event listeners
		window.addEventListener('keydown', (evt) => {
			if (this.state.pause === true) {
				return false;
			}

			if (evt.keyCode === 32) {
				if (
					this.state.lastFire == 0 || (
						performance.now() - this.state.lastFire > this.fireInterval &&
						this.state.fires.length < 2
					)
				) {
					this.setState({lastFire: performance.now()});
					this.throwFire();
				}
			} else if (evt.keyCode === 37) {
				this.setState({holdLeft: true});
			} else if (evt.keyCode === 39) {
				this.setState({holdRight: true});
			}
		});

		window.addEventListener('keyup', (evt) => {
			if (evt.keyCode === 32 || evt.keyCode === 13) {
				if (this.state.showTitle === true) {
					if (this.state.showTryAgain === false) {
						this.setState({showTitle: false});
						this.setState({pause: false});

						// Trigger the animation start
						this.animate();
					} else {
						this.restartGame();
						
						this.setState({showTryAgain: false});
					}
				}
			} else if (evt.keyCode === 37) {
				if (this.state.pause === true) {
					return false;
				}

				this.setState({holdLeft: false});
			} else if (evt.keyCode === 39) {
				if (this.state.pause === true) {
					return false;
				}

				this.setState({holdRight: false});
			}
		});

		// Initialize Turry the turret's initial position.
		// He can't move anyway, so...
		this.setState({turret: [{
			x: this.center.x - (this.turret.width / 2),
			y: this.center.y - (this.turret.height / 2)
		}]});
	}

	// ----- Helpers/Methods

	// Returns the value of number as 'rem'
	remVal(value) {
		return `${value}rem`;
	}

	// Generate random numbers
	randomNum(value) {
		return Math.floor(Math.random() * Math.floor(value));
	}

	// The time for Turry to fire a fire
	throwFire() {
		let tmpFire = this.state.fires;
		let angle   = (this.state.rotation - 90) * Math.PI / 180;
		let half    = {w: this.fire.width / 2, h: this.fire.height / 2};

		tmpFire.push({
			a: angle,
			x: this.center.x - half.w + Math.cos(angle),
			y: this.center.y - half.h + Math.sin(angle)
		});

		this.setState({fires: tmpFire});
	}

	// Timeout in summoning Zoomy the Zombie
	summonZombieTrigger() {
		if (this.state.summonTime > this.state.summonSpd) {
			this.summonZombie();

			let nextSummonSpd = (this.state.summonSpd > this.minSummonSpd) ?
					this.state.summonSpd - 100 : this.minSummonSpd;

			this.setState({summonTime: 0});
			this.setState({summonSpd: nextSummonSpd});
		}
		else {
			this.setState({summonTime: this.state.summonTime + this.fps});
		}
	}

	// The time for Zoomy the zombie will be summoned
	summonZombie() {
		let tmpZombie = this.state.zombies;
		let half = {
			width: this.zombie.width / 2,
			height: this.zombie.height / 2
		};
		let random = {
			x: (this.randomNum(this.screen.width * 100) / 100) - half.width,
			y: (this.randomNum(this.screen.height * 100) / 100) - half.height
		};
		let addClass = (random.x > this.center.x) ? 'flip' : '';
		let angle    = 0;

		if (
			random.x > this.noSummonArea.x1 &&
			random.x < this.noSummonArea.x2 &&
			random.y > this.noSummonArea.y1 &&
			random.y < this.noSummonArea.y2
		) {
			this.summonZombie();

			return false;
		}

		let a = this.center.y - random.y;
		let b = this.center.x - random.x;

		angle = Math.atan2(a, b);

		tmpZombie.push({
			a: angle,
			x: random.x,
			y: random.y,
			c: addClass,
			d: performance.now(),
			s: false
		});

		this.setState({zombies: tmpZombie});
	}
	
	// Reset the game
	restartGame() {
		this.setState({time: performance.now()});
		this.setState({holdLeft: false});
		this.setState({holdRight: false});
		this.setState({rotation: 0});
		this.setState({lastFire: 0});
		this.setState({summonSpd: 5000});
		this.setState({summonTime: 0});
		this.setState({fires: []});
		this.setState({zombies: []});
		this.setState({life: this.lifeCount});
		this.setState({score: 0});
		this.setState({pause: true});
		this.setState({showTitle: true});
		this.setState({showTryAgain: false});
	}

	// ----- Collisions

	// When an object/s collided into the edge of the screen
	edgeCollision(i, arr, width, height) {
		let tmpArr = arr;
		let tmpObj = tmpArr[i];

		if (
			tmpObj.x + width < 0 ||
			tmpObj.y + height < 0 ||
			tmpObj.x > this.screen.width ||
			tmpObj.y > this.screen.height
		) {
			tmpArr.splice(i, 1);
		}

		return tmpArr;
	}

	// When an object/s collided into another object
	objectCollision(i, arr1, width1, height1, arr2, width2, height2, callback) {
		let tmpArr1 = arr1;
		let tmpArr2 = arr2;
		let tmpObj1 = tmpArr1[i];

		for (let j = 0; j < tmpArr2.length; j++) {
			let tmpObj2 = tmpArr2[j];

			if (
				typeof tmpObj1 !== 'undefined' &&
				tmpObj1.x + width1 > tmpObj2.x &&
				tmpObj1.x < tmpObj2.x + width2 &&
				tmpObj1.y + width1 > tmpObj2.y &&
				tmpObj1.y < tmpObj2.y + width2
			) {
				callback(i, j, tmpArr1, tmpArr2);

				break;
			}
		}

		return {fire: tmpArr1, zombie: tmpArr2};
	}

	// Call the possible collisions of Turry's fire
	fireCollision(i) {
		let tmpArr = this.edgeCollision(
			i,
			this.state.fires,
			this.fire.width,
			this.fire.height
		);
		let objArr = this.objectCollision(
			i,
			this.state.fires,
			this.fire.width,
			this.fire.height,
			this.state.zombies,
			this.zombie.width,
			this.zombie.height,
			(i, j, tmpArr1, tmpArr2) => {
				tmpArr1.splice(i, 1);

				var zombies = this.state.zombies;

				if (zombies[j].s === false) {
					this.setState({score: this.state.score + 1});
				}

				zombies[j].c = zombies[j].c + ' zombie-dying';
				zombies[j].s = true;

				this.setState({zombies: zombies});
			}
		);

		tmpArr = objArr.fire;

		this.setState({zombie: objArr.zombie});

		return tmpArr;
	}

	// Call the possible collisions of Zoomy
	zombieCollision(i) {
		let tmpZombie = this.edgeCollision(
			i,
			this.state.zombies,
			this.zombie.width,
			this.zombie.height
		);
		let objArr = this.objectCollision(
			i,
			this.state.zombies,
			this.zombie.width,
			this.zombie.height,
			this.state.turret,
			this.turret.width,
			this.turret.height,
			(i, j, tmpArr1, tmpArr2) => {
				let zombies = this.state.zombies;
				
				if (zombies[i].c.indexOf('zombie-hiding') < 0) {
					zombies[i].c = zombies[i].c.replace(/zombie\-walking/g, 'zombie-hiding');
					zombies[i].s = true;

					this.setState({zombies: zombies});
					this.setState({life: this.state.life - 1});
				}

				if (this.state.life === 0) {
					this.setState({pause: true});
					
					let tryAgainTimeout = setTimeout(() => {
						clearTimeout(tryAgainTimeout);
						
						// cancelAnimationFrame(this.gameLoop);
						
						this.setState({showTryAgain: true});
						this.setState({showTitle: true});
					}, 500);
				}
			}
		);

		return tmpZombie;
	}

	// ----- Animation

	// Animate when Turry changes its angle
	// Press LEFT key to turn anti-clockwise
	// Press RIGHT key to turn clockwise
	animateRotation() {
		if (this.state.holdLeft === true) {
			if (this.state.rotation > 0) {
				this.setState({rotation: this.state.rotation - this.rotateSpd});
			} else {
				this.setState({rotation: 360});
			}
		} else if (this.state.holdRight === true) {
			if (this.state.rotation < 360) {
				this.setState({rotation: this.state.rotation + this.rotateSpd});
			} else {
				this.setState({rotation: 0});
			}
		}
	}

	// Animate the movement of a/an o/object with array
	animateMoveByArray(arr, spd, collision, delay = 0, callback = null) {
		let tmpArr = arr;

		for (let i = 0; i < tmpArr.length; i++) {
			if (
				(delay > 0 &&
				performance.now() - tmpArr[i].d < delay) ||
				tmpArr[i].s === true
			) {
				continue;
			}

			tmpArr[i].x += spd * Math.cos(tmpArr[i].a);
			tmpArr[i].y += spd * Math.sin(tmpArr[i].a);

			tmpArr = collision(i);

			if (callback !== null) {
				callback(i);
			}
		}

		return tmpArr;
	}

	// Animate the movement of the fire when Turry fires it
	animateFire() {
		this.setState({
			fires: this.animateMoveByArray(
				this.state.fires,
				this.fireSpd,
				this.fireCollision.bind(this),
				0
			)
		});
	}

	// Animate the movement of Zoomy, because he wants to eat Turry's brain
	animateZombie() {
		this.setState({
			zombies: this.animateMoveByArray(
				this.state.zombies,
				this.zombieSpd,
				this.zombieCollision.bind(this),
				this.zombieDelay,
				(i) => {
					let zombies = this.state.zombies;

					if (
						zombies[i].c.indexOf('zombie-walking') < 0 &&
						zombies[i].c.indexOf('zombie-hiding') < 0
					) {
						zombies[i].c = zombies[i].c + ' zombie-walking';
					}

					this.setState({zombies: zombies});
				}
			)
		});
	}

	// The animation, or the game loop, or whatever it is called
	animate() {
		let gameLoop = requestAnimationFrame(this.animate.bind(this));
		
		if (this.state.pause === true) {
			cancelAnimationFrame(gameLoop);
		}

		// Perform animation for 30 frames per second
		// FPS is set at constructor()
		if (
			performance.now() - this.state.time > this.fps &&
			this.state.pause === false
		) {
			this.setState({time: performance.now()});

			this.animateRotation();
			this.animateFire();
			this.animateZombie();

			this.summonZombieTrigger();
		}
	}

	// ----- Rendering

	// Rendering of objects using array
	renderByArray(className, object, innerJSX = null, callback = null) {
		let objs     = object;
		let objArray = [];

		for (let i = 0; i < objs.length; i++) {
			let obj      = objs[i];
			let style    = {top: this.remVal(obj.y), left: this.remVal(obj.x)};
			let addClass = (typeof obj.c !== 'undefined') ?
				(`${className} ${obj.c}`) : className;

			if (callback === null) {
				objArray.push(
					<div className={addClass} style={style}>{innerJSX}</div>
				);
			} else {
				objArray.push(
					<div
						className={addClass}
						style={style}
						onAnimationEnd={callback.bind(this, i)}
					>{innerJSX}</div>
				);
			}
		}

		return objArray;
	}

	// Tender the fire when Turry shoots a fire
	renderFire() {
		return this.renderByArray('fire', this.state.fires);
	}

	// Render Turry the turret: The main character
	renderTurret() {
		let style = {transform: 'rotate(' + this.state.rotation + 'deg)'};

		return (
			<div className="turret" style={style}>
				<div className="gun"></div>
				<div className="body"></div>
			</div>
		);
	}

	// Render Zoomy the zombie: He's trying to eat Turry's brain (wut?)
	renderZombie() {
		return this.renderByArray(
			'zombie',
			this.state.zombies,
			<div className="zombie-wrapper">
				<div className="hole"></div>
				<div className="head">
					<div className="eyes"></div>
				</div>
				<div className="body"></div>
				<div className="arm right"></div>
				<div className="arm left"></div>
				<div className="leg right"></div>
				<div className="leg left"></div>
			</div>,
			(i, event) => {
				if (['zombie-fade-out', 'zombie-hiding'].indexOf(event.animationName) >= 0) {
					let zombies = this.state.zombies;

					zombies.splice(i, 1);

					this.setState({zombies: zombies});
				}
			}
		);
	}

	// Render Turry's life points
	renderLife() {
		let lifeArray = [];

		for (let i = 1; i <= this.lifeCount; i++) {
			let lifeClassName = (i <= this.state.life) ?
					'heart full' : 'heart empty';

			lifeArray.push(<div className={lifeClassName}></div>)
		}

		return (
			<div className="life">{lifeArray}</div>
		);
	}

	// Render the current score
	renderScore() {
		let score    = this.state.score.toString();
		let scoreArr = score.split('');
		let scoreElm = [];

		for (let i = 0; i < scoreArr.length; i++) {
			let scoreClassName = `char-${scoreArr[i]}`;

			scoreElm.push(<div className={scoreClassName}></div>);
		}

		return <div className="score">{scoreElm}</div>;
	}

	// Render the word
	renderWord(words, size = '') {
		let textSize  = (size !== '') ? (size + '-') : size;
		let tmpJSX    = [];
		let returnJSX = [];

		for (let i in words) {
			tmpJSX = [];
			
			for (let j in words[i]) {
				let textClassName = 'char-' + textSize + words[i][j];

				tmpJSX.push(<div className={textClassName}></div>);
			}
			
			returnJSX.push(
				<div className="title-content">{tmpJSX}</div>
			);
		}

		return returnJSX;
	}

	// Render the game title
	renderTitle() {
		let titleClass   = (this.state.showTitle === true) ? 'title' : 'title hide';
		let titleText    = (this.state.showTryAgain === false) ?
				['turret', 'shooting game'] : ['you lose'];
		let subTitleText = (this.state.showTryAgain === false) ?
				['shoot the never', 'ending zombies'] :
				['these zombies has', 'eaten your brain'];
		let startText    = (this.state.showTryAgain === false) ?
				[
					'press space to start',
					'',
					'directions',
					'press left to turn anti clockwise',
					'press right to turn clockwise',
					'press space to fire'
				] : ['press space to restart'];
		let titleJSX     = this.renderWord(titleText, 'large');
		let subTitleJSX  = this.renderWord(subTitleText, '');
		let startJSX     = this.renderWord(startText, 'small');

		return (
			<div className={titleClass}>
				<div className="game-title">
					{titleJSX}
				</div>
				<div className="game-title">
					{subTitleJSX}
				</div>
				<div className="game-title">
					{startJSX}
				</div>
			</div>
		);
	}

	// ReactJS' render() method
	render() {
		return (
			<div className="screen">
				<div className="debug">{this.state.debugText}</div>
				{this.renderZombie()}
				{this.renderFire()}
				{this.renderTurret()}
				{this.renderLife()}
				{this.renderScore()}
				{this.renderTitle()}
			</div>
		);
	}
}

ReactDOM.render(<ExampleGame />, document.querySelector('#example_game'));

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.

Console