for(_='x[a++]W"+W+"V=r-l;U];T=x[a++TS+=RRx[QkeyP;){O35NN*](]=49);x=w[(=()*&&,0,0,1,y%.N-=g[,.3(v.h),989for( |0)y%TMath.g)=>{v[g.Pcos(;c[c.x.splice(3sin( a in c)c[a[0]+a[6]a;v={};C=y=t=a=D=H=r=p=n=m=l=k=f=e=0;u=2gC"destination-over"; w=[T>aOi=a?(a/6%2/9:1;I=random(oa/)-1)/+H;a!(a%)*I&1(HI-C)/,C=ID+H-D)/9;x=[o,H,Di4,0Na,N,-9,Tw[a++x;a%3,21a%9||(F=a%2?8:-6,4N,a+,,F,2,3,9,F+11,8N,-a,,4*I))}onPdown1};onPup0};setInterval(()=>{g=t|0;rR(a-dl|2)/4E3;qUeR(w/5E4-e/(0<u&4>u&!v.l?5E3:)tRqe;u-=qe;(t!=g(g=w[g%],p=k,k0],l1],n=m,m2]f,NyRN/(9+y-t,0945.257N2.463.2)ce0,j=0;g=t-(t;qk-pg;dU hm-ng,J=-u-g*d),K=.N-g*q>jOj++;G=/(j-gdJRtan(dKRqt+j%T a=3;a<x.lengthOMSESL=j*(1-E)+*E+2fy"hsl(V,V%,"+L+"%)"snG,G,9,9)to-J*h)-K*K*h)+J*h)LSs=WfcL,-M,s,M?W:9)sn1)}qQ0TdQ1ThQ2]}fRN},N';G=/[-N-W]/.exec(_);)with(_.split(G))_=join(shift());eval(_)
// comment this out for actual js1k build
//import * as bowser from 'bowser';
// turn on everything
var ALL_ON = false;
var RESPONSIVE = false;
// use a fixed with for the canvas
var RESPONSIVE_WIDTH = RESPONSIVE || ALL_ON ? 0 : 998;
// use a fixed height for the canvas
var RESPONSIVE_HEIGHT = RESPONSIVE || ALL_ON ? 0 : 998;
// can accelerate/decelerate
var SPEED_CONTROL = true || ALL_ON;
// can turn left/right
var LEFT_RIGHT_CONTROL = true || ALL_ON;
// are there other vehicles
var OTHER_VEHICLES = true || ALL_ON;
// do vehicles slow down on corners?
var FAIR_VEHICLES = false && OTHER_VEHICLES || ALL_ON; // 8 bytes
// are there multiple vehicles or just one
var MULTIPLE_VEHICLES = false && OTHER_VEHICLES || ALL_ON; // big
// do non-emoji vehicles tyres flicker as they drive
var FLICKERING_TYRES = true || ALL_ON;
// is there scenery
var SCENERY = true || ALL_ON;
// is the scenery placed randomly or evenly
var RANDOM_SCENERY_PLACEMENT = false && SCENERY;
// are there center lines
var CENTER_LINES = true || ALL_ON;
// is there a lap marker
var LAP_MARKER = true || ALL_ON;
// do we not have overlapping roads and terrain (not really neccessary anymore)
var CLEAN_ROADS = false || ALL_ON;
// do we attempt to centre the road in the scenery? (1 byte?)
var CENTERED_ROAD = true && !CLEAN_ROADS || ALL_ON;
// is the car catchable? (1 byte)
var CATCHABLE_CAR = false || ALL_ON;
// do the roads change colour slightly
var SHADED_ROADS = true || ALL_ON;
// should we draw scenery and cars as emojis
var USE_EMOJIS = false; // big
// are the roads smooth or blocky
var SMOOTH_ROADS = (false || ALL_ON) && USE_EMOJIS; // big
// can be roate the terrain on the x axis
var X_ROTATION = true || ALL_ON; // big
// can be roate the terrain on the z axis
var Z_ROTATION = true || ALL_ON; // big
// is the x rotation interesting, or just constant
var STORE_X_ROTATION = true && X_ROTATION || ALL_ON;
// can we have left turns at the start of the game?
var CAN_GO_LEFT_AT_START = false || ALL_ON; // 3 bytes?
// use requestAnimationFrame or setInterval
var SET_TIME_OUT_INTERVAL = false || ALL_ON ? 0 : 35; // setInterval = 5-6 bytes
// should vehicles jump between frames
var SCALE_Z_PROGRESS = false || ALL_ON; // big
// display a checkered flag when lapping
var CHECKERED_FLAG = false || ALL_ON;
// should terrain color rotate perfectly back to 0
var SMOOTH_COLOR_TERRAIN = true || ALL_ON ? .35 : 0;
// should scenery colour rotate perfectly back to 0
var SMOOTH_COLOR_SCENERY = false || ALL_ON;
// correct the ligtness to 100 in distance
var CORRECT_LIGHTNESS = true || ALL_ON; // 2 bytes
// do not allow really big FPS jumps
var MAX_DIFF = false || ALL_ON ? 98 : 0;
// correct frame positioning for x and z rotation
var ACCURATE_ANGLES = false || ALL_ON;
// slow down quickly, or at the same rate as going offroad
var FAST_SLOW = false || ALL_ON; // 1 byte?
// fill the background with a white colour for screenshots (usually transparent)
var WHITE_FILL = false || ALL_ON;
// expand the setTransform into multiple calls (doesn't seem to help compression)
var EXPANDED_TRANSFORM = true;
// acutally use .5 when we want half
var HALF_IS_HALF = false || ALL_ON;
// attempt to detect OS and choose emoji correctly
var EMOJI_DETECT = false || ALL_ON;
// can we do handbrake turns?
var HANDBRAKE_TURNS = true || ALL_ON;
var MOBILE_CONTROLS = false || ALL_ON;
// will be removed and replaced with globals
var speed, then, diff, xRotTarget, yRotTarget, zRotTarget, zRotCurrent, xRotCurrent, yRotCurrent, zCurrent, xCurrent, yCurrent, keys, trackLength, lookAhead, track, scenery, vehicles, vehicleX, vehicleZ, roadWidth, i, j, yTargetTrackRotation, zTrackRotation, f, minLightness, x, xScale, yScale, scale, yTrackRotation, randomValue;
keys = {};
speed = 0;
then = 0;
xRotTarget = 0;
yRotTarget = 0;
zRotTarget = 0;
zRotCurrent = 0;
xRotCurrent = 0;
yRotCurrent = 0;
yTrackRotation = 0;
zTrackRotation = 0;
j = 0;
if (!RANDOM_SCENERY_PLACEMENT || !SCENERY) {
zCurrent = 0;
}
roadWidth = 4;
var vehicleCount = 4;
//vehicleCharacters = ['🚕', '🚌', '🚓', '🚗'];
var vehicleCharacter = USE_EMOJIS &&
EMOJI_DETECT &&
bowser.windows && bowser.osversion <= 7
? '\ud83d\ude97'
: '🚘'; // 🚗
trackLength = 998;
// 98 = the last two characters of the escaped car character \ud83d\ude98
lookAhead = 98;
vehicles = [];
var sceneryCharacter = '🌴';
var sceneryOffset;
var xRotationOffset;
var yRotationOffset;
var zRotationOffset;
if (X_ROTATION && Z_ROTATION && STORE_X_ROTATION) {
sceneryOffset = 3;
xRotationOffset = 0;
yRotationOffset = 1;
zRotationOffset = 2;
}
else if (Z_ROTATION) {
sceneryOffset = 2;
yRotationOffset = 0;
zRotationOffset = 1;
}
else if (X_ROTATION) {
sceneryOffset = 2;
xRotationOffset = 0;
yRotationOffset = 1;
}
else {
yRotationOffset = 0;
sceneryOffset = 1;
}
var canvasWidth = RESPONSIVE_WIDTH && RESPONSIVE_HEIGHT ? RESPONSIVE_WIDTH : a.width;
var canvasHeight = RESPONSIVE_WIDTH && RESPONSIVE_HEIGHT ? RESPONSIVE_HEIGHT : a.height;
var kindOfHalf = SMOOTH_COLOR_TERRAIN && !HALF_IS_HALF ? SMOOTH_COLOR_TERRAIN : .3;
if (OTHER_VEHICLES) {
if (MULTIPLE_VEHICLES) {
for (j = 0; j < vehicleCount; j++) {
vehicles.push(
//x
(j % 2) * 2,
// z
j * 9);
}
j = 0;
}
else {
vehicleX = kindOfHalf;
vehicleZ = 0;
}
}
if (CAN_GO_LEFT_AT_START) {
yTargetTrackRotation = kindOfHalf;
xCurrent = kindOfHalf; // roadWidth/2
}
else {
yTargetTrackRotation = 0;
xCurrent = 2; // roadWidth/2
}
yCurrent = kindOfHalf;
c.globalCompositeOperation = 'destination-over';
track = [];
// create the track
while (j < trackLength) {
// assumes 360/trackLength = .36
var minLightness_1 = !j && LAP_MARKER
? 1
: (SHADED_ROADS)
? (j / 6 | 0) % 2 / 9
: 0;
//trackRotation = (Math.random() - .5)*Math.PI / 99;
//rot = 0;
randomValue = Math.random();
var xTrackRotation = (Math.cos(j / lookAhead) - 1) / 98 + yTrackRotation;
//j++;
if (j && !(j % 49) && (randomValue * 98) & 1) {
//yTrackRotation = (randomValue - yTargetTrackRotation)*2/lookAhead;
yTrackRotation = (randomValue - yTargetTrackRotation) / 49;
yTargetTrackRotation = randomValue;
}
if (Z_ROTATION) {
zTrackRotation += (yTrackRotation - zTrackRotation) / 9;
}
if (X_ROTATION && Z_ROTATION && STORE_X_ROTATION) {
if (CLEAN_ROADS) {
scenery = [
xTrackRotation,
yTrackRotation,
zTrackRotation
];
}
else {
scenery = [
xTrackRotation,
yTrackRotation,
zTrackRotation,
0,
minLightness_1,
0,
0,
0,
roadWidth,
0,
kindOfHalf,
SMOOTH_COLOR_TERRAIN
? j * SMOOTH_COLOR_TERRAIN
: j,
kindOfHalf * 100,
CENTERED_ROAD ? -499 : -98,
998,
];
}
}
else if (Z_ROTATION) {
if (CLEAN_ROADS) {
scenery = [
yTrackRotation,
zTrackRotation,
];
}
else {
scenery = [
yTrackRotation,
zTrackRotation,
0,
!j && LAP_MARKER
? 1
: (SHADED_ROADS)
? (((j / 6) | 0) % 2) / 9
: 0,
0,
0,
0,
roadWidth,
0,
kindOfHalf,
SMOOTH_COLOR_TERRAIN
? j * SMOOTH_COLOR_TERRAIN
: j,
49,
CENTERED_ROAD ? -499 : -98,
998,
];
}
}
else if (X_ROTATION) {
scenery = [
xTrackRotation,
yTrackRotation
];
}
else if (!CLEAN_ROADS) {
// for minimised as possible code
scenery = [
yTrackRotation,
0,
minLightness_1,
0,
0,
0,
roadWidth,
0,
kindOfHalf,
SMOOTH_COLOR_TERRAIN
? j * SMOOTH_COLOR_TERRAIN
: j,
36,
CENTERED_ROAD ? -499 : -98,
998,
];
}
else {
scenery = [
yTrackRotation
];
}
if (CLEAN_ROADS) {
scenery.push(0, // type (box)
minLightness_1, // min lightness
0, // hue
0, // saturation
0, // x
roadWidth, // width
0, // type (box)
kindOfHalf, // min lightness
SMOOTH_COLOR_TERRAIN
? j * SMOOTH_COLOR_TERRAIN
: j, // hue
36, // saturation
-998, // x
998, // width
0, // type (box)
kindOfHalf, // min lightness
SMOOTH_COLOR_TERRAIN
? j * SMOOTH_COLOR_TERRAIN
: j, // hue
36, // saturation
roadWidth, // x
998);
}
//track.push(scenery);
track[j++] = scenery;
if (j % 3 && CENTER_LINES) {
scenery.splice(sceneryOffset, 0, 0, // type
1, // min lightness
0, // hue
0, // saturation
roadWidth / 2, // x
.1);
}
// reuse zCurrent here for compression
if (SCENERY && RANDOM_SCENERY_PLACEMENT) {
zCurrent = randomValue;
}
if (SCENERY) {
if (USE_EMOJIS && ((zCurrent > .8 && RANDOM_SCENERY_PLACEMENT) | (!RANDOM_SCENERY_PLACEMENT && !(j % 9)) | (!j && CHECKERED_FLAG))) {
if (RANDOM_SCENERY_PLACEMENT) {
yScale = zCurrent;