User prompt
deliğe girince random bir yerde yeni delik çıksun
User prompt
deliği aşşa al
User prompt
Farenin hızı azalt, top sektikten sonra hızını çok kaybediyor onu düzelt
User prompt
Golf topu hızını düşür çok hızlı oldu duvarın içine giriyor top
User prompt
Apply this
User prompt
hala aynı şey
User prompt
duvarın içine girdi yine top
User prompt
Drag limiti artsın ve hızlansın, drag sembolü de daha hassas çalışsın
Code edit (4 edits merged)
Please save this source code
User prompt
duvara çok hızlı çarpınca duvarın içine girip kayboluyor top
Code edit (8 edits merged)
Please save this source code
User prompt
Topu çekmenin limitini arttır lütfen
Code edit (1 edits merged)
Please save this source code
Code edit (5 edits merged)
Please save this source code
User prompt
Topu çekme seviyesinin limitini arttır
Code edit (1 edits merged)
Please save this source code
User prompt
Yine öyle oldu yukarıya al şu topu
User prompt
Top duvarların içinde başladı öyle olmasın
User prompt
DUVARLARI NEDEN FONKSİYONLA KURUYORSUN EN BAŞTAN SABİT OLUŞTURSANA
User prompt
KALINLAŞTIR DUVARLARI
User prompt
TAMAM ŞİMDİ ORTAYA KOYDUĞUN DUVARIN UZUNLUĞUN ARTTIRARAK BİR ÇERÇEVE YAP KENARLARA
User prompt
GÖRÜNMEZ DUVARLARI DA KALDIR HALA ÇARPILIYOR TOP ORAYA GELİNCE
User prompt
kenardaki duvarları kaldır
User prompt
Ortadaki duvar gibi yapsana tüm duvarları haritanın ortasındaki duvar olması gerektiği gibi çalışıyor
User prompt
Still the ball gets stuck at the walls doesnt bounce
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Ball class
var GolfBall = Container.expand(function () {
var self = Container.call(this);
var ball = self.attachAsset('golfBall', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = ball.width / 2;
self.vx = 0;
self.vy = 0;
self.moving = false;
// For drag aiming
self.aimArrow = null;
// For tracking drag
self.isAiming = false;
self.aimStartX = 0;
self.aimStartY = 0;
self.aimEndX = 0;
self.aimEndY = 0;
// Show aim arrow
self.showArrow = function (dx, dy) {
if (!self.aimArrow) {
self.aimArrow = LK.getAsset('golfArrow', {
anchorX: 0.5,
anchorY: 1
});
self.addChild(self.aimArrow);
}
var len = Math.sqrt(dx * dx + dy * dy);
// Clamp arrow length for visual
var maxLen = 300;
var arrowLen = Math.min(len, maxLen);
self.aimArrow.height = arrowLen;
self.aimArrow.rotation = Math.atan2(dy, dx) + Math.PI / 2;
self.aimArrow.visible = true;
};
self.hideArrow = function () {
if (self.aimArrow) {
self.aimArrow.visible = false;
}
};
// Update ball physics
self.update = function () {
if (self.moving) {
// Move ball
self.x += self.vx;
self.y += self.vy;
// Friction
var speed = Math.sqrt(self.vx * self.vx + self.vy * self.vy);
if (speed > 0) {
var friction = 0.98;
self.vx *= friction;
self.vy *= friction;
// Stop if very slow
if (Math.sqrt(self.vx * self.vx + self.vy * self.vy) < 1.2) {
self.vx = 0;
self.vy = 0;
self.moving = false;
}
}
}
};
return self;
});
// Hole class
var GolfHole = Container.expand(function () {
var self = Container.call(this);
var hole = self.attachAsset('golfHole', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = hole.width / 2;
return self;
});
// Wall class
var GolfWall = Container.expand(function () {
var self = Container.call(this);
var wall = self.attachAsset('golfWall', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = wall.width;
self.height = wall.height;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x6abf4b // green grass
});
/****
* Game Code
****/
// Game area margins
// Ball: white circle
// Hole: black circle
// Wall: green rectangle
// Arrow: yellow rectangle (for aiming indicator)
var margin = 120;
// Course size
var courseWidth = 2048 - margin * 2;
var courseHeight = 2732 - margin * 2;
// Walls array
var walls = [];
// Top wall (static)
var topWall = new GolfWall();
topWall.width = courseWidth;
topWall.height = 300;
topWall.x = 2048 / 2;
topWall.y = margin + 55;
topWall.children[0].width = courseWidth;
topWall.children[0].height = 120;
walls.push(topWall);
game.addChild(topWall);
// Bottom wall (static)
var bottomWall = new GolfWall();
bottomWall.width = courseWidth;
bottomWall.height = 300;
bottomWall.x = 2048 / 2;
bottomWall.y = 2732 - margin + 200;
bottomWall.children[0].width = courseWidth;
bottomWall.children[0].height = 120;
walls.push(bottomWall);
game.addChild(bottomWall);
// Left wall (static)
var leftWall = new GolfWall();
leftWall.width = 125;
leftWall.height = courseHeight;
leftWall.x = margin - 75;
leftWall.y = 2732 / 2;
leftWall.children[0].width = 120;
leftWall.children[0].height = courseHeight;
walls.push(leftWall);
game.addChild(leftWall);
// Right wall (static)
var rightWall = new GolfWall();
rightWall.width = 125;
rightWall.height = courseHeight;
rightWall.x = 2048 - margin + 75;
rightWall.y = 2732 / 2;
rightWall.children[0].width = 120;
rightWall.children[0].height = courseHeight;
walls.push(rightWall);
game.addChild(rightWall);
// Create hole
var hole = new GolfHole();
hole.x = 2048 - margin - 200;
hole.y = margin + 500;
game.addChild(hole);
// Create ball
var ball = new GolfBall();
// Start ball at bottom left, well away from top wall
ball.x = margin + 200;
ball.y = 2732 - margin - 400;
game.addChild(ball);
// Walls are created statically above
// Strokes counter
var strokes = 0;
// Score text
var scoreTxt = new Text2('Strokes: 0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Drag/aim state
var isDragging = false;
var dragStartX = 0;
var dragStartY = 0;
// Helper: clamp ball inside course
function clampBallPosition() {
// No clamping to invisible walls; allow ball to go to the very edge of the course.
}
// Helper: ball-wall collision
function handleWallCollisions() {
// To prevent tunneling, subdivide the movement into smaller steps if velocity is high
var substeps = 1;
var maxStep = 15; // px per substep (reduced for more precise collision)
var speed = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy);
if (speed > maxStep) {
substeps = Math.ceil(speed / maxStep);
// Clamp to a reasonable max substeps to avoid performance issues
if (substeps > 32) substeps = 32;
}
var origX = ball.x;
var origY = ball.y;
var stepVX = ball.vx / substeps;
var stepVY = ball.vy / substeps;
for (var s = 0; s < substeps; s++) {
// Always move ball by substep velocity, even if substeps == 1
ball.x += stepVX;
ball.y += stepVY;
for (var i = 0; i < walls.length; i++) {
var w = walls[i];
// Axis-aligned rectangle collision
var wx = w.x;
var wy = w.y;
var ww = w.width;
var wh = w.height;
var bx = ball.x;
var by = ball.y;
var r = ball.radius;
// Rectangle bounds
var left = wx - ww / 2;
var right = wx + ww / 2;
var top = wy - wh / 2;
var bottom = wy + wh / 2;
// Find closest point on wall to ball
var closestX = Math.max(left, Math.min(bx, right));
var closestY = Math.max(top, Math.min(by, bottom));
var dx = bx - closestX;
var dy = by - closestY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < r) {
// Ball is colliding with wall
// Push ball out, and repeat if still inside (up to 3 times)
var resolveCount = 0;
while (dist < r && resolveCount < 3) {
var overlap = r - dist + 1;
if (dist === 0) {
// Prevent NaN
dx = 1;
dy = 0;
dist = 1;
}
// Move ball out of wall
ball.x += dx / dist * overlap;
ball.y += dy / dist * overlap;
// Recompute for next iteration
bx = ball.x;
by = ball.y;
dx = bx - closestX;
dy = by - closestY;
dist = Math.sqrt(dx * dx + dy * dy);
resolveCount++;
}
// Calculate the normal vector
var nx = dx / (dist === 0 ? 1 : dist);
var ny = dy / (dist === 0 ? 1 : dist);
// Calculate dot product of velocity and normal
var dot = ball.vx * nx + ball.vy * ny;
// Reflect velocity using the normal (like center wall)
ball.vx = ball.vx - 2 * dot * nx;
ball.vy = ball.vy - 2 * dot * ny;
// Dampen speed
ball.vx *= 0.7;
ball.vy *= 0.7;
// After a collision, break to avoid double-colliding in the same substep
break;
}
}
}
// If we subdivided, set ball position to final
if (substeps > 1) {
// Already at final position
}
}
// Helper: ball-in-hole detection
function checkHole() {
var dx = ball.x - hole.x;
var dy = ball.y - hole.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < hole.radius - ball.radius / 2) {
// Ball in hole!
ball.moving = false;
ball.vx = 0;
ball.vy = 0;
// Animate ball into hole
tween(ball, {
x: hole.x,
y: hole.y,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0
}, {
duration: 600,
easing: tween.easeIn,
onFinish: function onFinish() {
// Show win
LK.showYouWin();
}
});
return true;
}
return false;
}
// Helper: reset ball after win (not needed, handled by LK.showYouWin)
// Game move handler (for drag aiming)
function handleMove(x, y, obj) {
if (isDragging && !ball.moving) {
// Clamp drag to max length
var dx = x - dragStartX;
var dy = y - dragStartY;
var maxDrag = 1600; // Increased drag limit for aiming
var dragLen = Math.sqrt(dx * dx + dy * dy);
if (dragLen > maxDrag) {
var scale = maxDrag / dragLen;
dx *= scale;
dy *= scale;
}
// Show aim arrow
ball.showArrow(-dx, -dy);
}
}
// Game down handler (start drag)
game.down = function (x, y, obj) {
// Only allow aiming if ball is not moving and touch is near ball
if (!ball.moving) {
var dx = x - ball.x;
var dy = y - ball.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < ball.radius + 100) {
// More sensitive drag start
isDragging = true;
dragStartX = ball.x;
dragStartY = ball.y;
ball.aimStartX = x;
ball.aimStartY = y;
ball.showArrow(0, 0);
}
}
};
// Game move handler
game.move = function (x, y, obj) {
if (isDragging && !ball.moving) {
// Update aim arrow
var dx = x - dragStartX;
var dy = y - dragStartY;
var maxDrag = 1600; // Increased drag limit
var dragLen = Math.sqrt(dx * dx + dy * dy);
if (dragLen > maxDrag) {
var scale = maxDrag / dragLen;
dx *= scale;
dy *= scale;
}
ball.showArrow(-dx, -dy);
}
};
// Game up handler (release drag, shoot)
game.up = function (x, y, obj) {
if (isDragging && !ball.moving) {
var dx = x - dragStartX;
var dy = y - dragStartY;
// Power proportional to drag length
var power = Math.sqrt(dx * dx + dy * dy);
var maxPower = 80; // Increased max power
var minPower = 10;
var shotPower = Math.min(power / 8, maxPower) * 7; // More sensitive and powerful
if (shotPower < minPower / 2) {
// Too short, ignore
ball.hideArrow();
isDragging = false;
return;
}
// Set velocity (opposite direction of drag)
var angle = Math.atan2(dy, dx);
ball.vx = -Math.cos(angle) * shotPower;
ball.vy = -Math.sin(angle) * shotPower;
ball.moving = true;
ball.hideArrow();
isDragging = false;
// Increment strokes
strokes += 1;
scoreTxt.setText('Strokes: ' + strokes);
}
};
// Main game update
game.update = function () {
// Ball physics
ball.update();
// Clamp ball inside course
clampBallPosition();
// Ball-wall collisions
handleWallCollisions();
// Ball-in-hole
// If the ball is close enough to the hole, but not yet inside, auto-move it in
var dx = ball.x - hole.x;
var dy = ball.y - hole.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var autoSinkRadius = hole.radius * 0.85; // a bit smaller than the hole, but larger than the 'in' threshold
if (ball.moving && dist < autoSinkRadius && dist > hole.radius - ball.radius / 2) {
// Auto-move the ball into the hole
ball.moving = false;
ball.vx = 0;
ball.vy = 0;
tween(ball, {
x: hole.x,
y: hole.y,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.showYouWin();
}
});
} else if (!ball.moving) {
checkHole();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -185,23 +185,23 @@
// Helper: ball-wall collision
function handleWallCollisions() {
// To prevent tunneling, subdivide the movement into smaller steps if velocity is high
var substeps = 1;
- var maxStep = 40; // px per substep
+ var maxStep = 15; // px per substep (reduced for more precise collision)
var speed = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy);
if (speed > maxStep) {
substeps = Math.ceil(speed / maxStep);
+ // Clamp to a reasonable max substeps to avoid performance issues
+ if (substeps > 32) substeps = 32;
}
var origX = ball.x;
var origY = ball.y;
var stepVX = ball.vx / substeps;
var stepVY = ball.vy / substeps;
for (var s = 0; s < substeps; s++) {
- // Move ball by substep velocity
- if (substeps > 1) {
- ball.x += stepVX;
- ball.y += stepVY;
- }
+ // Always move ball by substep velocity, even if substeps == 1
+ ball.x += stepVX;
+ ball.y += stepVY;
for (var i = 0; i < walls.length; i++) {
var w = walls[i];
// Axis-aligned rectangle collision
var wx = w.x;
@@ -223,22 +223,32 @@
var dy = by - closestY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < r) {
// Ball is colliding with wall
- // Push ball out
- var overlap = r - dist + 1;
- if (dist === 0) {
- // Prevent NaN
- dx = 1;
- dy = 0;
- dist = 1;
+ // Push ball out, and repeat if still inside (up to 3 times)
+ var resolveCount = 0;
+ while (dist < r && resolveCount < 3) {
+ var overlap = r - dist + 1;
+ if (dist === 0) {
+ // Prevent NaN
+ dx = 1;
+ dy = 0;
+ dist = 1;
+ }
+ // Move ball out of wall
+ ball.x += dx / dist * overlap;
+ ball.y += dy / dist * overlap;
+ // Recompute for next iteration
+ bx = ball.x;
+ by = ball.y;
+ dx = bx - closestX;
+ dy = by - closestY;
+ dist = Math.sqrt(dx * dx + dy * dy);
+ resolveCount++;
}
- // Move ball out of wall
- ball.x += dx / dist * overlap;
- ball.y += dy / dist * overlap;
// Calculate the normal vector
- var nx = dx / dist;
- var ny = dy / dist;
+ var nx = dx / (dist === 0 ? 1 : dist);
+ var ny = dy / (dist === 0 ? 1 : dist);
// Calculate dot product of velocity and normal
var dot = ball.vx * nx + ball.vy * ny;
// Reflect velocity using the normal (like center wall)
ball.vx = ball.vx - 2 * dot * nx;