pull/28/head
Suvodip 2024-10-29 18:45:48 +05:30
parent cd15a8be17
commit 195756b892
20 changed files with 3124 additions and 2576 deletions

View File

@ -116,7 +116,7 @@ import Layout from "../../layouts/Layout.astro";
var assetsList = {} var assetsList = {}
var snapshotButton; var snapshotButton;
let submitButton; let submitButton;
let demoButtonButton; let demoButton;
let shortUniqueID; let shortUniqueID;
let noticeWidth; let noticeWidth;
let noticeHeight; let noticeHeight;
@ -158,12 +158,12 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 100; noticeWidth = window.innerWidth * 0.5 - 100;
noticeHeight = window.innerHeight * 0.38; noticeHeight = window.innerHeight * 0.38;
}else if(isTab){ }else if(isTab){
// topLogoWidth = 4.5; topLogoWidth = 4.5;
// muteIconWidth = 1.6; muteIconWidth = 1.6;
// resetIconWidth = 1.43; resetIconWidth = 1.43;
// tickIconWidth = 1.29; tickIconWidth = 1.29;
// cancelIconWidth = 1.18; cancelIconWidth = 1.18;
// galleryIconWidth = 1.81; galleryIconWidth = 1.81;
}else{ }else{
topLogoWidth = 6; topLogoWidth = 6;
muteIconWidth = 1.3; muteIconWidth = 1.3;

View File

@ -201,14 +201,6 @@ import Layout from "../../layouts/Layout.astro";
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png');
this.load.image('canvas', '/assets/canvas4.png');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image("muteIcon", '/assets/svg/mute.svg'); this.load.image("muteIcon", '/assets/svg/mute.svg');
@ -268,7 +260,6 @@ import Layout from "../../layouts/Layout.astro";
} }
}); });
let responsiveFontSize = isMobile ? 16 : 32; let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 4', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5); this.add.text(window.innerWidth / 2, 80, 'Number: 4', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write number : 4', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write number : 4', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);

View File

@ -210,7 +210,7 @@ import Layout from "../../layouts/Layout.astro";
} }
function create() { function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo"); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon"); muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon"); retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon"); submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");

View File

@ -2,27 +2,90 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
width: isMobile ? window.innerWidth : window.innerWidth / 2, width: isMobile ? window.innerWidth : window.innerWidth / 2,
height: window.innerHeight / 2, height: window.innerHeight / 2,
}; };
const config = { const config = {
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,14 +103,12 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
// console.log(x);
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -55,14 +116,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 70; letterHeight = 70;
letterScale = 1; letterScale = 1.2;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedAHeight = 35; animatedAHeight = 35;
animatedAScale = 0.65; animatedAScale = 0.8;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -78,14 +139,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 50; letterHeight = 50;
letterScale = 1; letterScale = 1.2;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedAHeight = 20; animatedAHeight = 0;
animatedAScale = 0.73; animatedAScale = 0.8;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -96,6 +157,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -114,130 +197,66 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : A", { font: '700 40px quicksand', fill: '#05b3a4', });
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterA').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterA').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterA').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterA').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedA').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedA').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
let responsiveFontSize = isMobile ? 16 : 32;
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; this.add.text(window.innerWidth / 2, 80, 'Letter: A', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const baseFontSize = 24; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : A', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : A', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedAHeight, 'animatedA').setDepth(2).setScale(animatedAScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedAHeight, 'animatedA').setDepth(2).setScale(animatedAScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -250,12 +269,12 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Slant Left',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant Left',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
firstLayer.setAlpha(0.5); firstLayer.setAlpha(0.5);
@ -263,7 +282,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Slant Right',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant Right',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -273,7 +292,7 @@ let scoreTotal = 0; let isDrawing = false;
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale); thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75; textX = isMobile ? customWidth / 3 : customWidth * 0.75;
const thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioThreeAudio = this.sound.add('audioThree'); const audioThreeAudio = this.sound.add('audioThree');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@ -287,8 +306,6 @@ let scoreTotal = 0; let isDrawing = false;
let secondDragStartPoint = { x: 0, y: 0 }; let secondDragStartPoint = { x: 0, y: 0 };
let thirdDragStartPoint = { x: 0, y: 0 }; let thirdDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer // Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => { firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x; firstDragStartPoint.x = pointer.x;
@ -350,7 +367,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -369,35 +385,55 @@ let scoreTotal = 0; let isDrawing = false;
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
function update() { function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 58; letterHeight = 58;
letterScale = 0.85; letterScale = 1.2;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.6; animatedVideoScale = 0.8;
animatedBHeight = 32; animatedBHeight = 22;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -73,14 +138,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 50; letterHeight = 50;
letterScale = 1; letterScale = 1.2;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedVideoScale = 0.70; animatedVideoScale = 0.8;
animatedBHeight = 20; animatedBHeight = 10;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -91,6 +156,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -110,139 +197,67 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : B", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterB').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterB').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterB').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterB').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedB').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedB').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
let responsiveFontSize = isMobile ? 16 : 32;
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; this.add.text(window.innerWidth / 2, 80, 'Letter: B', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const baseFontSize = 24; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : B', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : B', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedBHeight, 'animatedB').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedBHeight, 'animatedB').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -256,11 +271,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -269,7 +284,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Slide Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slide Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -279,7 +294,7 @@ let scoreTotal = 0; let isDrawing = false;
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale); thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75; textX = isMobile ? customWidth / 3 : customWidth * 0.75;
const thirdTextLayer = this.add.text(textX, textY, '3. Slide Around', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slide Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTHreeAudio = this.sound.add('audioTwo'); const audioTHreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@ -293,8 +308,6 @@ let scoreTotal = 0; let isDrawing = false;
let secondDragStartPoint = { x: 0, y: 0 }; let secondDragStartPoint = { x: 0, y: 0 };
let thirdDragStartPoint = { x: 0, y: 0 }; let thirdDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer // Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => { firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x; firstDragStartPoint.x = pointer.x;
@ -360,7 +373,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -378,31 +390,14 @@ let scoreTotal = 0; let isDrawing = false;
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
@ -410,4 +405,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer; let firstLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -57,7 +122,7 @@ let scoreTotal = 0; let isDrawing = false;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.59; animatedVideoScale = 0.59;
animatedAHeight = 32; animatedCHeight = 32;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
startButtonHeight = customHeight / 1.1; startButtonHeight = customHeight / 1.1;
@ -79,7 +144,7 @@ let scoreTotal = 0; let isDrawing = false;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedVideoScale = 0.70; animatedVideoScale = 0.70;
animatedAHeight = 20; animatedCHeight = 20;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -90,6 +155,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -98,7 +185,7 @@ let scoreTotal = 0; let isDrawing = false;
// let hideButton; // let hideButton;
function preload() { function preload() {
this.load.video('animatedA', '/assets/animated-letter/capital_c.mp4'); this.load.video('animatedC', '/assets/animated-letter/capital_c.mp4');
this.load.svg('letterC', '/assets/capital-letter/c.svg'); this.load.svg('letterC', '/assets/capital-letter/c.svg');
this.load.svg('layer1', '/assets/capital-letter/c.svg'); this.load.svg('layer1', '/assets/capital-letter/c.svg');
this.load.audio('audioOne', '/assets/audio/hook-around.mp3'); this.load.audio('audioOne', '/assets/audio/hook-around.mp3');
@ -106,139 +193,66 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('beanie', '/assets/beanieImage.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
this.load.image('canvasStand', '/assets/stand2.png');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false); submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : C", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterC').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterC').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterC').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterC').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedA').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedC').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; animatedLetter.setVisible(true);
const baseFontSize = 24; firstScreen.setVisible(true);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : C', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); }
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedAHeight, 'animatedA').setDepth(2).setScale(animatedVideoScale); })
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: C', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : C', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedCHeight, 'animatedC').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -252,11 +266,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -289,7 +303,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -307,37 +320,57 @@ let scoreTotal = 0; let isDrawing = false;
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
function update() { function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 58; letterHeight = 58;
letterScale = 0.85; letterScale = 1.2;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.6; animatedVideoScale = 0.8;
animatedDHeight = 32; animatedDHeight = 22;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -73,14 +138,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 50; letterHeight = 50;
letterScale = 1; letterScale = 1.2;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedVideoScale = 0.70; animatedVideoScale = 0.8;
animatedDHeight = 20; animatedDHeight = 10;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -91,6 +156,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -109,140 +196,68 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
submitNotic.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : D", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'letterD').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'letterD').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'letterD').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'letterD').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedD').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedD').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
let responsiveFontSize = isMobile ? 16 : 32;
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; this.add.text(window.innerWidth / 2, 80, 'Letter: D', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const baseFontSize = 24; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : D', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : D', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedDHeight, 'animatedD').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedDHeight, 'animatedD').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -256,11 +271,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -269,7 +284,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Slide Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slide Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -282,8 +297,6 @@ let scoreTotal = 0; let isDrawing = false;
let firstDragStartPoint = { x: 0, y: 0 }; let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 }; let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer // Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => { firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x; firstDragStartPoint.x = pointer.x;
@ -324,7 +337,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -341,30 +353,15 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
firstTextLayer.setVisible(false);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play();
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
graphics.setVisible(true);
}) })
} }
@ -372,4 +369,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer, fourthLayer; let firstLayer, secondLayer, thirdLayer, fourthLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -89,6 +154,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -108,137 +195,64 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : E", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterE').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterE').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterE').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterE').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedE').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedE').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
let responsiveFontSize = isMobile ? 16 : 32;
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; this.add.text(window.innerWidth / 2, 80, 'Letter: E', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const baseFontSize = 24; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : E', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : E', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedEHeight, 'animatedE').setDepth(2).setScale(0.73); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedEHeight, 'animatedE').setDepth(2).setScale(0.73);
// Play the video // Play the video
@ -254,11 +268,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -267,7 +281,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -277,7 +291,7 @@ let scoreTotal = 0; let isDrawing = false;
thirdLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale); thirdLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75; textX = isMobile ? customWidth / 3 : customWidth * 0.75;
const thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioThreeAudio = this.sound.add('audioTwo'); const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@ -288,7 +302,7 @@ let scoreTotal = 0; let isDrawing = false;
fourthLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer4').setScale(letterScale); fourthLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer4').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75; textX = isMobile ? customWidth / 3 : customWidth * 0.75;
const fourthTextLayer = this.add.text(textX, textY, '4. Slide', { font: '700 40px quicksand', fill: '#05b3a4'}); const fourthTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '4. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioFourthAudio = this.sound.add('audioTwo'); const audioFourthAudio = this.sound.add('audioTwo');
fourthTextLayer.setVisible(false); fourthTextLayer.setVisible(false);
fourthLayer.setDepth(1.1); fourthLayer.setDepth(1.1);
@ -389,7 +403,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -407,31 +420,14 @@ let scoreTotal = 0; let isDrawing = false;
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
@ -439,4 +435,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,28 +103,26 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
// let x = 100; let demoButton;
// // Use x
// console.log(x);
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
cloudHeight = 340; cloudHeight = 340;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 70; letterHeight = 35;
letterScale = 1; letterScale = 1.08;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedFHeight = 35; animatedFHeight = 0;
animatedFScale = 0.65; animatedFScale = 0.8;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -77,14 +138,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 50; letterHeight = 50;
letterScale = 1; letterScale = 1.1;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedFHeight = 20; animatedFHeight = 10;
animatedFScale = 0.73; animatedFScale = 0.8;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -95,6 +156,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -112,134 +195,63 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
font: '900 24px Quicksand', demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
fill: '#05b3a4', submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
backgroundColor : '#7c4c23', cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
padding: {x: 10, y: 10}, const borderBottom = this.add.graphics();
shadow: { const x = 0; const y = 54;
offsetX : 2, const lineWidth = window.innerWidth;
offsetY : 2, borderBottom.lineStyle(1, 0x0348A8);
color: '#000', borderBottom.setAlpha(0.2);
blur: 5, borderBottom.beginPath();
fill: true borderBottom.moveTo(x, y);
} borderBottom.lineTo(x + lineWidth, y);
}); borderBottom.strokePath();
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : F", { font: '700 40px quicksand', fill: '#05b3a4', });
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterA').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterA').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterA').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterA').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedF').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedF').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
let responsiveFontSize = isMobile ? 16 : 32;
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; this.add.text(window.innerWidth / 2, 80, 'Letter: F', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const baseFontSize = 24; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : F', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : F', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedFHeight, 'animatedF').setDepth(2).setScale(animatedFScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedFHeight, 'animatedF').setDepth(2).setScale(animatedFScale);
// Play the video // Play the video
@ -254,11 +266,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -267,7 +279,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -277,7 +289,7 @@ let scoreTotal = 0; let isDrawing = false;
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale); thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75; textX = isMobile ? customWidth / 3 : customWidth * 0.75;
const thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioThreeAudio = this.sound.add('audioTwo'); const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@ -351,7 +363,6 @@ let scoreTotal = 0; let isDrawing = false;
}); });
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -369,35 +380,56 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
function update() { function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,24 +103,26 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
cloudHeight = 340; cloudHeight = 340;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 58; letterHeight = 30;
letterScale = 0.85; letterScale = 1;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.60; animatedVideoScale = 0.7;
animatedGHeight = 32; animatedGHeight = 0;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -91,7 +156,33 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
// let hideButton; if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
// console.log("Page loaded on: " + formattedDateTime);
};
function preload() { function preload() {
this.load.video('animatedG', '/assets/animated-letter/capital_g.mp4'); this.load.video('animatedG', '/assets/animated-letter/capital_g.mp4');
@ -104,138 +195,65 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : G", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterG').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterG').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterG').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterG').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedG').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedG').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; animatedLetter.setVisible(true);
const baseFontSize = 24; firstScreen.setVisible(true);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : G', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); }
})
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: G', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : G', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedGHeight, 'animatedG').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedGHeight, 'animatedG').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -249,11 +267,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
audioOneAudio.play(); audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -262,7 +280,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -316,7 +334,6 @@ let scoreTotal = 0; let isDrawing = false;
}); });
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -333,31 +350,15 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
@ -365,4 +366,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,13 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
// let x = 100; let demoButton;
// // Use x
// console.log(x);
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -54,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 70; letterHeight = 70;
letterScale = 0.9; letterScale = 1.2;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedHHeight = 45; animatedHHeight = 30;
animatedHScale = 0.6; animatedHScale = 0.78;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -77,14 +138,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 50; letterHeight = 50;
letterScale = 1; letterScale = 1.2;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedHHeight = 20; animatedHHeight = 10;
animatedHScale = 0.70; animatedHScale = 0.78;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -95,6 +156,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -112,137 +195,65 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : H", { font: '700 40px quicksand', fill: '#05b3a4', });
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'letterH').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'letterH').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'letterH').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'letterH').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedH').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedH').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
let responsiveFontSize = isMobile ? 16 : 32;
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; this.add.text(window.innerWidth / 2, 80, 'Letter: H', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const baseFontSize = 24; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : H', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : H', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedHHeight, 'animatedH').setDepth(2).setScale(animatedHScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedHHeight, 'animatedH').setDepth(2).setScale(animatedHScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -255,11 +266,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -268,7 +279,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioOne'); const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -278,7 +289,7 @@ let scoreTotal = 0; let isDrawing = false;
thirdLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale); thirdLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75; textX = isMobile ? customWidth / 3 : customWidth * 0.75;
const thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioThreeAudio = this.sound.add('audioTwo'); const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@ -355,7 +366,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -373,35 +383,55 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); firstScreen.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
function update() { function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,10 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
// let x = 100; let demoButton;
// // Use x // // Use x
// console.log(x); // console.log(x);
@ -95,6 +159,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -118,129 +204,62 @@ let scoreTotal = 0; let isDrawing = false;
this.load.image('sun', '/assets/sun.png'); this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.image('canvasStand', '/assets/stand2.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo'); this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'letterI').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
this.add.text(customWidth / 10, 20, "Letter : I", { font: '700 40px quicksand', fill: '#05b3a4', });
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'letterI').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'letterI').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'letterI').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedI').setDepth(2); canvasStand
firstScreen.setVisible(false); demoButton.setInteractive().on('pointerdown', () => {
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale); animatedLetter.setCurrentTime(0);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale); animatedLetter.play(true);
// Set up a mask for the drawing area based on the canvas dimensions graphics.setVisible(false);
const maskGraphics = this.make.graphics() firstScreen.setVisible(true);
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale); if(animatedLetter.visible){
const mask = maskGraphics.createGeometryMask(); animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", { graphics.setVisible(false);
font: '900 24px quicksand', animatedLetter.setVisible(true);
fill: '#05b3a4', firstScreen.setVisible(true);
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
} }
}); })
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { let responsiveFontSize = isMobile ? 16 : 32;
animatedLetter.setCurrentTime(0); this.add.text(window.innerWidth / 2, 80, 'Letter: I', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
animatedLetter.play(true); const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : I', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
graphics.setVisible(false);
firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
});
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
const baseFontSize = 24;
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : I', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedIHeight, 'animatedI').setDepth(2).setScale(animatedIScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedIHeight, 'animatedI').setDepth(2).setScale(animatedIScale);
// Play the video // Play the video
@ -255,11 +274,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -268,7 +287,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -278,7 +297,7 @@ let scoreTotal = 0; let isDrawing = false;
thirdLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale); thirdLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75; textX = isMobile ? customWidth / 3 : customWidth * 0.75;
const thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioThreeAudio = this.sound.add('audioTwo'); const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@ -355,7 +374,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -372,35 +390,55 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
function update() { function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xeaeae8,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -92,6 +157,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -110,140 +197,63 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
font: '900 24px Quicksand', submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
fill: '#05b3a4', demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
backgroundColor : '#7c4c23', submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
padding: {x: 10, y: 10}, cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
shadow: { const borderBottom = this.add.graphics();
offsetX : 2, const x = 0; const y = 54;
offsetY : 2, const lineWidth = window.innerWidth;
color: '#000', borderBottom.lineStyle(1, 0x0348A8);
blur: 5, borderBottom.setAlpha(0.2);
fill: true borderBottom.beginPath();
} borderBottom.moveTo(x, y);
}); borderBottom.lineTo(x + lineWidth, y);
submitButton.setVisible(false); borderBottom.strokePath();
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : b", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'letterB').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'letterB').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'letterB').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'letterB').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedB').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedB').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; let responsiveFontSize = isMobile ? 16 : 32;
const baseFontSize = 24; this.add.text(window.innerWidth / 2, 80, 'Letter: b', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : b', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : b', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedBHeight, 'animatedB').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedBHeight, 'animatedB').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -257,11 +267,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -270,7 +280,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Roll Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Roll Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -325,7 +335,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -342,31 +351,15 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => {
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
@ -374,4 +367,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 40; letterHeight = 40;
letterScale = 1.3; letterScale = 1.7;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.6; animatedVideoScale = 0.75;
animatedCHeight = 32; animatedCHeight = 32;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -74,14 +139,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 30; letterHeight = 30;
letterScale = 1.5; letterScale = 1.7;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedVideoScale = 0.7; animatedVideoScale = 0.75;
animatedCHeight = 20; animatedCHeight = 20;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -93,6 +158,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -109,141 +196,67 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
this.load.image('canvasStand', '/assets/stand2.png');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
font: '900 24px Quicksand', submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
fill: '#05b3a4', demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
backgroundColor : '#7c4c23', submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
padding: {x: 10, y: 10}, cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
shadow: { const borderBottom = this.add.graphics();
offsetX : 2, const x = 0; const y = 54;
offsetY : 2, const lineWidth = window.innerWidth;
color: '#000', borderBottom.lineStyle(1, 0x0348A8);
blur: 5, borderBottom.setAlpha(0.2);
fill: true borderBottom.beginPath();
} borderBottom.moveTo(x, y);
}); borderBottom.lineTo(x + lineWidth, y);
submitButton.setVisible(false); borderBottom.strokePath();
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false); submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : c", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterC').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterC').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterC').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterC').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedC').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedC').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; animatedLetter.setVisible(true);
const baseFontSize = 24; firstScreen.setVisible(true);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : c', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); }
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedCHeight, 'animatedC').setDepth(2).setScale(animatedVideoScale); })
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: c', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : c', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedCHeight, 'animatedC').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -257,11 +270,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 7 : customWidth * 0.75; textX = isMobile ? customWidth / 7 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -273,8 +286,6 @@ let scoreTotal = 0; let isDrawing = false;
// Add these variables to keep track of start points // Add these variables to keep track of start points
let firstDragStartPoint = { x: 0, y: 0 }; let firstDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer // Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => { firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x; firstDragStartPoint.x = pointer.x;
@ -296,7 +307,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -313,38 +323,56 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
function update() { function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer; let firstLayer, secondLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -93,6 +158,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -111,141 +198,74 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
this.load.image('canvasStand', '/assets/stand2.png');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : d", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'letterD').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'letterD').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'letterD').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'letterD').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedD').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedD').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
// const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
// const baseFontSize = 24;
// const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
// const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : d', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
// animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedDHeight, 'animatedD').setDepth(2).setScale(animatedVideScale);
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; let responsiveFontSize = isMobile ? 16 : 32;
const baseFontSize = 24; this.add.text(window.innerWidth / 2, 80, 'Letter: d', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : d', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : d', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedDHeight, 'animatedD').setDepth(2).setScale(animatedVideScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedDHeight, 'animatedD').setDepth(2).setScale(animatedVideScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -259,11 +279,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const secondTextLayer = this.add.text(textX, textY, '2. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioOne'); const audioTwoAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -272,7 +292,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const firstTextLayer = this.add.text(textX, textY, '1. Roll Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Roll Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioTwo'); const audioOneAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -326,7 +346,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -343,30 +362,14 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); firstScreen.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
@ -374,4 +377,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xeaeae8,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 30; letterHeight = 30;
letterScale = 1.4; letterScale = 1.9;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.57; animatedVideoScale = 0.78;
animatedEHeight = 32; animatedEHeight = 32;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -74,14 +139,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 20; letterHeight = 20;
letterScale = 1.75; letterScale = 1.9;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedVideoScale = 0.7; animatedVideoScale = 0.78;
animatedEHeight = 20; animatedEHeight = 20;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -93,6 +158,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -111,141 +198,68 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
this.load.image('canvasStand', '/assets/stand2.png');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : e", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterE').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterE').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterE').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterE').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedE').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedE').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; let responsiveFontSize = isMobile ? 16 : 32;
const baseFontSize = 24; this.add.text(window.innerWidth / 2, 80, 'Letter: e', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : e', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : e', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedEHeight, 'animatedE').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedEHeight, 'animatedE').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -259,11 +273,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 6 : customWidth * 0.75; textX = isMobile ? customWidth / 6 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -272,7 +286,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -307,7 +321,6 @@ let scoreTotal = 0; let isDrawing = false;
firstLayer.setAlpha(0.5); firstLayer.setAlpha(0.5);
} }
}); });
``
// Repeat the above code for secondLayer and thirdLayer // Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer // Add this code for secondLayer
@ -329,7 +342,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -346,30 +358,15 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
firstTextLayer.setVisible(false);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play();
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
graphics.setVisible(true);
}) })
} }
@ -377,4 +374,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xeaeae8,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = -10; letterHeight = -10;
letterScale = 1; letterScale = 1.2;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.57; animatedVideoScale = 0.70;
animatedFHeight = 32; animatedFHeight = 38;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -73,14 +138,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = -20; letterHeight = -20;
letterScale = 1; letterScale = 1.2;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedVideoScale = 0.65; animatedVideoScale = 0.69;
animatedFHeight = 20; animatedFHeight = 40;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -91,6 +156,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -109,141 +196,66 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png');
this.load.image('canvas', '/assets/canvas4.png');
this.load.image('sun', '/assets/sun.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false); submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : f", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'letterF').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'letterF').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'letterF').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'letterF').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedF').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedF').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; animatedLetter.setVisible(true);
const baseFontSize = 24; firstScreen.setVisible(true);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : f', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); }
})
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: f', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : f', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedFHeight, 'animatedF').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedFHeight, 'animatedF').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -257,11 +269,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 6 : customWidth * 0.75; textX = isMobile ? customWidth / 6 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Hook Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -270,7 +282,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Cross',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Cross',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -282,8 +294,6 @@ let scoreTotal = 0; let isDrawing = false;
let firstDragStartPoint = { x: 0, y: 0 }; let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 }; let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer // Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => { firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x; firstDragStartPoint.x = pointer.x;
@ -326,7 +336,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -343,31 +352,15 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
@ -375,4 +368,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -50,15 +115,15 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 8; letterHeight = 8;
letterScale = 0.95; letterScale = 1.2;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.62; animatedVideoScale = 0.75;
animatedGHeight = 32; animatedGHeight = 45;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -74,14 +139,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = -20; letterHeight = -20;
letterScale = 1; letterScale = 1.2;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedVideoScale = 0.65; animatedVideoScale = 0.8;
animatedGHeight = 20; animatedGHeight = 20;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -93,6 +158,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -111,141 +198,66 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
this.load.image('canvasStand', '/assets/stand2.png');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : g", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterG').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterG').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterG').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterG').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedG').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedG').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
let responsiveFontSize = isMobile ? 16 : 32;
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; this.add.text(window.innerWidth / 2, 80, 'Letter: g', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const baseFontSize = 24; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : g', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : g', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedGHeight, 'animatedG').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedGHeight, 'animatedG').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -259,11 +271,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 6 : customWidth * 0.75; textX = isMobile ? customWidth / 6 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
audioOneAudio.play(); audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -272,7 +284,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Down Tail',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Down Tail',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -306,7 +318,6 @@ let scoreTotal = 0; let isDrawing = false;
firstLayer.setAlpha(0.5); firstLayer.setAlpha(0.5);
} }
}); });
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer // Add this code for secondLayer
secondLayer.on('dragstart', (pointer) => { secondLayer.on('dragstart', (pointer) => {
@ -327,7 +338,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -344,31 +354,14 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
@ -376,4 +369,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,78 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</div>
<div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +85,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xeaeae8,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +103,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 70; letterHeight = 70;
letterScale = 0.95; letterScale = 1.2;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.6; animatedVideoScale = 0.75;
animatedHHeight = 35; animatedHHeight = 35;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -74,15 +139,15 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 70; letterHeight = 70;
letterScale = 1; letterScale = 1.2;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedVideoScale = 0.63; animatedVideoScale = 0.75;
animatedHHeight = 42; animatedHHeight = 35;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -93,6 +158,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -111,138 +198,65 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('canvasStand', '/assets/stand2.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
} }
function create() { function create() {
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
font: '900 24px Quicksand', submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
fill: '#05b3a4', demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
backgroundColor : '#7c4c23', submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
padding: {x: 10, y: 10}, cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
shadow: { const borderBottom = this.add.graphics();
offsetX : 2, const x = 0; const y = 54;
offsetY : 2, const lineWidth = window.innerWidth;
color: '#000', borderBottom.lineStyle(1, 0x0348A8);
blur: 5, borderBottom.setAlpha(0.2);
fill: true borderBottom.beginPath();
} borderBottom.moveTo(x, y);
}); borderBottom.lineTo(x + lineWidth, y);
submitButton.setVisible(false); borderBottom.strokePath();
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : h", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 + 25, customHeight / 2 + letterHeight, 'letterH').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 25, customHeight / 2 + letterHeight, 'letterH').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 25, customHeight / 2 + letterHeight, 'letterH').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 25, customHeight / 2 + letterHeight, 'letterH').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedH').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedH').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
}); });
let responsiveFontSize = isMobile ? 16 : 32;
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; this.add.text(window.innerWidth / 2, 80, 'Letter: h', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const baseFontSize = 24; const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : h', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : h', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedHHeight, 'animatedH').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedHHeight, 'animatedH').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
@ -258,11 +272,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 25, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 25, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
audioOneAudio.play(); audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -271,7 +285,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 25, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 25, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Roll Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Roll Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -283,8 +297,6 @@ let scoreTotal = 0; let isDrawing = false;
let firstDragStartPoint = { x: 0, y: 0 }; let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 }; let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer // Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => { firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x; firstDragStartPoint.x = pointer.x;
@ -327,7 +339,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -344,31 +355,15 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
@ -376,4 +371,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>

View File

@ -2,15 +2,77 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div> <div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
</div> <div class="flex justify-center items-center h-screen ">
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</main> </div>
</Layout> </div>
<script src="/saveGameData.js" is:inline></script> <div id="parentMainContainer" class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute z-10" style="display: none;">
<div id="loadingState" style="display: none;" class="bg-white flex text-[#000] absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] items-center space-y-2 w-full px-6 py-16"></div>
</div>
<div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div class="flex absolute left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 max-w-lg flex-col rounded-[8px] bg-white space-y-2 w-full p-6" >
<div class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div>
</div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/animate-clipart.gif" alt="" style="width: 90.21px; height: 86.24px;" />
<p class="text-[#0348A8] text-[12px] font-[700] p-6 rounded-[10px] -ml-[10px]" style="background: linear-gradient(270.05deg, #FFFFFF 4.67%, #DAEAFF 99.61%);">Well done! <span id="countStar"></span> stars for your effort! <br> Keep pushing, youve got this!</p>
</div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="history.back();" class="rounded-[4px] bg-[#0348A8] text-[#FFF] text-[12px] font-[700] p-2.5 w-full border-[1px] border-[#0348A8]">Wow, Lets Go</button>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
<div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<div class="flex flex-row z-50 place-items-end clip-art">
<img src="/assets/clip-art-with-hand.svg" alt="Clip Art" class="">
<div class="relative bg-yellow-500 rounded-[4px] -ml-[10px]" style="background: linear-gradient(74.79deg, #E8EBFF 4.63%, #DDC9F1 97.93%); height: 200px; box-shadow: 0px 4px 8px 3px #CAD1F5;">
<img src="/assets/svg/bg-star.svg" alt="Left Star" class="absolute left-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<img src="/assets/svg/bg-star.svg" alt="Right Star" class="absolute right-0 top-1/4 transform -translate-y-1/2 w-12 h-12">
<!-- Content -->
<div class="flex flex-col space-y-3 px-10 py-10 w-[348px] h-[187px] ">
<p class="text-center text-[14px] font-[600] text-[#394FC0]">Want to find how much stars youve earned?</p>
<button class="text-[12px] font-[700] text-white bg-[#394FC0] rounded-[4px] w-full py-2.5" onclick="calculateFromAI();" >Ask to Beanie</button>
<a href="" class="text-center text-[12px] font-[600] text-[#394FC0] underline decoration-2 underline-offset-[4px]">Skip</a>
</div>
</div>
</div>
</div>
<div id="gallerySliderId" class="hidden p-2 z-10 absolute inset-0 bg-black w-full h-screen bg-opacity-50 flex justify-center items-center">
<div class="w-full max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
</div>
<div class="relative w-full aspect-video overflow-hidden rounded-b-lg shadow-lg">
<img id="slideImage" src="" alt="" class="slide active w-full h-full aspect-video transition-transform duration-500" />
<button id="prevButton" class="flex justify-center items-center w-[40px] h-[40px] absolute left-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/leftIcon.svg" alt=""></button>
<button id="nextButton" class="flex justify-center items-center w-[40px] h-[40px] absolute right-4 top-1/2 transform -translate-y-1/2 bg-[#F4F7FF] text-gray-800 p-2 rounded-full shadow-lg hover:bg-gray-100 transition"><img src="/assets/svg/rightIcon.svg" alt=""></button>
<div id="slidetInfo" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 p-2 text-center text-white">
<h2 class="text-lg font-bold" id="imageTitle">Image Title</h2>
<p class="text-sm" id="imageDescription">Description goes here.</p>
</div>
</div>
</div>
</div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
<script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4, x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4, y: window.innerHeight / 4,
@ -22,7 +84,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: 0xFFFFFF, backgroundColor: 0xecedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@ -40,9 +102,11 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer; let firstLayer, secondLayer, thirdLayer;
let graphics; let graphics;
let animatedLetter; let animatedLetter;
let scoreTotal = 0; let isDrawing = false; let scoreTotal = 0;
let isDrawing = false;
let formattedDateTime; let formattedDateTime;
let gameStartTime = "start time here"; let gameStartTime = "start time here";
let demoButton;
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@ -50,14 +114,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterIeight = 50; letterIeight = 50;
letterScale = 1.2; letterScale = 1.6;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
sunWidth = 70; sunWidth = 70;
sunHeight = 70; sunHeight = 70;
animatedVideoScale = 0.5; animatedVideoScale = 0.7;
animatedIHeight = 32; animatedIHeight = 32;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@ -74,14 +138,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterIeight = 30; letterIeight = 30;
letterScale = 1.3; letterScale = 1.6;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animatedVideoScale = 0.55; animatedVideoScale = 0.7;
animatedIHeight = 10; animatedIHeight = 10;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@ -93,6 +157,28 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
resetIconWidth = 1.40;
tickIconWidth = 1.21;
cancelIconWidth = 1.08;
galleryIconWidth = 2;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
} else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
}
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@ -111,141 +197,64 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('succesImage', '/assets/svg/tick.svg'); this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.svg'); this.load.svg('hintImage', '/assets/svg/hint.svg');
this.load.svg('handPointer', '/assets/svg/hand.svg'); this.load.svg('handPointer', '/assets/svg/hand.svg');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("resetIcon", '/assets/svg/reset.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.svg('helpIcons', '/assets/svg/help_icon.svg');
this.load.image('canvasStand', '/assets/stand2.png');
} }
function create() { function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false); muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
font: '900 24px Quicksand', demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
fill: '#05b3a4', submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
backgroundColor : '#7c4c23', cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
padding: {x: 10, y: 10}, const borderBottom = this.add.graphics();
shadow: { const x = 0; const y = 54;
offsetX : 2, const lineWidth = window.innerWidth;
offsetY : 2, borderBottom.lineStyle(1, 0x0348A8);
color: '#000', borderBottom.setAlpha(0.2);
blur: 5, borderBottom.beginPath();
fill: true borderBottom.moveTo(x, y);
} borderBottom.lineTo(x + lineWidth, y);
}); borderBottom.strokePath();
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitButton.setVisible(false);
// windowLoad(); // windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : i", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const scaleFactor = sunScalePlus; // Scale factor (2 means double the size)
const duration = 3000; // Duration of the animation in milliseconds
// Create a scaling tween
this.tweens.add({
targets: sun,
scaleX: scaleFactor,
scaleY: scaleFactor,
duration: duration,
ease: 'Linear',
yoyo: true, // Makes the animation play in reverse
repeat: -1 // Repeat indefinitely
});
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'letterI').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'letterI').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'letterI').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'letterI').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterIeight, 'animatedI').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterIeight, 'animatedI').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale);
// Set up a mask for the drawing area based on the canvas dimensions
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(customWidth / 2 - (canvas.width * canvasScale) / 2, customHeight / 2 + canvasHeight - (canvas.height * canvasScale) / 2, canvas.width * canvasScale, canvas.height * canvasScale);
const mask = maskGraphics.createGeometryMask();
let hideButton = this.add.text(helpButtonWidth, helpButtonHeight, "Let`s Do", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
hideButton.setInteractive().on('pointerdown', () => {
animatedLetter.stop();
isDemoButtonClicked = false;
firstScreen.setVisible(false);
hideButton.setVisible(false); // Hide the "Hide" button
demoButton.setVisible(true); // Show the "Demo" button
graphics.setVisible(true);
animatedLetter.setVisible(false);
});
hideButton.setVisible(false);
let demoButton = this.add.text(helpButtonWidth, helpButtonHeight, "Demo", {
font: '900 24px quicksand',
fill: '#05b3a4',
backgroundColor: '#7c4c23',
padding: { x: 20, y: 10 },
borderRadius: '15px', // Border radius
shadow: {
offsetX: 2, // X offset for the shadow
offsetY: 2, // Y offset for the shadow
color: '#000', // Shadow color
blur: 5, // Shadow blur
fill: true // Apply shadow to fill (background color)
}
});
demoButton.setInteractive().on('pointerdown', () => { demoButton.setInteractive().on('pointerdown', () => {
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
graphics.setVisible(false); graphics.setVisible(false);
firstScreen.setVisible(true); firstScreen.setVisible(true);
demoButton.setVisible(false); // Hide the "Demo" button if(animatedLetter.visible){
hideButton.setVisible(true); // Show the "Hide" button animatedLetter.setVisible(false);
animatedLetter.setVisible(true); graphics.setVisible(true);
}); firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; animatedLetter.setVisible(true);
const baseFontSize = 24; firstScreen.setVisible(true);
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : i', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); }
})
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: i', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write letter : i', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedIHeight, 'animatedI').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedIHeight, 'animatedI').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@ -259,11 +268,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 5.5 : customWidth * 0.75; textX = isMobile ? customWidth / 5.5 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Small Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Small Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@ -272,7 +281,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Dot',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Dot',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioTwoAudio = this.sound.add('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@ -284,8 +293,6 @@ let scoreTotal = 0; let isDrawing = false;
let firstDragStartPoint = { x: 0, y: 0 }; let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 }; let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer // Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => { firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x; firstDragStartPoint.x = pointer.x;
@ -328,7 +335,6 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha) graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) { this.input.on('pointerdown', function (pointer) {
isDrawing = true; isDrawing = true;
@ -345,30 +351,14 @@ let scoreTotal = 0; let isDrawing = false;
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
firstTextLayer.setVisible(false); firstTextLayer.setVisible(false);
startButton.setInteractive().on('pointerdown', () => { document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
audioOneAudio.play(); audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true); firstTextLayer.setVisible(true);
animatedLetter.setVisible(false); firstScreen.setVisible(false); animatedLetter.setVisible(false);
firstScreen.setVisible(false);
graphics.setVisible(true); graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
}) })
} }
@ -376,4 +366,41 @@ function update() {
} }
</script> </script>
<style>
.clear-button {
background-color: blue;
}
/* Animation styles */
@keyframes slideInUp {
0% {
opacity: 0;
transform: translateY(100%); /* Start below the viewport */
}
100% {
opacity: 1;
transform: translateY(0); /* End at its original position */
}
}
.clip-art-container {
overflow: hidden; /* Prevents overflow during the animation */
}
.clip-art {
transform: translateX(100%); /* Initially off-screen to the right */
opacity: 0; /* Initially hidden */
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out; /* Smooth transition */
}
.clip-art.show {
transform: translateX(0); /* Move the image into view */
opacity: 1; /* Fade in */
}
.slide{
display: none;
}
.active{
display: block;
}
</style>