User prompt
Fill TargetManager.targets, refer to current LevelManager data
Code edit (4 edits merged)
Please save this source code
User prompt
create a TargetManager class with the following properties: * targets = { // List of all available targets 'bird1' : { // Asset Name as the key asssetName : 'bird1', // Name of the asset startCorners : [5,7], // list of possible start corner indexes } }; and the following methods * getTarget(key){ /* Returns the target with the key (aka this.targets[key]) */ } * getAllKeys() { /* Returns the list of the keys of available target (aka Object.keys(this.targets)) */ }
Code edit (7 edits merged)
Please save this source code
User prompt
if endPosition.x is < startPosition.x, change the scale of the target to -1
Code edit (2 edits merged)
Please save this source code
User prompt
for Check if the target is out of the screen bounds with an offset, also check if th distance is below the offset
User prompt
in MovingTarget, reduce the logging rate of the position
Code edit (1 edits merged)
Please save this source code
User prompt
in getEndCorner, log sthe start and end corners
Code edit (1 edits merged)
Please save this source code
User prompt
log the selected start and en positions
User prompt
add an offset when "Check if the target is out of the screen bounds"
User prompt
if isDebug, log the moving target position
Code edit (1 edits merged)
Please save this source code
User prompt
Adapt the MovingTarget class to handle all new cases of going out of screen
User prompt
adapt the PositionManager offset so that start and end position are always out of the screen (kwown that targets have a size of 1024x1024)
User prompt
use the PositionManager
Code edit (1 edits merged)
Please save this source code
User prompt
create a PositionManager class with the following properties: * previousStartCornerIndex * nbMaxCorners = 8;// Constant and the following methods * getNextStartCorner(){ /* Returns a random index between 1 and nbMaxCorners and different from previousStartCornerIndex. Stores the selected index in previousStartCornerIndex */ } * getEndCorner(startCornerIndex) { /* Returns a random possible arrival corners from the startCornerIndex provided. for each startCornerIndex there are 3 possible arrival corners: 1+(startCornerIndex+2)%9, 1+(startCornerIndex+3)%9 and 1+(startCornerIndex+4)%9 ie: 1 => 4,5,6 / 2 => 5,6,7 / ... */ } * getCornerPosition(cornerIndex) { /* Returns a couple a coordinates {x, y} of the cornerIndex. 1 => {x: xMin - randomOffset, y: yMin } 2 => {x: xMin , y: yMin - randomOffset } 3 => {x: xMax , y: yMin - randomOffset } 4 => {x: xMax + randomOffset, y: yMin } 5 => {x: xMax + randomOffset, y: yMax } 6 => {x: xMax , y: yMax + randomOffset } 7 => {x: xMin , y: yMax + randomOffset} 8 => {x: xMin - randomOffset, y: yMax } */ }
User prompt
When score is 0, replace the text by "Missed!"
Code edit (9 edits merged)
Please save this source code
User prompt
reset targetShotX and targetShotY at each new round
User prompt
don't cumulate the score
Code edit (1 edits merged)
Please save this source code
/**** 
* Classes
****/ 
/***********************************************************************************/ 
/********************************** CAMERA HUD CLASS ************************************/
/***********************************************************************************/ 
var CameraHUD = Container.expand(function () {
	var self = Container.call(this);
	function createCorner(x, y, rotation) {
		var corner = new Container();
		var line1 = LK.getAsset('line', {
			width: 100,
			height: 20,
			anchorX: 0,
			anchorY: 0
		});
		var line2 = LK.getAsset('line', {
			width: 100,
			height: 20,
			anchorX: 0,
			anchorY: 0
		});
		line2.rotation = Math.PI / 2;
		line1.alpha = 0.5;
		line2.alpha = 0.5;
		corner.addChild(line1);
		corner.addChild(line2);
		corner.x = x;
		corner.y = y;
		corner.rotation = rotation;
		return corner;
	}
	var topLeft = createCorner(256, 700, 0);
	var topRight = createCorner(2048 - 256, 700, Math.PI / 2);
	var bottomLeft = createCorner(256, 2732 - 700, -Math.PI / 2);
	var bottomRight = createCorner(2048 - 256, 2732 - 700, Math.PI);
	self.addChild(topLeft);
	self.addChild(topRight);
	self.addChild(bottomLeft);
	self.addChild(bottomRight);
});
/***********************************************************************************/ 
/********************************** FRAME BACKGROUND CLASS *************************/
/***********************************************************************************/ 
var FrameBackground = Container.expand(function () {
	var self = Container.call(this);
	var frameBackground = self.attachAsset(currentBackground, {
		anchorX: 0.5,
		anchorY: 0.5,
		width: xMax - xMin,
		height: yMax - yMin,
		x: (xMax + xMin) / 2,
		y: (yMax + yMin) / 2
	});
});
/***********************************************************************************/ 
/********************************** FRAME MASK CLASS *************************/
/***********************************************************************************/ 
var FrameMask = Container.expand(function () {
	var self = Container.call(this);
	var top = self.attachAsset('line', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: yMin / 2,
		width: 2048,
		height: yMin,
		tint: isDebug ? 0xFF0000 : 0x8FA9B9 // Red tint in debug mode
	});
	var left = self.attachAsset('line', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: xMin / 2,
		y: 2732 / 2,
		width: xMin,
		height: 2732,
		tint: isDebug ? 0x00FF00 : 0x8FA9B9 // Green tint in debug mode
	});
	var bottom = self.attachAsset('line', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: (2732 + yMax) / 2,
		width: 2048,
		height: 2732 - yMax,
		tint: isDebug ? 0x0000FF : 0x8FA9B9 // Blue tint in debug mode
	});
	var right = self.attachAsset('line', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: (2048 + xMax) / 2,
		y: 2732 / 2,
		width: 2048 - xMax,
		height: 2732,
		tint: isDebug ? 0xFFFF00 : 0x8FA9B9 // Yellow tint in debug mode
	});
	self.addChild(top);
	self.addChild(left);
	self.addChild(bottom);
	self.addChild(right);
});
/***********************************************************************************/ 
/********************************** MOVING TARGET CLASS ************************************/
/***********************************************************************************/ 
var MovingTarget = Container.expand(function () {
	var self = Container.call(this);
	//var targets = levelManager.getTargets();
	//currentTargetAsset = targets[levelManager.currentRound % targets.length];
	currentTargetAsset = levelManager.getTarget();
	if (!currentTargetAsset) {
		console.error("Failed to get currentTargetAsset for round: ", levelManager.currentRound);
	}
	log("Current Target Asset: ", currentTargetAsset);
	log("Current Round: ", levelManager.currentRound);
	if (currentTargetAsset) {
		var targetGraphics = self.attachAsset(currentTargetAsset, {
			anchorX: 0.5,
			anchorY: 0.5
		});
	} else {
		console.error("currentTargetAsset is undefined");
	}
	self.speedX = 10;
	self.update = function () {
		if (!isPlaying) {
			return;
		}
		var dx = self.endX - self.x;
		var dy = self.endY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		self.x += dx / distance * self.speedX;
		self.y += dy / distance * self.speedX;
		if (isDebug) {
			console.log("MovingTarget position:", {
				x: self.x,
				y: self.y
			});
		}
		// Check if the target is out of the screen bounds
		if (self.x < -self.width || self.x > 2048 + self.width || self.y < -self.height || self.y > 2732 + self.height) {
			self.destroy();
			cleanPlayingState();
			initResultState();
		}
	};
});
/***********************************************************************************/ 
/********************************** PHOTOFRAME CLASS ************************************/
/***********************************************************************************/ 
var PhotoFrame = Container.expand(function () {
	var self = Container.call(this);
	var frameBorderTop = self.attachAsset('line', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	frameBorderTop.width = xMax - xMin + 16;
	frameBorderTop.height = 20;
	frameBorderTop.alpha = 1.0;
	frameBorderTop.x = (xMax + xMin) / 2;
	frameBorderTop.y = yMin;
	var frameBorderRight = self.attachAsset('line', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0xFFFFFF // Grey color
	});
	frameBorderRight.width = 20;
	frameBorderRight.height = yMax - yMin;
	frameBorderRight.alpha = 1.0;
	frameBorderRight.x = xMax;
	frameBorderRight.y = (yMax + yMin) / 2;
	var frameBorderBottom = self.attachAsset('line', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0xFFFFFF // Grey color
	});
	frameBorderBottom.width = xMax - xMin + 20;
	frameBorderBottom.height = 20;
	frameBorderBottom.alpha = 1.0;
	frameBorderBottom.x = (xMax + xMin) / 2;
	frameBorderBottom.y = yMax;
	var frameBorderLeft = self.attachAsset('line', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	frameBorderLeft.width = 20;
	frameBorderLeft.height = yMax - yMin;
	frameBorderLeft.alpha = 1.0;
	frameBorderLeft.x = xMin;
	frameBorderLeft.y = (yMax + yMin) / 2;
});
/***********************************************************************************/ 
/********************************** PHOTOFRAMESHADOW CLASS *************************/
/***********************************************************************************/ 
var PhotoFrameShadow = Container.expand(function () {
	var self = Container.call(this);
	for (var i = 0; i < 10; i++) {
		var shadowRight = self.attachAsset('line', {
			anchorX: 0,
			anchorY: 0,
			tint: 0x000000 // Red color for debugging
		});
		shadowRight.width = 20 + i * 2; // Increase width by i*2
		shadowRight.height = yMax - yMin;
		shadowRight.alpha = 0.1;
		shadowRight.x = xMax + 10; // Set the same x for all shadowRight
		shadowRight.y = yMin + 10;
		self.addChild(shadowRight);
	}
	for (var i = 0; i < 10; i++) {
		var shadowBottom = self.attachAsset('line', {
			anchorX: 0,
			anchorY: 0,
			tint: 0x000000 // Red color for debugging
		});
		shadowBottom.width = xMax - xMin;
		shadowBottom.height = 20 + i * 2; // Increase height by i*2
		shadowBottom.alpha = 0.1;
		shadowBottom.x = xMin + 10;
		shadowBottom.y = yMax + 10; // Set the same y for all shadowBottom
		self.addChild(shadowBottom);
	}
	// Add shadowCorner asset
	for (var i = 0; i < 10; i++) {
		var shadowCorner = self.attachAsset('line', {
			anchorX: 0,
			anchorY: 0,
			tint: 0x000000,
			x: xMax + 10,
			y: yMax + 10,
			width: 20 + i * 2,
			height: 20 + i * 2,
			alpha: 0.1
		});
		self.addChild(shadowCorner);
	}
});
/***********************************************************************************/ 
/********************************** SHOTBUTTON CLASS ************************************/
/***********************************************************************************/ 
var ShotButton = Container.expand(function () {
	var self = Container.call(this);
	var circle1 = self.attachAsset('shotButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var circle2 = self.attachAsset('shotButton', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0x000000,
		scaleX: 0.9,
		scaleY: 0.9
	});
	var circle3 = self.attachAsset('shotButton', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.85,
		scaleY: 0.85
	});
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x8FA9B9 //Init game with new color
});
/**** 
* Game Code
****/ 
// Enumeration for game states
/***********************************************************************************/ 
/********************************** POSITION MANAGER CLASS *************************/
/***********************************************************************************/ 
var PositionManager = function PositionManager() {
	this.previousStartCornerIndex = null;
	this.nbMaxCorners = 8; // Constant
};
PositionManager.prototype.getNextStartCorner = function () {
	var nextCorner;
	do {
		nextCorner = Math.floor(Math.random() * this.nbMaxCorners) + 1;
	} while (nextCorner === this.previousStartCornerIndex);
	this.previousStartCornerIndex = nextCorner;
	return nextCorner;
};
PositionManager.prototype.getEndCorner = function (startCornerIndex) {
	var possibleEndCorners = [1 + (startCornerIndex + 2) % 9, 1 + (startCornerIndex + 3) % 9, 1 + (startCornerIndex + 4) % 9];
	return possibleEndCorners[Math.floor(Math.random() * possibleEndCorners.length)];
};
PositionManager.prototype.getCornerPosition = function (cornerIndex) {
	var randomOffset = Math.random() * 100; // Example random offset
	var targetSize = 1024; // Size of the target
	switch (cornerIndex) {
		case 1:
			return {
				x: xMin - targetSize - randomOffset,
				y: yMin
			};
		case 2:
			return {
				x: xMin,
				y: yMin - targetSize - randomOffset
			};
		case 3:
			return {
				x: xMax,
				y: yMin - targetSize - randomOffset
			};
		case 4:
			return {
				x: xMax + targetSize + randomOffset,
				y: yMin
			};
		case 5:
			return {
				x: xMax + targetSize + randomOffset,
				y: yMax
			};
		case 6:
			return {
				x: xMax,
				y: yMax + targetSize + randomOffset
			};
		case 7:
			return {
				x: xMin,
				y: yMax + targetSize + randomOffset
			};
		case 8:
			return {
				x: xMin - targetSize - randomOffset,
				y: yMax
			};
		default:
			return {
				x: 0,
				y: 0
			};
	}
};
/***********************************************************************************/ 
/********************************** LEVEL MANAGER CLASS ****************************/
/***********************************************************************************/ 
var LevelManager = function LevelManager() {
	this.levels = [
	/*{
	name: 'Test',
	background: 'forest',
	targets: ['bird1', 'bird2']
	}, */
	{
		name: 'Forest',
		background: 'forest',
		targets: ['bird1', 'bird2']
	}, {
		name: 'Underwater',
		background: 'underwater',
		targets: ['fish1', 'fish2']
	}, {
		name: 'Countryside',
		background: 'countryside',
		targets: ['insect1', 'insect2']
	}, {
		name: 'Town',
		background: 'town',
		targets: ['townObject1', 'townObject2']
	}, {
		name: 'Space',
		background: 'space',
		targets: ['spaceObject1', 'spaceObject2']
	}];
	this.currentLevel = 0;
	this.currentRound = -1;
};
LevelManager.prototype.getBackground = function () {
	return this.levels[levelManager.currentLevel].background;
};
LevelManager.prototype.getTargets = function () {
	return this.levels[levelManager.currentLevel].targets;
};
LevelManager.prototype.getTarget = function () {
	return this.levels[levelManager.currentLevel].targets[levelManager.currentRound];
};
LevelManager.prototype.nextRound = function () {
	log("LevelManager nextRound() : was " + this.currentRound);
	this.currentRound++;
	log("now => " + this.currentRound);
	if (levelManager.currentLevel >= 0 && levelManager.currentLevel < this.levels.length && this.currentRound >= this.levels[levelManager.currentLevel].targets.length) {
		this.currentRound = 0;
		levelManager.currentLevel++;
		if (levelManager.currentLevel >= this.levels.length) {
			levelManager.currentLevel = 0; // Loop back to the first level
		}
	}
};
/****************************************************************************************** */ 
/************************************** GLOBAL VARIABLES ********************************** */
/****************************************************************************************** */ 
var GAME_STATE = {
	INIT: 'INIT',
	NEW_ROUND: 'NEW_ROUND',
	PLAYING: 'PLAYING',
	RESULT: 'RESULT',
	SCORE: 'SCORE'
};
// Game state variables
var levelManager;
var currentBackground = 'countryside';
var nbRoundsPerLevel = 5;
var gameState = GAME_STATE.INIT;
var isPlaying = false;
var score = 0;
var hasShot = false;
var targetShotX = 0;
var targetShotY = 0;
// Photo limits variables
var xMin = 256;
var xMax = 2048 - 256;
var yMin = 700;
var yMax = 2732 - 700;
// Game elements variables
var frameMask;
var photoFrame;
var photoFrameBackground;
var background;
var cameraHUD;
var currentTarget;
var currentTargetAsset;
var shotButton;
// Game layer variables
var photoFrameShadow;
var backgroundLayer;
var foregroundLayer;
// Result target variable
var resultTarget;
// UI variables
var scoreTxt;
var readyText;
// Debug variables
var isDebug = true;
var debugMarker;
var debugText;
/****************************************************************************************** */ 
/*********************************** UTILITY FUNCTIONS ************************************ */
/****************************************************************************************** */ 
function log() {
	if (isDebug) {
		var _console;
		(_console = console).log.apply(_console, arguments);
	}
}
/****************************************************************************************** */ 
/************************************** INPUT HANDLERS ************************************ */
/****************************************************************************************** */ 
game.down = function (x, y, obj) {
	switch (gameState) {
		case GAME_STATE.NEW_ROUND:
			gameNewRoundDown(x, y, obj);
			break;
		case GAME_STATE.PLAYING:
			gamePlayingDown(x, y, obj);
			break;
		case GAME_STATE.RESULT:
			gameResultDown(x, y, obj);
			break;
		case GAME_STATE.SCORE:
			gameScoreDown(x, y, obj);
			break;
	}
};
function gameNewRoundDown(x, y, obj) {
	log("gameNewRoundDown...");
	cleanNewRoundState();
	initPlayingState();
}
function gamePlayingDown(x, y, obj) {
	if (hasShot) {
		return;
	}
	hasShot = true;
	log("gamePlayingDown...");
	LK.getSound('cameraShot').play();
	targetShotX = currentTarget.x;
	targetShotY = currentTarget.y;
	// Add a black flash effect
	LK.effects.flashScreen(0x000000, 1000); // Flash duration of 1000ms
}
function gameResultDown(x, y, obj) {
	log("gameResultDown...from state " + gameState + " != " + GAME_STATE.NEW_ROUND);
	if (gameState != GAME_STATE.NEW_ROUND) {
		cleanResultState();
		initNewRoundState();
	}
}
function gameScoreDown(x, y, obj) {
	log("gameScoreDown...");
	cleanScoreState();
}
/****************************************************************************************** */ 
/************************************* GAME STATES **************************************** */
/****************************************************************************************** */ 
function gameInitialize() {
	log("Game initialize...");
	levelManager = new LevelManager();
	positionManager = new PositionManager();
	levelManager.currentLevel = 0; // Ensure levelManager.currentLevel is set to a valid index
	levelManager.nextRound();
	background = LK.getAsset(levelManager.getBackground(), {
		anchorX: 0,
		anchorY: 0,
		x: 0,
		y: 0
	});
	backgroundLayer = new Container();
	foregroundLayer = new Container();
	cameraHUD = new CameraHUD();
	photoFrameBackground = new FrameBackground();
	photoFrameBackground.visible = false;
	photoFrame = new PhotoFrame();
	photoFrameShadow = new PhotoFrameShadow();
	photoFrameShadow.visible = false;
	frameMask = new FrameMask();
	frameMask.visible = false;
	photoFrameBackground.visible = false;
	game.addChild(backgroundLayer);
	game.addChild(foregroundLayer);
	backgroundLayer.addChild(background);
	backgroundLayer.addChild(photoFrameBackground);
	backgroundLayer.addChild(cameraHUD);
	foregroundLayer.addChild(frameMask);
	foregroundLayer.addChild(photoFrame);
	foregroundLayer.addChild(frameMask);
	foregroundLayer.addChild(photoFrameShadow);
	// UI Elements
	score = 0;
	scoreTxt = new Text2('Quality: ' + score, {
		size: 100,
		fill: "#ffffff",
		weight: 1000,
		dropShadow: true
	});
	scoreTxt.anchor.set(0.5, 0);
	LK.gui.top.addChild(scoreTxt);
	readyText = new Text2('Get Ready...', {
		size: 100,
		fill: "#ffffff",
		weight: 1000,
		dropShadow: true,
		visible: false
	});
	readyText.anchor.set(0.5, 0); // Center the text horizontally and set anchor to top
	LK.gui.top.addChild(readyText);
	shotButton = new ShotButton();
	shotButton.x = 1024;
	shotButton.y = 2500;
	game.addChild(shotButton);
	if (isDebug) {
		debugMarker = LK.getAsset('debugMarker', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: 2048 / 2,
			y: 2732 - 50
		});
		game.addChild(debugMarker);
		debugText = new Text2('Debug Info', {
			size: 50,
			fill: "#ffffff"
		});
		debugText.anchor.set(0.5, 1); // Anchor to the bottom-right
		LK.gui.bottom.addChild(debugText);
	}
	initNewRoundState(true);
}
/**************************************** NEW ROUND STATE  *********************************/
function initNewRoundState(keepRound) {
	log("initNewRoundState...before:", 'Level: ' + levelManager.currentLevel + ' Round: ' + levelManager.currentRound);
	if (!keepRound) {
		levelManager.nextRound();
	}
	log("initNewRoundState...after:", 'Level: ' + levelManager.currentLevel + ' Round: ' + levelManager.currentRound);
	targetShotX = 0;
	targetShotY = 0;
	score = 0; // Reset score at the start of each new round
	scoreTxt.setText('Quality: ' + score + '%');
	if (isDebug) {
		debugText.setText('Level: ' + levelManager.currentLevel + ' Round: ' + levelManager.currentRound);
	}
	currentBackground = levelManager.getBackground();
	background = LK.getAsset(currentBackground, {
		anchorX: 0,
		anchorY: 0,
		x: 0,
		y: 0
	});
	backgroundLayer.addChild(background);
	backgroundLayer.addChild(cameraHUD);
	cameraHUD.visible = true;
	gameState = GAME_STATE.NEW_ROUND;
	// TODO : handle Level change and target change
	currentTarget = new MovingTarget();
	var startCornerIndex = positionManager.getNextStartCorner();
	var endCornerIndex = positionManager.getEndCorner(startCornerIndex);
	var startPosition = positionManager.getCornerPosition(startCornerIndex);
	var endPosition = positionManager.getCornerPosition(endCornerIndex);
	currentTarget.x = startPosition.x;
	currentTarget.y = startPosition.y;
	currentTarget.endX = endPosition.x;
	currentTarget.endY = endPosition.y;
	backgroundLayer.addChild(currentTarget);
	readyText.visible = true;
	photoFrame.visible = false;
	photoFrameShadow.visible = false;
	shotButton.visible = true;
	scoreTxt.visible = false;
	LK.getSound('forestSound').play();
	LK.setTimeout(function () {
		cleanNewRoundState();
		initPlayingState();
	}, 1000 + 1000 + Math.random());
}
function handleNewRoundLoop() {
	// Update New round elements
}
function cleanNewRoundState() {
	log("cleanNewRoundState...");
	// Remove New round elements
	readyText.visible = false;
}
/**************************************** PLAYING STATE  *********************************/
function initPlayingState() {
	log("initPlayingState...");
	gameState = GAME_STATE.PLAYING;
	isPlaying = true;
	hasShot = false;
}
function handlePlayingLoop() {
	// Update game elements
}
function cleanPlayingState() {
	log("cleanPlayingState...");
	isPlaying = false;
	// Remove game elements
	background.visible = false;
	cameraHUD.visible = false;
}
/**************************************** RESULT STATE  *********************************/
function initResultState() {
	log("initResultState...");
	shotButton.visible = false;
	scoreTxt.visible = true;
	frameMask.visible = true;
	foregroundLayer.addChildAt(frameMask, 0);
	gameState = GAME_STATE.RESULT;
	photoFrame.visible = true;
	photoFrameBackground = new FrameBackground();
	photoFrameBackground.visible = true;
	backgroundLayer.addChild(photoFrameBackground);
	photoFrameShadow.visible = true;
	background.tint = 0x000000; // Set background to black
	// Show the target again at the shot position if within limits
	if (targetShotX >= xMin - currentTarget.width / 2 && targetShotX <= xMax + currentTarget.width / 2 && targetShotY >= yMin - currentTarget.height / 2 && targetShotY <= yMax + currentTarget.height / 2) {
		resultTarget = new Container();
		var resultTargetGraphics = resultTarget.attachAsset(currentTargetAsset, {
			anchorX: 0.5,
			anchorY: 0.5
		});
		resultTarget.x = targetShotX;
		resultTarget.y = targetShotY;
		backgroundLayer.addChild(resultTarget);
	}
	// Calculate the center of the photo frame
	var centerX = (xMin + xMax) / 2;
	var centerY = (yMin + yMax) / 2;
	// Calculate the distance between the target shot and the center
	var distance = Math.sqrt(Math.pow(targetShotX - centerX, 2) + Math.pow(targetShotY - centerY, 2));
	// Calculate the maximum possible distance (from center to any corner)
	var maxDistance = Math.sqrt(Math.pow((xMax - xMin) / 2, 2) + Math.pow((yMax - yMin) / 2, 2));
	// Calculate the score (0 to 100)
	var shotScore = Math.max(0, 100 - distance / maxDistance * 100);
	// Update the score
	score = Math.round(shotScore);
	scoreTxt.setText(score === 0 ? 'Missed!' : 'Quality: ' + score + '%');
}
function handleResultLoop() {
	// Update result elements
}
function cleanResultState() {
	log("cleanResultState...");
	frameMask.visible = false;
	scoreTxt.visible = false;
	photoFrameBackground.visible = false;
	photoFrame.visible = false;
	photoFrameShadow.visible = false;
	foregroundLayer.removeChild(frameMask);
	if (resultTarget) {
		backgroundLayer.removeChild(resultTarget);
		resultTarget = null;
	}
	// Remove result elements
	//initNewRoundState();
}
/**************************************** SCORE STATE  *********************************/
function initScoreState() {
	log("initScoreState...");
	gameState = GAME_STATE.SCORE;
}
function handleScoreLoop() {
	// Update score elements
}
function cleanScoreState() {
	log("cleanScoreState...");
	LK.showGameOver();
}
/***********************************************************************************/ 
/******************************** MAIN GAME LOOP ***********************************/
/***********************************************************************************/ 
game.update = function () {
	currentTarget.update();
	switch (gameState) {
		case GAME_STATE.NEW_ROUND:
			handleNewRoundLoop();
			break;
		case GAME_STATE.PLAYING:
			handlePlayingLoop();
			break;
		case GAME_STATE.SCORE:
			handleScoreLoop();
			break;
	}
};
gameInitialize(); // Initialize the game ===================================================================
--- original.js
+++ change.js
@@ -129,8 +129,14 @@
 		var dy = self.endY - self.y;
 		var distance = Math.sqrt(dx * dx + dy * dy);
 		self.x += dx / distance * self.speedX;
 		self.y += dy / distance * self.speedX;
+		if (isDebug) {
+			console.log("MovingTarget position:", {
+				x: self.x,
+				y: self.y
+			});
+		}
 		// Check if the target is out of the screen bounds
 		if (self.x < -self.width || self.x > 2048 + self.width || self.y < -self.height || self.y > 2732 + self.height) {
 			self.destroy();
 			cleanPlayingState();
:quality(85)/https://cdn.frvr.ai/66580cb3348e66c1af08d07d.png%3F3) 
 a forest.
:quality(85)/https://cdn.frvr.ai/6658e7f9a8495880fae9b3cb.png%3F3) 
 flying Red-bellied Woodpecker.
:quality(85)/https://cdn.frvr.ai/6658eb7ea8495880fae9b3e4.png%3F3) 
 flying Yellow-headed Blackbird.
:quality(85)/https://cdn.frvr.ai/6658ee73a8495880fae9b3f1.png%3F3) 
 flying Painted Bunting.
:quality(85)/https://cdn.frvr.ai/665b2c7480434ae8b5e25f39.png%3F3) 
 Underwater. only water and corals. NO animals
:quality(85)/https://cdn.frvr.ai/665b2e0d80434ae8b5e25f50.png%3F3) 
 Countryside. 1 flower in foreground.
:quality(85)/https://cdn.frvr.ai/665b2ee680434ae8b5e25f63.png%3F3) 
 A Butterfly flying.
:quality(85)/https://cdn.frvr.ai/665b37dc80434ae8b5e25f94.png%3F3) 
 a fish swimming.
:quality(85)/https://cdn.frvr.ai/665b38f880434ae8b5e25fa9.png%3F3) 
 full dragonfly flying to the right.
:quality(85)/https://cdn.frvr.ai/665b39b180434ae8b5e25fc1.png%3F3) 
 full drone flying to the right.
:quality(85)/https://cdn.frvr.ai/665b3afc80434ae8b5e25fe4.png%3F3) 
 a full hot air balloon with a basket flying to the right.
:quality(85)/https://cdn.frvr.ai/665b3c7580434ae8b5e26010.png%3F3) 
 roofs of an empty modern city. day light
:quality(85)/https://cdn.frvr.ai/665b3ced80434ae8b5e26020.png%3F3) 
 a satellite.
:quality(85)/https://cdn.frvr.ai/665b3e3480434ae8b5e26059.png%3F3) 
 stary dark space. NO OBJECTS
:quality(85)/https://cdn.frvr.ai/665c8d9f67a4a5fa36339b68.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/665c90fb67a4a5fa36339bcc.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/665cafa867a4a5fa36339c87.png%3F3) 
 a multitude of polaroids in bulk, with photos of birds, fishes, butterflies, planes, hot air baloons, satelites, dragonflies.....
:quality(85)/https://cdn.frvr.ai/665cc51967a4a5fa36339cbf.png%3F3) 
 A flying owl.
:quality(85)/https://cdn.frvr.ai/665cc65067a4a5fa36339ccc.png%3F3) 
 A flying parrot.
:quality(85)/https://cdn.frvr.ai/665cd7925f34c2dd755574b0.png%3F3) 
 hippocampe.
:quality(85)/https://cdn.frvr.ai/665cda1a5f34c2dd755574e4.png%3F3) 
 shark. lateral view
:quality(85)/https://cdn.frvr.ai/665cdcb25f34c2dd75557524.png%3F3) 
 diodon hystrix swimming. lateral view
:quality(85)/https://cdn.frvr.ai/665cdd525f34c2dd7555752c.png%3F3) 
 fighting fish swimming. lateral view
:quality(85)/https://cdn.frvr.ai/665cdfee5f34c2dd75557579.png%3F3) 
 a hang glider flying. full lateral view
:quality(85)/https://cdn.frvr.ai/665ce0d15f34c2dd75557595.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/665d40945f34c2dd755575b0.png%3F3) 
 un cerf-volant multicolore.
:quality(85)/https://cdn.frvr.ai/665d41815f34c2dd755575c8.png%3F3) 
 une coccinelle volante.
:quality(85)/https://cdn.frvr.ai/665d42cf5f34c2dd755575e8.png%3F3) 
 un scarabΓ©e vert irisΓ© volant. side view
:quality(85)/https://cdn.frvr.ai/665d43c75f34c2dd755575f3.png%3F3) 
 une gueppe volante. side view
:quality(85)/https://cdn.frvr.ai/665d44665f34c2dd75557608.png%3F3) 
 un astronaute volant. full side view
:quality(85)/https://cdn.frvr.ai/665d44d95f34c2dd75557613.png%3F3) 
 une navette spaciale volante. full side view
:quality(85)/https://cdn.frvr.ai/665d48905f34c2dd75557642.png%3F3) 
 un astΓ©roΓ―de volant dans l'espace. full side view
:quality(85)/https://cdn.frvr.ai/665d4ab45f34c2dd75557672.png%3F3) 
 remove