Code edit (23 edits merged)
Please save this source code
User prompt
add a global array levelConfigs that contains an object for each level. each object is the config of a level and have the following properties : name, coinValue, baseSpeed
Code edit (1 edits merged)
Please save this source code
Code edit (2 edits merged)
Please save this source code
User prompt
in decoration reset log // Add left & right startX & endX here
Code edit (1 edits merged)
Please save this source code
User prompt
inside Decoration replace all leftEndX by self.leftEndX
User prompt
Please fix the bug: 'ReferenceError: leftStartX is not defined' in or related to this line: 'self.x = leftStartX;' Line Number: 259
User prompt
in Decoration, make leftEndX a property self.leftEndX; don't forget any previous ref
User prompt
Please fix the bug: 'ReferenceError: leftStartX is not defined' in or related to this line: 'leftEndX = leftStartX - xOffset * rand;' Line Number: 254
User prompt
Please fix the bug: 'ReferenceError: leftStartX is not defined' in or related to this line: 'var leftEndX = leftStartX - xOffset * (1.5 + rand);' Line Number: 184
User prompt
in Decoration, make leftStartX a property self.leftStartX
Code edit (8 edits merged)
Please save this source code
User prompt
Make the killing hit flash last longer
Code edit (1 edits merged)
Please save this source code
Code edit (8 edits merged)
Please save this source code
User prompt
There's a problem for decorations, they sometimes appear with a big size, not respecting the height dependency on progress. can you find why ?
Code edit (1 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
User prompt
add a global nbDecorations
Code edit (5 edits merged)
Please save this source code
User prompt
in Decoration update, also log y
Code edit (4 edits merged)
Please save this source code
User prompt
in decoration class reset(), log assetIndex and size
User prompt
pass i index to Decoration constructor and store it in an index property
/****
* Classes
****/
// Assets will be automatically created and loaded during gameplay
// Coin class
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin1', {
anchorX: 0.5,
anchorY: 0.5,
visible: currentCoinType == 0
});
var coinGraphics2 = self.attachAsset('coin2', {
//'dollarsBundle'
anchorX: 0.5,
anchorY: 0.5,
visible: currentCoinType == 1
});
var speed = 5;
var startY = roadTop + 50;
var endY = startY + roadHeight;
var leftStartX = 1024 - 100;
var leftEndX = 1024 - 650;
var rightStartX = 1024 + 100;
var rightEndX = 1024 + 650;
var startSize = 2;
var endSize = 140;
coinGraphics.width = startSize;
coinGraphics.height = startSize;
coinGraphics2.width = startSize;
coinGraphics2.height = startSize;
self.pathIndex = 0;
self.update = function () {
// Road should animate even if the game hasn't started
if (!isPlaying || isKilled) {
return;
}
self.progress = Math.max(0, self.y - startY) / (endY - startY); // Update progress property
coinGraphics.width = startSize + (endSize - startSize) * self.progress;
coinGraphics.height = startSize + (endSize - startSize) * self.progress;
coinGraphics2.width = startSize + (endSize - startSize) * self.progress;
coinGraphics2.height = startSize + (endSize - startSize) * self.progress;
var newSpeed = currentSpeed; // + 10 * self.progress;
var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3);
newSpeed = tempSpeed;
self.y += newSpeed;
// Move innerLineLeft x progressively to innerLeftLineEndX
if (self.pathIndex == 0 && self.x != leftEndX) {
self.x = leftStartX + (leftEndX - leftStartX) * self.progress;
}
if (self.pathIndex == 2 && self.x != rightEndX) {
self.x = rightStartX + (rightEndX - rightStartX) * self.progress;
}
if (self.y > endY + endSize / 2) {
self.reset();
}
// Check for collision with player
if (!player.isJumping && self.y > 2500 && self.y < 2732 && player.shadow.intersects(self)) {
score += 1;
coinsCollected += 1; // Increment coins collected counter
if (currentLevel == 1) {
scoreTxt.setText(score + "¢");
} else {
scoreTxt.setText("$" + score);
}
LK.effects.flashObject(player, 0xffd700, 500); // Flash gold for 0.5 seconds
self.reset();
// Increase speed every 3 coins collected
if (coinsCollected % nextCoinTypeThreshold === 0 && currentSpeed < maxSpeed) {
currentSpeed += 3; // Increase speed by 3
}
if (coinsCollected >= nextCoinTypeThreshold) {
currentCoinType = 1;
}
}
};
self.reset = function () {
self.y = startY;
self.progress = 0; // Initialize progress property
coinGraphics.width = startSize;
coinGraphics.height = startSize;
coinGraphics2.width = startSize;
coinGraphics2.height = startSize;
self.pathIndex = Math.floor(Math.random() * 3);
coinGraphics.visible = currentCoinType == 0;
coinGraphics2.visible = currentCoinType == 1;
if (self.pathIndex === 0) {
self.x = leftStartX;
} else if (self.pathIndex === 2) {
self.x = rightStartX;
} else {
self.x = 1024;
}
};
});
// CoinAnimation class
var CoinAnimation = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin1', {
anchorX: 0.5,
anchorY: 0.5,
visible: currentCoinType == 0
});
var coinGraphics2 = self.attachAsset('coin2', {
anchorX: 0.5,
anchorY: 0.5,
visible: currentCoinType == 1
});
// Initialize velocity and gravity
self.vx = (Math.random() < 0.5 ? -1 : 1) * 5; // Random horizontal velocity
self.vy = -15; // Initial vertical velocity
self.gravity = 0.5; // Gravity effect
self.update = function () {
self.vy += self.gravity; // Apply gravity to vertical velocity
self.x += self.vx; // Update horizontal position
self.y += self.vy; // Update vertical position
self.alpha -= 0.0035; // Fade out the coin
if (currentCoinType == 0) {
coinGraphics.alpha = 1;
coinGraphics2.alpha = 0;
} else if (currentCoinType == 1) {
coinGraphics.alpha = 0;
coinGraphics2.alpha = 1;
}
if (self.alpha <= 0) {
self.destroy(); // Remove the coin when it becomes invisible
}
};
});
// Decoration class
var Decoration = Container.expand(function (index) {
var self = Container.call(this);
self.index = index;
var assets = ['decoration_1_1', 'decoration_1_2'];
self.assets = assets.map(function (assetId) {
return self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
visible: false // Initially set all assets to invisible
});
});
var speed = 5;
var startY = roadTop + 50;
var endY = startY + roadHeight;
var xOffset = 2048;
var baseLeftStartX = 780;
var rand = Math.random();
var leftStartX = baseLeftStartX - rand * xOffset / 2;
var leftEndX = leftStartX - xOffset * (1 + rand);
var baseRightStartX = 1280;
var rightStartX = baseRightStartX + rand * xOffset / 2;
var rightEndX = rightStartX + xOffset * (1 + rand);
self.assetWidthRatios = [100 / 300, 1];
self.endSizes = [600, 400];
var startSize = 1;
self.assetIndex = Math.floor(Math.random() * self.assets.length);
mainGraphics = self.assets[self.assetIndex];
mainGraphics.width = startSize;
mainGraphics.height = startSize;
self.pathIndex = 0;
self.update = function () {
if (isKilled) {
return;
}
var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf;
mainGraphics.tint = newTint;
self.progress = Math.max(0, self.y - startY) / (endY - startY); // Update progress property
//mainGraphics = self.assets[self.assetIndex];
mainGraphics.height = startSize + (self.endSizes[self.assetIndex] - startSize) * self.progress;
mainGraphics.width = mainGraphics.height * self.assetWidthRatios[self.assetIndex];
var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3);
var newSpeed = currentSpeed; // + 10 * self.progress;
newSpeed = tempSpeed * 1; // TEMP DEBUG !!!
self.y += newSpeed;
// Move innerLineLeft x progressively to innerLeftLineEndX
if (self.pathIndex == 0 && self.x != leftEndX) {
self.x = leftStartX + (leftEndX - leftStartX) * self.progress;
}
if (self.pathIndex == 1 && self.x != rightEndX) {
self.x = rightStartX + (rightEndX - rightStartX) * self.progress;
}
if (self.y > endY + self.endSizes[self.assetIndex] / 2) {
//self.y = -startSize; // Move obstacle back to the top
self.reset();
}
};
self.reset = function () {
self.y = startY;
rand = Math.random();
self.progress = 0; // Initialize progress property
self.assetIndex = Math.floor(Math.random() * self.assets.length);
self.assets.forEach(function (asset, index) {
asset.visible = index === self.assetIndex;
});
mainGraphics = self.assets[self.assetIndex];
mainGraphics.height = startSize;
mainGraphics.width = mainGraphics.height * self.assetWidthRatios[self.assetIndex];
leftStartX = baseLeftStartX - rand * xOffset / 2;
leftEndX = leftStartX - xOffset * (1 + rand);
rightStartX = baseRightStartX + rand * xOffset / 2;
rightEndX = rightStartX + xOffset * (1 + rand);
self.pathIndex = Math.floor(rand * 2);
if (self.pathIndex === 0) {
self.x = leftStartX;
} else {
self.x = rightStartX;
}
};
});
var Killer = Container.expand(function () {
var self = Container.call(this);
var assets = ['killer3'];
self.assetIndex = Math.floor(Math.random() * assets.length);
var randomAsset = assets[self.assetIndex];
var killerGraphics = self.attachAsset(randomAsset, {
anchorX: 0.5,
anchorY: 0.5
});
var speed = 5;
var startY = roadTop - 1;
var endY = startY + roadHeight;
var leftStartX = 1024 - 100;
var leftEndX = 1024 - 650;
var rightStartX = 1024 + 100;
var rightEndX = 1024 + 650;
var startSize = 1;
var endSize = 800;
var assetHeightRatio = 500 / 400;
killerGraphics.width = startSize;
killerGraphics.height = startSize;
self.pathIndex = 0;
self.inactive = true;
self.inactiveStartTime = Date.now();
self.update = function () {
if (!isPlaying) {
return;
}
var currentTime = Date.now();
if (self.inactive) {
if (currentTime - self.inactiveStartTime >= killerDelay) {
self.inactive = false;
}
return;
}
if (!isKilled && player && self.y > 2500 && self.y < 2732 && player.shadow.intersects(self)) {
isKilled = true;
player.visible = false;
LK.effects.flashScreen(0xff0000, 1000);
// Spawn MurderShape at player's last position
var murderShape = new MurderShape();
murderShape.x = player.x;
murderShape.y = playerBaseY;
murderShape.fixPosition();
game.addChildAt(murderShape, game.getChildIndex(road) + 1);
return;
}
self.progress = Math.max(0, self.y - startY) / (endY - startY);
killerGraphics.width = startSize + (endSize - startSize) * self.progress;
debugTxt.setText(self.progress.toFixed(2));
killerGraphics.height = assetHeightRatio * killerGraphics.width;
var tempSpeed = currentSpeed * 0.5 + currentSpeed * (self.progress * 5);
var newSpeed = currentSpeed * 5;
newSpeed = tempSpeed * 1;
self.y += newSpeed;
if (self.pathIndex == 0 && self.x != leftEndX) {
self.x = leftStartX + (leftEndX - leftStartX) * self.progress;
}
if (self.pathIndex == 2 && self.x != rightEndX) {
self.x = rightStartX + (rightEndX - rightStartX) * self.progress;
}
if (self.y > endY + endSize / 2) {
self.reset();
}
};
self.reset = function () {
self.y = startY;
self.progress = 0;
killerGraphics.width = startSize;
killerGraphics.height = startSize;
self.pathIndex = Math.floor(Math.random() * 3);
if (self.pathIndex === 0) {
self.x = leftStartX;
} else if (self.pathIndex === 2) {
self.x = rightStartX;
} else {
self.x = 1024;
}
self.inactive = true;
self.inactiveStartTime = Date.now();
};
});
var Landscape = Container.expand(function () {
var self = Container.call(this);
var landscapeGraphics = self.attachAsset('landscape2', {
anchorX: 0.5,
anchorY: 0.0
});
var gradientGraphics = self.attachAsset('gradient', {
anchorX: 0.5,
anchorY: 0.0,
scaleY: -1,
y: 1050,
blendMode: 2,
alpha: 0.5,
tint: 0xFFFFFF,
height: 10
});
self.x = 2048 / 2; // Center horizontally
self.y = 0; // Position at the top
self.update = function () {
var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf;
landscapeGraphics.tint = newTint; // Apply reduced tint to the road based on the intensity
//debugTxt.setText(intensityHalf.toFixed(2));
};
});
var MurderShape = Container.expand(function () {
var self = Container.call(this);
var murderShapeGraphics = self.attachAsset('murderShape', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// MurderShape does not need to update its position or behavior
};
self.fixPosition = function () {
if (self.x < 600) {
self.x += 150;
} else if (self.x > 1400) {
self.x -= 150;
}
};
});
// Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var assets = ['obstacle1', 'obstacle2', 'obstacle3'];
self.assetIndex = Math.floor(Math.random() * assets.length);
var randomAsset = assets[self.assetIndex];
var obstacleGraphics = self.attachAsset(randomAsset, {
anchorX: 0.5,
anchorY: 0.5
});
var speed = 5;
var startY = roadTop + 50;
var endY = startY + roadHeight;
var leftStartX = 1024 - 100;
var leftEndX = 1024 - 650;
var rightStartX = 1024 + 100;
var rightEndX = 1024 + 650;
var innerLeftLineStartX = -150;
var innerLeftLineEndX = -390;
var startSize, endSize;
if (self.assetIndex == 0) {
startSize = 3;
endSize = 350;
} else if (self.assetIndex == 1) {
startSize = 1;
endSize = 140;
} else if (self.assetIndex == 2) {
startSize = 2;
endSize = 250;
}
obstacleGraphics.width = startSize;
obstacleGraphics.height = startSize;
self.pathIndex = 0;
self.update = function () {
if (!isPlaying || isKilled) {
return;
}
// Check for collision with player
var currentTime = Date.now();
if (currentTime - lastObstacleHitTime > immunityDelay && player && !player.isJumping && self.y > 2500 && self.y < 2732 && player.shadow.intersects(self)) {
lastObstacleHitTime = currentTime; // Update the last hit time
// Make player flash red for 1 second
LK.effects.flashObject(player, 0xff0000, 1000);
// Add coin animation only if score is greater than 0
if (score > 0) {
var coinAnimation = new CoinAnimation();
coinAnimation.x = player.x;
coinAnimation.y = player.y;
game.addChild(coinAnimation);
}
// Reduce score by 1
score = Math.max(0, score - 1);
if (currentLevel == 1) {
scoreTxt.setText(score + "¢");
} else {
scoreTxt.setText("$" + score);
}
console.log("Obstacle y:", self.y);
// Reduce currentSpeed by a factor (e.g., 0.8)
console.log("Old speed :", currentSpeed);
currentSpeed = Math.max(10, Math.min(20, Math.round(currentSpeed * 0.8)));
console.log("New speed :", currentSpeed);
}
self.progress = Math.max(0, self.y - startY) / (endY - startY); // Update progress property
obstacleGraphics.width = startSize + (endSize - startSize) * self.progress;
obstacleGraphics.height = startSize + (endSize - startSize) * self.progress;
var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3);
var newSpeed = currentSpeed; // + 10 * self.progress;
newSpeed = tempSpeed * 1; // TEMP DEBUG !!!
self.y += newSpeed;
// Move innerLineLeft x progressively to innerLeftLineEndX
if (self.pathIndex == 0 && self.x != leftEndX) {
self.x = leftStartX + (leftEndX - leftStartX) * self.progress;
}
if (self.pathIndex == 2 && self.x != rightEndX) {
self.x = rightStartX + (rightEndX - rightStartX) * self.progress;
}
if (self.y > endY + endSize / 2) {
//self.y = -startSize; // Move obstacle back to the top
self.reset();
}
};
self.reset = function () {
self.y = startY;
self.progress = 0; // Initialize progress property
obstacleGraphics.width = startSize;
obstacleGraphics.height = startSize;
self.pathIndex = Math.floor(Math.random() * 3);
if (self.pathIndex === 0) {
self.x = leftStartX;
} else if (self.pathIndex === 2) {
self.x = rightStartX;
} else {
self.x = 1024;
}
};
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
self.shadow = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5
});
self.isJumping = false; // Initialize isJumping to false
self.shadow.alpha = 0.5; // Make the shadow semi-transparent
self.shadow.y = 270; // Offset the shadow slightly below the player
var playerGraphics1 = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
x: -5
});
var playerGraphics2 = self.attachAsset('player2', {
anchorX: 0.5,
anchorY: 0.5,
x: 5
});
playerGraphics2.visible = false; // Initially hide player2 asset
var frame = 0;
self.update = function () {
if (!self.isJumping) {
frame += Math.min(currentSpeed, 20); // Add a max limit to avoid optical effects
if (frame >= 100) {
frame = 0;
// Swap frames every 10 game ticks
var visible = playerGraphics1.visible;
playerGraphics1.visible = !visible;
playerGraphics2.visible = visible;
}
}
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
var initialY = self.y;
var initialShadowY = self.shadow.y;
var jumpHeight = 300;
var jumpDuration = 30;
var jumpStep = jumpHeight / jumpDuration;
var fallStep = jumpHeight / jumpDuration;
var jumpStartTime = Date.now();
var jumpInterval = LK.setInterval(function () {
var elapsed = Date.now() - jumpStartTime;
var progress = elapsed / (jumpDuration * 1000 / 60);
if (progress < 1) {
var easeProgress = Math.sin(progress * Math.PI / 2);
self.y = initialY - jumpHeight * easeProgress;
self.shadow.y = initialShadowY + jumpHeight * easeProgress; // Move shadow inversely
self.shadow.width = 240 * (1 - 0.5 * easeProgress); // Reduce shadow width
self.shadow.height = 100 * (1 - 0.5 * easeProgress); // Reduce shadow height
} else {
LK.clearInterval(jumpInterval);
var fallStartTime = Date.now();
var fallInterval = LK.setInterval(function () {
var elapsed = Date.now() - fallStartTime;
var progress = elapsed / (jumpDuration * 1000 / 60);
if (progress < 1) {
var easeProgress = Math.sin(progress * Math.PI / 2);
self.y = initialY - jumpHeight + jumpHeight * easeProgress;
self.shadow.y = initialShadowY + jumpHeight - jumpHeight * easeProgress; // Move shadow inversely
self.shadow.width = 120 + 120 * easeProgress; // Reset shadow width
self.shadow.height = 50 + 50 * easeProgress; // Reset shadow height
} else {
self.y = initialY;
self.shadow.y = initialShadowY; // Reset shadow position
self.isJumping = false;
LK.clearInterval(fallInterval);
}
}, 1000 / 60);
}
}, 1000 / 60);
}
};
};
});
// Road class
var Road = Container.expand(function () {
var self = Container.call(this);
var baseY = 750;
var roadGraphics = self.attachAsset('triangle', {
tint: 0x555555,
// Initialize tint to white
anchorX: 0.5,
anchorY: 0,
width: 2048,
height: roadHeight,
y: baseY
});
var speed = 5;
var lineOffset = -150;
// Inner lines
var innerLineStartY = roadTop;
var innerLineEndY = roadTop + roadHeight + 200;
// Left
var innerLeftLineStartX = -50;
var innerLeftLineEndX = -412;
var innerLeftLineStartW = 3;
var innerLeftLineEndW = 80;
var innerLeftLineStartH = 3;
var innerLeftLineEndH = 500;
var innerLeftLineStartR = 0.22; //0.075;
var innerLeftLineEndR = 0.275;
// Right
var innerRightLineStartX = 50;
var innerRightLineEndX = 412;
var innerRightLineStartW = 3;
var innerRightLineEndW = 80;
var innerRightLineStartH = 3;
var innerRightLineEndH = 500;
var innerRightLineStartR = -0.22;
var innerRightLineEndR = -0.275;
// Lamp posts
// Left Lamp
var leftLampStartX = -130;
var leftLampEndX = -1600;
var leftLampStartY = roadTop;
var leftLampEndY = roadTop + roadHeight + 0; // Define leftLampEndY variable
var leftLampStartH = 2;
var leftLampEndH = 900;
var leftLampWRatio = 1 / 3;
// Right Lamp
var rightLampStartX = 130;
var rightLampEndX = 1600;
var rightLampStartY = roadTop;
var rightLampEndY = roadTop + roadHeight + 0; // Define leftLampEndY variable
var rightLampStartH = 2;
var rightLampEndH = 900;
var rightLampWRatio = 1 / 3;
var nbInnerLines = 6;
var leftLine = self.attachAsset('triangle', {
anchorX: 0.5,
anchorY: 0,
width: 100,
height: 1950,
rotation: 0.45
});
leftLine.x = lineOffset; // Position the left line on the left side of the road
leftLine.y = roadTop + 45; // Center the left line vertically
var rightLine = self.attachAsset('triangle', {
anchorX: 0.5,
anchorY: 0,
width: 100,
height: 1950,
rotation: -0.45
});
rightLine.x = -lineOffset; // Position the right line on the right side of the road
rightLine.y = roadTop + 45; // Center the right line vertically
self.innerLeftLines = [];
self.innerRightLines = [];
self.leftLampPosts = [];
self.rightLampPosts = [];
for (var i = 0; i < nbInnerLines; i++) {
var innerLineLeft = self.attachAsset('line', {
anchorX: 0.5,
anchorY: 0.5,
width: innerLeftLineStartW,
height: innerLeftLineStartH,
rotation: innerLeftLineStartR,
alpha: 1
});
innerLineLeft.x = innerLeftLineStartX;
innerLineLeft.y = innerLineStartY - 0.1 * i * roadHeight / nbInnerLines;
//console.log(i + " : " + innerLineStartY + " + " + i * roadHeight / nbInnerLines + " => " + innerLineLeft.y);
innerLineLeft.progress = 0; // Initialize progress property
self.innerLeftLines.push(innerLineLeft);
var innerLineRight = self.attachAsset('line', {
anchorX: 0.5,
anchorY: 0.5,
width: innerRightLineStartW,
height: innerRightLineStartH,
rotation: innerRightLineStartR,
alpha: 1
});
innerLineRight.x = innerRightLineStartX;
innerLineRight.y = innerLineStartY - 0.1 * i * roadHeight / nbInnerLines;
innerLineRight.progress = 0; // Initialize progress property
self.innerRightLines.push(innerLineRight);
if (i % 2 == 0) {
continue;
}
var leftLampPost = self.attachAsset('lampPost', {
anchorX: 0.5,
anchorY: 0.5,
height: leftLampStartH,
width: leftLampStartH * leftLampWRatio
});
var leftLampShadow = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5,
width: leftLampPost.width * 0.8,
height: leftLampPost.height * 0.1,
y: leftLampPost.height * 0.5 + 10 // Offset shadow slightly below the lamp post
});
leftLampPost.addChild(leftLampShadow);
leftLampPost.x = leftLampStartX;
leftLampPost.y = leftLampStartY - (i - 1) * 40;
self.addChild(leftLampPost);
self.leftLampPosts.push(leftLampPost);
var rightLampPost = self.attachAsset('lampPost', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: -1,
height: rightLampStartH,
width: rightLampStartH * rightLampWRatio
});
var rightLampShadow = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5,
width: rightLampPost.width * 0.8,
height: rightLampPost.height * 0.1,
y: rightLampPost.height * 0.5 + 10 // Offset shadow slightly below the lamp post
});
rightLampPost.addChild(rightLampShadow);
rightLampPost.x = rightLampStartX;
rightLampPost.y = rightLampStartY - (i - 1) * 40;
self.addChild(rightLampPost);
self.rightLampPosts.push(rightLampPost);
}
self.update = function () {
if (isKilled) {
return;
}
var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf;
//roadGraphics.tint = newTint; // Apply reduced tint to the road based on the intensity
leftLine.tint = newTint;
rightLine.tint = newTint;
// Add any update logic for the road if needed
for (var i = 0; i < self.innerLeftLines.length; i++) {
innerLineLeft = self.innerLeftLines[i];
innerLineLeft.tint = newTint;
if (innerLineLeft.y > innerLineEndY) {
self.resetInnerLine(innerLineLeft, true);
} else {
innerLineLeft.progress = Math.max(0, innerLineLeft.y - innerLineStartY) / (innerLineEndY - innerLineStartY); // Update progress property
}
var tempSpeed = currentSpeed * 0.05 + currentSpeed * (innerLineLeft.progress * 3);
var newSpeed = currentSpeed; // + 10 * self.progress;
newSpeed = tempSpeed * 1; // TEMP DEBUG !!!
innerLineLeft.y += newSpeed;
// Move innerLineLeft x progressively to innerLeftLineEndX
if (innerLineLeft.x != innerLeftLineEndX) {
innerLineLeft.x = innerLeftLineStartX + (innerLeftLineEndX - innerLeftLineStartX) * innerLineLeft.progress;
}
// Move innerLineLeft x progressively
if (innerLineLeft.rotation != innerLeftLineEndR) {
//innerLineLeft.rotation = innerLeftLineStartR + (innerLeftLineEndR - innerLeftLineStartR) * innerLineLeft.progress;
}
// Move innerLineLeft x progressively
if (innerLineLeft.width != innerLeftLineEndW) {
innerLineLeft.width = innerLeftLineStartW + (innerLeftLineEndW - innerLeftLineStartW) * innerLineLeft.progress;
}
// Move innerLineLeft x progressively
if (innerLineLeft.height != innerLeftLineEndH) {
innerLineLeft.height = innerLeftLineStartH + (innerLeftLineEndH - innerLeftLineStartH) * innerLineLeft.progress;
}
}
for (var i = 0; i < self.innerRightLines.length; i++) {
innerLineRight = self.innerRightLines[i];
innerLineRight.tint = newTint;
if (innerLineRight.y > innerLineEndY) {
self.resetInnerLine(innerLineRight, false);
} else {
innerLineRight.progress = Math.max(0, innerLineRight.y - innerLineStartY) / (innerLineEndY - innerLineStartY);
}
var tempSpeed = currentSpeed * 0.05 + currentSpeed * (innerLineRight.progress * 3);
var newSpeed = currentSpeed; // + 10 * self.progress;
newSpeed = tempSpeed * 1; // TEMP DEBUG !!!
innerLineRight.y += newSpeed;
// Move innerLineRight x progressively to innerRightLineEndX
if (innerLineRight.x != innerRightLineEndX) {
innerLineRight.x = innerRightLineStartX + (innerRightLineEndX - innerRightLineStartX) * innerLineRight.progress;
}
// Move innerLineRight x progressively
if (innerLineRight.rotation != innerRightLineEndR) {
//innerLineRight.rotation = innerRightLineStartR + (innerRightLineEndR - innerRightLineStartR) * innerLineRight.progress;
}
// Move innerLineRight x progressively
if (innerLineRight.width != innerRightLineEndW) {
innerLineRight.width = innerRightLineStartW + (innerRightLineEndW - innerRightLineStartW) * innerLineRight.progress;
}
// Move innerLineRight x progressively
if (innerLineRight.height != innerRightLineEndH) {
innerLineRight.height = innerRightLineStartH + (innerRightLineEndH - innerRightLineStartH) * innerLineRight.progress;
}
}
// Lamp posts
for (var i = 0; i < self.leftLampPosts.length; i++) {
var leftLampPost = self.leftLampPosts[i];
//leftLampPost.tint = newTint;
var tempProgress = Math.max(0, leftLampPost.y - leftLampStartY) / (leftLampEndY - leftLampStartY);
var tempSpeed = currentSpeed * 0.05 + currentSpeed * (tempProgress * 3);
leftLampPost.y += tempSpeed;
leftLampPost.visible = currentLevel !== 1; // Make lampPost not visible when level is 1
if (leftLampPost.y > leftLampEndY) {
leftLampPost.y = leftLampStartY;
leftLampPost.x = leftLampStartX;
leftLampPost.height = leftLampStartH;
}
leftLampPost.progress = Math.max(0, leftLampPost.y - leftLampStartY) / (leftLampEndY - leftLampStartY); // Update progress property
leftLampPost.alpha = 0.75 + Math.min(0.25, leftLampPost.progress);
if (i == 0) {
//debugTxt.setText(leftLampPost.progress.toFixed(2));
}
if (leftLampPost.x != leftLampEndX) {
leftLampPost.x = leftLampStartX + (leftLampEndX - leftLampStartX) * Math.min(1, leftLampPost.progress * 1);
}
if (leftLampPost.height != leftLampEndH) {
leftLampPost.height = Math.min(1, leftLampPost.progress * 2) * leftLampEndH; // leftLampStartH + (leftLampEndH - leftLampStartH) * Math.min(1, leftLampPost.progress * 1);
leftLampPost.width = leftLampPost.height * leftLampWRatio;
}
}
for (var i = 0; i < self.rightLampPosts.length; i++) {
var rightLampPost = self.rightLampPosts[i];
var tempProgress = Math.max(0, rightLampPost.y - rightLampStartY) / (rightLampEndY - rightLampStartY);
var tempSpeed = currentSpeed * 0.05 + currentSpeed * (tempProgress * 3);
rightLampPost.y += tempSpeed;
rightLampPost.visible = currentLevel !== 1; // Make right lampPost not visible when level is 1
if (rightLampPost.y > rightLampEndY) {
rightLampPost.y = rightLampStartY;
rightLampPost.x = rightLampStartX;
rightLampPost.height = rightLampStartH;
}
rightLampPost.progress = Math.max(0, rightLampPost.y - rightLampStartY) / (rightLampEndY - rightLampStartY);
rightLampPost.alpha = 0.75 + Math.min(0.25, rightLampPost.progress);
if (rightLampPost.x != rightLampEndX) {
rightLampPost.x = rightLampStartX + (rightLampEndX - rightLampStartX) * rightLampPost.progress;
}
if (rightLampPost.height != leftLampEndH) {
rightLampPost.height = rightLampStartH + (rightLampEndH - rightLampStartH) * Math.min(1, rightLampPost.progress * 2);
rightLampPost.width = rightLampPost.height * rightLampWRatio;
}
}
};
self.resetInnerLine = function (innerLine, isLeft) {
if (isLeft) {
innerLine.x = innerLeftLineStartX;
innerLine.rotation = innerLeftLineStartR;
innerLine.width = innerLeftLineStartW;
innerLine.height = innerLeftLineStartH;
} else {
innerLine.x = innerRightLineStartX;
innerLine.rotation = innerRightLineStartR;
innerLine.width = innerRightLineStartW;
innerLine.height = innerRightLineStartH;
}
innerLine.y = innerLineStartY - 0.2 * roadHeight / nbInnerLines;
innerLine.progress = 0; // Reset progress property
};
});
var StartButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.interactive = true;
self.buttonMode = true;
self.on('down', function () {
self.visible = false;
isPlaying = true;
scoreTxt.visible = true;
});
});
var Stripe = Container.expand(function () {
var self = Container.call(this);
self.stripeGraphics = self.attachAsset('stripe1', {
anchorX: 0,
anchorY: 1,
height: 1
});
self.progress = 0; // Initialize progress property
self.update = function () {
if (isKilled) {
return;
}
self.progress = Math.max(0, self.y - roadTop) / roadHeight; // Update progress property
var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf;
self.stripeGraphics.tint = newTint;
var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3);
self.y += tempSpeed;
self.stripeGraphics.height = 400 * self.progress; // Adjust height based on progress
if (self.y > roadTop + roadHeight) {
self.y = roadTop;
self.stripeGraphics.height = 0; // Reset height to initial value
self.stripeGraphics.tint = 0xFFFFFF; // Reset tint to initial value
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Init game with black background
});
/****
* Game Code
****/
function _toConsumableArray(r) {
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _iterableToArray(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) {
return Array.from(r);
}
}
function _arrayWithoutHoles(r) {
if (Array.isArray(r)) {
return _arrayLikeToArray(r);
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
var stripes = [];
var decorations = [];
// Initialize arrays and variables
var currentLevel = 1;
var isPlaying = false;
var isKilled = false;
var killerDelay = 10000; // Delay in milliseconds before updating killer
var lastKillerUpdate = 0; // Timestamp of the last killer update
var currentCoinType = 0;
var nextCoinTypeThreshold = 10;
var isNight = false;
var roadHeight = 2000;
var roadTop = 1000; // ~= road.height/2 - baseY
var background;
var landscape1;
var nbStripes = 33;
var coins = [];
var obstacles = [];
var road;
var score = 0;
var scoreTxt;
var startX = 0;
var startY = 0;
var endX = 0;
var endY = 0;
var intensity = 0;
var intensityHalf = 0;
var leftLampPosts = [];
var rightLampPosts = [];
var leftDecorations = [];
var rightDecorationss = [];
var maxSpeed = 50; // Define a maximum speed limit
var currentSpeed = 10; //20; // Initialize currentSpeed
var coinsCollected = 0; // Initialize coins collected counter
var isIntersectingObstacle = false; // Flag to track if the player is currently intersecting an obstacle
var lastObstacleHitTime = 0; // Timestamp of the last obstacle hit
var immunityDelay = 500; // Immunity delay in milliseconds
var playerPositionIndex = 1; // Initialize player position index
var playerBaseY = 2732 - 300;
// Define the three fixed x positions for the player
var playerPositions = [2048 / 5, 2048 / 2, 4 * 2048 / 5];
// Create player
var player;
var debugMarker;
var debugText;
var debugTxt;
function easeInOutQuad(t) {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}
function updateBackgroundColor() {
var time = new Date().getTime() * 0.0002;
intensity = Math.sin(time) * 127 + 128;
var color = Math.max(32, intensity) << 16 | Math.max(32, intensity) << 8 | Math.max(32, intensity);
background.tint = color;
isNight = intensity < 128;
intensityHalf = 128 + Math.floor(intensity * 0.5);
}
// Handle move events
game.down = function (x, y, obj) {
if (!isPlaying) {
return;
}
startX = x;
startY = y;
};
game.up = function (x, y, obj) {
if (isKilled) {
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
return;
}
if (!isPlaying) {
return;
}
endX = x;
endY = y;
var deltaX = endX - startX;
var deltaY = endY - startY;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
if (deltaX > 0) {
// Swipe right
if (playerPositionIndex < 2) {
playerPositionIndex++;
}
} else {
// Swipe left
if (playerPositionIndex > 0) {
playerPositionIndex--;
}
}
} else {
if (deltaY < 0) {
// Swipe up
player.jump();
}
}
// Make the player move progressively to the next path
var targetX = playerPositions[playerPositionIndex];
var initialX = player.x;
var moveDuration = 30;
var moveStartTime = Date.now();
var moveInterval = LK.setInterval(function () {
var elapsed = Date.now() - moveStartTime;
var progress = elapsed / (moveDuration * 1000 / 60);
if (progress < 1) {
var easeProgress = easeInOutQuad(progress);
player.x = initialX + (targetX - initialX) * easeProgress;
} else {
player.x = targetX;
LK.clearInterval(moveInterval);
}
}, 1000 / 60);
};
// Update game every tick
game.update = function () {
updateBackgroundColor();
if (!isPlaying || isKilled) {
return;
}
};
// Initialize game
function gameInitialize() {
// Initialize arrays and variables
// Attach the background asset to the game
background = game.attachAsset('background1', {
anchorX: 0.0,
anchorY: 0.0
});
//background.y = -2000;
game.addChild(background);
// Add a series of Stripe instances to cover the bottom half of the screen
for (var i = 0; i < nbStripes; i++) {
var stripe = new Stripe();
stripe.y = i === 0 ? roadTop : stripes[i - 1].y + stripes[i - 1].stripeGraphics.height; // Position stripe under the previous one using previous stripe y and height
stripe.progress = Math.max(0, stripe.y - roadTop) / roadHeight; // Calculate progress
stripes.push(stripe);
game.addChild(stripe);
stripe.stripeGraphics.height = 1 + 400 * stripe.progress; // Adjust height based on progress
//console.log("Stripe ", i, " y=", stripe.y, " h=", stripe.stripeGraphics.height, " p=", stripe.progress);
}
// Create and attach decoration instances to the game
for (var i = 0; i < 5; i++) {
var newDecoration = new Decoration(i);
newDecoration.reset();
decorations.push(newDecoration);
game.addChild(newDecoration);
}
// Create and attach the road instance to the game
road = game.addChild(new Road());
road.x = 2048 / 2;
road.y = 0;
// Create and attach the landscape instance to the game
var landscape = game.addChild(new Landscape());
score = 0;
scoreTxt = new Text2(currentLevel == 1 ? '0¢' : '$0', {
size: 150,
fill: "#ffffff",
dropShadow: true,
dropShadowColor: "#000000",
dropShadowBlur: 5,
dropShadowDistance: 5
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.visible = false;
LK.gui.top.addChild(scoreTxt);
coins = [];
for (var i = 0; i < 5; i++) {
var newCoin = new Coin();
newCoin.reset();
newCoin.y = roadTop - i * 50;
coins.push(newCoin);
game.addChild(newCoin);
}
// Create a variable to store the current player position index
playerPositionIndex = 1;
// Create and attach the obstacle instance to the game
var newObstacle = new Obstacle();
newObstacle.reset();
obstacles.push(newObstacle);
game.addChild(newObstacle);
// Create and attach the killer instance to the game
var newKiller = new Killer();
newKiller.reset();
obstacles.push(newKiller);
game.addChild(newKiller);
// Create player
player = game.addChild(new Player());
player.frame = 0;
player.x = playerPositions[playerPositionIndex]; // Start at the center position
player.y = playerBaseY;
// Attach a debugMarker asset to the game at position (1000, 0)
debugMarker = game.attachAsset('debugMarker', {
anchorX: 0.5,
anchorY: 0.5
});
debugMarker.x = 10;
debugMarker.y = 2500;
debugTxt = new Text2('Debug Info', {
size: 50,
fill: "#ff0000"
});
debugTxt.anchor.set(1, 1); // Set anchor to the bottom right corner
LK.gui.bottomRight.addChild(debugTxt);
var startButton = game.addChild(new StartButton());
startButton.x = 2048 / 2;
startButton.y = 2732 / 4;
// TEMP DEBUG !!!
startButton.width = 100;
startButton.height = 100;
isPlaying = false;
}
gameInitialize();
for (var i = 0; i < stripes.length; i++) {
stripes[i].update();
}
Directly overhead, plumb view of a beggar heading top (we see his back).. Zenith view, directly overhead, plumb view. NOT PERSPECTIVE! Fantasy theme. Pixel art
a traffic cone. video game sprite
face view of a big start button in the shape of a dollar bill. video game style
a tree. video game style
a black garbage bag. video game style
Dollar bill. Perspective. video game sprite
perspective of a simple snake rolled up on itself.. video game sprite
Ball of dry desert bushes. video game sprite
tractor. high definition video game sprite
street ad billboard with 1 or 2 posts with "Get rich!" on it. high definition video game sprite
a dog sleeping on a street. video game sprite
desert bush. video game sprite
profile view of an empty motorcycle helmet. black with a white vertical central band and another thiner orange band on the center. NOT PERSPECTIVE!. Pixel art high definition
simple red and white magnet. video game style
gold sign with a "X" and a "2". video game style
bgMusic
Music
coin_1
Sound effect
hit_1
Sound effect
hit_2
Sound effect
hit_3
Sound effect
levelWin_1
Sound effect
car_1
Sound effect
police_1
Sound effect
ambulance_1
Sound effect
accident_1
Sound effect
killed_1
Sound effect
jump_1
Sound effect
rip_1
Sound effect
bonus_take
Sound effect
bonus_approaching
Sound effect