User prompt
try (ball_speed + 3 * vehicle_speed) / 1,20
User prompt
try (ball_speed + 4 * vehicle_speed) / 2
User prompt
çok güzel oldu şimdi ortalama almadan önce aracın hızını 2 ile çarp yani bizim hızımızla aracın hızının 2 katının ortalamasını al (bizimhız+ 2araçhızı)/2
User prompt
düşünme modunda devam et bişey yapma. kesinlikle sağdan sola doğru giden araçlarda çarpişma hesaplamasında hata var ve sen bunu tespit edemiyorsun. çarpışma sistemini baştan yapıp topumuzun vektoru ve aracın vektörünün ortalamalarını almayı ve topumuzu ona göre hareket ettirmeyi deneyelim mi
User prompt
evet düşürdün ama hala mantıksız çarpıyor sağdan sola doğru giden araçlar
User prompt
sağdan sola doğru giden araçlarla etkileşimimizde problem var çok terse atıyor topumuzu diğer araçlar çok iyi
User prompt
sağdan sola doğru giden araçlarla etkileşimimizde problem var çok terse atıyor topumuzu
User prompt
çartığımız aracın hızı ve yönü bizi biraz daha etkilesin. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
araçlara çarpma mekaniği ekleyelim. palyançomuzun yani topumuzun her fırlattığımızda 5 canı olsun araçlara çarptığında 1 canı gitsin (bouncycar hariç ona asla kesinlikle hiçbir şekilde dokunma) iyi bir çarpma mekaniği yap çarptığımız aracın yönüne göre topun yönü değişmeli ama topun eski vektörü de çok iyi hesaba katılmalı bouncycar gibi değil ama zıplatmadan farkli bir çarma etkisi olmalı nasıl bir hesaplama yapamam gerektiğini bilmiyorum sana bırakıyorum. bir fırlatmada 5 kere çarptığımızda ( tekrar diyorum bouncycar eskisi gibi kalacak o sayılmaz ) oyun biter. her fırlatmada yeniden 5 can olur. bir arabaya 1 kez çarptığımızda o aracı 2 saniye görmezden gel ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
tüm araçlarda düşürdün di mi? %10 daha düşür
User prompt
araç spawn oranını %20 düşür
User prompt
motosikletin texturu ters olmuş geri geri gidiyor gibi texturunu çevir
User prompt
motosiklet geri geri gidiyor tersine çevir
User prompt
motosikletin texturunu 'moto' ile değiştir
User prompt
motosikletin atlarkenki büyümesini arttır atlarkenki çizdiğin hayali parabolun mantığını biraz daha düzeltip öyle bir büyüme küçülme efekti ayarla. üst persfektiften bakıyoruz unutma ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
şerit değiştirme hızını %80 azalt şerit değiştirirkenki ilerleme hızını da ayriyetten %20 azalt ve şerit değiştirdikten sonra normal hızına döndür ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
motosiklet ekle arabadan biraz daha küçük biraz daha yavaş. her saniye %20 olasılıkla zıplayarak şerit değiştirebilsin bir şeridi zıplayarak gececek karşıdan gelen araçlara çarpmıycak. şöyle anlatsam daha iyi yukarıdan aşşağı 6 şerit var biliyorsun ( en üst şerit 1 en alt şerit 6 olsun) motosikletler sadece 3. ve 4. şeritten gelecekler her saniye %20 olasılıkla zıpladıklarında 3. şeritten gelen motor 1. ya da 5. şeride doğru atlayacak. 4. şeritte gelen 2. ya da 6. şeride atlasın cool bi atlama efekti yap biraz büyüyüp küçülebilir perspektifsel olarak yukarı çıkıp aşşağı indiği belli olsun. 1 kere yapsın sadece atlamayı ve şerit değiştirirkenki motorun yönünün dönme açısını da iyi ayarla ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
karakterimizin boyunutu %25 küçült küçülsün büyümesin
User prompt
palyançomuzu %30 küçült
User prompt
tüm araçları %40 küçült ve hızlarını %5 azalt ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Remix started
Copy Street Slingers
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Ball (player) class
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGfx = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.7,
scaleY: 1.7
});
self.radius = ballGfx.width / 2;
self.vx = 0;
self.vy = 0;
self.launched = false;
self.resting = true; // true if waiting for launch
self.bounceCooldown = 0; // prevent double bounces
self.health = 5; // Lives per launch
self.update = function () {
if (self.launched) {
// Gravity
self.vy += 0.1344;
// Move
self.x += self.vx;
self.y += self.vy;
// Friction (air)
self.vx *= 0.995;
// Clamp to game area
if (self.x < self.radius) self.x = self.radius;
if (self.x > 2048 - self.radius) self.x = 2048 - self.radius;
// If falls below screen, game over
if (self.y > 2732 + 200) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
}
}
};
// Reset ball to start
self.reset = function () {
self.x = 2048 / 2;
self.y = typeof ballStartY !== "undefined" ? ballStartY : 2732 - 180;
self.vx = 0;
self.vy = 0;
self.launched = false;
self.resting = true;
self.bounceCooldown = 0;
self.health = 5; // Reset health for new launch
};
// Bounce up (from bouncy car)
self.bounce = function (strength) {
self.vy = -Math.abs(strength || 38 + Math.random() * 8);
self.launched = true;
self.resting = false;
self.bounceCooldown = 10;
};
return self;
});
// BouncyCar (bouncy vehicle) class
var BouncyCar = Container.expand(function () {
var self = Container.call(this);
var bouncyGfx = self.attachAsset('bouncycar', {
anchorX: 0.5,
anchorY: 0.5
});
self.scale.set(0.72, 0.72);
self.width = bouncyGfx.width * 0.72;
self.height = bouncyGfx.height * 0.72;
self.speed = 0;
self.lane = 0;
self.type = 'bouncycar';
self.bouncePhase = Math.random() * Math.PI * 2;
self.update = function () {
self.x += self.speed;
// Bouncy up-down
self.y0 = self.y0 || self.y;
self.y = self.y0 + Math.sin(LK.ticks / 12 + self.bouncePhase) * 38;
if (self.speed > 0 && self.x > 2048 + 200) self.destroyed = true;
if (self.speed < 0 && self.x < -200) self.destroyed = true;
};
return self;
});
// Car (normal) class
var Car = Container.expand(function () {
var self = Container.call(this);
var carGfx = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
self.scale.set(0.72, 0.72);
self.width = carGfx.width * 0.72;
self.height = carGfx.height * 0.72;
self.speed = 0;
self.lane = 0;
self.type = 'car';
self.hitCooldown = 0; // Cooldown after being hit by ball
self.update = function () {
self.x += self.speed;
// Update hit cooldown
if (self.hitCooldown > 0) self.hitCooldown--;
// Remove if out of screen
if (self.speed > 0 && self.x > 2048 + 200) self.destroyed = true;
if (self.speed < 0 && self.x < -200) self.destroyed = true;
};
return self;
});
// Motorcycle class
var Motorcycle = Container.expand(function () {
var self = Container.call(this);
var motorcycleGfx = self.attachAsset('moto', {
anchorX: 0.5,
anchorY: 0.5
});
self.scale.set(0.58, 0.58); // Smaller than cars (0.72 * 0.8)
self.width = motorcycleGfx.width * 0.58;
self.height = motorcycleGfx.height * 0.58;
self.speed = 0;
self.lane = 0;
self.type = 'motorcycle';
self.hitCooldown = 0; // Cooldown after being hit by ball
self.hasJumped = false; // Only jump once
self.lastJumpCheck = 0;
self.isJumping = false;
self.originalY = 0;
self.originalScale = 0.58;
self.update = function () {
self.x += self.speed;
// Update hit cooldown
if (self.hitCooldown > 0) self.hitCooldown--;
// Jump logic - check every second (60 ticks) with 20% chance
if (!self.hasJumped && !self.isJumping && LK.ticks - self.lastJumpCheck >= 60) {
self.lastJumpCheck = LK.ticks;
if (Math.random() < 0.2) {
self.performJump();
}
}
// Remove if out of screen
if (self.speed > 0 && self.x > 2048 + 200) self.destroyed = true;
if (self.speed < 0 && self.x < -200) self.destroyed = true;
};
self.performJump = function () {
if (self.hasJumped || self.isJumping) return;
self.isJumping = true;
self.hasJumped = true;
self.originalY = self.y;
// Reduce speed by 20% during jump
self.originalSpeed = self.speed;
self.speed = self.speed * 0.8;
// Determine target lane based on current lane
var targetLane;
if (self.lane === 2) {
// Lane 3 (index 2)
targetLane = Math.random() < 0.5 ? 0 : 4; // Jump to lane 1 or 5 (index 0 or 4)
} else if (self.lane === 3) {
// Lane 4 (index 3)
targetLane = Math.random() < 0.5 ? 1 : 5; // Jump to lane 2 or 6 (index 1 or 5)
}
var targetY = laneYs[targetLane];
// Calculate rotation angle based on jump direction
var rotationAngle = 0;
if (targetLane < self.lane) {
rotationAngle = self.speed > 0 ? -0.3 : 0.3; // Upward jump
} else {
rotationAngle = self.speed > 0 ? 0.3 : -0.3; // Downward jump
}
// Enhanced jump animation with parabolic trajectory and realistic scaling
var jumpDuration = 1500;
var peakScale = self.originalScale * 2.2; // Increased scale for more dramatic effect
var halfDuration = jumpDuration / 2;
// First half: jump up with scale increase (ascending arc)
tween(self, {
y: self.originalY + (targetY - self.originalY) * 0.5,
// Halfway point
scaleX: peakScale,
scaleY: peakScale,
rotation: rotationAngle * 0.7 // Partial rotation during ascent
}, {
duration: halfDuration,
easing: tween.easeOut,
// Slow down as it reaches peak
onFinish: function onFinish() {
// Second half: descend with scale decrease (descending arc)
tween(self, {
y: targetY,
scaleX: self.originalScale,
scaleY: self.originalScale,
rotation: rotationAngle
}, {
duration: halfDuration,
easing: tween.easeIn,
// Speed up as it falls
onFinish: function onFinish() {
// Final landing animation - quick rotation reset
tween(self, {
rotation: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isJumping = false;
// Restore original speed
self.speed = self.originalSpeed;
}
});
}
});
}
});
// Update lane
self.lane = targetLane;
};
return self;
});
// Truck (long vehicle) class
var Truck = Container.expand(function () {
var self = Container.call(this);
var truckGfx = self.attachAsset('truck', {
anchorX: 0.5,
anchorY: 0.5
});
self.scale.set(0.72, 0.72);
self.width = truckGfx.width * 0.72;
self.height = truckGfx.height * 0.72;
self.speed = 0;
self.lane = 0;
self.type = 'truck';
self.hitCooldown = 0; // Cooldown after being hit by ball
self.update = function () {
self.x += self.speed;
// Update hit cooldown
if (self.hitCooldown > 0) self.hitCooldown--;
if (self.speed > 0 && self.x > 2048 + 300) self.destroyed = true;
if (self.speed < 0 && self.x < -300) self.destroyed = true;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Slingshot band
// Bouncy car
// Truck
// Car
// Lane divider
// Road background
// Stop (target)
// Ball (player)
// --- Game variables ---
var lanes = [0, 1, 2, 3, 4, 5];
var laneYs = [];
var laneCount = 6;
var verticalOffset = -200; // Move everything up by 200px
var roadTop = 600 + verticalOffset;
var roadHeight = 1536;
var laneGap = roadHeight / laneCount;
for (var i = 0; i < laneCount; ++i) {
laneYs[i] = roadTop + laneGap / 2 + i * laneGap;
}
// Place stop (target) at the top of the road, centered horizontally
var stopY = roadTop - 100;
var stopX = 2048 / 2;
// Update stop trigger area to match new stop (target) width
var stopRadius = {
x: 158,
// half of stop image width (316/2), matches texture
y: 90
}; // x: horizontal radius, y: vertical radius
var level = 1;
var vehicles = [];
var ball = null;
var stop = null;
var slingshotBand = null;
var isDragging = false;
// Place the ball higher up (not at the very bottom)
var ballStartY = roadTop + roadHeight + 120;
var dragStart = {
x: 0,
y: 0
};
var dragCurrent = {
x: 0,
y: 0
};
var launchPower = 0;
var launchAngle = 0;
var canLaunch = true;
var scoreTxt = null;
var levelTxt = null;
var winTimeout = null;
// --- Draw road and lanes ---
var road = LK.getAsset('road', {
x: 0,
y: roadTop,
width: 2048,
height: roadHeight
});
game.addChild(road);
// Lane dividers
for (var i = 1; i < laneCount; ++i) {
var divider = LK.getAsset('divider', {
x: 0,
y: roadTop + i * laneGap - 12,
width: 2048,
height: 24
});
game.addChild(divider);
}
// --- Stop (target) ---
stop = LK.getAsset('stop', {
anchorX: 0.5,
anchorY: 0.5,
x: stopX,
y: stopY,
scaleX: 1.2,
scaleY: 1.2
});
game.addChild(stop);
// --- Ball (player) ---
ball = new Ball();
ball.scale.set(0.9, 0.9);
game.addChild(ball);
ball.reset();
// --- Slingshot band (visual) ---
slingshotBand = LK.getAsset('band', {
anchorX: 0.5,
anchorY: 1,
x: ball.x,
y: ball.y,
scaleX: 0.7,
scaleY: 0.7
});
slingshotBand.visible = false;
game.addChild(slingshotBand);
// --- GUI: Score and Level ---
scoreTxt = new Text2('0', {
size: 110,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
levelTxt = new Text2('1', {
size: 70,
fill: "#fff"
});
levelTxt.anchor.set(0.5, 0);
LK.gui.topRight.addChild(levelTxt);
// Health display
var healthTxt = new Text2('♥ 5', {
size: 80,
fill: 0xFF4444
});
healthTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(healthTxt);
healthTxt.x = -120; // Position to the left of level text
// --- Game state ---
function resetGameState() {
// Remove vehicles
for (var i = 0; i < vehicles.length; ++i) {
vehicles[i].destroy();
}
vehicles = [];
// Reset ball
ball.reset();
// Update health display
healthTxt.setText('♥ ' + ball.health);
// Reset slingshot
slingshotBand.visible = false;
isDragging = false;
canLaunch = true;
// Reset score/level
LK.setScore(0);
scoreTxt.setText('0');
level = 1;
levelTxt.setText('1');
}
resetGameState();
// --- Vehicle spawner ---
function spawnVehicle() {
// Check if we should spawn a motorcycle (only in lanes 2 and 3, which are indices 2 and 3)
var isMotorcycleSpawn = Math.random() < 0.15; // 15% chance for motorcycle
var lane;
var y;
var v, dir, speed;
if (isMotorcycleSpawn) {
// Motorcycles only spawn in lanes 3 and 4 (indices 2 and 3)
lane = Math.random() < 0.5 ? 2 : 3;
y = laneYs[lane];
v = new Motorcycle();
speed = (10 + level * 1.0 + Math.random() * 2) * 0.5 * 0.9; // Slightly slower than cars
} else {
// Randomly pick lane for other vehicles
lane = Math.floor(Math.random() * laneCount);
y = laneYs[lane];
// Adjusted spawn probabilities: All vehicle types reduced by 5%
// Old: Car 60%, Truck 25%, BouncyCar 15%
// New: Car 55%, Truck 20%, BouncyCar 10%
var t = Math.random();
if (t < 0.55) {
v = new Car();
speed = (12 + level * 1.2 + Math.random() * 2) * 0.5 * 0.95;
} else if (t < 0.75) {
v = new Truck();
speed = (8 + level * 1.1 + Math.random() * 2) * 0.5 * 0.9 * 0.95; // Truck speed reduced by 10% then by 5%
} else {
v = new BouncyCar();
speed = (10 + level * 1.3 + Math.random() * 2) * 0.5 * 1.1 * 0.95; // BouncyCar speed increased by 10% then reduced by 5%
}
}
// Direction: even lanes left->right, odd right->left
dir = lane % 2 === 0 ? 1 : -1;
v.lane = lane;
v.y = y;
v.y0 = y;
v.speed = speed * dir;
if (dir > 0) {
v.x = -200;
} else {
v.x = 2048 + 200;
// Flip the vehicle horizontally if moving right-to-left
if (v.children && v.children.length > 0 && v.children[0]) {
v.children[0].scale.x = -1;
}
}
vehicles.push(v);
game.addChild(v);
}
// --- Level progression ---
function nextLevel() {
level += 1;
levelTxt.setText(level + '');
// Remove all vehicles
for (var i = 0; i < vehicles.length; ++i) vehicles[i].destroy();
vehicles = [];
// Reset ball
ball.reset();
// Update health display
healthTxt.setText('♥ ' + ball.health);
canLaunch = true;
slingshotBand.visible = false;
}
// --- Game update ---
game.update = function () {
// Ball update
ball.update();
// Vehicles update
// --- Make vehicles follow the speed of the vehicle in front if they are too close in the same lane ---
for (var i = vehicles.length - 1; i >= 0; --i) {
var v = vehicles[i];
// Find the closest vehicle ahead in the same lane and direction
var minDist = Infinity;
var frontVehicle = null;
for (var j = 0; j < vehicles.length; ++j) {
if (i === j) continue;
var v2 = vehicles[j];
if (v2.lane !== v.lane) continue;
// Only consider vehicles in the same direction
if (v.speed > 0 && v2.x > v.x || v.speed < 0 && v2.x < v.x) {
var dist = Math.abs(v2.x - v.x);
if (dist < minDist) {
minDist = dist;
frontVehicle = v2;
}
}
}
// If too close, match speed to the front vehicle
if (frontVehicle) {
// Use the larger of the two widths for minimum gap
var minGap = Math.max(v.width, frontVehicle.width) * 0.85;
if (minDist < minGap) {
v.speed = frontVehicle.speed;
// Snap position to avoid overlap
if (v.speed > 0) {
v.x = Math.min(v.x, frontVehicle.x - minGap + 1);
} else {
v.x = Math.max(v.x, frontVehicle.x + minGap - 1);
}
}
}
v.update();
// Remove destroyed
if (v.destroyed) {
v.destroy();
vehicles.splice(i, 1);
continue;
}
}
// Ball-vehicle collision
if (ball.launched && ball.bounceCooldown <= 0) {
for (var i = 0; i < vehicles.length; ++i) {
var v = vehicles[i];
// Skip if vehicle is in hit cooldown
if (v.hitCooldown > 0) continue;
// AABB collision
var dx = Math.abs(ball.x - v.x);
var dy = Math.abs(ball.y - v.y);
var overlapX = dx < ball.radius + v.width / 2 - 10;
var overlapY = dy < ball.radius + v.height / 2 - 10;
if (overlapX && overlapY) {
if (v.type === 'bouncycar') {
// Calculate the incoming angle and speed
var incomingAngle = Math.atan2(ball.vy, ball.vx);
var speed = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy);
// Reverse the angle (go in the exact opposite direction)
var baseBounceAngle = incomingAngle + Math.PI;
// Add up to ±10% randomness to the angle
var randomAngle = (Math.random() - 0.5) * (Math.PI * 0.2); // ±0.1π ≈ ±18°
var bounceAngle = baseBounceAngle + randomAngle;
// Bounce speed is 120% of the incoming speed
var bounceSpeed = speed * 1.2;
// Set new velocity
ball.vx = Math.cos(bounceAngle) * bounceSpeed;
ball.vy = Math.sin(bounceAngle) * bounceSpeed;
ball.launched = true;
ball.resting = false;
ball.bounceCooldown = 12;
LK.effects.flashObject(v, 0xffff00, 400);
// Do NOT randomize X anymore, keep physics consistent
// After bounce, check if ball is immediately on stop (target)
var dxStop = ball.x - stop.x;
var dyStop = ball.y - stop.y;
// Use ellipse collision: (dx/a)^2 + (dy/b)^2 < 1
if (dxStop * dxStop / ((stopRadius.x + ball.radius - 10) * (stopRadius.x + ball.radius - 10)) + dyStop * dyStop / ((stopRadius.y + ball.radius - 10) * (stopRadius.y + ball.radius - 10)) < 1 && Math.abs(ball.vy) < 18) {
// Win!
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore() + '');
LK.effects.flashObject(stop, 0x00ff00, 600);
canLaunch = false;
ball.launched = false;
ball.resting = true;
// Randomize stop X position (avoid edges)
var stopMargin = 180 + stopRadius.x;
stop.x = stopMargin + Math.random() * (2048 - 2 * stopMargin);
// Next level after short delay
if (winTimeout) LK.clearTimeout(winTimeout);
winTimeout = LK.setTimeout(function () {
nextLevel();
}, 1200);
return;
}
} else {
// Vehicle collision - reduce health and deflect ball
ball.health -= 1;
healthTxt.setText('♥ ' + ball.health);
// Set vehicle hit cooldown (2 seconds = 120 ticks at 60fps)
v.hitCooldown = 120;
// Flash the vehicle red to indicate hit
LK.effects.flashObject(v, 0xff0000, 500);
// New collision logic: Average of ball's vector and vehicle's vector.
// Vehicle's velocity vector is (v.speed, 0) as it only moves horizontally.
// Ball's current velocity vector before collision is (ball.vx, ball.vy).
// Calculate the average vector components:
// new_vx = (ball.vx + vehicle.vx) / 2
// new_vy = (ball.vy + vehicle.vy) / 2
// Since vehicle.vy is 0:
// New formula: (ball_speed + 3 * vehicle_speed) / 1.20
var avgVx = (ball.vx + 3 * v.speed) / 1.20;
var avgVy = (ball.vy + 3 * 0) / 1.20; // vehicle.vy is 0
// Apply the new averaged velocity to the ball
ball.vx = avgVx;
ball.vy = avgVy;
// Set bounce cooldown to prevent multiple hits
ball.bounceCooldown = 8;
// Check if health is depleted
if (ball.health <= 0) {
// Game over
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
}
}
}
if (ball.bounceCooldown > 0) ball.bounceCooldown--;
// Ball-stop (target) collision
if (ball.launched && !ball.resting) {
var dx = ball.x - stop.x;
var dy = ball.y - stop.y;
// Use ellipse collision: (dx/a)^2 + (dy/b)^2 < 1
if (dx * dx / ((stopRadius.x + ball.radius - 10) * (stopRadius.x + ball.radius - 10)) + dy * dy / ((stopRadius.y + ball.radius - 10) * (stopRadius.y + ball.radius - 10)) < 1 && Math.abs(ball.vy) < 18) {
// Win!
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore() + '');
LK.effects.flashObject(stop, 0x00ff00, 600);
canLaunch = false;
ball.launched = false;
ball.resting = true;
// Randomize stop X position (avoid edges)
var margin = 180 + stopRadius.x;
stop.x = margin + Math.random() * (2048 - 2 * margin);
// Next level after short delay
if (winTimeout) LK.clearTimeout(winTimeout);
winTimeout = LK.setTimeout(function () {
nextLevel();
}, 1200);
}
}
// Vehicle spawn logic - reduced by 30% total (20% + 10%)
if (LK.ticks % Math.max(52 - Math.min(level * 2, 30), 13) === 0) {
spawnVehicle();
}
};
// --- Slingshot controls ---
function getDragVector() {
var dx = dragCurrent.x - dragStart.x;
var dy = dragCurrent.y - dragStart.y;
return {
dx: dx,
dy: dy
};
}
function updateSlingshotBand() {
if (!isDragging) {
slingshotBand.visible = false;
return;
}
var vec = getDragVector();
var len = Math.sqrt(vec.dx * vec.dx + vec.dy * vec.dy);
var maxLen = 420;
if (len > maxLen) {
vec.dx *= maxLen / len;
vec.dy *= maxLen / len;
len = maxLen;
}
// Band position: from ball center to drag point
slingshotBand.visible = true;
slingshotBand.x = ball.x;
slingshotBand.y = ball.y;
slingshotBand.height = len;
slingshotBand.rotation = Math.atan2(vec.dy, vec.dx) + Math.PI / 2;
}
// --- Input handlers ---
game.down = function (x, y, obj) {
// Only allow drag if ball is at rest and not in win state
if (!canLaunch || !ball.resting) return;
// Only allow drag if touch is near ball
var dx = x - ball.x;
var dy = y - ball.y;
if (dx * dx + dy * dy < ball.radius * ball.radius * 2.2) {
isDragging = true;
dragStart.x = ball.x;
dragStart.y = ball.y;
dragCurrent.x = x;
dragCurrent.y = y;
updateSlingshotBand();
}
};
game.move = function (x, y, obj) {
if (!isDragging) return;
dragCurrent.x = x;
dragCurrent.y = y;
updateSlingshotBand();
};
game.up = function (x, y, obj) {
if (!isDragging) return;
isDragging = false;
slingshotBand.visible = false;
// Launch!
var vec = getDragVector();
var len = Math.sqrt(vec.dx * vec.dx + vec.dy * vec.dy);
if (len < 60) return; // too short
var maxLen = 420;
if (len > maxLen) {
vec.dx *= maxLen / len;
vec.dy *= maxLen / len;
len = maxLen;
}
// Set velocity (scaled)
ball.vx = -vec.dx * 0.055;
ball.vy = -vec.dy * 0.055;
ball.launched = true;
ball.resting = false;
canLaunch = false;
};
// --- Game over/win handling ---
LK.on('gameover', function () {
resetGameState();
});
LK.on('youwin', function () {
resetGameState();
}); ===================================================================
--- original.js
+++ change.js
@@ -564,11 +564,11 @@
// Calculate the average vector components:
// new_vx = (ball.vx + vehicle.vx) / 2
// new_vy = (ball.vy + vehicle.vy) / 2
// Since vehicle.vy is 0:
- // New formula: (ball_speed + 4 * vehicle_speed) / 2
- var avgVx = (ball.vx + 4 * v.speed) / 2;
- var avgVy = (ball.vy + 4 * 0) / 2; // vehicle.vy is 0
+ // New formula: (ball_speed + 3 * vehicle_speed) / 1.20
+ var avgVx = (ball.vx + 3 * v.speed) / 1.20;
+ var avgVy = (ball.vy + 3 * 0) / 1.20; // vehicle.vy is 0
// Apply the new averaged velocity to the ball
ball.vx = avgVx;
ball.vy = avgVy;
// Set bounce cooldown to prevent multiple hits
bir palyanço kafasının arka üsten görünümü çizgi film stili. In-Game asset. 2d. High contrast. No shadows
ileriyi gösteren . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
zıpzıp taşıyan kamyonet üsten görünüm. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
lüks sarı araba üsten görünüş. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
birebir aynı tıs tekerlerin düzeltilmesi gerek sadece
otobuş durağı. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat