User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'punch')' in or related to this line: 'self.punch = function () {' Line Number: 1107
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'punch')' in or related to this line: 'self.punch = function () {' Line Number: 1107
User prompt
add a new punch function in knight class
User prompt
add a new class for buttonPunch but don't use it
Code edit (2 edits merged)
Please save this source code
User prompt
add a health property to knight with value 3
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'takeHit')' in or related to this line: 'self.takeHit = function (bullet) {' Line Number: 1077
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'takeHit')' in or related to this line: 'self.takeHit = function (bullet) {' Line Number: 1083
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'takeHit')' in or related to this line: 'self.takeHit = function (bullet) {' Line Number: 1077
User prompt
create a function takeHit in knight class that take bullet as an argument
User prompt
destroy firebeam if it intersets with knight boundingBox
Code edit (2 edits merged)
Please save this source code
User prompt
add a speed prperty in LaserBeam , and calculate animation duration to respect the speed
Code edit (5 edits merged)
Please save this source code
User prompt
Create a dedicated class for laserBeam
Code edit (1 edits merged)
Please save this source code
User prompt
call fire() when in attacking mode every second
User prompt
add a fire function in Drone class. use droneLaserBeam asset
Code edit (14 edits merged)
Please save this source code
User prompt
in updateAttacking, rotate droneScanBar in direction of the knight within the limit of(+/-Math.PI / 6.5)
Code edit (1 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
User prompt
in updateAttacking, continuously updateRotation to target the knight, don't wait 2000 ms
User prompt
in updateAttacking, continuously updateRotation to target the knight
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Import the tween plugin var Drone = Container.expand(function () { var self = Container.call(this); var droneGraphics = LK.getAsset('drone', { anchorX: 0.5, anchorY: 0.5 }); var shadowDrone = LK.getAsset('drone', { anchorX: 0.5, anchorY: 0.5 }); self.shadowOffset = { x: -30, y: 40 }; // Define shadow offset property shadowDrone.alpha = 0.5; shadowDrone.tint = 0x000000; shadowDrone.x = -10; shadowDrone.y = 40; self.addChild(shadowDrone); self.addChild(droneGraphics); self.droneScanLaser = LK.getAsset('droneScanLaser', { anchorX: 0.5, anchorY: 0.5 }); self.droneScanBar = LK.getAsset('droneScanBar', { anchorX: 0, anchorY: 0.5 }); self.droneScanLaser.visible = true; // Always visible self.droneScanLaser.x = droneGraphics.width * 2; self.droneScanLaser.alpha = 0.3; // Set alpha to 0.3 self.addChild(self.droneScanLaser); self.droneScanBar.x = droneGraphics.width / 2; // droneScanLaser.x; self.droneScanBar.blendMode = 3; self.droneScanBar.y = self.droneScanLaser.y; self.addChild(self.droneScanBar); function loopScanLaserTint() { if (self.state !== 'scanning') { return; } tween(self.droneScanLaser, { tint: 0x00FF00 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.droneScanLaser, { tint: 0x00AA00 }, { duration: 1000, easing: tween.easeInOut, onFinish: loopScanLaserTint // Recursively call to loop }); } }); } function animateScanBar() { if (self.state !== 'scanning') { return; } tween(self.droneScanBar, { alpha: 0.3, rotation: Math.PI / 6.5 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.droneScanBar, { alpha: 0.6, rotation: -Math.PI / 6.5 }, { duration: 1000, easing: tween.easeInOut, onFinish: animateScanBar // Recursively call to loop }); // Ensure the tween is started } }); // Ensure the tween is started } self.speed = 5; self.state = ''; // Possible states: scanning, attacking // Add debug text to track drone state self.debugText = new Text2(self.state, { size: 50, fill: 0xFFFFFF }); self.debugText.x = -droneGraphics.width / 2; self.debugText.y = -droneGraphics.height / 2 - 50; self.addChild(self.debugText); self.fireRange = 300; // Example fire range value self.currentTargetIndex = 0; self.target = { x: 0, y: 0 }; self.lastKnightCheckTime = 0; // Track when we last checked for knight intersection self.lastRotationTime = 0; // Track the last time we updated rotation self.isRotating = false; // Flag to track if we're currently rotating self.isMoving = false; // Flag to track if we're currently moving self.needsRotation = false; // Flag to track if we need to rotate before moving self.justSwitchedFromAttacking = false; // Flag to track if we just switched from attacking mode // Function to select a new random target self.selectTarget = function () { log("selectTarget...:"); var newTargetIndex; do { newTargetIndex = Math.floor(Math.random() * corners.length); } while (newTargetIndex === self.currentTargetIndex); self.currentTargetIndex = newTargetIndex; self.target = corners[newTargetIndex]; log("New target selected at position:", self.target.x, self.target.y); // Set a flag to indicate the target is new and needs rotation first self.needsRotation = true; // Return the new target (not used currently but could be useful) return self.target; }; // Function to handle state transitions self.switchState = function (newState) { // Don't do anything if the state isn't changing if (self.state === newState) { return; } log("Switching drone state from " + self.state + " to " + newState); // Stop any existing tweens to ensure clean state transition tween.stop(self); // Reset movement flags self.isRotating = false; self.isMoving = false; self.justSwitchedFromAttacking = newState === 'scanning' && self.state === 'attacking'; // Update the state self.state = newState; self.debugText.setText(self.state); // Update debug text with current state // Handle entry actions for new state if (newState === 'scanning') { // Entering scanning state self.debugText.tint = 0xFFFFFF; // Reset tint to white for other states self.droneScanLaser.tint = 0x00FF00; // Reset tint to green for scanning mode // Clear current target and set flag to select a new one self.target = null; self.needsRotation = true; animateScanBar(); // Select a new target (this will be handled in updateScanning on next update) } else if (newState === 'attacking') { // Entering attacking state self.debugText.tint = 0xFFA500; // Change tint to orange when attacking self.droneScanLaser.tint = 0xFFA500; // Change tint to orange when attacking // Start following the knight self.followKnight(); } }; self.init = function () { log("Drone initialized at position:", self.x, self.y); // Reset state flags self.isRotating = false; self.isMoving = false; self.needsRotation = true; // Start the animations animateScanBar(); loopScanLaserTint(); // Switch to scanning state to begin patrol self.switchState('scanning'); }; self.update = function () { if (self.state === 'scanning') { self.updateScanning(); } else if (self.state === 'attacking') { self.updateAttacking(); } // Update shadow position shadowDrone.x = self.shadowOffset.x * Math.cos(self.rotation); shadowDrone.y = self.shadowOffset.y * Math.sin(self.rotation); // Update droneScanBar width based on its rotation self.droneScanBar.width = 620 * (1 + 0.33 * Math.abs(Math.sin(self.droneScanBar.rotation))); }; // Function to perform a full 360° scan self.performFullScan = function (callback) { // Calculate duration based on a consistent rotation speed var scanRotationSpeed = 1.0; // Radians per second (slower for scanning) var fullRotationDuration = Math.PI * 2 / scanRotationSpeed * 1000; // ms // Store current rotation var startRotation = self.rotation; // Mark that we're rotating to prevent updateScanning from starting other rotations self.isRotating = true; log("Performing 360° scan"); // Perform a full 360° rotation tween(self, { rotation: startRotation + Math.PI * 2 // Full 360° rotation }, { duration: fullRotationDuration, easing: tween.linear, // Linear easing for constant speed onFinish: function onFinish() { // Clear rotation flag when done self.isRotating = false; log("Full scan complete"); // Call callback if provided if (callback) { callback(); } } }); }; // Handle scanning mode behavior self.updateScanning = function () { // Check for intersection with knight if (self.droneScanBar.intersects(knight.boundingBox)) { self.switchState('attacking'); log("Drone switched to attacking mode!"); return; } // If no target is set, select one if (!self.target) { log("No target set, selecting a new one"); // If we just switched from attacking to scanning mode, do a 360° scan first if (self.justSwitchedFromAttacking) { self.justSwitchedFromAttacking = false; // Perform full scan before selecting a new target self.performFullScan(function () { // After scan is complete, select a new target self.selectTarget(); }); return; } // Otherwise just select a new target self.selectTarget(); return; } // Calculate direction and distance to target var dx = self.target.x - self.x; var dy = self.target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // If very close to target, select a new one if (distance < 10) { log("Reached target, selecting a new one"); self.selectTarget(); return; } // Calculate target angle var targetAngle = Math.atan2(dy, dx); // Check if rotation is needed var angleDiff = Math.abs(calculateAngleDiff(targetAngle, self.rotation)); // If rotation is needed (more than 0.1 radians difference or flag is set) if (angleDiff > 0.1 || self.needsRotation) { // Only start a new rotation if not already rotating if (!self.isRotating) { log("Rotating to face target"); self.isRotating = true; // Use the updateRotation function with callback to clear isRotating flag self.updateRotation(targetAngle, 600, function () { self.isRotating = false; self.needsRotation = false; log("Rotation complete"); }); } } // If rotation is close enough and we're not currently moving, start movement else if (!self.isMoving) { log("Starting movement to target"); self.isMoving = true; // Calculate duration based on distance var moveSpeed = 0.2; // Adjust this value to control drone speed var duration = distance / moveSpeed; // Start moving toward the target tween(self, { x: self.target.x, y: self.target.y }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { self.isMoving = false; log("Movement complete"); // Don't automatically select a new target, let updateScanning handle it } }); } }; // Handle attacking mode behavior self.updateAttacking = function () { var currentTime = Date.now(); var dx = knight.x - self.x; var dy = knight.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var angle = Math.atan2(dy, dx); // Rotate droneScanBar to point at knight within limits var relativeAngle = calculateAngleDiff(angle, self.rotation); // Clamp the scan bar rotation to the maximum allowed range var maxRotation = Math.PI / 6.5; var clampedRotation = Math.max(-maxRotation, Math.min(maxRotation, relativeAngle)); // Set the scan bar rotation directly self.droneScanBar.rotation = clampedRotation; // First check if knight is still in range - do this every second if (currentTime - self.lastKnightCheckTime > 1000) { self.lastKnightCheckTime = currentTime; // Check if we can still see the knight if (!self.droneScanBar.intersects(knight.boundingBox)) { log("Knight lost! Returning to scanning mode."); self.switchState('scanning'); return; } log("Knight still in range at distance: " + distance); } // Position update logic - if we're not currently moving but need to if (!self.isMoving && distance > 550) { log("Knight moved - updating drone position"); // Move to a better position self.followKnight(); return; } // Rotation tracking logic - if we're not currently rotating // Only do smooth rotation tracking when not already moving to a new position if (!self.isRotating && !self.isMoving) { // Track the last time we updated rotation if (currentTime - self.lastRotationTime > 200) { self.lastRotationTime = currentTime; // Calculate a smoother intermediate angle for natural tracking var currentAngle = self.rotation; var angleDiff = calculateAngleDiff(angle, currentAngle); // Only rotate a portion of the way to the target for smoother tracking // This creates a slight lag effect that looks more natural var partialAngle = currentAngle + angleDiff * 0.3; self.isRotating = true; self.updateRotation(partialAngle, 400, function () { self.isRotating = false; }); } } }; self.followKnight = function () { // Cancel any existing movement tweens tween.stop(self); // Calculate direction to knight var dx = knight.x - self.x; var dy = knight.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var angle = Math.atan2(dy, dx); // Set the movement flag self.isMoving = true; self.isRotating = true; // First rotate to face knight, then move toward knight self.updateRotation(angle, 600, function () { self.isRotating = false; // After rotation is complete, start moving toward knight self.moveTowardKnight(); }); }; // Function to calculate distance to knight self.distanceToKnight = function () { var dx = knight.x - self.x; var dy = knight.y - self.y; return Math.sqrt(dx * dx + dy * dy); }; self.moveTowardKnight = function () { var dx = knight.x - self.x; var dy = knight.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // If already within the desired distance, stop moving if (distance <= 500) { return; } // Calculate target position that's 500 units away from knight var ratio = (distance - 500) / distance; var targetX = self.x + dx * ratio; var targetY = self.y + dy * ratio; // Move toward the target tween(self, { x: targetX, y: targetY }, { duration: distance * 2, // Speed based on distance easing: tween.linear, onUpdate: function onUpdate() { // Update rotation to continuously face the knight during movement var currentDx = knight.x - self.x; var currentDy = knight.y - self.y; var currentDistance = Math.sqrt(currentDx * currentDx + currentDy * currentDy); // Only update rotation if not very close to the target if (currentDistance > 10) { var currentAngle = Math.atan2(currentDy, currentDx); // Calculate target rotation with a smaller adjustment for smoothness using the utility function var newRotation = self.rotation + calculateAngleDiff(currentAngle, self.rotation) * 0.1; // Create a separate quick tween for the rotation tween(self, { rotation: newRotation }, { duration: 600, // Very short duration for responsive updates easing: tween.linear }); } }, onFinish: function onFinish() { // Check if we're still in attacking mode before continuing to follow if (self.state === 'attacking') { // Check if knight has moved and we need to follow again if (self.distanceToKnight() > 500) { self.moveTowardKnight(); } } } }); }; self.updateRotation = function (targetAngle, maxDuration, callback) { maxDuration = maxDuration || 500; // Default max duration if not specified // Cancel any existing rotation tweens to prevent conflicts tween.stop(self, 'rotation'); // Calculate the angle difference var angleDiff = calculateAngleDiff(targetAngle, self.rotation); var absDiff = Math.abs(angleDiff); // Calculate duration based on angle difference to achieve constant rotation speed // Use radians per second as the speed unit var rotationSpeed = 6; // Radians per second var duration = Math.min(absDiff / rotationSpeed * 1000, maxDuration); // Ensure a minimum duration for very small rotations duration = Math.max(duration, 50); var targetRotation = self.rotation + angleDiff; // Log the rotation parameters for debugging log("Rotating: angle diff=" + absDiff + ", duration=" + duration + "ms"); tween(self, { rotation: targetRotation }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { log("Rotation complete"); if (callback) { callback(); } } }); }; }); var Knight = Container.expand(function () { var self = Container.call(this); // Add boundingBox for collision detection self.boundingBox = LK.getAsset('boundingBox', { anchorX: 0.5, anchorY: 0.5, width: 80, height: 150, y: -50 }); self.addChild(self.boundingBox); self.boundingBox.alpha = isDebug ? 0.5 : 0; // Set to false if you don't want it visible var directionMapping = { 'down-left': 'dir1', 'left': 'dir2', 'up-left': 'dir3', 'up': 'dir4', 'up-right': 'dir5', 'right': 'dir6', 'down-right': 'dir7', 'down': 'dir8' }; // Pre-create a list of assets for each direction var knightAssets = {}; var shadowAssets = {}; // Shadow assets for the knight var knightIdleAssets = {}; // Idle assets for the knight var shadowIdleAssets = {}; // Shadow idle assets for the knight var color = 0xFFFFFF; // Original blue / 0xff4d4d; // Red / 0x9aff9a; // Green // Initialize run animation assets for (var dir in directionMapping) { knightAssets[dir] = []; shadowAssets[dir] = []; // Initialize shadow assets array for each direction for (var i = 1; i <= 8; i++) { var frameNumber = i.toString().padStart(3, '0'); // Create knight sprite knightAssets[dir].push(LK.getAsset('knight-run-' + directionMapping[dir] + '-' + frameNumber, { anchorX: 0.5, anchorY: 0.5, tint: color })); // Create shadow sprite using the same assets but with modifications var shadowSprite = LK.getAsset('knight-run-' + directionMapping[dir] + '-' + frameNumber, { anchorX: 0.5, anchorY: 0.5 }); // Apply shadow properties shadowSprite.alpha = 0.5; shadowSprite.tint = 0x000000; shadowSprite.rotation = Math.PI / 12; // Rotate by 15 degrees (π/12 radians) shadowSprite.scale.y = 0.5; // Flatten the shadow vertically shadowAssets[dir].push(shadowSprite); } // Initialize idle animation assets (one frame per direction) knightIdleAssets[dir] = LK.getAsset('knight-idle-' + directionMapping[dir] + '-001', { anchorX: 0.5, anchorY: 0.5, tint: color }); // Create shadow for idle animation var shadowIdleSprite = LK.getAsset('knight-idle-' + directionMapping[dir] + '-001', { anchorX: 0.5, anchorY: 0.5 }); // Apply shadow properties shadowIdleSprite.alpha = 0.5; shadowIdleSprite.tint = 0x000000; shadowIdleSprite.rotation = Math.PI / 12; shadowIdleSprite.scale.y = 0.5; shadowIdleAssets[dir] = shadowIdleSprite; } var currentFrame = 0; var animationSpeed = 0.2; // Controls how fast the animation plays var frameCounter = 0; var knightGraphics = knightIdleAssets['down']; // Initialize with the 'down' direction idle asset var shadowGraphics = shadowIdleAssets['down']; // Initialize shadow with the 'down' direction idle asset // Add shadow first (so it appears behind the knight) self.addChild(shadowGraphics); // Then add the knight self.addChild(knightGraphics); knightGraphics.anchor.set(0.5, 0.5); knightGraphics.visible = true; shadowGraphics.visible = true; // Position the shadow slightly offset from the knight var shadowOffsetX = -5; var shadowOffsetY = 20; shadowGraphics.x = shadowOffsetX; shadowGraphics.y = shadowOffsetY; self.lastDirection = 'down'; // Initialize lastDirection to track previous direction self.isMoving = false; // Track if the knight is currently moving self.speed = 9; self.switchAsset = function (direction) { if (!knightGraphics) { return; } // Detach current assets // Hide current assets knightGraphics.visible = false; shadowGraphics.visible = false; // Switch to new assets based on direction and movement state if (self.isMoving) { // Use running animation knightGraphics = knightAssets[direction][currentFrame]; shadowGraphics = shadowAssets[direction][currentFrame]; } else { // Use idle animation knightGraphics = knightIdleAssets[direction]; shadowGraphics = shadowIdleAssets[direction]; } self.addChild(shadowGraphics); self.addChild(knightGraphics); // Show new assets knightGraphics.visible = true; shadowGraphics.visible = true; // Position the shadow slightly offset from the knight shadowGraphics.x = shadowOffsetX; shadowGraphics.y = shadowOffsetY; // Update last direction self.lastDirection = direction; }; self.updateAnimation = function () { if (self.isMoving) { // Only update animation if moving frameCounter += animationSpeed; if (frameCounter >= 1) { frameCounter = 0; currentFrame = (currentFrame + 1) % 8; // Cycle through 8 frames if (self.lastDirection) { self.switchAsset(self.lastDirection); } } } else if (self.lastDirection) { // Make sure we're showing the idle animation when not moving self.switchAsset(self.lastDirection); } }; self.moveToDirection = function (direction) { if (self.lastDirection !== direction) { self.switchAsset(direction); self.lastDirection = direction; } switch (direction) { case 'up': self.y -= self.speed; break; case 'down': self.y += self.speed; break; case 'left': self.x -= self.speed; break; case 'right': self.x += self.speed; break; case 'up-left': self.x -= self.speed / Math.sqrt(2); self.y -= self.speed / Math.sqrt(2); break; case 'up-right': self.x += self.speed / Math.sqrt(2); self.y -= self.speed / Math.sqrt(2); break; case 'down-left': self.x -= self.speed / Math.sqrt(2); self.y += self.speed / Math.sqrt(2); break; case 'down-right': self.x += self.speed / Math.sqrt(2); self.y += self.speed / Math.sqrt(2); break; } }; }); var Target = Container.expand(function () { var self = Container.call(this); self.x = 0; self.y = 0; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ // Utility function to calculate the angle difference function calculateAngleDiff(targetAngle, currentAngle) { var angleDiff = targetAngle - currentAngle; // Normalize angle difference to [-PI, PI] while (angleDiff > Math.PI) { angleDiff -= 2 * Math.PI; } while (angleDiff < -Math.PI) { angleDiff += 2 * Math.PI; } return angleDiff; } //<Write entity 'classes' with empty functions for important behavior here> //<Write imports for supported plugins here> //<Assets used in the game will automatically appear here> //<Write game logic code here, including initializing arrays and variables> var DroneManager = function DroneManager() { var self = this; self.drones = []; self.start = function () { // Spawn a drone in a random corner var currentTargetIndex = Math.floor(Math.random() * corners.length); var cornerPosition = corners[currentTargetIndex]; // Create the drone var drone = new Drone(); // Explicitly set position before adding to the scene drone.x = cornerPosition.x; drone.y = cornerPosition.y; // Store the current target index drone.currentTargetIndex = currentTargetIndex; // Set the initial target to the current corner position drone.target = { x: cornerPosition.x, y: cornerPosition.y }; // Add to container and array middlegroundContainer.addChild(drone); self.drones.push(drone); // This ensures all properties are set before tweening begins LK.setTimeout(function () { drone.init(); }, 100); }; }; /**** * Global variables ****/ var isDebug = true; var gameStarted = false; var droneManager; var backgroundContainer; var middlegroundContainer; var foregroundContainer; var knight; var target; var runSoundInterval; var borderOffset = 380; var corners = [{ x: borderOffset, y: borderOffset }, { x: 2048 - borderOffset, y: borderOffset }, { x: borderOffset, y: 2732 - borderOffset }, { x: 2048 - borderOffset, y: 2732 - borderOffset }]; function log() { if (isDebug) { console.log.apply(console, arguments); } } function initializeGame() { // Create containers backgroundContainer = new Container(); middlegroundContainer = new Container(); foregroundContainer = new Container(); // Add containers to game game.addChild(backgroundContainer); game.addChild(middlegroundContainer); game.addChild(foregroundContainer); // Initialize background var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 }); background.x = 2048 / 2; background.y = 2732 / 2; backgroundContainer.addChild(background); // Initialize knight knight = new Knight(); knight.x = 2048 / 2; knight.y = 2732 / 2; middlegroundContainer.addChild(knight); // Initialize target target = new Target(); target.x = knight.x; target.y = knight.y; foregroundContainer.addChild(target); // Initialize sound runSoundInterval = LK.setInterval(playRunSound, 350); droneManager = new DroneManager(); LK.setTimeout(function () { gameStarted = true; droneManager.start(); }, 1000); } function playRunSound() { if (knight.isMoving) { LK.getSound('knight-run').play(); } } game.down = function (x, y, obj) { var game_position = game.toLocal(obj.global); target.x = game_position.x; target.y = game_position.y; }; game.update = function () { var dx = target.x - knight.x; var dy = target.y - knight.y; var distance = Math.sqrt(dx * dx + dy * dy); var distanceThreshold = 8; // Define a threshold to avoid small movements var directionThreshold = 5; // Define a threshold for direction changes to avoid shaking if (distance > distanceThreshold) { // Set knight to moving state if not already moving if (!knight.isMoving) { knight.isMoving = true; knight.switchAsset(knight.lastDirection || 'down'); // Update asset to running animation } // Determine the primary direction based on the larger component (dx or dy) if (Math.abs(dx) > Math.abs(dy) + directionThreshold) { // Horizontal movement dominates if (dx > 0) { if (dy > directionThreshold) { knight.moveToDirection('down-right'); } else if (dy < -directionThreshold) { knight.moveToDirection('up-right'); } else { knight.moveToDirection('right'); } } else { if (dy > directionThreshold) { knight.moveToDirection('down-left'); } else if (dy < -directionThreshold) { knight.moveToDirection('up-left'); } else { knight.moveToDirection('left'); } } } else if (Math.abs(dy) > Math.abs(dx) + directionThreshold) { // Vertical movement dominates if (dy > 0) { if (dx > directionThreshold) { knight.moveToDirection('down-right'); } else if (dx < -directionThreshold) { knight.moveToDirection('down-left'); } else { knight.moveToDirection('down'); } } else { if (dx > directionThreshold) { knight.moveToDirection('up-right'); } else if (dx < -directionThreshold) { knight.moveToDirection('up-left'); } else { knight.moveToDirection('up'); } } } else { // The difference between dx and dy is small, use diagonal movement if (dx > 0 && dy > 0) { knight.moveToDirection('down-right'); } else if (dx > 0 && dy < 0) { knight.moveToDirection('up-right'); } else if (dx < 0 && dy > 0) { knight.moveToDirection('down-left'); } else if (dx < 0 && dy < 0) { knight.moveToDirection('up-left'); } } } else { // Set knight to idle state if currently moving if (knight.isMoving) { knight.isMoving = false; knight.switchAsset(knight.lastDirection || 'down'); // Update asset to idle animation } } // Update knight animation knight.updateAnimation(); }; initializeGame();
===================================================================
--- original.js
+++ change.js
@@ -289,8 +289,15 @@
var dx = knight.x - self.x;
var dy = knight.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var angle = Math.atan2(dy, dx);
+ // Rotate droneScanBar to point at knight within limits
+ var relativeAngle = calculateAngleDiff(angle, self.rotation);
+ // Clamp the scan bar rotation to the maximum allowed range
+ var maxRotation = Math.PI / 6.5;
+ var clampedRotation = Math.max(-maxRotation, Math.min(maxRotation, relativeAngle));
+ // Set the scan bar rotation directly
+ self.droneScanBar.rotation = clampedRotation;
// First check if knight is still in range - do this every second
if (currentTime - self.lastKnightCheckTime > 1000) {
self.lastKnightCheckTime = currentTime;
// Check if we can still see the knight
@@ -316,15 +323,8 @@
self.lastRotationTime = currentTime;
// Calculate a smoother intermediate angle for natural tracking
var currentAngle = self.rotation;
var angleDiff = calculateAngleDiff(angle, currentAngle);
- // Limit the angle difference to +/- Math.PI / 6.5
- var maxAngleDiff = Math.PI / 6.5;
- if (angleDiff > maxAngleDiff) {
- angleDiff = maxAngleDiff;
- } else if (angleDiff < -maxAngleDiff) {
- angleDiff = -maxAngleDiff;
- }
// Only rotate a portion of the way to the target for smoother tracking
// This creates a slight lag effect that looks more natural
var partialAngle = currentAngle + angleDiff * 0.3;
self.isRotating = true;