User prompt
short range more
User prompt
short range ball reach
User prompt
swipe for direct
User prompt
rebuild new control rule. use tap methode
User prompt
game over when golf ball out of screen
User prompt
easy control aim arrow
User prompt
easy target
User prompt
more long range after power shoot
User prompt
more long range after power shoot
User prompt
more long range after power shoot
User prompt
ball long range after shoot
User prompt
add time
User prompt
game ended when golf in to hole
User prompt
erase bunker and water asset
User prompt
repair game
User prompt
fix invicible ball
User prompt
fix bug when golf ball hit water
User prompt
slow gauge speed
User prompt
long gauge and long range ball
User prompt
make feature cancel shoot
User prompt
slow speed gaugh
User prompt
next
Code edit (1 edits merged)
Please save this source code
User prompt
8-Bit Fairway
Initial prompt
make 8 bit game. simple golf game top down. random golf hole. background is green field gold court
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { bestScore: "undefined" }); /**** * Classes ****/ var AimGuide = Container.expand(function () { var self = Container.call(this); var arrowGraphics = self.attachAsset('aimArrow', { anchorX: 0, anchorY: 0.5 }); self.setAngle = function (angle) { self.rotation = angle; }; self.setVisible = function (visible) { self.visible = visible; }; return self; }); var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.friction = 0.96; self.isMoving = false; self.inWater = false; self.inHole = false; self.update = function () { if (self.isMoving && !self.inHole) { self.x += self.vx; self.y += self.vy; self.vx *= self.friction; self.vy *= self.friction; // Check if ball has basically stopped if (Math.abs(self.vx) < 0.1 && Math.abs(self.vy) < 0.1) { self.vx = 0; self.vy = 0; self.isMoving = false; self.checkIfStoppedInHazard(); } // Check if ball is out of screen if (self.x < 0 || self.x > COURSE_WIDTH || self.y < 0 || self.y > COURSE_HEIGHT) { LK.showGameOver(); // Trigger game over when the ball goes out of screen } } }; self.hit = function (angle, power) { if (!self.isMoving && !self.inHole && !self.inWater) { self.vx = Math.cos(angle) * power * 1.5; // Reduce power multiplier for shorter range self.vy = Math.sin(angle) * power * 1.5; // Reduce power multiplier for shorter range self.isMoving = true; LK.getSound('hit').play(); } }; self.bounce = function () { // Reduced velocity bounce self.vx *= -0.7; self.vy *= -0.7; LK.getSound('bounce').play(); }; self.resetPosition = function (x, y) { self.x = x; self.y = y; self.vx = 0; self.vy = 0; self.isMoving = false; self.inWater = false; self.inHole = false; self.visible = true; self.alpha = 1; // Reset ball transparency to fully visible }; self.fallInHole = function () { self.inHole = true; self.isMoving = false; LK.getSound('holeIn').play(); tween(self, { alpha: 0, width: 15, height: 15 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { self.visible = false; } }); }; self.checkIfStoppedInHazard = function () { // This will be implemented in the main game code when hazards are detected }; self.fallInWater = function () { self.inWater = true; self.isMoving = false; LK.getSound('splash').play(); tween(self, { alpha: 0 }, { duration: 800, easing: tween.easeIn, onFinish: function onFinish() { self.visible = false; self.alpha = 0; // Ensure ball is fully transparent when in water } }); }; return self; }); var Hole = Container.expand(function () { var self = Container.call(this); var holeGraphics = self.attachAsset('hole', { anchorX: 0.5, anchorY: 0.5 }); // Add a flag or other indicator later return self; }); var Obstacle = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'bunker'; var obstacleGraphics = self.attachAsset(self.type, { anchorX: 0.5, anchorY: 0.5 }); return self; }); var PowerMeter = Container.expand(function () { var self = Container.call(this); var barBg = self.attachAsset('powerBar', { anchorX: 0, anchorY: 0.5 }); var barFill = self.attachAsset('powerFill', { anchorX: 0, anchorY: 0.5, width: 0 // Start with no power }); self.power = 0; self.charging = false; self.chargeRate = 0.0025; // Further slow down the charge rate for an even slower speed gauge self.maxPower = 30; self.update = function () { if (self.charging) { self.power += self.chargeRate; if (self.power > 1) { self.power = 0; self.chargeRate *= -1; // Reverse direction } else if (self.power < 0) { self.power = 0; self.chargeRate *= -1; // Reverse direction } barFill.width = barBg.width * self.power; } }; self.startCharging = function () { self.power = 0; self.chargeRate = Math.abs(self.chargeRate); self.charging = true; }; self.stopCharging = function () { self.charging = false; return self.power * self.maxPower; // Return actual power value }; self.reset = function () { self.power = 0; self.charging = false; barFill.width = 0; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x33AA33 // Initial color for the grass }); /**** * Game Code ****/ // UI elements var timerText = new Text2('Time: 0s', { size: 60, fill: 0xFFFFFF }); timerText.anchor.set(0, 0); LK.gui.topLeft.addChild(timerText); timerText.x = 200; // Position next to the hole text var holeTimer = 0; var timerInterval; var COURSE_WIDTH = 2048; var COURSE_HEIGHT = 2732; var TILE_SIZE = 100; var GAME_STATE = { AIMING: 'aiming', CHARGING: 'charging', BALL_MOVING: 'ballMoving', HOLE_COMPLETE: 'holeComplete' }; // Game variables var courseLayout = []; var ball; var currentHole; var obstacles = []; var aimGuide; var powerMeter; var currentState; var strokeCount = 0; var holeNumber = 1; var startX, startY; var ballLastPosition = { x: 0, y: 0 }; var maxCols = Math.ceil(COURSE_WIDTH / TILE_SIZE); var maxRows = Math.ceil(COURSE_HEIGHT / TILE_SIZE); // UI elements var strokeText = new Text2('Strokes: 0', { size: 60, fill: 0xFFFFFF }); strokeText.anchor.set(0, 0); LK.gui.topRight.addChild(strokeText); var holeText = new Text2('Hole: 1', { size: 60, fill: 0xFFFFFF }); holeText.anchor.set(1, 0); LK.gui.topLeft.addChild(holeText); holeText.x = 100; // Move away from the top left corner // Generate a random course layout function generateCourse() { clearCourse(); courseLayout = []; // Start the timer holeTimer = 0; timerText.setText('Time: ' + holeTimer + 's'); timerInterval = LK.setInterval(function () { holeTimer++; timerText.setText('Time: ' + holeTimer + 's'); }, 1000); // Set initial game state for (var i = 0; i < maxRows; i++) { courseLayout[i] = []; for (var j = 0; j < maxCols; j++) { courseLayout[i][j] = { type: 'grass', object: null }; } } // Create a fairway from start to hole using a simple algorithm createFairway(); // Add random bunkers and water hazards addHazards(); // Render the course renderCourse(); // Place the hole placeHole(); // Place the ball at the starting position placeBall(); // Update UI updateUI(); // Set initial game state currentState = GAME_STATE.AIMING; } function clearCourse() { // Remove all existing course elements if (ball) { game.removeChild(ball); } if (currentHole) { game.removeChild(currentHole); } for (var i = 0; i < obstacles.length; i++) { game.removeChild(obstacles[i]); } obstacles = []; } function createFairway() { // Define start and end points startX = Math.floor(maxCols / 2); startY = maxRows - 2; var endX = Math.floor(Math.random() * (maxCols - 4)) + 2; var endY = 2; // Mark the path as fairway var x = startX; var y = startY; while (x !== endX || y !== endY) { // Mark current and surrounding tiles as fairway for (var i = -1; i <= 1; i++) { for (var j = -1; j <= 1; j++) { var newY = y + i; var newX = x + j; if (newY >= 0 && newY < maxRows && newX >= 0 && newX < maxCols) { courseLayout[newY][newX].type = 'fairway'; } } } // Move one step closer to the hole if (x < endX) { x++; } else if (x > endX) { x--; } if (y < endY) { y++; } else if (y > endY) { y--; } } // Mark the end point (hole location) courseLayout[endY][endX].type = 'fairway'; for (var i = -1; i <= 1; i++) { for (var j = -1; j <= 1; j++) { var y = endY + i; var x = endX + j; if (y >= 0 && y < maxRows && x >= 0 && x < maxCols) { courseLayout[y][x].type = 'fairway'; } } } // Remember hole position holeX = endX; holeY = endY; } function addHazards() { // Add rough along the sides of the fairway for (var y = 0; y < maxRows; y++) { for (var x = 0; x < maxCols; x++) { if (courseLayout[y][x].type === 'grass') { // Check if adjacent to fairway var adjacentToFairway = false; for (var j = -1; j <= 1; j++) { for (var k = -1; k <= 1; k++) { var newY = y + j; var newX = x + k; if (newY >= 0 && newY < maxRows && newX >= 0 && newX < maxCols && courseLayout[newY][newX].type === 'fairway') { adjacentToFairway = true; break; } } if (adjacentToFairway) { break; } } if (adjacentToFairway) { courseLayout[y][x].type = 'roughGrass'; } } } } } function renderCourse() { // Create the obstacles for hazards for (var y = 0; y < maxRows; y++) { for (var x = 0; x < maxCols; x++) { var tileType = courseLayout[y][x].type; var screenX = x * TILE_SIZE; var screenY = y * TILE_SIZE; } } } function placeHole() { currentHole = new Hole(); currentHole.x = holeX * TILE_SIZE + TILE_SIZE / 2; currentHole.y = holeY * TILE_SIZE + TILE_SIZE / 2; game.addChild(currentHole); } function placeBall() { if (!ball) { ball = new Ball(); game.addChild(ball); // Create aim guide aimGuide = new AimGuide(); game.addChild(aimGuide); // Create power meter powerMeter = new PowerMeter(); game.addChild(powerMeter); powerMeter.x = COURSE_WIDTH / 2 - 200; powerMeter.y = COURSE_HEIGHT - 100; powerMeter.visible = false; } // Position the ball at the starting point ball.resetPosition(startX * TILE_SIZE + TILE_SIZE / 2, startY * TILE_SIZE + TILE_SIZE / 2); ballLastPosition = { x: ball.x, y: ball.y }; // Update aim guide position aimGuide.x = ball.x; aimGuide.y = ball.y; aimGuide.visible = true; aimGuide.setAngle(Math.PI * 1.5); // Point upward by default } function updateUI() { strokeText.setText('Strokes: ' + strokeCount); holeText.setText('Hole: ' + holeNumber); } function getTileAtPosition(x, y) { var gridX = Math.floor(x / TILE_SIZE); var gridY = Math.floor(y / TILE_SIZE); if (gridX >= 0 && gridX < maxCols && gridY >= 0 && gridY < maxRows) { return courseLayout[gridY][gridX]; } return null; } function checkBallCollisions() { // Get current tile var tile = getTileAtPosition(ball.x, ball.y); if (!tile) { return; } // Check for hole if (Math.sqrt(Math.pow(ball.x - currentHole.x, 2) + Math.pow(ball.y - currentHole.y, 2)) < 20) { ball.fallInHole(); completeHole(); LK.showGameOver(); // Trigger game over when the ball falls into the hole return; } // Check for bunker (slows the ball down more) if (tile.type === 'bunker') { ball.friction = 0.92; // More friction in bunkers } else if (tile.type === 'fairway') { ball.friction = 0.98; // Less friction on fairway for easier target } else { ball.friction = 0.96; } // Check for course boundaries if (ball.x < 0 || ball.x > COURSE_WIDTH || ball.y < 0 || ball.y > COURSE_HEIGHT) { ball.bounce(); } } function resetBallToLastPosition() { strokeCount++; // Penalty stroke updateUI(); ball.resetPosition(ballLastPosition.x, ballLastPosition.y); ball.visible = true; // Ensure ball is visible after repositioning ball.alpha = 1; // Reset ball transparency to fully visible currentState = GAME_STATE.AIMING; aimGuide.x = ball.x; aimGuide.y = ball.y; aimGuide.visible = true; } function completeHole() { currentState = GAME_STATE.HOLE_COMPLETE; // Stop the timer LK.clearInterval(timerInterval); // Show score for this hole var scoreText = new Text2('Hole ' + holeNumber + ' completed in ' + strokeCount + ' strokes!', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0.5); scoreText.x = COURSE_WIDTH / 2; scoreText.y = COURSE_HEIGHT / 2 - 100; game.addChild(scoreText); // Save best score var bestHoleScore = storage['hole' + holeNumber] || null; if (bestHoleScore === null || strokeCount < bestHoleScore) { storage['hole' + holeNumber] = strokeCount; var newRecordText = new Text2('New Best Score!', { size: 50, fill: 0xFFFF00 }); newRecordText.anchor.set(0.5, 0.5); newRecordText.x = COURSE_WIDTH / 2; newRecordText.y = COURSE_HEIGHT / 2; game.addChild(newRecordText); } // Add continue button var continueText = new Text2('Tap to continue', { size: 40, fill: 0xFFFFFF }); continueText.anchor.set(0.5, 0.5); continueText.x = COURSE_WIDTH / 2; continueText.y = COURSE_HEIGHT / 2 + 100; game.addChild(continueText); // Flash the text var flashInterval = LK.setInterval(function () { continueText.visible = !continueText.visible; }, 500); // Wait for tap to continue var tapHandler = function tapHandler(x, y) { LK.clearInterval(flashInterval); game.removeChild(scoreText); game.removeChild(continueText); if (newRecordText) { game.removeChild(newRecordText); } // Prepare next hole holeNumber++; strokeCount = 0; generateCourse(); // Remove this handler game.up = function () {}; }; game.up = tapHandler; } // Initialize the course generateCourse(); // Start playing background music LK.playMusic('bgMusic'); // Input handling game.down = function (x, y) { if (currentState === GAME_STATE.AIMING && !ball.isMoving && !ball.inHole && !ball.inWater) { // Start tracking swipe swipeStartX = x; swipeStartY = y; aimGuide.x = ball.x; aimGuide.y = ball.y; aimGuide.visible = true; } }; game.move = function (x, y) { if (currentState === GAME_STATE.AIMING && aimGuide.visible) { // Calculate angle from swipe movement var dx = x - swipeStartX; var dy = y - swipeStartY; var angle = Math.atan2(dy, dx); aimGuide.setAngle(angle); } }; game.up = function (x, y) { if (currentState === GAME_STATE.AIMING && aimGuide.visible) { // Calculate power based on swipe distance var dx = x - swipeStartX; var dy = y - swipeStartY; var distance = Math.sqrt(dx * dx + dy * dy); var power = Math.min(distance / 100, 1) * powerMeter.maxPower; // Hit the ball var angle = aimGuide.rotation; ball.hit(angle, power); aimGuide.visible = false; currentState = GAME_STATE.BALL_MOVING; strokeCount++; updateUI(); // Remember position for potential penalty ballLastPosition = { x: ball.x, y: ball.y }; } }; // Game update loop game.update = function () { // Update ball physics if (ball && currentState === GAME_STATE.BALL_MOVING) { checkBallCollisions(); // Check if ball has stopped moving if (!ball.isMoving && !ball.inHole && !ball.inWater) { currentState = GAME_STATE.AIMING; aimGuide.x = ball.x; aimGuide.y = ball.y; aimGuide.visible = true; } } // Update power meter if (powerMeter && currentState === GAME_STATE.CHARGING) { powerMeter.update(); } };
===================================================================
--- original.js
+++ change.js
@@ -55,10 +55,10 @@
}
};
self.hit = function (angle, power) {
if (!self.isMoving && !self.inHole && !self.inWater) {
- self.vx = Math.cos(angle) * power * 3.0; // Further increase power multiplier for even longer range
- self.vy = Math.sin(angle) * power * 3.0; // Further increase power multiplier for even longer range
+ self.vx = Math.cos(angle) * power * 1.5; // Reduce power multiplier for shorter range
+ self.vy = Math.sin(angle) * power * 1.5; // Reduce power multiplier for shorter range
self.isMoving = true;
LK.getSound('hit').play();
}
};