User prompt
mesajları çok az küçült tamam
User prompt
shop mesajlarını biraz daha yukarı taşırsan tamamdır
User prompt
beyaz panelin içine koymak bu kadar zor olmamalı amk shop mesajlarını açılan beyaz karenin içine okunakşı bir şekilde orantıla
User prompt
upgrade mesajlarının tamamı mesaj panelinin içinde olsun
User prompt
shop açılınca upgrade capacity mesajını beyaz menünün sol en üstünden bailat
User prompt
bus capacity mesajını eski yerine kou
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'shopPanelBg.addChild')' in or related to this line: 'var dragBus = false;' Line Number: 249
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'shopPanelBg.addChild')' in or related to this line: 'shopPanelBg.addChild(busCapacityBarText);' Line Number: 247
User prompt
yapsana yarrak kafası capacity mesajı aynı yerde en sol en üstten başlamalı
User prompt
shop upgrade yazılarını beyaz panelin en üst en solundan başlat
User prompt
shop yazılarını soldan sağa yazdır
User prompt
beyaz menünün en solundan yazıların başlamasını sağla
User prompt
yazıları shop menüsünün açıldığı yere orantıla
User prompt
hâlâ yazılar alakasız duruyor yazıları white panele göre ayarla
User prompt
shop menüsündeki yazıları açılan menüye koy sağ altta alakasız durmasın ve beyaz renk assets oluşturup menü rengini beyaz yap
User prompt
shop menüsündeki yazıları ekrana ortala
User prompt
shop menüsünü daha estetik yap yazıyı yazıp sağına buton koy
User prompt
shop butonunu sola koy
User prompt
shop butonu ekle puanlarla kapasite arttırabilelim hız arttırabilelim ve yolculardan gelen parayı arttırabilelim
User prompt
kapasiteyi aşmayı düzelt mesela 8/10 ise ve durakta 5 yolcu varsa 2 tane alalım 3 tanesi durakta kalsın
User prompt
bir zaman sonra durak spawn olmamasını düzelt oyunu bitmeyen bir oyun yap
User prompt
yolcu alma duraklarına giderken metrenin artmasını düzelt her zaman en yakın durağa kaç metre kaldığını göstersin
User prompt
metre barına text ekle ne kadar metre kaldığını sayıyla görelim
User prompt
durağa yolcuları bırakınca kaybolmalarını düzelt
User prompt
hâlâ çok yakın spawn oluyolar spawn olma sayılarını azalt ve aralarında boşlukları arttır 1 ekranda en fazla 2 durak gözüksün
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bus (player) class var Bus = Container.expand(function () { var self = Container.call(this); var busAsset = self.attachAsset('bus', { anchorX: 0.5, anchorY: 1 }); // For touch drag self.dragging = false; self.dragOffsetY = 0; // Called every tick self.update = function () { // Clamp bus to road (vertical bounds) if (self.y < 400) self.y = 400; if (self.y > 2200) self.y = 2200; }; // Touch down on bus self.down = function (x, y, obj) { self.dragging = true; self.dragOffsetY = y - self.y; }; // Touch up on bus self.up = function (x, y, obj) { self.dragging = false; }; return self; }); // Bus Station class var BusStation = Container.expand(function () { var self = Container.call(this); // Use dropStation asset if isPickup is false, otherwise use station var assetId = typeof self.isPickup !== "undefined" && self.isPickup === false ? 'dropStation' : 'station'; var stationAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 1 }); // List of travelers at this station self.travelers = []; // Travelers are now spawned in spawnStation, not here // Remove traveler from this station self.removeTraveler = function (traveler) { for (var i = 0; i < self.travelers.length; i++) { if (self.travelers[i] === traveler) { self.travelers.splice(i, 1); break; } } }; // Called every tick self.update = function () { // No longer remove station when bus passes; stations persist }; return self; }); // Traveler class var Traveler = Container.expand(function () { var self = Container.call(this); var travelerAsset = self.attachAsset('traveler', { anchorX: 0.5, anchorY: 1 }); // Reference to the station this traveler belongs to self.station = null; // Whether this traveler is still waiting at the station self.waiting = true; // Track if this traveler was dropped (for possible future logic) self.dropped = false; // Time (in ticks) until this traveler leaves self.leaveTick = 0; // Called every tick self.update = function () { // If not waiting, do nothing if (!self.waiting) return; // Travelers no longer leave by themselves // Remove the leave-tick logic entirely }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // visually distinguish drop station (flipX as example) var streetBgWidth = 900; var streetBgHeight = 400; var streetBgY = 1500; var streetBgs = []; for (var i = 0; i < 3; i++) { var streetBg = LK.getAsset('streetBg', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + (i - 1) * streetBgWidth, y: streetBgY }); game.addChild(streetBg); streetBgs.push(streetBg); } // Traveler // Bus station // Bus (player vehicle) // Game world scroll variables var scrollX = 0; // How far the world has scrolled right var scrollSpeed = 10; // Pixels per tick // Bus (player) var bus = new Bus(); game.addChild(bus); bus.x = 400; bus.y = 1500; // List of stations in the world var stations = []; // Spawn fewer stations, with much greater spacing, and ensure max 2 stations visible on screen var lastStationX = 1200; var NUM_STATIONS = 6; // fewer stations for less crowding var minStationSpacing = 1200; // minimum distance between stations (at least 1 screen width) var maxStationSpacing = 1600; // maximum distance between stations var stationWidth = 400; for (var i = 0; i < NUM_STATIONS; i++) { var isPickup = i % 2 === 0; var tryCount = 0; var valid = false; var tryX = 0; while (!valid && tryCount < 100) { var spacing = minStationSpacing + Math.floor(Math.random() * (maxStationSpacing - minStationSpacing + 1)); if (i === 0) { tryX = 1200; } else { tryX = lastStationX + spacing; } // Check for overlap with all previous stations (ensure at least minStationSpacing between centers) valid = true; for (var j = 0; j < stations.length; j++) { var prev = stations[j]; if (Math.abs(tryX - prev.x) < minStationSpacing) { valid = false; break; } } tryCount++; } lastStationX = tryX; spawnStation(lastStationX, isPickup); } // GUI: Score (number of travelers picked up) var score = 0; var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Meter Bar UI --- var meterBarBg = LK.getAsset('streetBg', { anchorX: 0, anchorY: 0.5, x: 200, y: 120, width: 600, height: 40, color: 0x222222 }); var meterBarFill = LK.getAsset('streetBg', { anchorX: 0, anchorY: 0.5, x: 200, y: 120, width: 600, height: 40, color: 0x2d8cf0 }); meterBarFill.width = 0; LK.gui.top.addChild(meterBarBg); LK.gui.top.addChild(meterBarFill); var meterBarText = new Text2('0m', { size: 60, fill: 0xffffff }); meterBarText.anchor.set(0, 0.5); meterBarText.x = 820; meterBarText.y = 120; LK.gui.top.addChild(meterBarText); // --- Bus Capacity Bar UI --- var busCapacityBarBg = LK.getAsset('streetBg', { anchorX: 0, anchorY: 0.5, x: 200, y: 200, width: 600, height: 32, color: 0x444444 }); var busCapacityBarFill = LK.getAsset('streetBg', { anchorX: 0, anchorY: 0.5, x: 200, y: 200, width: 600, height: 32, color: 0x83de44 }); busCapacityBarFill.width = 0; LK.gui.top.addChild(busCapacityBarBg); LK.gui.top.addChild(busCapacityBarFill); // Add text to capacity bar var busCapacityBarText = new Text2('0/10', { size: 48, fill: 0xffffff }); busCapacityBarText.anchor.set(0.5, 0.5); busCapacityBarText.x = 200 + 600 / 2; busCapacityBarText.y = 200; LK.gui.top.addChild(busCapacityBarText); // For dragging bus var dragBus = false; // --- Take Travelers Button --- var takeBtnBg = LK.getAsset('takeBtnBg', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 220, y: 2732 - 200 }); var takeBtnTxt = new Text2('Take Travelers', { size: 60, fill: 0xffffff }); takeBtnTxt.anchor.set(0.5, 0.5); takeBtnBg.addChild(takeBtnTxt); game.addChild(takeBtnBg); // --- Drop Travelers Button --- var dropBtnBg = LK.getAsset('takeBtnBg', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 220, y: 2732 - 200 }); var dropBtnTxt = new Text2('Drop Travelers', { size: 60, fill: 0xffffff }); dropBtnTxt.anchor.set(0.5, 0.5); dropBtnBg.addChild(dropBtnTxt); game.addChild(dropBtnBg); // Track if take or drop button is pressed this frame var takeBtnPressed = false; var dropBtnPressed = false; // Button press handlers takeBtnBg.down = function (x, y, obj) { if (takeBtnBg.interactive !== false) { takeBtnPressed = true; } }; dropBtnBg.down = function (x, y, obj) { if (dropBtnBg.interactive !== false) { dropBtnPressed = true; } }; // Generate a station at a given x, alternating pickup/drop and up/down function spawnStation(x, isPickup) { var station = new BusStation(); station.isPickup = !!isPickup; // Re-attach correct asset if drop station (for existing BusStation instances) if (!station.isPickup) { if (station.children.length > 0) { station.removeChild(station.children[0]); } station.attachAsset('dropStation', { anchorX: 0.5, anchorY: 1 }); } // Alternate up/down for each station var streetCenterY = streetBgY; if (stations.length % 2 === 0) { station.y = streetCenterY - streetBgHeight / 2 - 40; // above street } else { station.y = streetCenterY + streetBgHeight / 2 + 40; // below street } // Place at given x station.x = x; // Spawn travelers immediately if pickup station if (station.isPickup) { var numTravelers = 1 + Math.floor(Math.random() * 10); var travelerYOffset = station.y < streetCenterY ? -140 : 140; for (var i = 0; i < numTravelers; i++) { var traveler = new Traveler(); traveler.station = station; traveler.x = 0; traveler.y = travelerYOffset + (station.y < streetCenterY ? -i * 130 : i * 130); station.addChild(traveler); station.travelers.push(traveler); } } game.addChild(station); stations.push(station); } // (removed duplicate old station spawn code) // Move handler for dragging bus function handleMove(x, y, obj) { // Only drag if started on bus if (bus.dragging) { bus.y = y - bus.dragOffsetY; } } game.move = handleMove; // Down handler: start drag if on bus, or start holding for rightward movement var holdingRight = false; game.down = function (x, y, obj) { // Convert to bus local coordinates var local = bus.toLocal(game.toGlobal({ x: x, y: y })); // If within bus bounds, start drag if (local.x > -bus.width / 2 && local.x < bus.width / 2 && local.y > -bus.height && local.y < 0) { bus.dragging = true; bus.dragOffsetY = y - bus.y; } else { // Start holding for rightward movement holdingRight = true; } }; // Up handler: stop drag and stop holding rightward movement game.up = function (x, y, obj) { bus.dragging = false; holdingRight = false; }; // Main game update loop game.update = function () { // Move bus/world right if holding if (typeof holdingRight !== "undefined" && holdingRight) { var moveAmount = scrollSpeed; // Instead of moving the bus, move the world and keep bus centered scrollX += moveAmount; for (var i = 0; i < stations.length; i++) { stations[i].x -= moveAmount; } // Move and repeat street backgrounds for (var i = 0; i < streetBgs.length; i++) { streetBgs[i].x -= moveAmount; // If streetBg is fully off the left, move it to the right end if (streetBgs[i].x < -streetBgWidth / 2) { // Find the rightmost streetBg var maxX = streetBgs[0].x; for (var j = 1; j < streetBgs.length; j++) { if (streetBgs[j].x > maxX) maxX = streetBgs[j].x; } streetBgs[i].x = maxX + streetBgWidth; } } } // Always keep bus in the center of the screen horizontally bus.x = 2048 / 2; // Move all stations and their travelers (no auto scroll) for (var i = 0; i < stations.length; i++) { var station = stations[i]; // No station.x -= scrollSpeed; station.update(); for (var j = 0; j < station.travelers.length; j++) { station.travelers[j].update(); } } // Update bus bus.update(); // --- Meter Bar Update: Show distance to next station --- var nextStation = null; if (bus.lastPickupStationIndex !== undefined && bus.lastPickupStationIndex + 1 < stations.length) { nextStation = stations[bus.lastPickupStationIndex + 1]; } if (!nextStation && stations.length > 1) { nextStation = stations[1]; } if (nextStation) { var dist = Math.max(0, Math.floor(Math.abs(nextStation.x - bus.x))); var maxDist = 1200; // Max distance for full bar var barWidth = Math.max(0, Math.min(600, 600 * (1 - dist / maxDist))); meterBarFill.width = barWidth; meterBarText.setText(dist + "m"); } else { meterBarFill.width = 0; meterBarText.setText("0m"); } // (No need to spawn or remove stations here, handled at game start) // --- Manual pickup and drop-off logic with Take Travelers button --- // --- Manual pickup and drop-off logic with Take Travelers button --- if (typeof bus.travelersOnBoard === "undefined") { bus.travelersOnBoard = []; bus.lastPickupStationIndex = -1; bus.lastDropStationIndex = -1; } // --- Enable/disable Take Travelers button based on action possibility --- var canTake = false; var canDrop = false; var dropStationIndex = -1; // Check if we can take travelers at a nearby station for (var i = 0; i < stations.length; i++) { var station = stations[i]; // Take: must be pickup station, has travelers, close, and not already picked up here if (station.isPickup && station.travelers.length > 0 && Math.abs(station.x - bus.x) < 180 && bus.lastPickupStationIndex !== i) { canTake = true; } // Drop: must be drop station, bus has travelers, close, and not already dropped here if (!station.isPickup && bus.travelersOnBoard && bus.travelersOnBoard.length > 0 && Math.abs(station.x - bus.x) < 180 && bus.lastDropStationIndex !== i) { canDrop = true; dropStationIndex = i; } } // --- Bus Capacity Bar Update --- var maxCapacity = 10; var travelersOnBoardCount = bus.travelersOnBoard ? bus.travelersOnBoard.length : 0; var capBarWidth = Math.max(0, Math.min(600, 600 * (travelersOnBoardCount / maxCapacity))); busCapacityBarFill.width = capBarWidth; busCapacityBarText.setText(travelersOnBoardCount + "/" + maxCapacity); // Visually enable/disable the take and drop buttons takeBtnBg.alpha = canTake ? 1 : 0.4; takeBtnBg.interactive = canTake; dropBtnBg.alpha = canDrop ? 1 : 0.4; dropBtnBg.interactive = canDrop; // --- Manual Pickup logic: only when button pressed --- if (takeBtnPressed) { for (var i = 0; i < stations.length; i++) { var station = stations[i]; // Only pick up if bus is close to pickup station, this is a new station, and this station has travelers if (station.isPickup && station.travelers.length > 0 && Math.abs(station.x - bus.x) < 180 && bus.lastPickupStationIndex !== i) { // Pick up all waiting travelers at this station var waitingTravelers = []; for (var j = station.travelers.length - 1; j >= 0; j--) { var traveler = station.travelers[j]; if (traveler.waiting) { waitingTravelers.push(traveler); } } // Actually pick up the travelers for (var w = 0; w < waitingTravelers.length; w++) { var traveler = waitingTravelers[w]; traveler.waiting = false; // Animate traveler to bus, then destroy tween(traveler, { x: bus.x - station.x, y: bus.y - station.y - 100, alpha: 0 }, { duration: 400, easing: tween.easeIn, onFinish: function (trav) { return function () { trav.destroy(); }; }(traveler) }); // Add to bus's onboard list if (!bus.travelersOnBoard) bus.travelersOnBoard = []; bus.travelersOnBoard.push({ traveler: traveler, pickedUpAt: i }); // Remove from station station.removeTraveler(traveler); score += 1; scoreTxt.setText(score); } // Mark this station as the last pickup bus.lastPickupStationIndex = i; break; // Only pick up at one station per press } } takeBtnPressed = false; // Reset button press } // --- Manual Drop-off logic: only when drop button pressed --- if (dropBtnPressed && canDrop && dropStationIndex !== -1) { var station = stations[dropStationIndex]; // Drop all travelers currently on the bus if (bus.travelersOnBoard && bus.travelersOnBoard.length > 0) { // Calculate base Y for stacking var baseY = 0; var stackDir = 1; // If station is above street, stack upwards; if below, stack downwards var streetCenterY = streetBgY; if (station.y < streetCenterY) { baseY = -140; stackDir = -1; } else { baseY = 140; stackDir = 1; } // Count how many travelers are already at this drop station (for stacking) var alreadyDropped = 0; for (var tt = 0; tt < station.travelers.length; tt++) { if (station.travelers[tt].dropped) alreadyDropped++; } for (var t = 0; t < bus.travelersOnBoard.length; t++) { var travelerObj = bus.travelersOnBoard[t]; var traveler = travelerObj.traveler; // Animate traveler to station, then destroy var newTraveler = new Traveler(); newTraveler.x = bus.x - station.x; newTraveler.y = bus.y - station.y - 100; newTraveler.alpha = 0; newTraveler.waiting = false; newTraveler.dropped = true; newTraveler.station = station; // Stack vertically at the station var stackIndex = alreadyDropped + t; newTraveler.x = 0; newTraveler.y = baseY + stackDir * stackIndex * 130; newTraveler.alpha = 0; station.addChild(newTraveler); station.travelers.push(newTraveler); tween(newTraveler, { x: 0, y: baseY + stackDir * stackIndex * 130, alpha: 1 }, { duration: 400, easing: tween.easeOut, onFinish: function (trav) { return function () { trav.destroy(); }; }(newTraveler) }); } // Clear bus bus.travelersOnBoard = []; // Mark this station as the last drop bus.lastDropStationIndex = dropStationIndex; } dropBtnPressed = false; // Reset button press } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Bus (player) class
var Bus = Container.expand(function () {
var self = Container.call(this);
var busAsset = self.attachAsset('bus', {
anchorX: 0.5,
anchorY: 1
});
// For touch drag
self.dragging = false;
self.dragOffsetY = 0;
// Called every tick
self.update = function () {
// Clamp bus to road (vertical bounds)
if (self.y < 400) self.y = 400;
if (self.y > 2200) self.y = 2200;
};
// Touch down on bus
self.down = function (x, y, obj) {
self.dragging = true;
self.dragOffsetY = y - self.y;
};
// Touch up on bus
self.up = function (x, y, obj) {
self.dragging = false;
};
return self;
});
// Bus Station class
var BusStation = Container.expand(function () {
var self = Container.call(this);
// Use dropStation asset if isPickup is false, otherwise use station
var assetId = typeof self.isPickup !== "undefined" && self.isPickup === false ? 'dropStation' : 'station';
var stationAsset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 1
});
// List of travelers at this station
self.travelers = [];
// Travelers are now spawned in spawnStation, not here
// Remove traveler from this station
self.removeTraveler = function (traveler) {
for (var i = 0; i < self.travelers.length; i++) {
if (self.travelers[i] === traveler) {
self.travelers.splice(i, 1);
break;
}
}
};
// Called every tick
self.update = function () {
// No longer remove station when bus passes; stations persist
};
return self;
});
// Traveler class
var Traveler = Container.expand(function () {
var self = Container.call(this);
var travelerAsset = self.attachAsset('traveler', {
anchorX: 0.5,
anchorY: 1
});
// Reference to the station this traveler belongs to
self.station = null;
// Whether this traveler is still waiting at the station
self.waiting = true;
// Track if this traveler was dropped (for possible future logic)
self.dropped = false;
// Time (in ticks) until this traveler leaves
self.leaveTick = 0;
// Called every tick
self.update = function () {
// If not waiting, do nothing
if (!self.waiting) return;
// Travelers no longer leave by themselves
// Remove the leave-tick logic entirely
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// visually distinguish drop station (flipX as example)
var streetBgWidth = 900;
var streetBgHeight = 400;
var streetBgY = 1500;
var streetBgs = [];
for (var i = 0; i < 3; i++) {
var streetBg = LK.getAsset('streetBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + (i - 1) * streetBgWidth,
y: streetBgY
});
game.addChild(streetBg);
streetBgs.push(streetBg);
}
// Traveler
// Bus station
// Bus (player vehicle)
// Game world scroll variables
var scrollX = 0; // How far the world has scrolled right
var scrollSpeed = 10; // Pixels per tick
// Bus (player)
var bus = new Bus();
game.addChild(bus);
bus.x = 400;
bus.y = 1500;
// List of stations in the world
var stations = [];
// Spawn fewer stations, with much greater spacing, and ensure max 2 stations visible on screen
var lastStationX = 1200;
var NUM_STATIONS = 6; // fewer stations for less crowding
var minStationSpacing = 1200; // minimum distance between stations (at least 1 screen width)
var maxStationSpacing = 1600; // maximum distance between stations
var stationWidth = 400;
for (var i = 0; i < NUM_STATIONS; i++) {
var isPickup = i % 2 === 0;
var tryCount = 0;
var valid = false;
var tryX = 0;
while (!valid && tryCount < 100) {
var spacing = minStationSpacing + Math.floor(Math.random() * (maxStationSpacing - minStationSpacing + 1));
if (i === 0) {
tryX = 1200;
} else {
tryX = lastStationX + spacing;
}
// Check for overlap with all previous stations (ensure at least minStationSpacing between centers)
valid = true;
for (var j = 0; j < stations.length; j++) {
var prev = stations[j];
if (Math.abs(tryX - prev.x) < minStationSpacing) {
valid = false;
break;
}
}
tryCount++;
}
lastStationX = tryX;
spawnStation(lastStationX, isPickup);
}
// GUI: Score (number of travelers picked up)
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// --- Meter Bar UI ---
var meterBarBg = LK.getAsset('streetBg', {
anchorX: 0,
anchorY: 0.5,
x: 200,
y: 120,
width: 600,
height: 40,
color: 0x222222
});
var meterBarFill = LK.getAsset('streetBg', {
anchorX: 0,
anchorY: 0.5,
x: 200,
y: 120,
width: 600,
height: 40,
color: 0x2d8cf0
});
meterBarFill.width = 0;
LK.gui.top.addChild(meterBarBg);
LK.gui.top.addChild(meterBarFill);
var meterBarText = new Text2('0m', {
size: 60,
fill: 0xffffff
});
meterBarText.anchor.set(0, 0.5);
meterBarText.x = 820;
meterBarText.y = 120;
LK.gui.top.addChild(meterBarText);
// --- Bus Capacity Bar UI ---
var busCapacityBarBg = LK.getAsset('streetBg', {
anchorX: 0,
anchorY: 0.5,
x: 200,
y: 200,
width: 600,
height: 32,
color: 0x444444
});
var busCapacityBarFill = LK.getAsset('streetBg', {
anchorX: 0,
anchorY: 0.5,
x: 200,
y: 200,
width: 600,
height: 32,
color: 0x83de44
});
busCapacityBarFill.width = 0;
LK.gui.top.addChild(busCapacityBarBg);
LK.gui.top.addChild(busCapacityBarFill);
// Add text to capacity bar
var busCapacityBarText = new Text2('0/10', {
size: 48,
fill: 0xffffff
});
busCapacityBarText.anchor.set(0.5, 0.5);
busCapacityBarText.x = 200 + 600 / 2;
busCapacityBarText.y = 200;
LK.gui.top.addChild(busCapacityBarText);
// For dragging bus
var dragBus = false;
// --- Take Travelers Button ---
var takeBtnBg = LK.getAsset('takeBtnBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 220,
y: 2732 - 200
});
var takeBtnTxt = new Text2('Take Travelers', {
size: 60,
fill: 0xffffff
});
takeBtnTxt.anchor.set(0.5, 0.5);
takeBtnBg.addChild(takeBtnTxt);
game.addChild(takeBtnBg);
// --- Drop Travelers Button ---
var dropBtnBg = LK.getAsset('takeBtnBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 220,
y: 2732 - 200
});
var dropBtnTxt = new Text2('Drop Travelers', {
size: 60,
fill: 0xffffff
});
dropBtnTxt.anchor.set(0.5, 0.5);
dropBtnBg.addChild(dropBtnTxt);
game.addChild(dropBtnBg);
// Track if take or drop button is pressed this frame
var takeBtnPressed = false;
var dropBtnPressed = false;
// Button press handlers
takeBtnBg.down = function (x, y, obj) {
if (takeBtnBg.interactive !== false) {
takeBtnPressed = true;
}
};
dropBtnBg.down = function (x, y, obj) {
if (dropBtnBg.interactive !== false) {
dropBtnPressed = true;
}
};
// Generate a station at a given x, alternating pickup/drop and up/down
function spawnStation(x, isPickup) {
var station = new BusStation();
station.isPickup = !!isPickup;
// Re-attach correct asset if drop station (for existing BusStation instances)
if (!station.isPickup) {
if (station.children.length > 0) {
station.removeChild(station.children[0]);
}
station.attachAsset('dropStation', {
anchorX: 0.5,
anchorY: 1
});
}
// Alternate up/down for each station
var streetCenterY = streetBgY;
if (stations.length % 2 === 0) {
station.y = streetCenterY - streetBgHeight / 2 - 40; // above street
} else {
station.y = streetCenterY + streetBgHeight / 2 + 40; // below street
}
// Place at given x
station.x = x;
// Spawn travelers immediately if pickup station
if (station.isPickup) {
var numTravelers = 1 + Math.floor(Math.random() * 10);
var travelerYOffset = station.y < streetCenterY ? -140 : 140;
for (var i = 0; i < numTravelers; i++) {
var traveler = new Traveler();
traveler.station = station;
traveler.x = 0;
traveler.y = travelerYOffset + (station.y < streetCenterY ? -i * 130 : i * 130);
station.addChild(traveler);
station.travelers.push(traveler);
}
}
game.addChild(station);
stations.push(station);
}
// (removed duplicate old station spawn code)
// Move handler for dragging bus
function handleMove(x, y, obj) {
// Only drag if started on bus
if (bus.dragging) {
bus.y = y - bus.dragOffsetY;
}
}
game.move = handleMove;
// Down handler: start drag if on bus, or start holding for rightward movement
var holdingRight = false;
game.down = function (x, y, obj) {
// Convert to bus local coordinates
var local = bus.toLocal(game.toGlobal({
x: x,
y: y
}));
// If within bus bounds, start drag
if (local.x > -bus.width / 2 && local.x < bus.width / 2 && local.y > -bus.height && local.y < 0) {
bus.dragging = true;
bus.dragOffsetY = y - bus.y;
} else {
// Start holding for rightward movement
holdingRight = true;
}
};
// Up handler: stop drag and stop holding rightward movement
game.up = function (x, y, obj) {
bus.dragging = false;
holdingRight = false;
};
// Main game update loop
game.update = function () {
// Move bus/world right if holding
if (typeof holdingRight !== "undefined" && holdingRight) {
var moveAmount = scrollSpeed;
// Instead of moving the bus, move the world and keep bus centered
scrollX += moveAmount;
for (var i = 0; i < stations.length; i++) {
stations[i].x -= moveAmount;
}
// Move and repeat street backgrounds
for (var i = 0; i < streetBgs.length; i++) {
streetBgs[i].x -= moveAmount;
// If streetBg is fully off the left, move it to the right end
if (streetBgs[i].x < -streetBgWidth / 2) {
// Find the rightmost streetBg
var maxX = streetBgs[0].x;
for (var j = 1; j < streetBgs.length; j++) {
if (streetBgs[j].x > maxX) maxX = streetBgs[j].x;
}
streetBgs[i].x = maxX + streetBgWidth;
}
}
}
// Always keep bus in the center of the screen horizontally
bus.x = 2048 / 2;
// Move all stations and their travelers (no auto scroll)
for (var i = 0; i < stations.length; i++) {
var station = stations[i];
// No station.x -= scrollSpeed;
station.update();
for (var j = 0; j < station.travelers.length; j++) {
station.travelers[j].update();
}
}
// Update bus
bus.update();
// --- Meter Bar Update: Show distance to next station ---
var nextStation = null;
if (bus.lastPickupStationIndex !== undefined && bus.lastPickupStationIndex + 1 < stations.length) {
nextStation = stations[bus.lastPickupStationIndex + 1];
}
if (!nextStation && stations.length > 1) {
nextStation = stations[1];
}
if (nextStation) {
var dist = Math.max(0, Math.floor(Math.abs(nextStation.x - bus.x)));
var maxDist = 1200; // Max distance for full bar
var barWidth = Math.max(0, Math.min(600, 600 * (1 - dist / maxDist)));
meterBarFill.width = barWidth;
meterBarText.setText(dist + "m");
} else {
meterBarFill.width = 0;
meterBarText.setText("0m");
}
// (No need to spawn or remove stations here, handled at game start)
// --- Manual pickup and drop-off logic with Take Travelers button ---
// --- Manual pickup and drop-off logic with Take Travelers button ---
if (typeof bus.travelersOnBoard === "undefined") {
bus.travelersOnBoard = [];
bus.lastPickupStationIndex = -1;
bus.lastDropStationIndex = -1;
}
// --- Enable/disable Take Travelers button based on action possibility ---
var canTake = false;
var canDrop = false;
var dropStationIndex = -1;
// Check if we can take travelers at a nearby station
for (var i = 0; i < stations.length; i++) {
var station = stations[i];
// Take: must be pickup station, has travelers, close, and not already picked up here
if (station.isPickup && station.travelers.length > 0 && Math.abs(station.x - bus.x) < 180 && bus.lastPickupStationIndex !== i) {
canTake = true;
}
// Drop: must be drop station, bus has travelers, close, and not already dropped here
if (!station.isPickup && bus.travelersOnBoard && bus.travelersOnBoard.length > 0 && Math.abs(station.x - bus.x) < 180 && bus.lastDropStationIndex !== i) {
canDrop = true;
dropStationIndex = i;
}
}
// --- Bus Capacity Bar Update ---
var maxCapacity = 10;
var travelersOnBoardCount = bus.travelersOnBoard ? bus.travelersOnBoard.length : 0;
var capBarWidth = Math.max(0, Math.min(600, 600 * (travelersOnBoardCount / maxCapacity)));
busCapacityBarFill.width = capBarWidth;
busCapacityBarText.setText(travelersOnBoardCount + "/" + maxCapacity);
// Visually enable/disable the take and drop buttons
takeBtnBg.alpha = canTake ? 1 : 0.4;
takeBtnBg.interactive = canTake;
dropBtnBg.alpha = canDrop ? 1 : 0.4;
dropBtnBg.interactive = canDrop;
// --- Manual Pickup logic: only when button pressed ---
if (takeBtnPressed) {
for (var i = 0; i < stations.length; i++) {
var station = stations[i];
// Only pick up if bus is close to pickup station, this is a new station, and this station has travelers
if (station.isPickup && station.travelers.length > 0 && Math.abs(station.x - bus.x) < 180 && bus.lastPickupStationIndex !== i) {
// Pick up all waiting travelers at this station
var waitingTravelers = [];
for (var j = station.travelers.length - 1; j >= 0; j--) {
var traveler = station.travelers[j];
if (traveler.waiting) {
waitingTravelers.push(traveler);
}
}
// Actually pick up the travelers
for (var w = 0; w < waitingTravelers.length; w++) {
var traveler = waitingTravelers[w];
traveler.waiting = false;
// Animate traveler to bus, then destroy
tween(traveler, {
x: bus.x - station.x,
y: bus.y - station.y - 100,
alpha: 0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function (trav) {
return function () {
trav.destroy();
};
}(traveler)
});
// Add to bus's onboard list
if (!bus.travelersOnBoard) bus.travelersOnBoard = [];
bus.travelersOnBoard.push({
traveler: traveler,
pickedUpAt: i
});
// Remove from station
station.removeTraveler(traveler);
score += 1;
scoreTxt.setText(score);
}
// Mark this station as the last pickup
bus.lastPickupStationIndex = i;
break; // Only pick up at one station per press
}
}
takeBtnPressed = false; // Reset button press
}
// --- Manual Drop-off logic: only when drop button pressed ---
if (dropBtnPressed && canDrop && dropStationIndex !== -1) {
var station = stations[dropStationIndex];
// Drop all travelers currently on the bus
if (bus.travelersOnBoard && bus.travelersOnBoard.length > 0) {
// Calculate base Y for stacking
var baseY = 0;
var stackDir = 1;
// If station is above street, stack upwards; if below, stack downwards
var streetCenterY = streetBgY;
if (station.y < streetCenterY) {
baseY = -140;
stackDir = -1;
} else {
baseY = 140;
stackDir = 1;
}
// Count how many travelers are already at this drop station (for stacking)
var alreadyDropped = 0;
for (var tt = 0; tt < station.travelers.length; tt++) {
if (station.travelers[tt].dropped) alreadyDropped++;
}
for (var t = 0; t < bus.travelersOnBoard.length; t++) {
var travelerObj = bus.travelersOnBoard[t];
var traveler = travelerObj.traveler;
// Animate traveler to station, then destroy
var newTraveler = new Traveler();
newTraveler.x = bus.x - station.x;
newTraveler.y = bus.y - station.y - 100;
newTraveler.alpha = 0;
newTraveler.waiting = false;
newTraveler.dropped = true;
newTraveler.station = station;
// Stack vertically at the station
var stackIndex = alreadyDropped + t;
newTraveler.x = 0;
newTraveler.y = baseY + stackDir * stackIndex * 130;
newTraveler.alpha = 0;
station.addChild(newTraveler);
station.travelers.push(newTraveler);
tween(newTraveler, {
x: 0,
y: baseY + stackDir * stackIndex * 130,
alpha: 1
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function (trav) {
return function () {
trav.destroy();
};
}(newTraveler)
});
}
// Clear bus
bus.travelersOnBoard = [];
// Mark this station as the last drop
bus.lastDropStationIndex = dropStationIndex;
}
dropBtnPressed = false; // Reset button press
}
};