User prompt
Move start game button right by 12 units
User prompt
But no the gap is to much. You should move it next to it.
User prompt
Start game button is covering car button. Avoid this display fault. Move start game button right next to the car button
User prompt
rename particle asset to wheel track
User prompt
Here is the single bubble prompt in English for AVA: --- “The current snow/dust trail behind the car is too weak and looks like light dust instead of a proper winter effect. Please transform it into a strong winter drift snow system: significantly increase the particle count (at least 4–6x more), use larger snow chunks with varied scaling, and greatly extend their lifetime (around 2–3x longer than current). The motion should feel heavier and slower, like dense drifting snow clouds rather than fast disappearing dust. During turns and drifting, add extra burst effects behind the wheels to simulate snow being thrown up from the road. The overall look should be visually thick, layered, and clearly noticeable, as if the car is aggressively plowing through deep snow.”
User prompt
display BLIZZARD snow fall effect to the map
User prompt
add BLIZZARD effect to the map
User prompt
Create a strict, structured Dirt Rally style main menu UI with NO overlapping elements. CRITICAL UI RULES: - All menu elements MUST be placed in fixed groups - NO floating layout - NO automatic positioning - NO overlapping UI elements - Every category must be visually separated --- LAYOUT STRUCTURE (STRICT GRID): BOTTOM BAR (navigation): - Difficulty button - Weather button - Car button - Start Game button All placed in a single horizontal row with equal spacing. --- CENTER PANEL (active selection area): Display ONLY ONE category at a time: - Difficulty OR Weather OR Car Each category must appear in a clean grid: DIFFICULTY GRID: [ EASY ] [ MEDIUM ] [ HARD ] WEATHER GRID: [ CLEAR_WINTER ] [ LIGHT_SNOW ] [ HEAVY_SNOW ] [ BLIZZARD ] [ ICE_PATCH ] CAR GRID: horizontal or carousel style, but spaced items only --- TOP AREA: - Background image / car preview - Must not contain interactive UI elements --- STATE SYSTEM: Use a single gameState object: - difficulty - weather - car Rules: - Only ONE selected option per category - Selected item must be visually highlighted - Non-selected items must remain visible but dimmed --- INTERACTION RULES: - Clicking category button switches CENTER PANEL content - Clicking option updates gameState only - No side effects in UI - Start Game reads gameState and launches scene --- VISUAL SEPARATION RULES: - Each category must be in its own container panel - Minimum spacing between panels: 50–100px - Use background panels or overlays to separate sections - No text or buttons may overlap other categories --- GOAL: Recreate a clean, structured rally game menu similar to modern racing games: - clear hierarchy - strict separation - no UI blending or clutter - professional grid-based layout
User prompt
Create a Dirt Rally style main menu system with a state-based architecture. CORE STRUCTURE: - Use a central gameState object: { difficulty: "MEDIUM", weather: "CLEAR_WINTER", car: "default" } --- DIFFICULTY SYSTEM: Implement 3 selectable difficulty levels: - EASY: - forgiving driving physics - higher grip - wider road tolerance - MEDIUM: - balanced standard experience - default grip and handling - HARD: - reduced grip - more sensitive handling - stricter road tolerance --- WEATHER SYSTEM (winter rally theme): Implement selectable weather modes: - CLEAR_WINTER: - no snowfall - good visibility - icy road surface (reduced grip) - LIGHT_SNOW: - light snowfall particles - slightly reduced visibility - mild grip reduction - HEAVY_SNOW: - strong snowfall particles - reduced visibility - significantly reduced grip - BLIZZARD: - heavy storm + strong snow particles - very low visibility - very low grip - cinematic storm atmosphere - ICE_PATCH (optional modifier or toggle): - random icy zones on road - sudden loss of traction in specific areas --- MENU BEHAVIOR: - All buttons must update only gameState - No gameplay logic inside UI buttons - Selected options must be visually highlighted - Only one option per category can be active --- START GAME: - Start Game button must: - read current gameState - pass it to the game scene - initialize physics and weather based on selected values --- VISUAL REQUIREMENTS: - Dirt Rally inspired UI style - Clean category layout: - Difficulty (EASY / MEDIUM / HARD) - Weather (CLEAR / LIGHT SNOW / HEAVY SNOW / BLIZZARD / ICE PATCH) - Car selection (optional) - Start Game button --- GOAL: Create a professional rally game menu system with: - clean state management - realistic winter weather variation - responsive UI - no direct coupling between buttons and gameplay logic
User prompt
Fix the car turning system to match the original responsive gameplay. Remove the current steering system completely. Requirements: - Do NOT use gradual steering or steering variables - Remove: - steering - maxSteeringAngle - appliedSteering - speed-based steering scaling Implement instant direction switching: - On player input: - Immediately call changeDirection() - Toggle direction between 0 and 1 - Movement must be based only on direction: if direction == 0: move forward along X axis if direction == 1: move forward along Y axis - Keep momentum system, but do NOT use steering to modify it - Turning must feel instant and sharp (arcade style) - No smoothing, no interpolation, no damping Goal: Recreate the original snap-turn rally behavior where the car instantly switches direction instead of slowly turning.
User prompt
Fix the car steering system to behave like a realistic rally game (similar to Dirt Rally 2.0). Requirements: - Steering must respond immediately to player input (no heavy smoothing or delay) - Remove excessive interpolation (reduce or eliminate lerp on steering) - Apply direct input mapping to steering angle - Increase steering sensitivity significantly - Add speed-based steering reduction (less steering at high speed) Implementation details: - Use raw horizontal input (A/D or left/right) - Steering angle should be directly proportional to input - Example: steering = input * maxSteeringAngle - Reduce smoothing: currentSteering = steering (NOT heavily lerped) - Add slight stabilization only: currentSteering = lerp(currentSteering, steering, 0.2) // small smoothing only - Add speed factor: speedFactor = clamp(1 - (speed / maxSpeed), 0.3, 1) finalSteering = currentSteering * speedFactor - Ensure the car can turn sharply at low speed - Ensure responsive, aggressive turning like a rally car Do NOT: - Do not heavily dampen input - Do not limit steering too much - Do not make turning slow or floaty Goal: Make steering feel tight, responsive, and arcade-rally like Dirt Rally 2.
User prompt
game.on('down', function (x, y) { if (!mainContainer.visible) return; var centerX = 2048 / 2; if (x < centerX) { car.steering = -1; } else { car.steering = 1; } }); game.on('up', function () { car.steering = 0; });
User prompt
Fix the car steering and input handling in my Upit (LK) game. Current issues: - The car does not respond to input (steering seems blocked). - Steering is being reset every frame. - The steering variable is not actually affecting movement. - There are multiple input handlers that may conflict. Tasks: 1. Remove any line that resets steering every frame (e.g. "self.steering = 0" inside movement/update functions). 2. Ensure that steering input (left/right) is preserved between frames until changed by user input. 3. Modify the movement logic so that steering affects the car’s momentum: - When moving forward, steering should add perpendicular momentum (simulate turning/drifting). 4. Use only ONE input handler (prefer game.on('down')) to control steering. 5. Ensure input works only when the main game container is visible. 6. Do NOT override steering in update/tick unless input changes it. 7. Keep movement smooth and continuous (no instant resets). Expected behavior: - Clicking left side → car turns left - Clicking right side → car turns right - Car keeps turning smoothly, not just for 1 frame - Movement feels like drifting, not grid snapping Return the corrected Car movement function and input handling code.
Code edit (1 edits merged)
Please save this source code
User prompt
game.on('down', function (x, y) {
User prompt
The car is not turning when the player clicked on map. Why? Fix it
User prompt
the car should turn by mirrored verically when the player click on the map. This event not working in the menu to avoid bugs.
User prompt
Change the car direction when the player click on the map. This event not working in the menu to avoid bugs.
User prompt
Task: Fix the steering so that the car responds correctly to user input. Current issue: * The car no longer turns at all when clicking or pressing controls. Requirements: 1. Keep steering reset at the start of each frame: steering = 0; 2. Immediately after resetting, apply input logic: * If left input is active → steering = -1 * If right input is active → steering = +1 3. Ensure input conditions actually trigger (mouse, touch, or keyboard must be correctly detected). 4. Do NOT leave steering at 0 when input is present. 5. Apply rotation using the steering value: rotation += steering * turnSpeed; 6. Add debug logging: * Log when input is detected * Log steering value each frame Expected behavior: * No input → car goes straight * Input → car turns accordingly * Clicking/pressing must visibly change direction Important: Do not remove input handling. Ensure steering is BOTH reset and reassigned based on input every frame.
User prompt
Task: Fix the issue where the car automatically turns left immediately after the scene loads, without any user input. Requirements: 1. Inspect all input handling, especially horizontal/steering input. 2. Ensure the steering/input value is reset to 0 at the start of every frame. 3. Prevent any leftover steering values from previous frames. 4. Check for sign errors (e.g. unintended negative multipliers or inverted axes). 5. Make sure the car only rotates when there is actual user input. 6. If necessary, invert the steering direction so right input results in right turning. 7. Add temporary debug logging to verify steering/input values at startup. Expected behavior: * The car remains straight when no input is given. * The car only turns when the user presses left/right controls. * Right input turns the car to the right, left input turns it to the left. Implementation guideline (if missing): * Initialize steering = 0 at the beginning of each frame/update * Modify steering only when input is detected * Apply rotation strictly based on steering value Validation: * At startup, steering must be 0 * No automatic turning occurs * Steering direction matches user input correctly
User prompt
ADD W3 ASSET TO CHANGING WALLPAPPERS
User prompt
You added this task: ,,Initialize wallpaper rotation when Menu is created" What is this? Remove this task. This occours a wrong car direction bug in the map.
User prompt
RENAME W0 ASSET NAME TO W1
User prompt
RENAME W1 ASSET NAME TO W2
User prompt
Remove wallpapper asset from the GAME, FROM THE ASSET LIST AND FROM THE MAP
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Button = Container.expand(function (label, width, height) {
var self = Container.call(this);
//{button_init}
self.interactive = true;
self.buttonMode = true;
var buttonBg = self.attachAsset('Button', {
anchorX: 0.5,
anchorY: 0.5
}); //{button_bg}
buttonBg.width = width;
buttonBg.height = height;
buttonBg.scale.x = 1;
buttonBg.scale.y = 1;
var buttonText = new Text2(label, {
size: 80,
fill: 0x000000,
weight: '800'
}); //{button_text}
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.onDown = function () {
buttonBg.alpha = 0.7;
}; //{button_down}
self.onUp = function () {
buttonBg.alpha = 1;
}; //{button_up}
return self;
});
var Car = Container.expand(function () {
var self = Container.call(this);
self.projectMovement = function (vector) {
var angle = -Math.PI / 4;
var cosAngle = Math.cos(angle);
var sinAngle = Math.sin(angle);
return {
x: vector.x * cosAngle - vector.y * sinAngle,
y: vector.x * sinAngle + vector.y * cosAngle
};
};
var carGraphics = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.direction = 0;
self.momentum = {
x: 0,
y: 0
};
self._move_migrated = function () {
var momentumModifier = 0.1;
if (self.direction === 0) {
// Move along X axis
self.momentum.x += self.speed * momentumModifier;
} else {
// Move along Y axis
self.momentum.y -= self.speed * momentumModifier;
}
var projectedMovement = self.projectMovement(self.momentum);
// Check if car reaches the center of the screen on the X coordinate
if (self.lastX <= 2048 / 2 && self.x > 2048 / 2) {
console.log("Car reached the center of the screen on the X coordinate");
}
self.lastX = self.x;
self.x += projectedMovement.x;
self.y += projectedMovement.y;
// Check if car arrives at a specific X, Y coordinate
if (self.lastY <= 1500 && self.y > 1500 && self.lastX <= 1000 && self.x > 1000) {
console.log("Car arrived at the specific X, Y coordinate");
}
self.lastY = self.y;
self.lastX = self.x;
// Check if car comes close to the bottom of the screen on the Y coordinate
if (self.lastY <= 2732 - 100 && self.y > 2732 - 100) {
console.log("Car is close to the bottom of the screen");
}
self.lastY = self.y;
var nonTravelMomentum;
if (self.direction === 0) {
self.momentum.x *= 0.98;
self.momentum.y *= 0.95;
nonTravelMomentum = self.momentum.y;
} else {
self.momentum.x *= 0.95;
self.momentum.y *= 0.98;
nonTravelMomentum = self.momentum.x;
}
self.nonTravelMomentum = nonTravelMomentum;
};
self.changeDirection = function () {
self.direction = self.direction === 0 ? 1 : 0;
carGraphics.scale.x *= -1;
};
});
var DriftAndDodge = Container.expand(function () {
var self = Container.call(this);
});
//{button_end}
var Menu = Container.expand(function () {
var self = Container.call(this);
//{1a_menu}
var currentWallpaperIndex = 0;
var wallpaperAssets = ['W2', 'W1', 'W3'];
var menuBackground = self.attachAsset(wallpaperAssets[currentWallpaperIndex], {
anchorX: 0.5,
//{1a_menu_bg1}
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}); //{1a_menu_bg2}
menuBackground.alpha = 0.8;
self.startWallpaperRotation = function () {
var _rotateWallpaper = function rotateWallpaper() {
currentWallpaperIndex = (currentWallpaperIndex + 1) % wallpaperAssets.length;
var newBackground = self.attachAsset(wallpaperAssets[currentWallpaperIndex], {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
newBackground.alpha = 0;
self.addChildAt(newBackground, 0);
tween(menuBackground, {
alpha: 0
}, {
duration: 1500,
easing: tween.easeInOut
});
tween(newBackground, {
alpha: 0.8
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
menuBackground.destroy();
menuBackground = newBackground;
LK.setTimeout(_rotateWallpaper, 3000);
}
});
};
LK.setTimeout(_rotateWallpaper, 3000);
};
var titleText = new Text2('DIRT RALLY', {
size: 120,
//{1a_menu_title1}
fill: 0x00FFFF,
weight: '800',
//{1a_menu_title2}
dropShadow: true,
dropShadowColor: '#373330',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6 //{1a_menu_title3}
}); //{1a_menu_title4}
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 200;
self.addChild(titleText);
var currentPanel = null;
var panelsContainer = new Container();
panelsContainer.x = 2048 / 2;
panelsContainer.y = 2732 / 2;
self.addChild(panelsContainer);
var difficultyPanel = new MenuPanel('DIFFICULTY', ['EASY', 'MEDIUM', 'HARD'], function (option) {
gameState.difficulty = option;
});
difficultyPanel.visible = false;
panelsContainer.addChild(difficultyPanel);
var weatherPanel = new MenuPanel('WEATHER', ['CLEAR_WINTER', 'LIGHT_SNOW', 'HEAVY_SNOW', 'BLIZZARD'], function (option) {
gameState.weather = option;
});
weatherPanel.visible = false;
panelsContainer.addChild(weatherPanel);
var carPanel = new MenuPanel('CAR', ['default', 'sport', 'rally'], function (option) {
gameState.car = option;
});
carPanel.visible = false;
panelsContainer.addChild(carPanel);
var mainMenuButtonsContainer = new Container(); //{menu_button_container}
mainMenuButtonsContainer.x = 2048 / 2;
mainMenuButtonsContainer.y = 2732 / 2 + 200;
self.addChild(mainMenuButtonsContainer);
var difficultyBtn = new Button('Difficulty', 400, 160); //{menu_diff_btn}
difficultyBtn.x = -600;
difficultyBtn.y = 0;
mainMenuButtonsContainer.addChild(difficultyBtn);
difficultyBtn.down = function (x, y, obj) {
mainMenuButtonsContainer.visible = false;
difficultyPanel.visible = true;
difficultyPanel.selectOption(gameState.difficulty);
currentPanel = 'difficulty';
}; //{menu_diff_down}
var weatherBtn = new Button('Weather', 400, 160); //{menu_weather_btn}
weatherBtn.x = -200;
weatherBtn.y = 0;
mainMenuButtonsContainer.addChild(weatherBtn);
weatherBtn.down = function (x, y, obj) {
mainMenuButtonsContainer.visible = false;
weatherPanel.visible = true;
weatherPanel.selectOption(gameState.weather);
currentPanel = 'weather';
}; //{menu_weather_down}
var carBtn = new Button('Car', 400, 160); //{menu_car_btn}
carBtn.x = 200;
carBtn.y = 0;
mainMenuButtonsContainer.addChild(carBtn);
carBtn.down = function (x, y, obj) {
mainMenuButtonsContainer.visible = false;
carPanel.visible = true;
carPanel.selectOption(gameState.car);
currentPanel = 'car';
}; //{menu_car_down}
var backBtn = new Button('BACK', 350, 80);
backBtn.x = 0;
backBtn.y = 500;
panelsContainer.addChild(backBtn);
backBtn.visible = false;
backBtn.down = function () {
difficultyPanel.visible = false;
weatherPanel.visible = false;
carPanel.visible = false;
backBtn.visible = false;
mainMenuButtonsContainer.visible = true;
currentPanel = null;
};
var startBtn = Container.call(new Container());
startBtn.interactive = true;
startBtn.buttonMode = true;
var startButtonBg = startBtn.attachAsset('Startbutton', {
anchorX: 0.5,
anchorY: 0.5
});
startButtonBg.width = 500;
startButtonBg.height = 160;
startButtonBg.scale.x = 1;
startButtonBg.scale.y = 1;
var startButtonText = new Text2('START GAME', {
size: 80,
fill: 0x000000,
weight: '800'
});
startButtonText.anchor.set(0.5, 0.5);
startBtn.addChild(startButtonText);
startBtn.onDown = function () {
startButtonBg.alpha = 0.7;
};
startBtn.onUp = function () {
startButtonBg.alpha = 1;
};
startBtn.x = 600;
startBtn.y = 400;
mainMenuButtonsContainer.addChild(startBtn);
startBtn.down = function (x, y, obj) {
self.visible = false;
self.interactive = false;
}; //{menu_start_down}
self.startWallpaperRotation();
return self;
});
var MenuPanel = Container.expand(function (title, options, onSelect) {
var self = Container.call(this);
var panelWidth = 600;
var panelHeight = 400;
var optionButtons = [];
var panelBg = new Container();
var bgShape = LK.getAsset('Button', {
anchorX: 0.5,
anchorY: 0.5
});
bgShape.width = panelWidth;
bgShape.height = panelHeight;
bgShape.alpha = 0.9;
panelBg.addChild(bgShape);
self.addChild(panelBg);
var titleText = new Text2(title, {
size: 60,
fill: 0x00FFFF,
weight: '800'
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -panelHeight / 2 + 50;
self.addChild(titleText);
var optionsContainer = new Container();
optionsContainer.y = -panelHeight / 2 + 130;
self.addChild(optionsContainer);
var optionSpacing = 60;
options.forEach(function (option, index) {
var optionBtn = new Button(option, 450, 80);
optionBtn.y = index * optionSpacing;
optionBtn.isSelected = false;
optionBtn.optionValue = option;
optionBtn.down = function () {
optionButtons.forEach(function (btn) {
btn.isSelected = false;
});
optionBtn.isSelected = true;
onSelect(option);
};
optionsContainer.addChild(optionBtn);
optionButtons.push(optionBtn);
});
self.selectOption = function (optionValue) {
optionButtons.forEach(function (btn) {
if (btn.optionValue === optionValue) {
btn.isSelected = true;
} else {
btn.isSelected = false;
}
});
};
self.getOptionButtons = function () {
return optionButtons;
};
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
particleGraphics.rotation = Math.PI / 4;
self.lifetime = 100;
self.tick = function () {
if (--self.lifetime <= 0) {
self.destroy();
}
};
});
var Rock = Container.expand(function () {
var self = Container.call(this);
var rockGraphics = self.attachAsset('rock', {
anchorX: 0.5,
anchorY: 0.5
});
});
var SnowFog = Container.expand(function () {
var self = Container.call(this);
var fogGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
fogGraphics.scale.x = 0.6;
fogGraphics.scale.y = 0.6;
fogGraphics.tint = 0xFFFFFF;
self.lifetime = 80;
self.initialize = function (startX, startY) {
self.x = startX;
self.y = startY;
self.alpha = 0.7;
tween(self, {
alpha: 0,
y: self.y - 200
}, {
duration: 800,
easing: tween.easeOut
});
};
self.tick = function () {
if (--self.lifetime <= 0) {
self.destroy();
}
};
});
var SnowyEmbankment = Container.expand(function () {
var self = Container.call(this);
var embankmentGraphics = self.attachAsset('rods', {
anchorX: 0.5,
anchorY: 0.5
});
});
var Tree = Container.expand(function () {
var self = Container.call(this);
var treeGraphics = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 0.5
});
});
var Tree2 = Container.expand(function () {
var self = Container.call(this);
var treeGraphics = self.attachAsset('tree2', {
anchorX: 0.5,
anchorY: 0.5
});
});
/****
* Initialize Game
****/
//{1a_menu_end}
var game = new LK.Game({
backgroundColor: 0xFFFFFF
});
/****
* Game Code
****/
var driftAndDodge = game.addChild(new DriftAndDodge());
game.calculateDistanceToPoint = function (point, segmentStart, segmentEnd) {
var A = point.x - segmentStart.x;
var B = point.y - segmentStart.y;
var C = segmentEnd.x - segmentStart.x;
var D = segmentEnd.y - segmentStart.y;
var dot = A * C + B * D;
var len_sq = C * C + D * D;
var param = -1;
if (len_sq != 0) {
param = dot / len_sq;
}
var xx, yy;
if (param < 0) {
xx = segmentStart.x;
yy = segmentStart.y;
} else if (param > 1) {
xx = segmentEnd.x;
yy = segmentEnd.y;
} else {
xx = segmentStart.x + param * C;
yy = segmentStart.y + param * D;
}
var dx = point.x - xx;
var dy = point.y - yy;
return Math.sqrt(dx * dx + dy * dy);
};
game.addRoadSegment = function () {
var lastSegment = roadSegments[roadSegments.length - 1];
zigzag = !zigzag;
var segment = roadContainer.attachAsset('roadSegment', {
anchorX: 0.5
});
segment.width = segmentWidth;
// Reduce road width more during turns to make turns harder but still playable
if (zigzag) {
segmentWidth = Math.max(400, segmentWidth - 45); // Less narrow on turns after turn 10
} else {
segmentWidth = Math.max(400, segmentWidth - 12); // Less narrow on straights after turn 10
}
segment.height = (i === 1 ? 3000 : Math.floor(Math.random() * (4000 - 1200 + 1)) + 1200) * 2;
segment.rotation = zigzag ? -Math.PI - Math.PI / 4 : -Math.PI + Math.PI / 4;
segment.y = currentY;
segment.x = currentX;
var adjustedHeight = segment.height - segmentWidth / 2;
currentY += adjustedHeight * Math.cos(segment.rotation);
currentX -= adjustedHeight * Math.sin(segment.rotation);
segment.shadow = roadContainer.attachAsset('roadSegmentShadow', {
anchorX: 0.5
});
segment.shadow.width = segment.width;
segment.shadow.height = segment.height;
segment.shadow.rotation = segment.rotation;
segment.shadow.x = segment.x;
segment.shadow.y = segment.y + 50;
segment.shadow.alpha = 1;
segment.used = false;
roadSegments.push(segment);
roadContainer.addChildAt(segment.shadow, 0);
roadContainer.addChild(segment);
// Add multiple trees to the left and right of the road segment
var treeSpacing = 150; // Space between trees
var numberOfTrees = Math.floor(segment.height / treeSpacing) - 3; // Decrease the number of trees by 3
var numberOfTree2 = Math.floor(segment.height / treeSpacing) - 3; // Decrease the number of tree2 by 3
for (var i = 0; i < numberOfTree2; i++) {
var leftTree = new Tree();
leftTree.x = segment.x - segment.width - 200 - i * treeSpacing; // Decrease the distance from the road by 100 units
leftTree.y = segment.y + i * treeSpacing;
roadContainer.addChild(leftTree);
var rightTree = new Tree2();
rightTree.x = segment.x + segment.width + 200 + i * treeSpacing; // Decrease the distance from the road by 100 units
rightTree.y = segment.y + i * treeSpacing;
roadContainer.addChild(rightTree);
}
// Add rocks to the left and right of the road segment
var leftRock = new Rock();
leftRock.x = segment.x - segment.width - 1000; // Double the distance from the road
leftRock.y = segment.y;
roadContainer.addChildAt(leftRock, 0);
var rightRock = new Rock();
rightRock.x = segment.x + segment.width + 1000; // Double the distance from the road
rightRock.y = segment.y;
roadContainer.addChildAt(rightRock, 0);
// Attach snowy embankments to the left and right of the road segment
var leftEmbankment = new SnowyEmbankment();
leftEmbankment.x = segment.x - segment.width / 2 - 50; // Increase distance by 50 units
leftEmbankment.y = segment.y;
roadContainer.addChild(leftEmbankment);
var rightEmbankment = new SnowyEmbankment();
rightEmbankment.x = segment.x + segment.width / 2 + 50; // Increase distance by 50 units
rightEmbankment.y = segment.y;
roadContainer.addChild(rightEmbankment);
};
var gameState = {
difficulty: "MEDIUM",
weather: "CLEAR_WINTER",
car: "default"
};
var menu = game.addChild(new Menu());
var particles = [];
var snowFogs = [];
var mainContainer = game.addChild(new Container()); //{1x_main}
mainContainer.visible = false;
var roadContainer = mainContainer.addChild(new Container());
var roadSegments = [];
var segmentLength = Math.floor(Math.random() * (1000 - 200 + 1)) + 200;
var segmentWidth = 1200;
var currentX = 2048 / 2;
var currentY = 2732 / 2;
var zigzag = true;
for (var i = 1; i <= 15; i++) {
// Gradually increase turn sharpness and narrow road as player progresses
if (i > 5 && i <= 10) {
segmentWidth = Math.max(400, segmentWidth - 30); // Slightly harder
} else if (i > 10) {
segmentWidth = Math.max(450, segmentWidth - 40); // Less narrow after turn 10
}
game.addRoadSegment();
}
var scoreText = new Text2('Turn: 0', {
size: 75,
fill: 0xFFFFFF,
weight: '800',
dropShadow: true,
dropShadowColor: '#373330',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
scoreText.anchor.set(1, 0); // Anchor to the top right
scoreText.visible = false;
LK.gui.topRight.addChild(scoreText);
// Timer Text2 for minutes:seconds display
var timerText = new Text2('00:00', {
size: 50,
fill: 0xFFFFFF,
weight: '800',
dropShadow: true,
dropShadowColor: '#373330',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
timerText.anchor.set(1, 1); // Bottom right
timerText.visible = false;
LK.gui.bottomRight.addChild(timerText);
// Timer variables
var timerStartTicks = LK.ticks;
var timerLastSeconds = 0;
// Add a neon blue-colored speedometer to the bottom left corner of the map
var speedometer = new Text2('Speed: 0', {
size: 50,
fill: 0x00FFFF,
// Neon blue color
weight: '800',
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
speedometer.anchor.set(0, 1); // Anchor to bottom left
speedometer.visible = false;
LK.gui.bottomLeft.addChild(speedometer);
var car = mainContainer.addChild(new Car());
car.x = 2048 / 2;
car.y = 2732 / 2;
var isGameOver = false;
var score = 0;
var closestSegment = null;
game.down = function (x, y, obj) {
if (!mainContainer.visible) return;
car.changeDirection();
};
game.up = function () {};
LK.on('tick', function () {
if (!mainContainer.visible && !menu.visible) {
mainContainer.visible = true;
scoreText.visible = true;
timerText.visible = true;
speedometer.visible = true;
car._move_migrated();
LK.playMusic('Car', {
loop: true
});
} else if (mainContainer.visible) {
car._move_migrated();
LK.playMusic('Car', {
loop: true
});
}
// Update timerText with hours:minutes:seconds:milliseconds format
var elapsedTicks = LK.ticks - timerStartTicks;
var elapsedMilliseconds = Math.floor(elapsedTicks % 60 * (1000 / 60));
var elapsedSeconds = Math.floor(elapsedTicks / 60);
var elapsedMinutes = Math.floor(elapsedSeconds / 60);
var elapsedHours = Math.floor(elapsedMinutes / 60);
var hours = elapsedHours;
var minutes = elapsedMinutes % 60;
var seconds = elapsedSeconds % 60;
var milliseconds = elapsedMilliseconds;
var hourStr = hours < 10 ? '0' + hours : '' + hours;
var minStr = minutes < 10 ? '0' + minutes : '' + minutes;
var secStr = seconds < 10 ? '0' + seconds : '' + seconds;
var msStr = milliseconds < 100 ? milliseconds < 10 ? '00' + milliseconds : '0' + milliseconds : '' + milliseconds;
timerText.setText(hourStr + ':' + minStr + ':' + secStr + ':' + msStr);
var carIsOnRoad = false;
var carPosition = {
x: car.x,
y: car.y
};
// Update the speedometer with the current speed
speedometer.setText('Speed: ' + Math.round(Math.sqrt(car.momentum.x * car.momentum.x + car.momentum.y * car.momentum.y) * 5) + ' km/h');
var currentClosestSegment = null;
var currentClosestDistance = Infinity;
roadSegments.forEach(function (segment) {
var segmentStart = {
x: segment.x + Math.sin(segment.rotation) * 100,
y: segment.y - Math.cos(segment.rotation) * 100
};
var segmentEnd = {
x: segment.x - Math.sin(segment.rotation) * (segment.height - segment.width / 2),
y: segment.y + Math.cos(segment.rotation) * (segment.height - segment.width / 2)
};
var distance = game.calculateDistanceToPoint(carPosition, segmentStart, segmentEnd);
if (distance < currentClosestDistance) {
currentClosestDistance = distance;
currentClosestSegment = segment;
}
if (distance < segment.width / 2 - 50) {
carIsOnRoad = true;
}
});
if (closestSegment !== currentClosestSegment && !currentClosestSegment.used) {
// Check for intersection between car and road segment
if (car.lastWasIntersecting === false && car.intersects(currentClosestSegment)) {
console.log("Car intersected with a road segment");
}
car.lastWasIntersecting = car.intersects(currentClosestSegment);
closestSegment = currentClosestSegment;
closestSegment.used = true;
score++;
LK.setScore(score);
scoreText.setText('Turn: ' + score.toString());
}
if (!carIsOnRoad) {
LK.showGameOver();
} else {}
var particle = new Particle();
particle.alpha = Math.max(0, Math.min(1, Math.abs(car.nonTravelMomentum) / 5 - 0.5));
if (particle.alpha > 0) {
var noiseX = (Math.random() - 0.5) * 10;
var noiseY = (Math.random() - 0.5) * 10;
particle.x = car.x + noiseX;
particle.y = car.y + noiseY;
mainContainer.addChildAt(particle, 1);
particles.push(particle);
}
particles.forEach(function (particle, index) {
particle.tick();
if (particle.lifetime <= 0) {
particles.splice(index, 1);
}
});
if (LK.ticks % 3 === 0 && Math.abs(car.nonTravelMomentum) > 0.5) {
var snowFog = new SnowFog();
var fogOffsetX = (Math.random() - 0.5) * 150;
var fogOffsetY = 150;
snowFog.initialize(car.x + fogOffsetX, car.y + fogOffsetY);
mainContainer.addChildAt(snowFog, 1);
snowFogs.push(snowFog);
}
snowFogs.forEach(function (fog, index) {
fog.tick();
if (fog.lifetime <= 0) {
snowFogs.splice(index, 1);
}
});
var carLocalPosition = game.toLocal(car.position, car.parent);
var offsetX = (2048 / 2 - carLocalPosition.x) / 20;
var offsetY = (2732 - 450 - carLocalPosition.y) / 20;
mainContainer.x += offsetX;
mainContainer.y += offsetY;
for (var i = roadSegments.length - 1; i >= 0; i--) {
var segmentGlobalPosition = game.toLocal(roadSegments[i].position, roadSegments[i].parent);
if (segmentGlobalPosition.y - roadSegments[i].height > 2732 * 2) {
roadSegments[i].shadow.destroy();
roadSegments[i].destroy();
roadSegments.splice(i, 1);
game.addRoadSegment();
}
// Destroy embankments which are off screen
if (roadSegments[i].leftEmbankment && roadSegments[i].leftEmbankment.y < -50) {
roadSegments[i].leftEmbankment.destroy();
}
if (roadSegments[i].rightEmbankment && roadSegments[i].rightEmbankment.y < -50) {
roadSegments[i].rightEmbankment.destroy();
}
}
});
// Add the game logic for 'DriftAndDodge' here ===================================================================
--- original.js
+++ change.js
@@ -147,9 +147,9 @@
});
};
LK.setTimeout(_rotateWallpaper, 3000);
};
- var titleText = new Text2('DRIFT AND DODGE', {
+ var titleText = new Text2('DIRT RALLY', {
size: 120,
//{1a_menu_title1}
fill: 0x00FFFF,
weight: '800',
@@ -161,36 +161,77 @@
dropShadowDistance: 6 //{1a_menu_title3}
}); //{1a_menu_title4}
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
- titleText.y = 2732 / 3;
- titleText.visible = false;
+ titleText.y = 200;
self.addChild(titleText);
- var buttonContainerMenu = new Container(); //{menu_button_container}
- buttonContainerMenu.x = 2048 / 2;
- buttonContainerMenu.y = 2732 / 2 + 100 + 555 + 777 - 333;
- self.addChild(buttonContainerMenu);
+ var currentPanel = null;
+ var panelsContainer = new Container();
+ panelsContainer.x = 2048 / 2;
+ panelsContainer.y = 2732 / 2;
+ self.addChild(panelsContainer);
+ var difficultyPanel = new MenuPanel('DIFFICULTY', ['EASY', 'MEDIUM', 'HARD'], function (option) {
+ gameState.difficulty = option;
+ });
+ difficultyPanel.visible = false;
+ panelsContainer.addChild(difficultyPanel);
+ var weatherPanel = new MenuPanel('WEATHER', ['CLEAR_WINTER', 'LIGHT_SNOW', 'HEAVY_SNOW', 'BLIZZARD'], function (option) {
+ gameState.weather = option;
+ });
+ weatherPanel.visible = false;
+ panelsContainer.addChild(weatherPanel);
+ var carPanel = new MenuPanel('CAR', ['default', 'sport', 'rally'], function (option) {
+ gameState.car = option;
+ });
+ carPanel.visible = false;
+ panelsContainer.addChild(carPanel);
+ var mainMenuButtonsContainer = new Container(); //{menu_button_container}
+ mainMenuButtonsContainer.x = 2048 / 2;
+ mainMenuButtonsContainer.y = 2732 / 2 + 200;
+ self.addChild(mainMenuButtonsContainer);
var difficultyBtn = new Button('Difficulty', 400, 160); //{menu_diff_btn}
difficultyBtn.x = -600;
difficultyBtn.y = 0;
- buttonContainerMenu.addChild(difficultyBtn);
+ mainMenuButtonsContainer.addChild(difficultyBtn);
difficultyBtn.down = function (x, y, obj) {
- console.log("Difficulty selected");
+ mainMenuButtonsContainer.visible = false;
+ difficultyPanel.visible = true;
+ difficultyPanel.selectOption(gameState.difficulty);
+ currentPanel = 'difficulty';
}; //{menu_diff_down}
var weatherBtn = new Button('Weather', 400, 160); //{menu_weather_btn}
weatherBtn.x = -200;
weatherBtn.y = 0;
- buttonContainerMenu.addChild(weatherBtn);
+ mainMenuButtonsContainer.addChild(weatherBtn);
weatherBtn.down = function (x, y, obj) {
- console.log("Weather selected");
+ mainMenuButtonsContainer.visible = false;
+ weatherPanel.visible = true;
+ weatherPanel.selectOption(gameState.weather);
+ currentPanel = 'weather';
}; //{menu_weather_down}
var carBtn = new Button('Car', 400, 160); //{menu_car_btn}
carBtn.x = 200;
carBtn.y = 0;
- buttonContainerMenu.addChild(carBtn);
+ mainMenuButtonsContainer.addChild(carBtn);
carBtn.down = function (x, y, obj) {
- console.log("Car selected");
+ mainMenuButtonsContainer.visible = false;
+ carPanel.visible = true;
+ carPanel.selectOption(gameState.car);
+ currentPanel = 'car';
}; //{menu_car_down}
+ var backBtn = new Button('BACK', 350, 80);
+ backBtn.x = 0;
+ backBtn.y = 500;
+ panelsContainer.addChild(backBtn);
+ backBtn.visible = false;
+ backBtn.down = function () {
+ difficultyPanel.visible = false;
+ weatherPanel.visible = false;
+ carPanel.visible = false;
+ backBtn.visible = false;
+ mainMenuButtonsContainer.visible = true;
+ currentPanel = null;
+ };
var startBtn = Container.call(new Container());
startBtn.interactive = true;
startBtn.buttonMode = true;
var startButtonBg = startBtn.attachAsset('Startbutton', {
@@ -214,17 +255,73 @@
startBtn.onUp = function () {
startButtonBg.alpha = 1;
};
startBtn.x = 600;
- startBtn.y = 0;
- buttonContainerMenu.addChild(startBtn);
+ startBtn.y = 400;
+ mainMenuButtonsContainer.addChild(startBtn);
startBtn.down = function (x, y, obj) {
self.visible = false;
self.interactive = false;
}; //{menu_start_down}
self.startWallpaperRotation();
return self;
});
+var MenuPanel = Container.expand(function (title, options, onSelect) {
+ var self = Container.call(this);
+ var panelWidth = 600;
+ var panelHeight = 400;
+ var optionButtons = [];
+ var panelBg = new Container();
+ var bgShape = LK.getAsset('Button', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ bgShape.width = panelWidth;
+ bgShape.height = panelHeight;
+ bgShape.alpha = 0.9;
+ panelBg.addChild(bgShape);
+ self.addChild(panelBg);
+ var titleText = new Text2(title, {
+ size: 60,
+ fill: 0x00FFFF,
+ weight: '800'
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleText.y = -panelHeight / 2 + 50;
+ self.addChild(titleText);
+ var optionsContainer = new Container();
+ optionsContainer.y = -panelHeight / 2 + 130;
+ self.addChild(optionsContainer);
+ var optionSpacing = 60;
+ options.forEach(function (option, index) {
+ var optionBtn = new Button(option, 450, 80);
+ optionBtn.y = index * optionSpacing;
+ optionBtn.isSelected = false;
+ optionBtn.optionValue = option;
+ optionBtn.down = function () {
+ optionButtons.forEach(function (btn) {
+ btn.isSelected = false;
+ });
+ optionBtn.isSelected = true;
+ onSelect(option);
+ };
+ optionsContainer.addChild(optionBtn);
+ optionButtons.push(optionBtn);
+ });
+ self.selectOption = function (optionValue) {
+ optionButtons.forEach(function (btn) {
+ if (btn.optionValue === optionValue) {
+ btn.isSelected = true;
+ } else {
+ btn.isSelected = false;
+ }
+ });
+ };
+ self.getOptionButtons = function () {
+ return optionButtons;
+ };
+ return self;
+});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
@@ -398,8 +495,13 @@
rightEmbankment.x = segment.x + segment.width / 2 + 50; // Increase distance by 50 units
rightEmbankment.y = segment.y;
roadContainer.addChild(rightEmbankment);
};
+var gameState = {
+ difficulty: "MEDIUM",
+ weather: "CLEAR_WINTER",
+ car: "default"
+};
var menu = game.addChild(new Menu());
var particles = [];
var snowFogs = [];
var mainContainer = game.addChild(new Container()); //{1x_main}