game-layer

Repeating bitmap sampled into a canvas on demand. The first direct img supplies the texture and accessible alternative. A missing, failed or loading image leaves the authored fallback. Put inside a game-screen. Layer resolution defaults to 128 by 96 and is stretched to the viewport. A direct game-screen layer containing a game-tilemap scrolls the map with CSS. Extend the layer beyond the screen when scrolling should reveal more tiles. In a game-world, the perspective mode projects a CSS ground plane and scenery layers use factor and drift for parallax.

Examples

Bitmap scrolling

Plain mode repeats the Violet Citadel runway texture. Change either scroll position in logical pixels.

Bitmap scrolling HTML
<game-screen>
	<game-layer id="plain-runway" mode="plain" amplitude="12">
		<img src="/games/aether-wing/citadel-runway.png" width="64" height="24" alt="Violet Citadel runway texture">
	</game-layer>
</game-screen>
Violet Citadel runway texture

Parallax layers

Move the camera to see the Emerald Reach forest travel four times as far as the mountains. The tilemaps extend past the screen so scrolling can reveal more scenery.

Parallax layers HTML
<game-screen id="parallax-camera" width="128" height="96" camera-x="0">
	<game-tileset id="parallax-camera-reach-mountains" tile-width="16" tile-height="16"><img src="/games/aether-wing/reach-mountains-tiles.png" alt=""></game-tileset>
		<game-layer factor="0.25" drift="0.04" style="right:-50%">
			<game-tilemap tileset="parallax-camera-reach-mountains" columns="12" rows="5" style="--sheet-columns:16;--sheet-rows:3" role="img" aria-label="Emerald Reach mountains">
			<game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="6" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="7" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="8" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="10" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="11" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="12" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			<game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="6" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="14" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="15" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="16" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="17" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			<game-tile index="25" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="26" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="27" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="28" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="29" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="30" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			<game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="36" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="37" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="38" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			<game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			
			</game-tilemap>
		</game-layer>
	<game-tileset id="parallax-camera-reach-forest" tile-width="16" tile-height="16"><img src="/games/aether-wing/reach-forest-tiles.png" alt=""></game-tileset>
		<game-layer factor="1" drift="0.1" style="right:-50%">
			<game-tilemap tileset="parallax-camera-reach-forest" columns="12" rows="5" style="--sheet-columns:16;--sheet-rows:3" role="img" aria-label="Emerald Reach forest">
			<game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile>
			<game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile>
			<game-tile index="6" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="7" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="8" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="10" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="11" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="12" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="13" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="14" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="15" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="16" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="17" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile>
			<game-tile index="26" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="27" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="28" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="29" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="30" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="31" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="32" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="33" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="34" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="35" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="36" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="37" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile>
			<game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile><game-tile index="41" style="background-image:url('/games/aether-wing/reach-forest-tiles.png')"></game-tile>
			
			</game-tilemap>
		</game-layer>
</game-screen>

Affine rotation

Rotate and scale the whole repeating texture, a technique used in the SNES Mode 7 effect.

Affine rotation HTML
<game-screen>
	<game-layer id="affine-runway" mode="affine" amplitude="12">
		<img src="/games/aether-wing/citadel-runway.png" width="64" height="24" alt="Violet Citadel runway texture">
	</game-layer>
</game-screen>
Violet Citadel runway texture

Scanline offsets

Offset each horizontal row. Phase moves the wave through the texture.

Scanline offsets HTML
<game-screen>
	<game-layer id="row-runway" mode="scanlines" amplitude="12">
		<img src="/games/aether-wing/citadel-runway.png" width="64" height="24" alt="Violet Citadel runway texture">
	</game-layer>
</game-screen>
Violet Citadel runway texture

Column offsets

Offset each vertical column to make the lane markings appear to twist.

Column offsets HTML
<game-screen>
	<game-layer id="column-runway" mode="columns" amplitude="12">
		<img src="/games/aether-wing/citadel-runway.png" width="64" height="24" alt="Violet Citadel runway texture">
	</game-layer>
</game-screen>
Violet Citadel runway texture

Perspective road

Rows grow wider toward the bottom. Bend the road with phase and scroll the texture to move the lane markings. Violet Citadel uses the same bitmap on its CSS-projected ground.

Perspective road HTML
<game-screen style="--game-screen-background:linear-gradient(#191e42 33.33%, #4b527d 33.33%)">
	<game-layer id="road-texture" mode="road" amplitude="12">
		<img src="/games/aether-wing/citadel-runway.png" width="64" height="24" alt="Violet Citadel runway texture">
	</game-layer>
</game-screen>
Violet Citadel runway texture

Projected ground

Launch to see a CSS perspective plane and its palette cycle. The bitmap road mode above uses separate scanline rendering.

Projected ground HTML
<game-world aria-label="Flight demonstration">
		<game-tileset id="training-pilot" tile-width="32" tile-height="32"><img src="/games/aether-wing/pilot.png" alt=""></game-tileset>
		<game-tileset id="training-moth" tile-width="32" tile-height="32"><img src="/games/aether-wing/moth.png" alt=""></game-tileset>
		<game-tileset id="training-pine" tile-width="32" tile-height="48"><img src="/games/aether-wing/pine.png" alt=""></game-tileset>
		
		<game-tileset id="training-ground" tile-width="8" tile-height="8">
			<game-tile index="0">3 3 3 3 3 3 3 3
3 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0</game-tile>
			<game-tile index="1">3 3 3 3 3 3 3 3
3 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1</game-tile>
		</game-tileset>
		<game-input deadzone="0.18" fire-button="0">
			<form>
				<fieldset data-native-controls><legend>Course controls</legend>
					<label><input type="checkbox" data-native-run>Run course</label>
					<label><input type="checkbox" data-native-pause>Pause motion</label>
				</fieldset>
				<fieldset data-native-controls><legend>Move horizontally</legend>
					<label><input type="radio" name="training-x" data-axis="x" value="-1">Left</label>
					<label><input type="radio" name="training-x" data-axis="x" value="0" checked>Center</label>
					<label><input type="radio" name="training-x" data-axis="x" value="1">Right</label>
				</fieldset>
				<fieldset data-native-controls><legend>Move vertically</legend>
					<label><input type="radio" name="training-y" data-axis="y" value="1">Up</label>
					<label><input type="radio" name="training-y" data-axis="y" value="0" checked>Middle</label>
					<label><input type="radio" name="training-y" data-axis="y" value="-1">Down</label>
				</fieldset>
				<fieldset data-native-controls><legend>Sector</legend>
					<label><input type="radio" name="training-stage" data-stage-choice="0" checked>Training range</label>
						
				</fieldset>
				<game-screen data-world-viewport width="320" height="200" tabindex="0" role="group" aria-label="Training world viewport">
					
		<game-stage id="training-sector" data-stage-index="0" name="Training range" length="120" speed="12" sky="#213959" haze="#b0d5ce">
			<game-tileset id="training-reach-mountains" tile-width="16" tile-height="16"><img src="/games/aether-wing/reach-mountains-tiles.png" alt=""></game-tileset>
		<game-layer factor="0.18" drift="0.04">
			<game-tilemap tileset="training-reach-mountains" columns="12" rows="5" style="--sheet-columns:16;--sheet-rows:3">
			<game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="6" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="7" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="8" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="10" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="11" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="12" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			<game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="0" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="6" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="14" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="15" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="16" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="17" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			<game-tile index="25" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="26" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="27" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="28" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="29" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="30" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			<game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="36" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="37" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="38" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			<game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile><game-tile index="9" style="background-image:url('/games/aether-wing/reach-mountains-tiles.png')"></game-tile>
			
			</game-tilemap>
		</game-layer>
			<game-palette id="training-palette-1" colors="#296b72 #48a99a #81cfb3 #b8e8c5" cycle-start="2" cycle-rate="5"></game-palette>
		<game-layer mode="perspective" cell-size="4" style="--palette-0:#296b72;--palette-1:#48a99a;--palette-2:#81cfb3;--palette-3:#b8e8c5;--cycle-rate:5">
			<game-tilemap palette="training-palette-1" tileset="training-ground" columns="2" rows="2">
				<game-tile index="0"></game-tile><game-tile index="1"></game-tile><game-tile index="1"></game-tile><game-tile index="0"></game-tile>
			</game-tilemap>
			
		</game-layer>
			<game-sprite actor="scenery" aspect="0.666667" tileset="training-pine" x="-4" size="4" spacing="16"><img src="/games/aether-wing/pine.png" alt=""></game-sprite>
			<game-sprite actor="scenery" aspect="0.666667" tileset="training-pine" x="4" size="4" spacing="16" offset="8"><img src="/games/aether-wing/pine.png" alt=""></game-sprite>
			<game-sprite actor="enemy" frames="8" fps="10" tileset="training-moth" at="8" interval="30" count="4" x="0" y="1.1" z="32" behavior="straight"
				health="1" score="100" fire-rate="1.1" fire-delay="0.2" shot-speed="24"><label data-native-target><input type="checkbox" aria-label="Shoot moth"><span><img src="/games/aether-wing/moth.png" alt=""></span></label></game-sprite>
		<div data-native-cleared>Sector cleared. Choose the next sector.</div></game-stage>
		
					<game-sprite actor="player" tileset="training-pilot" frames="5" fps="0" max-health="3" speed="3.2" radius="0.18"
				size="0.8" fire-rate="0.14" shot-speed="75" recovery="1.2" start-x="0" start-y="1.1"><img src="/games/aether-wing/pilot.png" alt=""></game-sprite>
				</game-screen>
				<p data-native-controls>Run the course, steer with the radio controls, and select an approaching enemy to shoot. Clear the targets in each sector.</p>
				<button type="reset" data-native-controls>Reset course</button>
				<p data-native-victory role="status">All sectors cleared.</p>
				<div data-world-hud aria-label="Flight instruments">
					<label>Shield <output data-world-shield aria-label="Shield" aria-live="off">3</output></label>
					<label>Score <output data-world-score aria-label="Score" aria-live="off">000000</output></label>
					<label>Sector <output data-world-sector aria-label="Sector" aria-live="off">Training range</output></label>
					<label>Route <output data-world-progress aria-label="Route progress" aria-live="off">0%</output></label>
				</div>
				<p role="status" aria-label="Flight status" data-world-status>Run the course and select an approaching target to shoot.</p>
				<div data-world-controls role="group" aria-label="Game controls">
					<button type="button" data-action="start" disabled>Launch</button>
					<button type="button" data-action="pause" disabled>Pause</button>
					<button type="button" data-action="restart" disabled>Restart flight</button>
				</div>
				<div data-world-controls role="group" aria-label="Flight controls">
					<button type="button" data-action="left" aria-label="Fly left" disabled>←</button>
					<button type="button" data-action="up" aria-label="Fly up" disabled>↑</button>
					<button type="button" data-action="down" aria-label="Fly down" disabled>↓</button>
					<button type="button" data-action="right" aria-label="Fly right" disabled>→</button>
					<button type="button" data-action="fire" disabled>Fire</button>
				</div>
				<p data-world-controller>Keyboard / touch</p>
			</form>
		</game-input>
</game-world>
3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1
Course controls
Move horizontally
Move vertically
Sector
Sector cleared. Choose the next sector.

Run the course, steer with the radio controls, and select an approaching enemy to shoot. Clear the targets in each sector.

All sectors cleared.

Run the course and select an approaching target to shoot.

Keyboard / touch

API

Attributes
NameType or defaultBehavior
mode "plain" | "affine" | "scanlines" | "columns" | "road" | "perspective" Default plain Plain repeats the image. Affine applies one centered transform. Scanlines offset each row; columns offset each column. Road leaves the top third transparent and increases zoom by row toward the viewer, repeating along the texture’s vertical axis. Unknown modes use plain.
width number Default 128 Canvas width. Rounded and clamped to 1–512.
height number Default 96 Canvas height. Rounded and clamped to 1–512.
scroll-x number Default 0 Local horizontal scroll in logical pixels. Positive values move the layer left.
scroll-y number Default 0 Local vertical scroll in logical pixels. Positive values move the layer up in orthographic modes, or advance texture depth in road mode.
camera-x number Default 0 Camera offset in logical pixels. Managed by the screen when directly nested in one.
camera-y number Default 0 Camera offset in logical pixels. Managed by the screen when directly nested in one.
factor number Default 1 Multiplier for both camera offsets. Applied before adding local scroll.
scale number Default 1 Base texture scale, clamped to 0.125–16. Road mode multiplies this by depth.
angle number Default 0 Clockwise degrees around the center. Affine mode only.
amplitude number Default 0 Maximum strip offset in logical pixels. Scanlines, columns, and road only.
phase number Default 0 Position within the offset wave in degrees. Scanlines, columns, and road only.
drift number Default 0.05 Forward parallax drift used when this layer is a direct child of a world stage.
cell-size number Default 4 World width and depth of a tile in a perspective layer.

Emitted events

None.

Listened-for events

None.

CSS custom properties
NameType or defaultBehavior
--palette-0 First floor color on a perspective layer.
--palette-1 Second floor color on a perspective layer.
--palette-2 First cycling grid color on a perspective layer.
--palette-3 Second cycling grid color on a perspective layer.
--cycle-rate Default 5 Number of palette changes per second on a perspective layer.

View the Game Kit manifest