Code edit (1 edits merged)
Please save this source code
User prompt
Toca FaceTime Friends
Initial prompt
Toca FaceTime (2014). Let’s FaceTime Lucas 🦁, or ruby 🐰, or Lilly 🐱, or brody 🐻, or baby 🦁, or the powerpuff girls. Tap the green call button to make the iPad come to life, and then tap on the red done button to make the iPad say goodbye.
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var Character = Container.expand(function (name, color) {
	var self = Container.call(this);
	var face = self.attachAsset('character', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: color
	});
	var leftEye = self.attachAsset('eyes', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: -80,
		y: -50
	});
	var rightEye = self.attachAsset('eyes', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 80,
		y: -50
	});
	var mouth = self.attachAsset('mouth', {
		anchorX: 0.5,
		anchorY: 0.5,
		y: 80
	});
	self.name = name;
	self.animationState = 'idle';
	self.lastAnimation = 0;
	self.wave = function () {
		tween(self, {
			rotation: 0.3
		}, {
			duration: 300,
			easing: tween.easeInOut
		});
		tween(self, {
			rotation: -0.3
		}, {
			duration: 300,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(self, {
					rotation: 0.3
				}, {
					duration: 300,
					easing: tween.easeInOut
				});
				tween(self, {
					rotation: 0
				}, {
					duration: 300,
					easing: tween.easeInOut
				});
			}
		});
		LK.getSound('wave').play();
	};
	self.blink = function () {
		tween(leftEye, {
			scaleY: 0.1
		}, {
			duration: 100,
			easing: tween.easeInOut
		});
		tween(rightEye, {
			scaleY: 0.1
		}, {
			duration: 100,
			easing: tween.easeInOut
		});
		tween(leftEye, {
			scaleY: 1
		}, {
			duration: 100,
			easing: tween.easeInOut
		});
		tween(rightEye, {
			scaleY: 1
		}, {
			duration: 100,
			easing: tween.easeInOut
		});
	};
	self.smile = function () {
		tween(mouth, {
			scaleX: 1.5,
			scaleY: 0.7
		}, {
			duration: 500,
			easing: tween.easeInOut
		});
		tween(mouth, {
			scaleX: 1,
			scaleY: 1
		}, {
			duration: 500,
			easing: tween.easeInOut
		});
		LK.getSound('laugh').play();
	};
	self.update = function () {
		if (LK.ticks - self.lastAnimation > 180) {
			// 3 seconds at 60fps
			var randomAction = Math.floor(Math.random() * 3);
			if (randomAction === 0) {
				self.blink();
			} else if (randomAction === 1 && Math.random() > 0.7) {
				self.smile();
			}
			self.lastAnimation = LK.ticks;
		}
	};
	self.down = function (x, y, obj) {
		var actions = ['wave', 'smile', 'blink'];
		var randomAction = actions[Math.floor(Math.random() * actions.length)];
		self[randomAction]();
	};
	return self;
});
var ContactCard = Container.expand(function (characterName, color) {
	var self = Container.call(this);
	var background = self.attachAsset('contactCard', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var nameText = new Text2(characterName, {
		size: 60,
		fill: 0x333333
	});
	nameText.anchor.set(0.5, 0.5);
	nameText.x = 0;
	nameText.y = 0;
	self.addChild(nameText);
	self.characterName = characterName;
	self.characterColor = color;
	self.down = function (x, y, obj) {
		startCall(self.characterName, self.characterColor);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xffffff
});
/**** 
* Game Code
****/ 
var gameState = 'contacts'; // 'contacts', 'calling', 'incall'
var currentCharacter = null;
var callTimer = 0;
var callDuration = 1800; // 30 seconds at 60fps
var characters = [{
	name: 'Lucas',
	color: 0x4169e1
}, {
	name: 'Ruby',
	color: 0xff69b4
}, {
	name: 'Lilly',
	color: 0x98fb98
}, {
	name: 'Brody',
	color: 0xffa500
}, {
	name: 'Baby',
	color: 0xffb6c1
}, {
	name: 'Powerpuff Girl',
	color: 0xff1493
}];
// Contact list interface
var contactsList = new Container();
game.addChild(contactsList);
var titleText = new Text2('FaceTime Friends', {
	size: 120,
	fill: 0x333333
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 200;
contactsList.addChild(titleText);
// Create contact cards
var contactCards = [];
for (var i = 0; i < characters.length; i++) {
	var card = new ContactCard(characters[i].name, characters[i].color);
	card.x = 2048 / 2;
	card.y = 600 + i * 200;
	contactsList.addChild(card);
	contactCards.push(card);
}
// Call interface
var callInterface = new Container();
callInterface.visible = false;
game.addChild(callInterface);
var videoBackground = callInterface.attachAsset('videoFrame', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 2048 / 2,
	y: 2732 / 2
});
var callButton = callInterface.attachAsset('callButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 2048 / 2 - 250,
	y: 2732 - 200
});
var hangupButton = callInterface.attachAsset('hangupButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 2048 / 2 + 250,
	y: 2732 - 200
});
var callingText = new Text2('Calling...', {
	size: 80,
	fill: 0xFFFFFF
});
callingText.anchor.set(0.5, 0.5);
callingText.x = 2048 / 2;
callingText.y = 300;
callInterface.addChild(callingText);
function startCall(characterName, characterColor) {
	gameState = 'calling';
	contactsList.visible = false;
	callInterface.visible = true;
	callTimer = 0;
	callingText.setText('Calling ' + characterName + '...');
	callingText.visible = true;
	LK.getSound('ring').play();
	LK.setTimeout(function () {
		answerCall(characterName, characterColor);
	}, 2000);
}
function answerCall(characterName, characterColor) {
	gameState = 'incall';
	callingText.visible = false;
	currentCharacter = new Character(characterName, characterColor);
	currentCharacter.x = 2048 / 2;
	currentCharacter.y = 2732 / 2;
	callInterface.addChild(currentCharacter);
	LK.getSound('hello').play();
	currentCharacter.wave();
	callTimer = 0;
}
function endCall() {
	if (currentCharacter) {
		currentCharacter.wave();
		LK.getSound('goodbye').play();
		LK.setTimeout(function () {
			currentCharacter.destroy();
			currentCharacter = null;
			gameState = 'contacts';
			contactsList.visible = true;
			callInterface.visible = false;
			callTimer = 0;
		}, 1500);
	}
}
callButton.down = function (x, y, obj) {
	if (gameState === 'calling') {
		// Skip to answer immediately
		answerCall(callingText.text.replace('Calling ', '').replace('...', ''), 0x87ceeb);
	}
};
hangupButton.down = function (x, y, obj) {
	if (gameState === 'incall' || gameState === 'calling') {
		endCall();
	}
};
game.update = function () {
	if (gameState === 'incall') {
		callTimer++;
		// Auto end call after duration
		if (callTimer >= callDuration) {
			endCall();
		}
		// Random character actions during call
		if (currentCharacter && callTimer % 300 === 0) {
			// Every 5 seconds
			var actions = ['wave', 'smile'];
			var randomAction = actions[Math.floor(Math.random() * actions.length)];
			currentCharacter[randomAction]();
		}
	}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,295 @@
-/****
+/**** 
+* Plugins
+****/ 
+var tween = LK.import("@upit/tween.v1");
+
+/**** 
+* Classes
+****/ 
+var Character = Container.expand(function (name, color) {
+	var self = Container.call(this);
+	var face = self.attachAsset('character', {
+		anchorX: 0.5,
+		anchorY: 0.5,
+		tint: color
+	});
+	var leftEye = self.attachAsset('eyes', {
+		anchorX: 0.5,
+		anchorY: 0.5,
+		x: -80,
+		y: -50
+	});
+	var rightEye = self.attachAsset('eyes', {
+		anchorX: 0.5,
+		anchorY: 0.5,
+		x: 80,
+		y: -50
+	});
+	var mouth = self.attachAsset('mouth', {
+		anchorX: 0.5,
+		anchorY: 0.5,
+		y: 80
+	});
+	self.name = name;
+	self.animationState = 'idle';
+	self.lastAnimation = 0;
+	self.wave = function () {
+		tween(self, {
+			rotation: 0.3
+		}, {
+			duration: 300,
+			easing: tween.easeInOut
+		});
+		tween(self, {
+			rotation: -0.3
+		}, {
+			duration: 300,
+			easing: tween.easeInOut,
+			onFinish: function onFinish() {
+				tween(self, {
+					rotation: 0.3
+				}, {
+					duration: 300,
+					easing: tween.easeInOut
+				});
+				tween(self, {
+					rotation: 0
+				}, {
+					duration: 300,
+					easing: tween.easeInOut
+				});
+			}
+		});
+		LK.getSound('wave').play();
+	};
+	self.blink = function () {
+		tween(leftEye, {
+			scaleY: 0.1
+		}, {
+			duration: 100,
+			easing: tween.easeInOut
+		});
+		tween(rightEye, {
+			scaleY: 0.1
+		}, {
+			duration: 100,
+			easing: tween.easeInOut
+		});
+		tween(leftEye, {
+			scaleY: 1
+		}, {
+			duration: 100,
+			easing: tween.easeInOut
+		});
+		tween(rightEye, {
+			scaleY: 1
+		}, {
+			duration: 100,
+			easing: tween.easeInOut
+		});
+	};
+	self.smile = function () {
+		tween(mouth, {
+			scaleX: 1.5,
+			scaleY: 0.7
+		}, {
+			duration: 500,
+			easing: tween.easeInOut
+		});
+		tween(mouth, {
+			scaleX: 1,
+			scaleY: 1
+		}, {
+			duration: 500,
+			easing: tween.easeInOut
+		});
+		LK.getSound('laugh').play();
+	};
+	self.update = function () {
+		if (LK.ticks - self.lastAnimation > 180) {
+			// 3 seconds at 60fps
+			var randomAction = Math.floor(Math.random() * 3);
+			if (randomAction === 0) {
+				self.blink();
+			} else if (randomAction === 1 && Math.random() > 0.7) {
+				self.smile();
+			}
+			self.lastAnimation = LK.ticks;
+		}
+	};
+	self.down = function (x, y, obj) {
+		var actions = ['wave', 'smile', 'blink'];
+		var randomAction = actions[Math.floor(Math.random() * actions.length)];
+		self[randomAction]();
+	};
+	return self;
+});
+var ContactCard = Container.expand(function (characterName, color) {
+	var self = Container.call(this);
+	var background = self.attachAsset('contactCard', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	var nameText = new Text2(characterName, {
+		size: 60,
+		fill: 0x333333
+	});
+	nameText.anchor.set(0.5, 0.5);
+	nameText.x = 0;
+	nameText.y = 0;
+	self.addChild(nameText);
+	self.characterName = characterName;
+	self.characterColor = color;
+	self.down = function (x, y, obj) {
+		startCall(self.characterName, self.characterColor);
+	};
+	return self;
+});
+
+/**** 
 * Initialize Game
-****/
+****/ 
 var game = new LK.Game({
-	backgroundColor: 0x000000
-});
\ No newline at end of file
+	backgroundColor: 0xffffff
+});
+
+/**** 
+* Game Code
+****/ 
+var gameState = 'contacts'; // 'contacts', 'calling', 'incall'
+var currentCharacter = null;
+var callTimer = 0;
+var callDuration = 1800; // 30 seconds at 60fps
+var characters = [{
+	name: 'Lucas',
+	color: 0x4169e1
+}, {
+	name: 'Ruby',
+	color: 0xff69b4
+}, {
+	name: 'Lilly',
+	color: 0x98fb98
+}, {
+	name: 'Brody',
+	color: 0xffa500
+}, {
+	name: 'Baby',
+	color: 0xffb6c1
+}, {
+	name: 'Powerpuff Girl',
+	color: 0xff1493
+}];
+// Contact list interface
+var contactsList = new Container();
+game.addChild(contactsList);
+var titleText = new Text2('FaceTime Friends', {
+	size: 120,
+	fill: 0x333333
+});
+titleText.anchor.set(0.5, 0);
+titleText.x = 2048 / 2;
+titleText.y = 200;
+contactsList.addChild(titleText);
+// Create contact cards
+var contactCards = [];
+for (var i = 0; i < characters.length; i++) {
+	var card = new ContactCard(characters[i].name, characters[i].color);
+	card.x = 2048 / 2;
+	card.y = 600 + i * 200;
+	contactsList.addChild(card);
+	contactCards.push(card);
+}
+// Call interface
+var callInterface = new Container();
+callInterface.visible = false;
+game.addChild(callInterface);
+var videoBackground = callInterface.attachAsset('videoFrame', {
+	anchorX: 0.5,
+	anchorY: 0.5,
+	x: 2048 / 2,
+	y: 2732 / 2
+});
+var callButton = callInterface.attachAsset('callButton', {
+	anchorX: 0.5,
+	anchorY: 0.5,
+	x: 2048 / 2 - 250,
+	y: 2732 - 200
+});
+var hangupButton = callInterface.attachAsset('hangupButton', {
+	anchorX: 0.5,
+	anchorY: 0.5,
+	x: 2048 / 2 + 250,
+	y: 2732 - 200
+});
+var callingText = new Text2('Calling...', {
+	size: 80,
+	fill: 0xFFFFFF
+});
+callingText.anchor.set(0.5, 0.5);
+callingText.x = 2048 / 2;
+callingText.y = 300;
+callInterface.addChild(callingText);
+function startCall(characterName, characterColor) {
+	gameState = 'calling';
+	contactsList.visible = false;
+	callInterface.visible = true;
+	callTimer = 0;
+	callingText.setText('Calling ' + characterName + '...');
+	callingText.visible = true;
+	LK.getSound('ring').play();
+	LK.setTimeout(function () {
+		answerCall(characterName, characterColor);
+	}, 2000);
+}
+function answerCall(characterName, characterColor) {
+	gameState = 'incall';
+	callingText.visible = false;
+	currentCharacter = new Character(characterName, characterColor);
+	currentCharacter.x = 2048 / 2;
+	currentCharacter.y = 2732 / 2;
+	callInterface.addChild(currentCharacter);
+	LK.getSound('hello').play();
+	currentCharacter.wave();
+	callTimer = 0;
+}
+function endCall() {
+	if (currentCharacter) {
+		currentCharacter.wave();
+		LK.getSound('goodbye').play();
+		LK.setTimeout(function () {
+			currentCharacter.destroy();
+			currentCharacter = null;
+			gameState = 'contacts';
+			contactsList.visible = true;
+			callInterface.visible = false;
+			callTimer = 0;
+		}, 1500);
+	}
+}
+callButton.down = function (x, y, obj) {
+	if (gameState === 'calling') {
+		// Skip to answer immediately
+		answerCall(callingText.text.replace('Calling ', '').replace('...', ''), 0x87ceeb);
+	}
+};
+hangupButton.down = function (x, y, obj) {
+	if (gameState === 'incall' || gameState === 'calling') {
+		endCall();
+	}
+};
+game.update = function () {
+	if (gameState === 'incall') {
+		callTimer++;
+		// Auto end call after duration
+		if (callTimer >= callDuration) {
+			endCall();
+		}
+		// Random character actions during call
+		if (currentCharacter && callTimer % 300 === 0) {
+			// Every 5 seconds
+			var actions = ['wave', 'smile'];
+			var randomAction = actions[Math.floor(Math.random() * actions.length)];
+			currentCharacter[randomAction]();
+		}
+	}
+};
\ No newline at end of file