21 Commits
b4 ... newb

Author SHA1 Message Date
Suvodip
eac8a4719a s1 2024-12-12 16:36:47 +05:30
Suvodip
cedb4ad01e s1 2024-12-12 16:36:08 +05:30
Suvodip
8e96e7b4ba chnage lap 2024-12-03 19:19:54 +05:30
Suvodip
4372f87838 ui modifications in drawing game 2024-11-27 17:40:35 +05:30
Suvodip
4a303849ad audio done 2024-11-27 16:10:18 +05:30
Suvodip
c999045fe4 next work start from tick_phonics_v1 2024-11-26 19:53:39 +05:30
Suvodip
2d6e01e184 s1 2024-11-22 17:57:22 +05:30
Suvodip
f3dd30e909 s1 2024-11-22 17:34:31 +05:30
Suvodip
12aeec0947 s1 2024-11-22 17:14:50 +05:30
Suvodip
e4dc874374 s1 2024-11-21 16:57:31 +05:30
Suvodip
7e44149a4a fix sub learning area key issue (copy) 2024-11-19 12:32:05 +05:30
Suvodip
b8444a361a s1 2024-11-08 16:39:40 +05:30
Suvodip
d64bc840bc s1 2024-11-08 16:27:37 +05:30
Suvodip
399186819c s1 2024-11-07 19:30:53 +05:30
Suvodip
1bd86ba8cc s1 2024-11-06 19:05:11 +05:30
Suvodip
ebd61445de fix color issue over the button 2024-11-05 18:22:34 +05:30
Suvodip
eab9dd370f Change All Guided Tracing Desgine 2024-11-05 16:46:43 +05:30
Suvodip
3392dea286 CS 2024-10-30 16:46:38 +05:30
Suvodip
195756b892 CI 2024-10-29 18:45:48 +05:30
Suvodip
cd15a8be17 add new desgine from 0 to a 2024-10-28 18:48:04 +05:30
Suvodip
41ae75207b newb 2024-10-26 18:57:45 +05:30
101 changed files with 25272 additions and 13124 deletions

8145
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@
"astro-eslint-parser": "^0.14.0", "astro-eslint-parser": "^0.14.0",
"eslint": "^8.44.0", "eslint": "^8.44.0",
"flowbite-typography": "^1.0.3", "flowbite-typography": "^1.0.3",
"html2canvas": "^1.4.1",
"phaser": "^3.60.0", "phaser": "^3.60.0",
"shiki": "^0.14.3", "shiki": "^0.14.3",
"tailwind-scrollbar": "^3.0.4", "tailwind-scrollbar": "^3.0.4",

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,4 @@
<svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12.832" cy="12.6328" r="12" fill="#F7A915"/>
<path d="M12.834 3.76953L12.834 21.9905" stroke="black" stroke-opacity="0.5" stroke-linecap="round" stroke-dasharray="3 3"/>
</svg>

After

Width:  |  Height:  |  Size: 285 B

View File

@@ -0,0 +1,6 @@
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="0.9375" width="23" height="23" fill="white"/>
<rect x="0.5" y="0.9375" width="23" height="23" stroke="black"/>
<path d="M12.1367 3.52344L12.1367 22.1211" stroke="black" stroke-opacity="0.5" stroke-linecap="round" stroke-dasharray="3 3"/>
<path d="M2.83594 12.8242H21.4336" stroke="black" stroke-opacity="0.5" stroke-linecap="round" stroke-dasharray="3 3"/>
</svg>

After

Width:  |  Height:  |  Size: 477 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 31 KiB

45
public/galleryFunction.js Normal file
View File

@@ -0,0 +1,45 @@
const jsonData = [
{
"src": "/assets/back.jpeg",
"title": "Image Title 1",
"description": "Description for image 1 goes here."
},
{
"src": "/assets/background.jpg",
"title": "Image Title 2",
"description": "Description for image 2 goes here."
},
{
"src": "/assets/backgroundImage.png",
"title": "Image Title 3",
"description": "Description for image 3 goes here."
},
{
"src": "/assets/beanieImage.png",
"title": "Image Title 4",
"description": "Description for image 4 goes here."
}
];
let currentSlide = 0;
function updateSlide(){
const slide = jsonData[currentSlide];
document.getElementById('slideImage').src = slide.src;
document.getElementById('imageTitle').textContent = slide.title;
document.getElementById('imageDescription').textContent = slide.description;
}
document.getElementById('nextButton').addEventListener('click', () => {
currentSlide = (currentSlide + 1) % jsonData.length;
console.log(currentSlide)
updateSlide();
})
document.getElementById('prevButton').addEventListener('click', () => {
currentSlide = (currentSlide - 1 + jsonData.length) % jsonData.length;
updateSlide();
})
updateSlide();
let parentMainContainer = document.getElementById('parentMainContainer');
let gallerySliderId = document.getElementById('gallerySliderId');
function closeGallery(){
gallerySliderId.classList.add('hidden');
}

View File

@@ -1,12 +1,11 @@
function retryGame(){ function retryGame(){
window.location.reload(); window.location.reload();
} }
const queryString = window.location.search; const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString); const urlParams = new URLSearchParams(queryString);
const userId = urlParams.get('userId'); const userId = urlParams.get('userId');
const gameVersion = urlParams.get('gameName'); const gameVersion = urlParams.get('gameName');
let gameId; const gameId = urlParams.get('id');
let submitNotic; let submitNotic;
console.log(userId); console.log(userId);
@@ -50,11 +49,14 @@
function submitUserData(drawingZone) { function submitUserData(drawingZone) {
submitButton.setVisible(false); submitButton.setVisible(false);
if(!gameType[0] === 'guided-tracing'){
snapshotButton.setVisible(false); snapshotButton.setVisible(false);
customCursor.setVisible(false); customCursor.setVisible(false);
galleryButton.setVisible(false);
}
muteIcon.setVisible(false); muteIcon.setVisible(false);
retryButton.setVisible(false); retryButton.setVisible(false);
galleryButton.setVisible(false);
const endTime = Date.now(); const endTime = Date.now();
const timeDifference = endTime - startTime; const timeDifference = endTime - startTime;
const timeDifferenceInSeconds = timeDifference / 1000; const timeDifferenceInSeconds = timeDifference / 1000;
@@ -64,11 +66,15 @@ function submitUserData(drawingZone) {
// console.log('This is from main point', scoreTotal); // console.log('This is from main point', scoreTotal);
drawingZone.renderer.snapshot((image) => { drawingZone.renderer.snapshot((image) => {
submitButton.setVisible(true); submitButton.setVisible(true);
if(!gameType[0] == "guided-tracing"){
snapshotButton.setVisible(true); snapshotButton.setVisible(true);
customCursor.setVisible(true); customCursor.setVisible(true);
galleryButton.setVisible(true);
}
muteIcon.setVisible(true); muteIcon.setVisible(true);
retryButton.setVisible(true); retryButton.setVisible(true);
galleryButton.setVisible(true);
if(gameType[0] == 'drawing'){ if(gameType[0] == 'drawing'){
// submitButton.setVisible(true); // submitButton.setVisible(true);
// snapshotButton.setVisible(true); // snapshotButton.setVisible(true);
@@ -112,7 +118,7 @@ function submitUserData(drawingZone) {
}; };
console.log(userData); console.log(userData);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'

View File

@@ -6,7 +6,7 @@ const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString); const urlParams = new URLSearchParams(queryString);
const userId = urlParams.get('userId'); const userId = urlParams.get('userId');
const gameVersion = urlParams.get('gameName'); const gameVersion = urlParams.get('gameName');
let gameId; const gameId = urlParams.get('id');
let submitNotic; let submitNotic;
console.log(userId); console.log(userId);
@@ -194,7 +194,7 @@ function submitUserData(drawingZone) {
'gameStar' : starValue 'gameStar' : starValue
}; };
console.log(userData); console.log(userData);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'

View File

@@ -0,0 +1,128 @@
function retryGame(){
window.location.reload();
}
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const userId = urlParams.get('userId');
const gameVersion = urlParams.get('gameName');
const gameId = urlParams.get('id');
let submitNotic;
console.log(userId);
let startTime = Date.now();
const url = window.location.href;
const gameName = url.split('/');
const gameType = gameName[3].split('?id=');
// let gameVersion;iVBORw0KGgoAAAANSUhEUgAAB4A
// console.log('Type - 1');
// } else if(gameName.length == 4){
// gameVersion = gameName[3].split('?')[0];
// gameId = urlParams.get('id');
// }
// else if(gameName.length == 5){
// gameVersion = gameName[3] + '-' + gameName[4].split('?')[0];
// gameId = urlParams.get('id');
// console.log('Type - 2');
// }else if(gameName.length == 6){
// gameVersion = gameType[0] + '-' + gameName[4];
// gameId = urlParams.get('id');
// console.log('Type - 3');
// }
console.log(gameVersion)
function submitUserData(drawingZone) {
const endTime = Date.now();
const timeDifference = endTime - startTime;
const timeDifferenceInSeconds = timeDifference / 1000;
// console.log(`Time difference: ${timeDifferenceInSeconds} seconds`);
let imageCode;
let gameScore;
if(scoreTotal){
gameScore = scoreTotal;
}else{
gameScore = 0;
}
// console.log('This is from main point', scoreTotal);
drawingZone.renderer.snapshot((image) => {
if(gameType[0] == 'drawing'){
submitButton.setVisible(true);
snapshotButton.setVisible(true);
customCursor.setVisible(true);
image.style.width = '160px';
image.style.height = '120px';
image.style.paddingLeft = '2px';
document.body.appendChild(image);
// Download the snapshot as an image
// const link = document.createElement('a');
// link.href = image.src;
// link.download = 'my_drawing.png';
// link.click();
document.body.removeChild(image);
imageCode = image.src;
}else if( gameType[0] == "guided-tracing"){
// submitButton.setVisible(true);
// snapshotButton.setVisible(true);
// customCursor.setVisible(true);
image.style.width = '160px';
image.style.height = '120px';
image.style.paddingLeft = '2px';
document.body.appendChild(image);
// Download the snapshot as an image
// const link = document.createElement('a');
// link.href = image.src;
// link.download = `guided-tracing-${gameId}.png`;
// link.click();
document.body.removeChild(image);
imageCode = image.src;
}
let starValue;
if(scoreTotal === maxScore){
starValue = 5;
} else if(scoreTotal === maxScore - 1){
starValue = 4;
} else{
starValue = 3;
}
let userData = {
'gameName': gameVersion,
'gameID': gameId,
'screenShot': imageCode,
'userId' : userId,
'gameTime' : timeDifferenceInSeconds,
'score' : scoreTotal,
'gameStar' : starValue
};
console.log(userData);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(userData)
})
.then(response => {
setTimeout(() => {
if (response.ok) {
if (response.status == 200) {
document.getElementById('wsSavedImg').classList.remove('-z-10');
}
} else {
console.log('Something went wrong', response);
}
}, 100);
})
.catch(error => {
console.error('An error occurred', error);
});
// Clear the drawing
// graphics.clear();
});
};

1012
src/pages/buzzboard.astro Normal file

File diff suppressed because one or more lines are too long

View File

@@ -11,10 +11,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4"> <div class="container mx-auto px-4">
<!-- <div class="flex flex-col"> <!-- <div class="flex flex-col">
<p id="LearningArea"></p> <p id="LearningArea"></p>
<p id="LearningSubArea_copy"></p> <p id="LearningSubArea"></p>
</div> --> </div> -->
<p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p> <p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p>
<form id="contactForm"> <form id="contactForm">
@@ -90,8 +90,8 @@ import Layout from "../../layouts/Layout.astro";
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame()" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -99,9 +99,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -122,6 +143,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){ if(gameData.label1){
@@ -143,7 +168,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label6").innerHTML = gameData.label6; document.getElementById("label6").innerHTML = gameData.label6;
} }
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea; // document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy; // document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/'; const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 6; i++) { for (let i = 1; i <= 6; i++) {
@@ -311,7 +336,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -430,7 +455,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23; color: #7C4C23;
padding-top: 10px; padding-top: 10px;
} }
#LearningArea, #LearningSubArea_copy{ #LearningArea, #LearningSubArea{
font-size: 20px; font-size: 20px;
color: #7C4C23; color: #7C4C23;
font-weight: bold; font-weight: bold;

View File

@@ -11,10 +11,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4"> <div class="container mx-auto px-4">
<!-- <div class="flex flex-col"> <!-- <div class="flex flex-col">
<p id="LearningArea"></p> <p id="LearningArea"></p>
<p id="LearningSubArea_copy"></p> <p id="LearningSubArea"></p>
</div> --> </div> -->
<p class="sm:text-2xl md:text-3xl lg:text-3xl text-center font-[600] text-[#60C6CB] my-2 select-none" id="gameDescription"></p> <p class="sm:text-2xl md:text-3xl lg:text-3xl text-center font-[600] text-[#60C6CB] my-2 select-none" id="gameDescription"></p>
<form id="contactForm"> <form id="contactForm">
@@ -108,8 +108,8 @@ import Layout from "../../layouts/Layout.astro";
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame()" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -117,9 +117,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -139,6 +160,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){ if(gameData.label1){
@@ -169,7 +194,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label9").innerHTML = gameData.label9; document.getElementById("label9").innerHTML = gameData.label9;
} }
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea; // document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy; // document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/'; const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 9; i++) { for (let i = 1; i <= 9; i++) {
const imageId = `image${i}`; const imageId = `image${i}`;
@@ -345,7 +370,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -464,7 +489,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23; color: #7C4C23;
padding-top: 10px; padding-top: 10px;
} }
#LearningArea, #LearningSubArea_copy{ #LearningArea, #LearningSubArea{
font-size: 20px; font-size: 20px;
color: #7C4C23; color: #7C4C23;
font-weight: bold; font-weight: bold;

View File

@@ -11,10 +11,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4"> <div class="container mx-auto px-4">
<!-- <div class="flex flex-col"> <!-- <div class="flex flex-col">
<p id="LearningArea"></p> <p id="LearningArea"></p>
<p id="LearningSubArea_copy"></p> <p id="LearningSubArea"></p>
</div> --> </div> -->
<p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p> <p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p>
<form id="contactForm"> <form id="contactForm">
@@ -90,8 +90,8 @@ import Layout from "../../layouts/Layout.astro";
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame()" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -99,9 +99,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -123,6 +144,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){ if(gameData.label1){
@@ -144,7 +169,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label6").innerHTML = gameData.label6; document.getElementById("label6").innerHTML = gameData.label6;
} }
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea; // document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy; // document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/'; const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 6; i++) { for (let i = 1; i <= 6; i++) {
@@ -312,7 +337,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
// console.log(userData); // console.log(userData);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -431,7 +456,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23; color: #7C4C23;
padding-top: 10px; padding-top: 10px;
} }
#LearningArea, #LearningSubArea_copy{ #LearningArea, #LearningSubArea{
font-size: 20px; font-size: 20px;
color: #7C4C23; color: #7C4C23;
font-weight: bold; font-weight: bold;

View File

@@ -11,10 +11,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
</div> </div>
@@ -103,8 +103,8 @@ import Layout from "../../layouts/Layout.astro";
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame()" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -112,9 +112,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -135,6 +156,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){ if(gameData.label1){
@@ -331,7 +356,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -451,7 +476,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23; color: #7C4C23;
padding-top: 10px; padding-top: 10px;
} }
#LearningArea, #LearningSubArea_copy{ #LearningArea, #LearningSubArea{
font-size: 20px; font-size: 20px;
color: #7C4C23; color: #7C4C23;
font-weight: bold; font-weight: bold;

View File

@@ -12,10 +12,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
@@ -78,8 +78,8 @@ import Layout from "../../layouts/Layout.astro";
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame()" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -87,9 +87,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -109,6 +130,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameLabel").innerHTML = gameData.label; document.getElementById("gameLabel").innerHTML = gameData.label;
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
@@ -282,7 +307,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
// console.log(userData); // console.log(userData);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'

View File

@@ -17,7 +17,7 @@ import Layout from '../../layouts/Layout.astro';
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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 onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
@@ -56,6 +56,9 @@ import Layout from '../../layouts/Layout.astro';
let cancelIconWidth; let cancelIconWidth;
let retryButton; let retryButton;
let blockMatches; let blockMatches;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
@@ -142,6 +145,10 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drag_drop_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drag_drop_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
const {image1, image2, image3, image4, image5, image6, image7, image8} = data; const {image1, image2, image3, image4, image5, image6, image7, image8} = data;
if(isMobile){ if(isMobile){
imageCustomWidth = "?width=80"; imageCustomWidth = "?width=80";
@@ -239,6 +246,9 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) {
this.load.image('logo'+i, '/assets/background.jpg'); this.load.image('logo'+i, '/assets/background.jpg');
} }
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image("topMatch", "/assets/top_match.jpg"); this.load.image("topMatch", "/assets/top_match.jpg");
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -410,10 +420,10 @@ import Layout from '../../layouts/Layout.astro';
// window.load // window.load
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale(); this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale(); let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale(); const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale(); submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale(); this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
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); 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(window.innerWidth / 2 - buttonWidth, window.innerHeight / 2 - buttonHeight, "Submit", { // submitButton = this.add.text(window.innerWidth / 2 - buttonWidth, window.innerHeight / 2 - buttonHeight, "Submit", {
@@ -432,7 +442,19 @@ import Layout from '../../layouts/Layout.astro';
showAnimation(); showAnimation();
}) })
let blocks1Width1, blocks1Width2, blocks1Width3, blocks1Width4, blocks1Width5, blocks1Width6, blocks1Width7, blocks1Width8; let blocks1Width1, blocks1Width2, blocks1Width3, blocks1Width4, blocks1Width5, blocks1Width6, blocks1Width7, blocks1Width8;
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
soundButton.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
if(isMobile){ if(isMobile){
blocks1Width1 = 180; blocks1Width1 = 180;

View File

@@ -22,7 +22,7 @@ const numberOfTimes = starNumberOfTime;
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button onclick="" 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 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 onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
@@ -59,6 +59,9 @@ const numberOfTimes = starNumberOfTime;
let resetIconWidth; let resetIconWidth;
let tickIconWidth; let tickIconWidth;
let cancelIconWidth; let cancelIconWidth;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
@@ -168,6 +171,11 @@ const numberOfTimes = starNumberOfTime;
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
// console.log(audioData)
const {left_image1, left_image2, left_image3, left_image4, right_image1, right_image2, right_image3, right_image4} = data; const {left_image1, left_image2, left_image3, left_image4, right_image1, right_image2, right_image3, right_image4} = data;
if(isMobile){ if(isMobile){
imageCustomWidth = "?width=100"; imageCustomWidth = "?width=100";
@@ -264,6 +272,9 @@ const numberOfTimes = starNumberOfTime;
for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) {
this.load.image('logo'+i, '/assets/background.jpg'); this.load.image('logo'+i, '/assets/background.jpg');
} }
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image("topMatch", "/assets/top_match.jpg"); this.load.image("topMatch", "/assets/top_match.jpg");
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -340,7 +351,7 @@ const numberOfTimes = starNumberOfTime;
}, },
]; ];
// this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea_copy, {font: `19px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 70, data.LearningSubArea, {font: `19px`}).setTint(0x7c4c23);
// Left Image Name // Left Image Name
this.add.text(displayW / 14 - 15, 240, data.left_image1_name).setTint(0x7c4c23); this.add.text(displayW / 14 - 15, 240, data.left_image1_name).setTint(0x7c4c23);
this.add.text(displayW / 14 - 15, 409, data.left_image2_name).setTint(0x7c4c23); this.add.text(displayW / 14 - 15, 409, data.left_image2_name).setTint(0x7c4c23);
@@ -397,18 +408,11 @@ const numberOfTimes = starNumberOfTime;
graphics.strokePath(); graphics.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); 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(window.innerWidth / 2 - buttonWidth, window.innerHeight / 2 - buttonHeight, "Submit", {
// font: '600 30px Quicksand',
// fill: '#fff',
// backgroundColor: 'blue',
// padding: { x: 20, y: 10 },
// }).setDepth(1);
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale(); this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale(); let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale(); const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale(); submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale(); this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
this.add.image(displayW * 0.9-32, 170, "target1"); this.add.image(displayW * 0.9-32, 170, "target1");
// this.add.image(displayW * 0.9-33, 170, "border").setAlpha(1).setScale(1).setDepth(-1); // this.add.image(displayW * 0.9-33, 170, "border").setAlpha(1).setScale(1).setDepth(-1);
this.add.image(displayW * 0.9-32, 340, "target2"); this.add.image(displayW * 0.9-32, 340, "target2");
@@ -417,6 +421,20 @@ const numberOfTimes = starNumberOfTime;
// this.add.image(displayW * 0.9-33, 510, "border").setAlpha(1).setScale(1).setDepth(-1); // this.add.image(displayW * 0.9-33, 510, "border").setAlpha(1).setScale(1).setDepth(-1);
this.add.image(displayW * 0.9-32, 680, "target4"); this.add.image(displayW * 0.9-32, 680, "target4");
// this.add.image(displayW * 0.9-33, 680, "border").setAlpha(1).setScale(1).setDepth(-1); // this.add.image(displayW * 0.9-33, 680, "border").setAlpha(1).setScale(1).setDepth(-1);
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
soundButton.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
const blocks = [ const blocks = [
{ {
@@ -465,7 +483,7 @@ const numberOfTimes = starNumberOfTime;
counter++; counter++;
return 'borderCorrect'; return 'borderCorrect';
} else { } else {
console.log(`Score Total: ${scoreTotal}`); // console.log(`Score Total: ${scoreTotal}`);
return 'borderWrong'; return 'borderWrong';
} }
}; };

View File

@@ -18,7 +18,7 @@ import Layout from '../../layouts/Layout.astro';
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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 onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
@@ -55,6 +55,9 @@ import Layout from '../../layouts/Layout.astro';
let resetIconWidth; let resetIconWidth;
let tickIconWidth; let tickIconWidth;
let cancelIconWidth; let cancelIconWidth;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
@@ -147,6 +150,10 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drag_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drag_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
const {left_image1, left_image2, left_image3, left_image4, right_image1, right_image2, right_image3, right_image4} = data; const {left_image1, left_image2, left_image3, left_image4, right_image1, right_image2, right_image3, right_image4} = data;
if(isMobile){ if(isMobile){
imageCustomWidth = "?width=100"; imageCustomWidth = "?width=100";
@@ -243,6 +250,9 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) {
this.load.image('logo'+i, '/assets/background.jpg'); this.load.image('logo'+i, '/assets/background.jpg');
} }
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image("topMatch", "/assets/top_match.jpg"); this.load.image("topMatch", "/assets/top_match.jpg");
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tick", '/assets/tick.png'); this.load.image("tick", '/assets/tick.png');
@@ -327,7 +337,7 @@ import Layout from '../../layouts/Layout.astro';
const responsiveFontSize = (window.innerWidth / textSizeScale) * baseFontSize; const responsiveFontSize = (window.innerWidth / textSizeScale) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 85, data.description, { font: `${responsiveFontSize}px quicksand`, fill: '#60C6CB', align: "center", wordWrap: {width: window.innerWidth-wrapWidth}}, ).setOrigin(0.5); const descrptText = this.add.text(screenCenterX, 85, data.description, { font: `${responsiveFontSize}px quicksand`, fill: '#60C6CB', align: "center", wordWrap: {width: window.innerWidth-wrapWidth}}, ).setOrigin(0.5);
// this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea_copy, {font: `19px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 70, data.LearningSubArea, {font: `19px`}).setTint(0x7c4c23);
// Left Image Name // Left Image Name
this.add.text(displayW / 14 - 15, 240, data.left_image1_name).setTint(0x7c4c23); this.add.text(displayW / 14 - 15, 240, data.left_image1_name).setTint(0x7c4c23);
this.add.text(displayW / 14 - 15, 409, data.left_image2_name).setTint(0x7c4c23); this.add.text(displayW / 14 - 15, 409, data.left_image2_name).setTint(0x7c4c23);
@@ -372,10 +382,10 @@ import Layout from '../../layouts/Layout.astro';
// }); // });
// }; // };
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale(); this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale(); let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale(); const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale(); submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale(); this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
this.add.image(displayW * 0.9-32, 170, "target1"); this.add.image(displayW * 0.9-32, 170, "target1");
// this.add.image(displayW * 0.9-33, 170, "border").setAlpha(1).setScale(1).setDepth(-1); // this.add.image(displayW * 0.9-33, 170, "border").setAlpha(1).setScale(1).setDepth(-1);
this.add.image(displayW * 0.9-32, 340, "target2"); this.add.image(displayW * 0.9-32, 340, "target2");
@@ -385,6 +395,19 @@ import Layout from '../../layouts/Layout.astro';
this.add.image(displayW * 0.9-32, 680, "target4"); this.add.image(displayW * 0.9-32, 680, "target4");
// this.add.image(displayW * 0.9-33, 680, "border").setAlpha(1).setScale(1).setDepth(-1); // this.add.image(displayW * 0.9-33, 680, "border").setAlpha(1).setScale(1).setDepth(-1);
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
soundButton.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
const graphics = this.add.graphics(); const graphics = this.add.graphics();
const x = 0; const y = 54; const x = 0; const y = 54;

View File

@@ -365,7 +365,7 @@ import Layout from '../../layouts/Layout.astro';
fill: '#7c4c23', fill: '#7c4c23',
}).setOrigin(0.5); }).setOrigin(0.5);
// this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea_copy, {font: `19px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 70, data.LearningSubArea, {font: `19px`}).setTint(0x7c4c23);
// Left Image Name // Left Image Name
this.add.text(leftTargetZoneW - 45, 240, data.left_image1_name).setTint(0x7c4c23); this.add.text(leftTargetZoneW - 45, 240, data.left_image1_name).setTint(0x7c4c23);
this.add.text(leftTargetZoneW - 45, 409, data.left_image2_name).setTint(0x7c4c23); this.add.text(leftTargetZoneW - 45, 409, data.left_image2_name).setTint(0x7c4c23);

View File

@@ -18,7 +18,7 @@ import Layout from '../../layouts/Layout.astro';
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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 onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
@@ -56,6 +56,10 @@ import Layout from '../../layouts/Layout.astro';
let tickIconWidth; let tickIconWidth;
let cancelIconWidth; let cancelIconWidth;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
muteIconWidth = 1.8; muteIconWidth = 1.8;
@@ -147,6 +151,11 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag_v2/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag_v2/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
const {left_image1, left_image2, left_image3, left_image4, right_image1, right_image2, right_image3, right_image4} = data; const {left_image1, left_image2, left_image3, left_image4, right_image1, right_image2, right_image3, right_image4} = data;
if(isMobile){ if(isMobile){
imageCustomWidth = "?width=100"; imageCustomWidth = "?width=100";
@@ -243,6 +252,9 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) {
this.load.image('logo'+i, '/assets/background.jpg'); this.load.image('logo'+i, '/assets/background.jpg');
} }
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image("topMatch", "/assets/top_match.jpg"); this.load.image("topMatch", "/assets/top_match.jpg");
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tick", '/assets/tick.png'); this.load.image("tick", '/assets/tick.png');
@@ -327,7 +339,7 @@ import Layout from '../../layouts/Layout.astro';
const responsiveFontSize = (window.innerWidth / textSizeScale) * baseFontSize; const responsiveFontSize = (window.innerWidth / textSizeScale) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 110, data.description, { font: `${responsiveFontSize}px quicksand`, fill: '#60C6CB', align: "center", wordWrap: {width: window.innerWidth-wrapWidth}}, ).setOrigin(0.5); const descrptText = this.add.text(screenCenterX, 110, data.description, { font: `${responsiveFontSize}px quicksand`, fill: '#60C6CB', align: "center", wordWrap: {width: window.innerWidth-wrapWidth}}, ).setOrigin(0.5);
// this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea_copy, {font: `19px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 70, data.LearningSubArea, {font: `19px`}).setTint(0x7c4c23);
// Left Image Name // Left Image Name
this.add.text(displayW / 14 - 15, 240, data.left_image1_name).setTint(0x7c4c23); this.add.text(displayW / 14 - 15, 240, data.left_image1_name).setTint(0x7c4c23);
this.add.text(displayW / 14 - 15, 409, data.left_image2_name).setTint(0x7c4c23); this.add.text(displayW / 14 - 15, 409, data.left_image2_name).setTint(0x7c4c23);
@@ -372,10 +384,10 @@ import Layout from '../../layouts/Layout.astro';
// }); // });
// }; // };
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale(); this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale(); let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale(); const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale(); submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale(); this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
this.add.image(displayW * 0.9-32, 170, "target1"); this.add.image(displayW * 0.9-32, 170, "target1");
// this.add.image(displayW * 0.9-33, 170, "border").setAlpha(1).setScale(1).setDepth(-1); // this.add.image(displayW * 0.9-33, 170, "border").setAlpha(1).setScale(1).setDepth(-1);
this.add.image(displayW * 0.9-32, 340, "target2"); this.add.image(displayW * 0.9-32, 340, "target2");
@@ -384,7 +396,19 @@ import Layout from '../../layouts/Layout.astro';
// this.add.image(displayW * 0.9-33, 510, "border").setAlpha(1).setScale(1).setDepth(-1); // this.add.image(displayW * 0.9-33, 510, "border").setAlpha(1).setScale(1).setDepth(-1);
this.add.image(displayW * 0.9-32, 680, "target4"); this.add.image(displayW * 0.9-32, 680, "target4");
// this.add.image(displayW * 0.9-33, 680, "border").setAlpha(1).setScale(1).setDepth(-1); // this.add.image(displayW * 0.9-33, 680, "border").setAlpha(1).setScale(1).setDepth(-1);
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
soundButton.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
const graphics = this.add.graphics(); const graphics = this.add.graphics();
const x = 0; const y = 54; const x = 0; const y = 54;

View File

@@ -309,7 +309,7 @@ import Layout from '../../layouts/Layout.astro';
fill: '#7c4c23', fill: '#7c4c23',
}).setOrigin(0.5); }).setOrigin(0.5);
// this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea_copy, {font: `19px`}).setTint(0x7c4c23); // this.add.text(displayW / 14 - 15, 70, data.LearningSubArea, {font: `19px`}).setTint(0x7c4c23);
// Left Image Name // Left Image Name
this.add.text(displayW / 14 - 15, 240, data.left_image1_name).setTint(0x7c4c23); this.add.text(displayW / 14 - 15, 240, data.left_image1_name).setTint(0x7c4c23);
this.add.text(displayW / 14 - 15, 409, data.left_image2_name).setTint(0x7c4c23); this.add.text(displayW / 14 - 15, 409, data.left_image2_name).setTint(0x7c4c23);

View File

@@ -18,7 +18,7 @@ import Layout from '../../layouts/Layout.astro';
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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 onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
@@ -59,6 +59,9 @@ import Layout from '../../layouts/Layout.astro';
let blockMatches; let blockMatches;
let retryButtonWidth; let retryButtonWidth;
let leftTargetZoneW; let leftTargetZoneW;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
@@ -179,6 +182,10 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag_v3/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag_v3/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
const {image1, image2, image3, image4, image5, image6, image7, image8} = data; const {image1, image2, image3, image4, image5, image6, image7, image8} = data;
if(isMobile){ if(isMobile){
imageCustomWidth = "?width=100"; imageCustomWidth = "?width=100";
@@ -274,6 +281,9 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) {
this.load.image('logo'+i, '/assets/background.jpg'); this.load.image('logo'+i, '/assets/background.jpg');
} }
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image("topMatch", "/assets/top_match.jpg"); this.load.image("topMatch", "/assets/top_match.jpg");
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tick", '/assets/tick.png'); this.load.image("tick", '/assets/tick.png');
@@ -422,12 +432,25 @@ import Layout from '../../layouts/Layout.astro';
graphics.strokePath(); graphics.strokePath();
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale(); this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale(); let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale(); const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale(); submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale(); this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
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); 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);
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
soundButton.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
// submitButton = this.add.text(window.innerWidth / 2 - buttonWidth, window.innerHeight / 2 - buttonHeight, "Submit", { // submitButton = this.add.text(window.innerWidth / 2 - buttonWidth, window.innerHeight / 2 - buttonHeight, "Submit", {
// font: '600 30px Quicksand', // font: '600 30px Quicksand',
// fill: '#fff', // fill: '#fff',

View File

@@ -17,7 +17,7 @@ import Layout from '../../layouts/Layout.astro';
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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 onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
@@ -59,6 +59,9 @@ import Layout from '../../layouts/Layout.astro';
let leftTargetZoneW; let leftTargetZoneW;
let rightTargetZoneW; let rightTargetZoneW;
let retryButtonWidth; let retryButtonWidth;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
@@ -145,6 +148,10 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag_v4/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag_v4/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
const {image1, image2, image3, image4, image5, image6, image7, image8} = data; const {image1, image2, image3, image4, image5, image6, image7, image8} = data;
if(isMobile){imageCustomWidth = "?width=100";} else{imageCustomWidth = "?width=100";}; if(isMobile){imageCustomWidth = "?width=100";} else{imageCustomWidth = "?width=100";};
const assetsURL = "https://game-du.teachertrainingkolkata.in/assets/" const assetsURL = "https://game-du.teachertrainingkolkata.in/assets/"
@@ -238,6 +245,9 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) {
this.load.image('logo'+i, '/assets/background.jpg'); this.load.image('logo'+i, '/assets/background.jpg');
} }
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image("topMatch", "/assets/top_match.jpg"); this.load.image("topMatch", "/assets/top_match.jpg");
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
// this.load.image("tick", '/assets/tick.png'); // this.load.image("tick", '/assets/tick.png');
@@ -249,8 +259,6 @@ import Layout from '../../layouts/Layout.astro';
// this.load.image("retryIcon", "/assets/svg/retry.svg") // this.load.image("retryIcon", "/assets/svg/retry.svg")
this.load.image("border", '/assets/squar.png'); this.load.image("border", '/assets/squar.png');
this.load.spritesheet("blocks1", assetsList.element5,{ this.load.spritesheet("blocks1", assetsList.element5,{
frameWidth: 100, frameWidth: 100,
frameHeight: 100, frameHeight: 100,
@@ -405,10 +413,23 @@ import Layout from '../../layouts/Layout.astro';
graphics.strokePath(); graphics.strokePath();
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale(); this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale(); let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale(); const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale(); submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale(); this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
soundButton.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
// submitButton = this.add.text(window.innerWidth / 2 - buttonWidth, window.innerHeight / 2 - buttonHeight, "Submit", { // submitButton = this.add.text(window.innerWidth / 2 - buttonWidth, window.innerHeight / 2 - buttonHeight, "Submit", {
// font: '600 30px Quicksand', // font: '600 30px Quicksand',
// fill: '#fff', // fill: '#fff',

View File

@@ -3,14 +3,102 @@ import Layout from '../../layouts/Layout.astro';
--- ---
<Layout title='Drawing Game'> <Layout title='Drawing Game'>
<main> <main>
<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 onclick="retryGame()" 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-3xl lg:max-w-4xl 2xl: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>
</div>
</div>
</div> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
const jsonData = [
{
"src": "/assets/back.jpeg"
},
{
"src": "/assets/background.jpg"
},
{
"src": "/assets/backgroundImage.png"
},
{
"src": "/assets/beanieImage.png"
}
];
let currentSlide = 0;
function updateSlide(){
const slide = jsonData[currentSlide];
document.getElementById('slideImage').src = slide.src;
}
document.getElementById('nextButton').addEventListener('click', () => {
currentSlide = (currentSlide + 1) % jsonData.length;
console.log(currentSlide)
updateSlide();
})
document.getElementById('prevButton').addEventListener('click', () => {
currentSlide = (currentSlide - 1 + jsonData.length) % jsonData.length;
updateSlide();
})
updateSlide();
let parentMainContainer = document.getElementById('parentMainContainer');
let gallerySliderId = document.getElementById('gallerySliderId');
function closeGallery(){
parentMainContainer.classList.add('hidden');
gallerySliderId.classList.add('hidden');
}
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; // Define your mobile breakpoint as needed const isMobile = window.innerWidth <= 768; // Define your mobile breakpoint as needed
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416; const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
@@ -32,24 +120,34 @@ import Layout from '../../layouts/Layout.astro';
let shortUniqueID; let shortUniqueID;
let scoreTotal = 0; let scoreTotal = 0;
let maxScore; let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
let galleryIconWidth;
let galleryButton;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
muteIconWidth = 1.8; muteIconWidth = 1.8;
resetIconWidth = 1.47; resetIconWidth = 1.47;
tickIconWidth = 1.24; tickIconWidth = 1.24;
cancelIconWidth = 1.08; cancelIconWidth = 1.08;
galleryIconWidth = 2;
}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;
}else{ }else{
topLogoWidth = 6; topLogoWidth = 6;
muteIconWidth = 1.3; muteIconWidth = 1.3;
resetIconWidth = 1.26; resetIconWidth = 1.26;
tickIconWidth = 1.222; tickIconWidth = 1.222;
cancelIconWidth = 1.185; cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
} }
if(isMobile){ if(isMobile){
submitWidth = 250; submitWidth = 250;
@@ -94,6 +192,10 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drawing_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drawing_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
// console.log(data) // console.log(data)
// colorList = data.colors; // colorList = data.colors;
const {image} = data; const {image} = data;
@@ -133,6 +235,9 @@ import Layout from '../../layouts/Layout.astro';
let colorList; let colorList;
function preload() { function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('outline', assetsList.image); this.load.image('outline', assetsList.image);
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -142,6 +247,7 @@ import Layout from '../../layouts/Layout.astro';
this.load.svg('buttonIcons', '/assets/svg/button-icon.svg'); this.load.svg('buttonIcons', '/assets/svg/button-icon.svg');
this.load.svg('cursorImage', '/assets/svg/pencil.svg'); this.load.svg('cursorImage', '/assets/svg/pencil.svg');
this.load.image('colorButton', '/assets/color_button.png'); this.load.image('colorButton', '/assets/color_button.png');
this.load.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
} }
function create() { function create() {
@@ -175,15 +281,34 @@ import Layout from '../../layouts/Layout.astro';
borderBottom.lineTo(x + lineWidth, y); borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath(); borderBottom.strokePath();
// this.add.image(customWidth / topLogoWidth, 30, "topLogo");
// this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
// const retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
// submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
this.add.image(customWidth / topLogoWidth, 30, "topLogo"); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
this.add.image(customWidth / muteIconWidth, 30, "muteIcon"); muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
const 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");
galleryButton = this.add.image(customWidth / galleryIconWidth, 30, "galleryIcons");
retryButton.setInteractive().on('pointerdown', () => { retryButton.setInteractive().on('pointerdown', () => {
window.location.reload(); graphics.clear();
}); });
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
muteIcon.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
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); 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(window.innerWidth - submitWidth, window.innerHeight - submitHeight, "Submit", { // submitButton = this.add.text(window.innerWidth - submitWidth, window.innerHeight - submitHeight, "Submit", {
// font: '600 30px Quicksand', // font: '600 30px Quicksand',
@@ -193,8 +318,17 @@ import Layout from '../../layouts/Layout.astro';
// }); // });
submitButton.setVisible(true); submitButton.setVisible(true);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
if(isMobile){
colorContainer.style.display = 'none';
// parentMainContainer.classList.remove('hidden');
}
});
galleryButton.setInteractive().on('pointerdown', () => {
parentMainContainer.classList.remove('hidden');
gallerySliderId.classList.remove('hidden');
}); });
const textStyle = {font: 'bold 40px quicksand', fill: '#05b3a4',}; const textStyle = {font: 'bold 40px quicksand', fill: '#05b3a4',};
@@ -216,7 +350,12 @@ import Layout from '../../layouts/Layout.astro';
outlineImage.setDepth(1).setScale(0.5); outlineImage.setDepth(1).setScale(0.5);
} }
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
const colorContainer = document.createElement('div'); const colorContainer = document.createElement('div');
colorContainer.style.position = 'absolute'; colorContainer.style.position = 'absolute';
colorContainer.style.top = '13%'; colorContainer.style.top = '13%';
@@ -229,7 +368,16 @@ import Layout from '../../layouts/Layout.astro';
} }
if(isMobile){ if(isMobile){
colorContainer.style.display = 'none'; colorContainer.style.display = 'none';
colorContainer.style.flexDirection = 'row';
} }
colorContainer.style.backgroundColor = '#FFFFFF';
colorContainer.style.padding = '30px 20px';
colorContainer.style.borderRadius = '80px';
colorContainer.style.boxShadow = '2px 6px 12.4px 4px #D2D1D170';
colorContainer.style.left = '0px';
colorContainer.style.top = '50%';
colorContainer.style.transform = 'translate(0, -50%)';
colorContainer.style.border = '1px solid #F9F9F9';
let colorViewButton = this.add.image(window.innerWidth / 7, window.innerHeight / 1.25, 'colorButton'); let colorViewButton = this.add.image(window.innerWidth / 7, window.innerHeight / 1.25, 'colorButton');
if(!isMobile){ if(!isMobile){
@@ -245,6 +393,14 @@ import Layout from '../../layouts/Layout.astro';
// Create the color picker // Create the color picker
let colorAndClearContainer = document.createElement('div');
colorAndClearContainer.style.display = 'flex';
colorAndClearContainer.flexDirection = 'row';
colorAndClearContainer.style.alignItems = 'center';
const clearButton = document.createElement('button');
clearButton.innerHTML ='<img src="/assets/svg/clear.svg">';
clearButton.style.marginTop = !isMobile ? `-10px` :`0px`;
const colorPicker = document.createElement('input'); const colorPicker = document.createElement('input');
colorPicker.type = 'color'; colorPicker.type = 'color';
colorPicker.value = selectedColor; colorPicker.value = selectedColor;
@@ -271,7 +427,10 @@ import Layout from '../../layouts/Layout.astro';
} }
}); });
// Append the color picker to the color container data // Append the color picker to the color container data
colorContainer.appendChild(colorPicker);
colorAndClearContainer.appendChild(colorPicker)
colorAndClearContainer.appendChild(clearButton)
colorContainer.appendChild(colorAndClearContainer);
// const colors = data.colors; // const colors = data.colors;
// var colors = colorList; // var colors = colorList;
var colors = isMobile ? ['#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB', '#FFD700'] : ['#FF0000', '#FFFF00', '#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB']; var colors = isMobile ? ['#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB', '#FFD700'] : ['#FF0000', '#FFFF00', '#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB'];
@@ -499,20 +658,19 @@ import Layout from '../../layouts/Layout.astro';
// buttonsContainer.style.left = `${window.innerWidth * 0.03}px`; // Position 5% from the left edge // buttonsContainer.style.left = `${window.innerWidth * 0.03}px`; // Position 5% from the left edge
document.body.appendChild(buttonsContainer); document.body.appendChild(buttonsContainer);
// Create the Clear button // Create the Clear button
const clearButton = document.createElement('button');
clearButton.innerHTML ='<img src="/assets/svg/clear.svg">';
// clearButton.style.border = '3px solid blue'; // clearButton.style.border = '3px solid blue';
// clearButton.style.color = 'blue'; // clearButton.style.color = 'blue';
// clearButton.style.width = 'fit-content'; // clearButton.style.width = 'fit-content';
// clearButton.style.marginRight = '10px'; // clearButton.style.marginRight = '10px';
if(isMobile){ // if(isMobile){
clearButton.style.padding = '2px 8px'; // clearButton.style.padding = '2px 8px';
clearButton.style.display = 'none'; // clearButton.style.display = 'none';
buttonsContainer.style.top = '9.5%'; // buttonsContainer.style.top = '9.5%';
buttonsContainer.style.marginLeft = '30px'; // buttonsContainer.style.marginLeft = '30px';
} else { // } else {
clearButton.style.padding = '5px 10px'; // clearButton.style.padding = '5px 10px';
} // }
// clearButton.style.fontWeight = 'bold'; // clearButton.style.fontWeight = 'bold';
// clearButton.style.borderRadius = '20%'; // clearButton.style.borderRadius = '20%';
// clearButton.style.boxShadow = '5px 10px 30px #7c4c2390'; // clearButton.style.boxShadow = '5px 10px 30px #7c4c2390';
@@ -561,7 +719,7 @@ import Layout from '../../layouts/Layout.astro';
} }
}); });
// Add the Clear and Eraser buttons to the container // Add the Clear and Eraser buttons to the container
buttonsContainer.appendChild(clearButton); // buttonsContainer.appendChild(clearButton);
// colorPicker.appendChild(clearButton); // colorPicker.appendChild(clearButton);
// buttonsContainer.appendChild(eraserButton).setVisible; // buttonsContainer.appendChild(eraserButton).setVisible;
@@ -655,10 +813,17 @@ import Layout from '../../layouts/Layout.astro';
submitButton.setVisible(false); submitButton.setVisible(false);
snapshotButton.setVisible(false); snapshotButton.setVisible(false);
customCursor.setVisible(false); customCursor.setVisible(false);
muteIcon.setVisible(false);
retryButton.setVisible(false);
galleryButton.setVisible(false);
drawingZone.renderer.snapshot((image) => { drawingZone.renderer.snapshot((image) => {
submitButton.setVisible(true); submitButton.setVisible(true);
snapshotButton.setVisible(true); snapshotButton.setVisible(true);
customCursor.setVisible(true); customCursor.setVisible(true);
muteIcon.setVisible(true);
retryButton.setVisible(true);
galleryButton.setVisible(true);
image.style.width = '160px'; image.style.width = '160px';
image.style.height = '120px'; image.style.height = '120px';
image.style.paddingLeft = '2px'; image.style.paddingLeft = '2px';
@@ -790,12 +955,49 @@ import Layout from '../../layouts/Layout.astro';
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`; slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
}; };
const cursorSize = brushSize * cursorSizeMultiplier; const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear(); // Clear the previous frame customCursor.clear();
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color) customCursor.lineStyle(1.5, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize); customCursor.strokeCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x; customCursor.x = this.input.x;
customCursor.y = this.input.y; customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
if (erase === true) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
} else if (erase === false) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
}
} }
// function update() { // function update() {
@@ -835,5 +1037,30 @@ import Layout from '../../layouts/Layout.astro';
.clear-button { .clear-button {
background-color: blue; 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 */
}
</style> </style>
<!-- <svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M11.4001 18.1612L11.4001 18.1612L18.796 10.7653C17.7894 10.3464 16.5972 9.6582 15.4697 8.53068C14.342 7.40298 13.6537 6.21058 13.2348 5.2039L5.83882 12.5999L5.83879 12.5999C5.26166 13.1771 4.97307 13.4657 4.7249 13.7838C4.43213 14.1592 4.18114 14.5653 3.97634 14.995C3.80273 15.3593 3.67368 15.7465 3.41556 16.5208L2.05445 20.6042C1.92743 20.9852 2.0266 21.4053 2.31063 21.6894C2.59466 21.9734 3.01478 22.0726 3.39584 21.9456L7.47918 20.5844C8.25351 20.3263 8.6407 20.1973 9.00498 20.0237C9.43469 19.8189 9.84082 19.5679 10.2162 19.2751C10.5343 19.0269 10.823 18.7383 11.4001 18.1612Z" fill="#1C274C"></path> <path d="M20.8482 8.71306C22.3839 7.17735 22.3839 4.68748 20.8482 3.15178C19.3125 1.61607 16.8226 1.61607 15.2869 3.15178L14.3999 4.03882C14.4121 4.0755 14.4246 4.11268 14.4377 4.15035C14.7628 5.0875 15.3763 6.31601 16.5303 7.47002C17.6843 8.62403 18.9128 9.23749 19.85 9.56262C19.8875 9.57563 19.9245 9.58817 19.961 9.60026L20.8482 8.71306Z" fill="#1C274C"></path> </g></svg> -->

View File

@@ -3,14 +3,102 @@ import Layout from '../../layouts/Layout.astro';
--- ---
<Layout title='Drawing Game'> <Layout title='Drawing Game'>
<main> <main>
<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 onclick="retryGame()" 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-3xl lg:max-w-4xl 2xl: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>
</div>
</div>
</div> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
const jsonData = [
{
"src": "/assets/back.jpeg"
},
{
"src": "/assets/background.jpg"
},
{
"src": "/assets/backgroundImage.png"
},
{
"src": "/assets/beanieImage.png"
}
];
let currentSlide = 0;
function updateSlide(){
const slide = jsonData[currentSlide];
document.getElementById('slideImage').src = slide.src;
}
document.getElementById('nextButton').addEventListener('click', () => {
currentSlide = (currentSlide + 1) % jsonData.length;
console.log(currentSlide)
updateSlide();
})
document.getElementById('prevButton').addEventListener('click', () => {
currentSlide = (currentSlide - 1 + jsonData.length) % jsonData.length;
updateSlide();
})
updateSlide();
let parentMainContainer = document.getElementById('parentMainContainer');
let gallerySliderId = document.getElementById('gallerySliderId');
function closeGallery(){
parentMainContainer.classList.add('hidden');
gallerySliderId.classList.add('hidden');
}
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; // Define your mobile breakpoint as needed const isMobile = window.innerWidth <= 768; // Define your mobile breakpoint as needed
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416; const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
@@ -32,24 +120,34 @@ import Layout from '../../layouts/Layout.astro';
let shortUniqueID; let shortUniqueID;
let scoreTotal = 0; let scoreTotal = 0;
let maxScore; let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
let galleryIconWidth;
let galleryButton;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
muteIconWidth = 1.8; muteIconWidth = 1.8;
resetIconWidth = 1.47; resetIconWidth = 1.47;
tickIconWidth = 1.24; tickIconWidth = 1.24;
cancelIconWidth = 1.08; cancelIconWidth = 1.08;
galleryIconWidth = 2;
}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;
}else{ }else{
topLogoWidth = 6; topLogoWidth = 6;
muteIconWidth = 1.3; muteIconWidth = 1.3;
resetIconWidth = 1.26; resetIconWidth = 1.26;
tickIconWidth = 1.222; tickIconWidth = 1.222;
cancelIconWidth = 1.185; cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
} }
if(isMobile){ if(isMobile){
@@ -95,6 +193,10 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drawing_writo/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drawing_writo/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
// console.log(data) // console.log(data)
// colorList = data.colors; // colorList = data.colors;
const {image} = data; const {image} = data;
@@ -134,6 +236,9 @@ import Layout from '../../layouts/Layout.astro';
let colorList; let colorList;
function preload() { function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('outline', assetsList.image); this.load.image('outline', assetsList.image);
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -143,6 +248,7 @@ import Layout from '../../layouts/Layout.astro';
this.load.svg('buttonIcons', '/assets/svg/button-icon.svg'); this.load.svg('buttonIcons', '/assets/svg/button-icon.svg');
this.load.svg('cursorImage', '/assets/svg/pencil.svg'); this.load.svg('cursorImage', '/assets/svg/pencil.svg');
this.load.image('colorButton', '/assets/color_button.png'); this.load.image('colorButton', '/assets/color_button.png');
this.load.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
} }
function create() { function create() {
@@ -166,6 +272,8 @@ import Layout from '../../layouts/Layout.astro';
}); });
// window.load // window.load
const borderBottom = this.add.graphics(); const borderBottom = this.add.graphics();
const x = 0; const y = 54; const x = 0; const y = 54;
const lineWidth = window.innerWidth; const lineWidth = window.innerWidth;
@@ -176,14 +284,33 @@ import Layout from '../../layouts/Layout.astro';
borderBottom.lineTo(x + lineWidth, y); borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath(); borderBottom.strokePath();
this.add.image(customWidth / topLogoWidth, 30, "topLogo"); // this.add.image(customWidth / topLogoWidth, 30, "topLogo");
this.add.image(customWidth / muteIconWidth, 30, "muteIcon"); // this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
const retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon"); // const retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon"); // submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
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");
galleryButton = this.add.image(customWidth / galleryIconWidth, 30, "galleryIcons");
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
muteIcon.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
retryButton.setInteractive().on('pointerdown', () => { retryButton.setInteractive().on('pointerdown', () => {
window.location.reload(); graphics.clear();
}); });
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); 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);
@@ -195,8 +322,18 @@ import Layout from '../../layouts/Layout.astro';
// }); // });
submitButton.setVisible(true); submitButton.setVisible(true);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// windowLoad();
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
if(isMobile){
colorContainer.style.display = 'none';
// parentMainContainer.classList.remove('hidden');
}
});
galleryButton.setInteractive().on('pointerdown', () => {
parentMainContainer.classList.remove('hidden');
gallerySliderId.classList.remove('hidden');
}); });
const textStyle = {font: 'bold 40px quicksand', fill: '#05b3a4',}; const textStyle = {font: 'bold 40px quicksand', fill: '#05b3a4',};
@@ -226,7 +363,12 @@ import Layout from '../../layouts/Layout.astro';
// } else{ // } else{
// outlineImage.setDepth(1).setScale(0.65); // outlineImage.setDepth(1).setScale(0.65);
// } // }
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
const colorContainer = document.createElement('div'); const colorContainer = document.createElement('div');
colorContainer.style.position = 'absolute'; colorContainer.style.position = 'absolute';
colorContainer.style.top = '13%'; colorContainer.style.top = '13%';
@@ -239,7 +381,16 @@ import Layout from '../../layouts/Layout.astro';
} }
if(isMobile){ if(isMobile){
colorContainer.style.display = 'none'; colorContainer.style.display = 'none';
colorContainer.style.flexDirection = 'row';
} }
colorContainer.style.backgroundColor = '#FFFFFF';
colorContainer.style.padding = '30px 20px';
colorContainer.style.borderRadius = '80px';
colorContainer.style.boxShadow = '2px 6px 12.4px 4px #D2D1D170';
colorContainer.style.left = '0px';
colorContainer.style.top = '50%';
colorContainer.style.transform = 'translate(0, -50%)';
colorContainer.style.border = '1px solid #F9F9F9';
let colorViewButton = this.add.image(window.innerWidth / 7, window.innerHeight / 1.25, 'colorButton'); let colorViewButton = this.add.image(window.innerWidth / 7, window.innerHeight / 1.25, 'colorButton');
if(!isMobile){ if(!isMobile){
@@ -253,6 +404,14 @@ import Layout from '../../layouts/Layout.astro';
} }
}); });
let colorAndClearContainer = document.createElement('div');
colorAndClearContainer.style.display = 'flex';
colorAndClearContainer.flexDirection = 'row';
colorAndClearContainer.style.alignItems = 'center';
const clearButton = document.createElement('button');
clearButton.innerHTML ='<img src="/assets/svg/clear.svg">';
clearButton.style.marginTop = !isMobile ? `-10px` :`0px`;
// Create the color picker // Create the color picker
const colorPicker = document.createElement('input'); const colorPicker = document.createElement('input');
@@ -281,7 +440,9 @@ import Layout from '../../layouts/Layout.astro';
} }
}); });
// Append the color picker to the color container data // Append the color picker to the color container data
colorContainer.appendChild(colorPicker); colorAndClearContainer.appendChild(colorPicker)
colorAndClearContainer.appendChild(clearButton)
colorContainer.appendChild(colorAndClearContainer);
// const colors = data.colors; // const colors = data.colors;
// var colors = colorList; // var colors = colorList;
var colors = isMobile ? ['#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB', '#FFD700'] : ['#FF0000', '#FFFF00', '#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB']; var colors = isMobile ? ['#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB', '#FFD700'] : ['#FF0000', '#FFFF00', '#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB'];
@@ -508,21 +669,6 @@ import Layout from '../../layouts/Layout.astro';
buttonsContainer.style.left = '20px'; buttonsContainer.style.left = '20px';
// buttonsContainer.style.left = `${window.innerWidth * 0.03}px`; // Position 5% from the left edge // buttonsContainer.style.left = `${window.innerWidth * 0.03}px`; // Position 5% from the left edge
document.body.appendChild(buttonsContainer); document.body.appendChild(buttonsContainer);
// Create the Clear button
const clearButton = document.createElement('button');
clearButton.innerHTML ='<img src="/assets/svg/clear.svg">';
// clearButton.style.border = '3px solid blue';
// clearButton.style.color = 'blue';
// clearButton.style.width = 'fit-content';
// clearButton.style.marginRight = '10px';
if(isMobile){
clearButton.style.padding = '2px 8px';
clearButton.style.display = 'none';
buttonsContainer.style.top = '9.5%';
buttonsContainer.style.marginLeft = '30px';
} else {
clearButton.style.padding = '5px 10px';
}
// clearButton.style.fontWeight = 'bold'; // clearButton.style.fontWeight = 'bold';
// clearButton.style.borderRadius = '20%'; // clearButton.style.borderRadius = '20%';
// clearButton.style.boxShadow = '5px 10px 30px #7c4c2390'; // clearButton.style.boxShadow = '5px 10px 30px #7c4c2390';
@@ -571,7 +717,7 @@ import Layout from '../../layouts/Layout.astro';
} }
}); });
// Add the Clear and Eraser buttons to the container // Add the Clear and Eraser buttons to the container
buttonsContainer.appendChild(clearButton); // buttonsContainer.appendChild(clearButton);
// colorPicker.appendChild(clearButton); // colorPicker.appendChild(clearButton);
// buttonsContainer.appendChild(eraserButton).setVisible; // buttonsContainer.appendChild(eraserButton).setVisible;
@@ -665,10 +811,18 @@ import Layout from '../../layouts/Layout.astro';
submitButton.setVisible(false); submitButton.setVisible(false);
snapshotButton.setVisible(false); snapshotButton.setVisible(false);
customCursor.setVisible(false); customCursor.setVisible(false);
muteIcon.setVisible(false);
retryButton.setVisible(false);
galleryButton.setVisible(false);
drawingZone.renderer.snapshot((image) => { drawingZone.renderer.snapshot((image) => {
submitButton.setVisible(true); submitButton.setVisible(true);
snapshotButton.setVisible(true); snapshotButton.setVisible(true);
customCursor.setVisible(true); customCursor.setVisible(true);
muteIcon.setVisible(true);
retryButton.setVisible(true);
galleryButton.setVisible(true);
image.style.width = '160px'; image.style.width = '160px';
image.style.height = '120px'; image.style.height = '120px';
image.style.paddingLeft = '2px'; image.style.paddingLeft = '2px';
@@ -800,50 +954,76 @@ import Layout from '../../layouts/Layout.astro';
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`; slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
}; };
const cursorSize = brushSize * cursorSizeMultiplier; const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear(); // Clear the previous frame customCursor.clear();
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color) customCursor.lineStyle(1.5, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize); customCursor.strokeCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x; customCursor.x = this.input.x;
customCursor.y = this.input.y; customCursor.y = this.input.y;
customCursor.moveTo(0, - cursorSize + 3);
customCursor.lineTo(0, cursorSize - 3);
customCursor.moveTo(- cursorSize + 3, 0);
customCursor.lineTo(cursorSize - 3, 0);
customCursor.strokePath();
if (erase === true) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, - cursorSize + 3);
customCursor.lineTo(0, cursorSize - 3);
customCursor.moveTo(- cursorSize + 3, 0);
customCursor.lineTo(cursorSize - 3, 0);
customCursor.strokePath();
} else if (erase === false) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, - cursorSize + 3);
customCursor.lineTo(0, cursorSize - 3);
customCursor.moveTo(- cursorSize + 3, 0);
customCursor.lineTo(cursorSize - 3, 0);
customCursor.strokePath();
}
} }
// function update() {
// const slider = document.querySelector('input[type="range"]');
// if (slider && !isDrawing) {
// const sliderValue = parseInt(slider.value);
// const max = parseInt(slider.max);
// const width = slider.offsetWidth;
// const offsetX = (sliderValue - 2) / (max - 2) * width;
// slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
// }
// const cursorSize = brushSize * cursorSizeMultiplier;
// const cursorScale = 1; // Adjust this value to increase/decrease the cursor size
// // Assuming 'this' refers to your Phaser.Scene instance
// if (!this.customCursor) {
// // Create the custom cursor sprite
// this.customCursor = this.add.sprite(0, 0, 'cursorImage'); // Replace 'yourCursorImage' with the key of your loaded PNG image
// this.customCursor.setOrigin(0.3, 0.8);
// }
// // Set the tint or fill color dynamically based on the selectedColor
// const color = Phaser.Display.Color.HexStringToColor(selectedColor).color;
// this.customCursor.setTint(color);
// // Resize the cursor
// this.customCursor.setScale( cursorScale);
// // Position the cursor at the current mouse pointer coordinates
// this.customCursor.x = this.input.x;
// this.customCursor.y = this.input.y;
// }
</script> </script>
<style> <style>
.clear-button { /* Animation styles */
background-color: blue; @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 */
} }
</style> </style>
<!-- <svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M11.4001 18.1612L11.4001 18.1612L18.796 10.7653C17.7894 10.3464 16.5972 9.6582 15.4697 8.53068C14.342 7.40298 13.6537 6.21058 13.2348 5.2039L5.83882 12.5999L5.83879 12.5999C5.26166 13.1771 4.97307 13.4657 4.7249 13.7838C4.43213 14.1592 4.18114 14.5653 3.97634 14.995C3.80273 15.3593 3.67368 15.7465 3.41556 16.5208L2.05445 20.6042C1.92743 20.9852 2.0266 21.4053 2.31063 21.6894C2.59466 21.9734 3.01478 22.0726 3.39584 21.9456L7.47918 20.5844C8.25351 20.3263 8.6407 20.1973 9.00498 20.0237C9.43469 19.8189 9.84082 19.5679 10.2162 19.2751C10.5343 19.0269 10.823 18.7383 11.4001 18.1612Z" fill="#1C274C"></path> <path d="M20.8482 8.71306C22.3839 7.17735 22.3839 4.68748 20.8482 3.15178C19.3125 1.61607 16.8226 1.61607 15.2869 3.15178L14.3999 4.03882C14.4121 4.0755 14.4246 4.11268 14.4377 4.15035C14.7628 5.0875 15.3763 6.31601 16.5303 7.47002C17.6843 8.62403 18.9128 9.23749 19.85 9.56262C19.8875 9.57563 19.9245 9.58817 19.961 9.60026L20.8482 8.71306Z" fill="#1C274C"></path> </g></svg> -->

View File

@@ -18,7 +18,7 @@ import Layout from '../../layouts/Layout.astro';
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <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 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> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -39,7 +39,7 @@ import Layout from '../../layouts/Layout.astro';
</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 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="w-full max-w-3xl lg:max-w-4xl 2xl:max-w-6xl bg-white rounded-lg">
<div class="flex justify-between p-3"> <div class="flex justify-between p-3">
<p class="text-[19px] font-[700]">Attempt 2</p> <p class="text-[19px] font-[700]">Attempt 2</p>
<button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button> <button onclick="closeGallery();"> <img src="/assets/svg/crossIcon.svg"></button>
@@ -49,11 +49,6 @@ import Layout from '../../layouts/Layout.astro';
<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="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> <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>
</div> </div>
@@ -61,38 +56,35 @@ import Layout from '../../layouts/Layout.astro';
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </main>
<!-- http://localhost:2022/drawing/?id=525&userId=6746c2e9cd3b551fae55cb67&gameName=birdWS1 -->
</Layout> </Layout>
<script src="/saveGameAI.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
// const findBuddies = JSON.parse(localStorage.getItem('userChildDetails') || '{}');
// const buddiesName = findBuddies.metadata.sprite
const retrievedData = localStorage.getItem('akademyPlans')
const parsedObject = JSON.parse(retrievedData);
console.log('buddName', window.location.href);
const jsonData = [ const jsonData = [
{ {
"src": "/assets/back.jpeg", "src": "/assets/back.jpeg"
"title": "Image Title 1",
"description": "Description for image 1 goes here."
}, },
{ {
"src": "/assets/background.jpg", "src": "/assets/background.jpg"
"title": "Image Title 2",
"description": "Description for image 2 goes here."
}, },
{ {
"src": "/assets/backgroundImage.png", "src": "/assets/backgroundImage.png"
"title": "Image Title 3",
"description": "Description for image 3 goes here."
}, },
{ {
"src": "/assets/beanieImage.png", "src": "/assets/beanieImage.png"
"title": "Image Title 4",
"description": "Description for image 4 goes here."
} }
]; ];
let currentSlide = 0; let currentSlide = 0;
function updateSlide(){ function updateSlide(){
const slide = jsonData[currentSlide]; const slide = jsonData[currentSlide];
document.getElementById('slideImage').src = slide.src; document.getElementById('slideImage').src = slide.src;
document.getElementById('imageTitle').textContent = slide.title;
document.getElementById('imageDescription').textContent = slide.description;
} }
document.getElementById('nextButton').addEventListener('click', () => { document.getElementById('nextButton').addEventListener('click', () => {
currentSlide = (currentSlide + 1) % jsonData.length; currentSlide = (currentSlide + 1) % jsonData.length;
@@ -142,6 +134,10 @@ import Layout from '../../layouts/Layout.astro';
let muteIcon; let muteIcon;
let retryButton; let retryButton;
let maxScore; let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
muteIconWidth = 1.65; muteIconWidth = 1.65;
@@ -208,6 +204,10 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drawing/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drawing/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
// console.log(data) // console.log(data)
// colorList = data.colors; // colorList = data.colors;
const {image} = data; const {image} = data;
@@ -248,6 +248,9 @@ import Layout from '../../layouts/Layout.astro';
let colorList; let colorList;
function preload() { function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('outline', assetsList.image); this.load.image('outline', assetsList.image);
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -297,6 +300,19 @@ import Layout from '../../layouts/Layout.astro';
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon"); submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
galleryButton = this.add.image(customWidth / galleryIconWidth, 30, "galleryIcons"); galleryButton = this.add.image(customWidth / galleryIconWidth, 30, "galleryIcons");
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
muteIcon.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
retryButton.setInteractive().on('pointerdown', () => { retryButton.setInteractive().on('pointerdown', () => {
// window.location.reload(); // window.location.reload();
@@ -345,7 +361,14 @@ import Layout from '../../layouts/Layout.astro';
} else{ } else{
outlineImage.setDepth(1).setScale(0.65); outlineImage.setDepth(1).setScale(0.65);
} }
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
const colorContainer = document.createElement('div'); const colorContainer = document.createElement('div');
colorContainer.style.zIndex = '1'; colorContainer.style.zIndex = '1';
colorContainer.style.position = 'absolute'; colorContainer.style.position = 'absolute';
@@ -701,13 +724,17 @@ import Layout from '../../layouts/Layout.astro';
eraserButton.style.boxShadow = '5px 10px 15px #7c4c2390'; eraserButton.style.boxShadow = '5px 10px 15px #7c4c2390';
eraserButton.addEventListener('click', () => { eraserButton.addEventListener('click', () => {
isErasing = !isErasing; isErasing = !isErasing;
erase = false;
if (isErasing) { if (isErasing) {
eraserButton.style.border = '2px solid #0348A8'; erase = true;
eraserButton.style.border = '3px solid #0348A8';
eraserButton.style.backgroundColor = '#0348A820';
} else { } else {
// Return to drawing mode // Return to drawing mode
// eraserButton.style.backgroundColor = 'green'; // Restore eraser button color // eraserButton.style.backgroundColor = 'green'; // Restore eraser button color
eraserButton.style.color = 'blue'; eraserButton.style.color = 'blue';
eraserButton.style.border = 'none'; eraserButton.style.border = 'none';
eraserButton.style.backgroundColor = 'transparent';
} }
}); });
// Add the Clear and Eraser buttons to the container // Add the Clear and Eraser buttons to the container
@@ -836,85 +863,6 @@ import Layout from '../../layouts/Layout.astro';
}); });
} }
// const url = window.location.href;
// const gameName = url.split('/');
// const gameType = gameName[3].split('?id=');
// function submitUserData(drawingZone) {
// let imageCode;
// // console.log(drawingZone);
// drawingZone.renderer.snapshot((image) => {
// submitButton.setVisible(true);
// snapshotButton.setVisible(true);
// customCursor.setVisible(true);
// image.style.width = '160px';
// image.style.height = '120px';
// image.style.paddingLeft = '2px';
// document.body.appendChild(image);
// // Download the snapshot as an image
// const link = document.createElement('a');
// link.href = image.src;
// link.download = 'my_drawing.png';
// link.click();
// document.body.removeChild(image);
// imageCode = image.src;
// let userData = {
// 'userID': 'drawing@beanstalkedu.com',
// 'gameType': gameType[0],
// 'gameID': gameType[1],
// 'screenShot': imageCode
// // 'starts': formattedDateTime,
// // 'game_start' : gameStartTime,
// };
// console.log(userData);
// fetch(`https://save-game-data.teachertrainingchennai.in/saveGameData`, {
// method: 'POST',
// headers: {
// 'Content-Type' : 'application/json'
// },
// body: JSON.stringify(userData)
// })
// .then(response => {
// if(response.ok){
// console.log('Data Saved', response)
// } else{
// // console.log('Something Wrong', response)
// }
// })
// .catch(error => {
// console.error('An error occured', error)
// });
// // Clear the drawing
// // graphics.clear();
// });
// };
// function captureSnapshot(drawingZone) {
// submitButton.setVisible(false);
// // snapNotice.setVisible(true);
// snapshotButton.setVisible(false);
// customCursor.setVisible(false);
// drawingZone.renderer.snapshot((image) => {
// submitButton.setVisible(true);
// snapshotButton.setVisible(true);
// customCursor.setVisible(true);
// image.style.width = '160px';
// image.style.height = '120px';
// image.style.paddingLeft = '2px';
// document.body.appendChild(image);
// // Download the snapshot as an image
// const link = document.createElement('a');
// link.href = image.src;
// link.download = 'my_drawing.png';
// link.click();
// document.body.removeChild(image);
// // Clear the drawing
// // graphics.clear();
// });
// }
function startDrawing(x, y) { function startDrawing(x, y) {
if (!isErasing) { if (!isErasing) {
graphics.lineStyle(brushSize * 2, Phaser.Display.Color.HexStringToColor(selectedColor).color); graphics.lineStyle(brushSize * 2, Phaser.Display.Color.HexStringToColor(selectedColor).color);
@@ -952,12 +900,49 @@ import Layout from '../../layouts/Layout.astro';
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`; slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
}; };
const cursorSize = brushSize * cursorSizeMultiplier; const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear(); // Clear the previous frame customCursor.clear();
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color) customCursor.lineStyle(1.5, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize); customCursor.strokeCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x; customCursor.x = this.input.x;
customCursor.y = this.input.y; customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
if (erase === true) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
} else if (erase === false) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
}
} }
// function update() { // function update() {
@@ -1030,4 +1015,3 @@ import Layout from '../../layouts/Layout.astro';
display: block; display: block;
} }
</style> </style>
<!-- <svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M11.4001 18.1612L11.4001 18.1612L18.796 10.7653C17.7894 10.3464 16.5972 9.6582 15.4697 8.53068C14.342 7.40298 13.6537 6.21058 13.2348 5.2039L5.83882 12.5999L5.83879 12.5999C5.26166 13.1771 4.97307 13.4657 4.7249 13.7838C4.43213 14.1592 4.18114 14.5653 3.97634 14.995C3.80273 15.3593 3.67368 15.7465 3.41556 16.5208L2.05445 20.6042C1.92743 20.9852 2.0266 21.4053 2.31063 21.6894C2.59466 21.9734 3.01478 22.0726 3.39584 21.9456L7.47918 20.5844C8.25351 20.3263 8.6407 20.1973 9.00498 20.0237C9.43469 19.8189 9.84082 19.5679 10.2162 19.2751C10.5343 19.0269 10.823 18.7383 11.4001 18.1612Z" fill="#1C274C"></path> <path d="M20.8482 8.71306C22.3839 7.17735 22.3839 4.68748 20.8482 3.15178C19.3125 1.61607 16.8226 1.61607 15.2869 3.15178L14.3999 4.03882C14.4121 4.0755 14.4246 4.11268 14.4377 4.15035C14.7628 5.0875 15.3763 6.31601 16.5303 7.47002C17.6843 8.62403 18.9128 9.23749 19.85 9.56262C19.8875 9.57563 19.9245 9.58817 19.961 9.60026L20.8482 8.71306Z" fill="#1C274C"></path> </g></svg> -->

View File

@@ -3,35 +3,98 @@ import Layout from '../../layouts/Layout.astro';
--- ---
<Layout title='Drawing Game'> <Layout title='Drawing Game'>
<main> <main>
<div> <div id="parentMainContainer"class="hidden">
<div id="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute" style="display: none;"> <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 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>
</div> <div id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
<div id="scoreBoard" class=" 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 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 class="flex flex-row space-x-4 items-center justify-center">
<div id="star-container"></div> <div id="star-container"></div>
</div> </div>
<div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;"> <div class="flex flex-row" style="margin-top: 15px; margin-bottom: 15px;">
<img class="z-10" src="/assets/clip-art.svg" alt="" /> <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> <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>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame()" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
<div class="clip-art-container absolute bottom-0 right-0"> <div class="clip-art-container absolute bottom-10 right-10" id="bottomAnimateClipart">
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <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>
</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-3xl lg:max-w-4xl 2xl: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>
</div>
</div>
</div>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
const jsonData = [
{
"src": "/assets/back.jpeg"
},
{
"src": "/assets/background.jpg"
},
{
"src": "/assets/backgroundImage.png"
},
{
"src": "/assets/beanieImage.png"
}
];
let currentSlide = 0;
function updateSlide(){
const slide = jsonData[currentSlide];
document.getElementById('slideImage').src = slide.src;
}
document.getElementById('nextButton').addEventListener('click', () => {
currentSlide = (currentSlide + 1) % jsonData.length;
console.log(currentSlide)
updateSlide();
})
document.getElementById('prevButton').addEventListener('click', () => {
currentSlide = (currentSlide - 1 + jsonData.length) % jsonData.length;
updateSlide();
})
updateSlide();
let parentMainContainer = document.getElementById('parentMainContainer');
let gallerySliderId = document.getElementById('gallerySliderId');
function closeGallery(){
parentMainContainer.classList.add('hidden');
gallerySliderId.classList.add('hidden');
}
function showAnimation() { function showAnimation() {
const clipArt = document.querySelector('.clip-art'); const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show'); clipArt.classList.add('show');
@@ -65,24 +128,34 @@ import Layout from '../../layouts/Layout.astro';
let noticeWidth; let noticeWidth;
let noticeHeight; let noticeHeight;
let maxScore; let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
let galleryIconWidth;
let galleryButton;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
muteIconWidth = 1.8; muteIconWidth = 1.8;
resetIconWidth = 1.47; resetIconWidth = 1.47;
tickIconWidth = 1.24; tickIconWidth = 1.24;
cancelIconWidth = 1.08; cancelIconWidth = 1.08;
galleryIconWidth = 2;
}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;
}else{ }else{
topLogoWidth = 6; topLogoWidth = 6;
muteIconWidth = 1.3; muteIconWidth = 1.3;
resetIconWidth = 1.26; resetIconWidth = 1.26;
tickIconWidth = 1.222; tickIconWidth = 1.222;
cancelIconWidth = 1.185; cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
} }
if(isMobile){ if(isMobile){
submitWidth = 250; submitWidth = 250;
@@ -137,6 +210,10 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drawing_v2/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drawing_v2/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
colorList = data.colors; colorList = data.colors;
defaultColor = colorList[0]; defaultColor = colorList[0];
const {image1, image2} = data; const {image1, image2} = data;
@@ -177,6 +254,9 @@ import Layout from '../../layouts/Layout.astro';
let colorList; let colorList;
function preload() { function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('image1', assetsList.image1); this.load.image('image1', assetsList.image1);
this.load.image('image2', assetsList.image2); this.load.image('image2', assetsList.image2);
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
@@ -188,6 +268,7 @@ import Layout from '../../layouts/Layout.astro';
this.load.svg('cursorImage', '/assets/svg/pencil.svg'); this.load.svg('cursorImage', '/assets/svg/pencil.svg');
this.load.image('waxTexture', '/assets/texture.png'); this.load.image('waxTexture', '/assets/texture.png');
this.load.image('colorButton', '/assets/color_button.png'); this.load.image('colorButton', '/assets/color_button.png');
this.load.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
} }
function create() { function create() {
@@ -254,12 +335,32 @@ import Layout from '../../layouts/Layout.astro';
const outlineImage1 = this.add.image(customWidth / image1Width, customHeight / image1Height, 'image1'); const outlineImage1 = this.add.image(customWidth / image1Width, customHeight / image1Height, 'image1');
const outlineImage2 = this.add.image(customWidth / image2Width + image2Right, customHeight / image2Height + image2Bottom, 'image2'); const outlineImage2 = this.add.image(customWidth / image2Width + image2Right, customHeight / image2Height + image2Bottom, 'image2');
// this.add.image(customWidth / topLogoWidth, 30, "topLogo");
// this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
// const retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
// submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
this.add.image(customWidth / topLogoWidth, 30, "topLogo"); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
this.add.image(customWidth / muteIconWidth, 30, "muteIcon"); muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
const 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");
galleryButton = this.add.image(customWidth / galleryIconWidth, 30, "galleryIcons");
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
muteIcon.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
retryButton.setInteractive().on('pointerdown', ()=>{ retryButton.setInteractive().on('pointerdown', ()=>{
window.location.reload(); graphics.clear();
}) })
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); 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(window.innerWidth - submitWidth, window.innerHeight - submitHeight, "Submit", { // submitButton = this.add.text(window.innerWidth - submitWidth, window.innerHeight - submitHeight, "Submit", {
@@ -268,21 +369,21 @@ import Layout from '../../layouts/Layout.astro';
// backgroundColor: 'blue', // backgroundColor: 'blue',
// padding: { x: 20, y: 10 }, // padding: { x: 20, y: 10 },
// }); // });
submitButton.setVisible(true);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
// windowLoad();
// submitUserData();
submitUserData(this); submitUserData(this);
showAnimation(); showAnimation();
}) parentMainContainer.classList.remove('hidden');
const textStyle = {font: 'bold 40px quicksand', fill: '#05b3a4',}; if(isMobile){
if(!isMobile){ colorContainer.style.display = 'none';
// this.add.text(customWidth / 10, 20, "Drawing", textStyle); // parentMainContainer.classList.remove('hidden');
// this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
} else {
// this.add.text(customWidth / 30, 0, "Drawing", textStyle);
// this.add.image(customWidth / 2 * 1.6 - 0.5, 25, 'topLogo');
} }
});
galleryButton.setInteractive().on('pointerdown', () => {
parentMainContainer.classList.remove('hidden');
gallerySliderId.classList.remove('hidden');
});
const textStyle = {font: 'bold 40px quicksand', fill: '#05b3a4',};
if(isMobile){ if(isMobile){
outlineImage1.setDepth(-5).setScale(0.28); outlineImage1.setDepth(-5).setScale(0.28);
@@ -294,29 +395,46 @@ import Layout from '../../layouts/Layout.astro';
outlineImage1.setDepth(-5).setScale(0.60); outlineImage1.setDepth(-5).setScale(0.60);
outlineImage2.setDepth(-5).setScale(0.60); outlineImage2.setDepth(-5).setScale(0.60);
} }
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
const colorContainer = document.createElement('div'); const colorContainer = document.createElement('div');
colorContainer.style.zIndex = '1';
colorContainer.style.position = 'absolute'; colorContainer.style.position = 'absolute';
colorContainer.style.top = '13%'; colorContainer.style.top = '13%';
if(isMobile){
colorContainer.style.marginTop = '13%';
}
colorContainer.style.left = '10px'; colorContainer.style.left = '10px';
colorContainer.style.display = 'flex'; colorContainer.style.display = 'flex';
colorContainer.style.marginBottom = '15px'; colorContainer.style.marginBottom = '0';
if(!isMobile){ if(!isMobile){
colorContainer.style.top = '25%'; colorContainer.style.top = '10%';
colorContainer.style.flexDirection = 'column'; colorContainer.style.flexDirection = 'column';
} }
if(isMobile){ if(isMobile){
colorContainer.style.display = 'none'; colorContainer.style.display = 'none';
} colorContainer.style.flexDirection = 'row';
let colorViewButton = this.add.image(window.innerWidth / 7, window.innerHeight / 1.25, 'colorButton');
if(!isMobile){
colorViewButton.setVisible(false);
} }
colorContainer.style.backgroundColor = '#FFFFFF';
colorContainer.style.padding = '30px 20px';
colorContainer.style.borderRadius = '80px';
colorContainer.style.boxShadow = '2px 6px 12.4px 4px #D2D1D170';
colorContainer.style.left = '0px';
colorContainer.style.top = '50%';
colorContainer.style.transform = 'translate(0, -50%)';
colorContainer.style.border = '1px solid #F9F9F9';
let colorEraserCont = document.createElement('div');
colorEraserCont.style.display = 'flex';
colorEraserCont.style.flexDirection = 'row';
colorContainer.appendChild(colorEraserCont);
let colorViewButton = this.add.image(window.innerWidth / 7, window.innerHeight / 1.25, 'colorButton');
!isMobile ? colorViewButton.setVisible(false) : '';
// if(!isMobile){colorViewButton.setVisible(false);}
colorViewButton.setInteractive().on('pointerdown', () => { colorViewButton.setInteractive().on('pointerdown', () => {
if(colorContainer.style.display === 'block') { if(colorContainer.style.display === 'block') {
@@ -333,17 +451,47 @@ import Layout from '../../layouts/Layout.astro';
buttonsContainer.style.display = 'block'; buttonsContainer.style.display = 'block';
} }
}); });
const eraserButton = document.createElement('button');
eraserButton.innerHTML = '<svg width="23" height="22" viewBox="0 0 23 22" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22.1167 7.01651L16.1167 1.01651C15.897 0.796427 15.636 0.621831 15.3486 0.502706C15.0613 0.383582 14.7534 0.322266 14.4423 0.322266C14.1313 0.322266 13.8234 0.383582 13.5361 0.502706C13.2487 0.621831 12.9877 0.796427 12.768 1.01651L1.42422 12.3265C1.20414 12.5463 1.02955 12.8073 0.910421 13.0946C0.791296 13.3819 0.72998 13.6899 0.72998 14.0009C0.72998 14.3119 0.791296 14.6199 0.910421 14.9072C1.02955 15.1945 1.20414 15.4555 1.42422 15.6753L6.29922 20.5503H3.40047C3.25129 20.5503 3.10822 20.6095 3.00273 20.715C2.89724 20.8205 2.83797 20.9636 2.83797 21.1128C2.83797 21.2619 2.89724 21.405 3.00273 21.5105C3.10822 21.616 3.25129 21.6753 3.40047 21.6753H20.9167C21.0659 21.6753 21.209 21.616 21.3145 21.5105C21.42 21.405 21.4792 21.2619 21.4792 21.1128C21.4792 20.9636 21.42 20.8205 21.3145 20.715C21.209 20.6095 21.0659 20.5503 20.9167 20.5503H11.9392L22.1167 10.3653C22.5594 9.92043 22.8079 9.31843 22.8079 8.69088C22.8079 8.06334 22.5594 7.46133 22.1167 7.01651ZM10.3492 20.5428H7.87797L2.21922 14.8803C1.98725 14.6464 1.85708 14.3303 1.85708 14.0009C1.85708 13.6715 1.98725 13.3554 2.21922 13.1215L7.46922 7.87151L15.2617 15.6303L10.3492 20.5428Z" fill="#0348A8"/></svg>';
eraserButton.style.color = 'blue';
// eraserButton.style.border = '3px solid blue';
// eraserButton.style.color = 'white';
eraserButton.style.width = 'fit-content';
eraserButton.style.marginRight = '15px';
// eraserButton.style.marginTop = '0px';
eraserButton.style.marginBottom = '0px';
if(isMobile){
eraserButton.style.padding = '4px 4px';
}else{
eraserButton.style.padding = '5px 9px';
eraserButton.style.top = '50%';
eraserButton.style.marginBottom = '15px';
}
eraserButton.style.fontWeight = 'bold';
eraserButton.style.borderRadius = '20%';
eraserButton.style.boxShadow = '5px 10px 15px #7c4c2390';
eraserButton.addEventListener('click', () => {
isErasing = !isErasing;
erase = false;
if (isErasing) {
erase = true;
eraserButton.style.border = '3px solid #0348A8';
eraserButton.style.backgroundColor = '#0348A820';
} else {
// Return to drawing mode
// eraserButton.style.backgroundColor = 'green'; // Restore eraser button color
eraserButton.style.color = 'blue';
eraserButton.style.border = 'none';
eraserButton.style.backgroundColor = 'transparent';
}
});
var colors = colorList; var colors = colorList;
const buttonSize = 60; const buttonSize = 60;
const buttonSpacing = 15; const buttonSpacing = 15;
const clearEraserContainer = document.createElement('div'); const clearEraserContainer = document.createElement('div');
clearEraserContainer.style.display = 'flex'; clearEraserContainer.style.display = 'flex';
clearEraserContainer.style.flexDirection = 'row'; clearEraserContainer.style.flexDirection = 'row';
if(isMobile){ isMobile ? clearEraserContainer.style.marginTop = '-60px' : clearEraserContainer.style.marginTop = '40px';
clearEraserContainer.style.marginTop = '-60px';
}else{
clearEraserContainer.style.marginTop = '40px';
}
const colorButtonsContainer = document.createElement('div'); const colorButtonsContainer = document.createElement('div');
colorButtonsContainer.style.display = 'flex'; colorButtonsContainer.style.display = 'flex';
colorButtonsContainer.style.flexDirection = 'column'; colorButtonsContainer.style.flexDirection = 'column';
@@ -548,51 +696,15 @@ import Layout from '../../layouts/Layout.astro';
// Create the Clear button // Create the Clear button
const clearButton = document.createElement('button'); const clearButton = document.createElement('button');
clearButton.innerHTML ='<img src="/assets/svg/clear.svg">'; clearButton.innerHTML ='<img src="/assets/svg/clear.svg">';
// // clearButton.style.border = '3px solid blue'; clearButton.style.marginTop = !isMobile ? `-10px` :`0px`;
// clearButton.style.color = 'blue';
// clearButton.style.width = 'fit-content';
// clearButton.style.marginLeft = '30px';
if(isMobile){
clearButton.style.padding = '2px 8px';
buttonsContainer.style.top = '17%';
} else {
clearButton.style.padding = '5px 10px';
}
// clearButton.style.fontWeight = 'bold';
// clearButton.style.borderRadius = '20%';
// clearButton.style.boxShadow = '5px 10px 30px #7c4c2390';
clearButton.addEventListener('click', () => { clearButton.addEventListener('click', () => {
clearDrawing(); clearDrawing();
}); });
// Create the Eraser button
const eraserButton = document.createElement('button');
// eraserButton.textContent = 'Eraser';
eraserButton.innerHTML = '<i class="fa fa-eraser" style="font-size:30px"></i>';
eraserButton.style.color = 'blue';
eraserButton.style.width = 'fit-content';
eraserButton.style.marginLeft = '30px';
eraserButton.style.fontWeight = 'bold'; colorEraserCont.append(eraserButton);
eraserButton.style.borderRadius = '20%'; colorEraserCont.append(clearButton);
eraserButton.style.boxShadow = '5px 10px 15px #7c4c2390'; // buttonsContainer.appendChild(clearEraserContainer);
eraserButton.addEventListener('click', () => {
isErasing = !isErasing;
if (isErasing) {
// eraserButton.style.backgroundColor = 'red';
eraserButton.style.color = 'red';
eraserButton.style.border = '3px solid red';
} else {
// Return to drawing mode
// eraserButton.style.backgroundColor = 'green';
eraserButton.style.color = 'blue';
eraserButton.style.border = 'none';
}
});
// Add the Clear and Eraser buttons to the container
clearEraserContainer.appendChild(eraserButton);
clearEraserContainer.appendChild(clearButton);
// buttonsContainer.appendChild(clearButton);
buttonsContainer.appendChild(clearEraserContainer);
const sliderContainer = document.createElement('div'); const sliderContainer = document.createElement('div');
sliderContainer.className = 'slider-container'; sliderContainer.className = 'slider-container';
@@ -669,10 +781,17 @@ import Layout from '../../layouts/Layout.astro';
submitButton.setVisible(false); submitButton.setVisible(false);
snapshotButton.setVisible(false); snapshotButton.setVisible(false);
customCursor.setVisible(false); customCursor.setVisible(false);
muteIcon.setVisible(false);
retryButton.setVisible(false);
galleryButton.setVisible(false);
drawingZone.renderer.snapshot((image) => { drawingZone.renderer.snapshot((image) => {
submitButton.setVisible(true); submitButton.setVisible(true);
snapshotButton.setVisible(true); snapshotButton.setVisible(true);
customCursor.setVisible(true); customCursor.setVisible(true);
muteIcon.setVisible(true);
retryButton.setVisible(true);
galleryButton.setVisible(true);
image.style.width = '160px'; image.style.width = '160px';
image.style.height = '120px'; image.style.height = '120px';
image.style.paddingLeft = '2px'; image.style.paddingLeft = '2px';
@@ -724,12 +843,49 @@ import Layout from '../../layouts/Layout.astro';
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`; slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
}; };
const cursorSize = brushSize * cursorSizeMultiplier; const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear(); // Clear the previous frame customCursor.clear();
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color) customCursor.lineStyle(1.5, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize); customCursor.strokeCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(defaultColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x; customCursor.x = this.input.x;
customCursor.y = this.input.y; customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
if (erase === true) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
} else if (erase === false) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(defaultColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
}
} }
</script> </script>
<style> <style>

View File

@@ -3,14 +3,107 @@ import Layout from '../../layouts/Layout.astro';
--- ---
<Layout title='Drawing Game'> <Layout title='Drawing Game'>
<main> <main>
<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 onclick="retryGame()" 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-3xl lg:max-w-4xl 2xl: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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveGameAI.js" is:inline></script>
<script is:inline> <script is:inline>
const jsonData = [
{
"src": "/assets/back.jpeg"
},
{
"src": "/assets/background.jpg"
},
{
"src": "/assets/backgroundImage.png"
},
{
"src": "/assets/beanieImage.png"
}
];
let currentSlide = 0;
function updateSlide(){
const slide = jsonData[currentSlide];
document.getElementById('slideImage').src = slide.src;
}
document.getElementById('nextButton').addEventListener('click', () => {
currentSlide = (currentSlide + 1) % jsonData.length;
console.log(currentSlide)
updateSlide();
})
document.getElementById('prevButton').addEventListener('click', () => {
currentSlide = (currentSlide - 1 + jsonData.length) % jsonData.length;
updateSlide();
})
updateSlide();
let parentMainContainer = document.getElementById('parentMainContainer');
let gallerySliderId = document.getElementById('gallerySliderId');
function closeGallery(){
parentMainContainer.classList.add('hidden');
gallerySliderId.classList.add('hidden');
}
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768; // Define your mobile breakpoint as needed const isMobile = window.innerWidth <= 768; // Define your mobile breakpoint as needed
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416; const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
@@ -32,6 +125,12 @@ import Layout from '../../layouts/Layout.astro';
let tickIconWidth; let tickIconWidth;
let cancelIconWidth; let cancelIconWidth;
let maxScore; let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
let galleryIconWidth;
let galleryButton;
if(isMobile){ if(isMobile){
topLogoWidth = 4.5; topLogoWidth = 4.5;
@@ -39,18 +138,21 @@ import Layout from '../../layouts/Layout.astro';
resetIconWidth = 1.47; resetIconWidth = 1.47;
tickIconWidth = 1.24; tickIconWidth = 1.24;
cancelIconWidth = 1.08; cancelIconWidth = 1.08;
galleryIconWidth = 2;
}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;
}else{ }else{
topLogoWidth = 6; topLogoWidth = 6;
muteIconWidth = 1.3; muteIconWidth = 1.3;
resetIconWidth = 1.26; resetIconWidth = 1.26;
tickIconWidth = 1.222; tickIconWidth = 1.222;
cancelIconWidth = 1.185; cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
} }
if(isMobile){ if(isMobile){
@@ -96,6 +198,10 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drawing_v3/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`) const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drawing_v3/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json()) .then(response => response.json())
.then(({data}) => { .then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
// console.log(data) // console.log(data)
// colorList = data.colors; // colorList = data.colors;
const {image} = data; const {image} = data;
@@ -135,6 +241,9 @@ import Layout from '../../layouts/Layout.astro';
let colorList; let colorList;
function preload() { function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('outline', assetsList.image); this.load.image('outline', assetsList.image);
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -144,6 +253,7 @@ import Layout from '../../layouts/Layout.astro';
this.load.svg('buttonIcons', '/assets/svg/button-icon.svg'); this.load.svg('buttonIcons', '/assets/svg/button-icon.svg');
this.load.svg('cursorImage', '/assets/svg/pencil.svg'); this.load.svg('cursorImage', '/assets/svg/pencil.svg');
this.load.image('colorButton', '/assets/color_button.png'); this.load.image('colorButton', '/assets/color_button.png');
this.load.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
} }
function create() { function create() {
@@ -208,12 +318,34 @@ import Layout from '../../layouts/Layout.astro';
borderBottom.strokePath(); borderBottom.strokePath();
const outlineImage = this.add.image(customWidth / 2, customHeight / 2 + 20, 'outline'); const outlineImage = this.add.image(customWidth / 2, customHeight / 2 + 20, 'outline');
// this.add.image(customWidth / topLogoWidth, 30, "topLogo");
// this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
// const retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
// submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
this.add.image(customWidth / topLogoWidth, 30, "topLogo"); this.add.image(customWidth / topLogoWidth, 30, "topLogo");
this.add.image(customWidth / muteIconWidth, 30, "muteIcon"); muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
const 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");
galleryButton = this.add.image(customWidth / galleryIconWidth, 30, "galleryIcons");
if(audioFileId === true){
let instructionAudio = this.sound.add('instructAudio')
muteIcon.setInteractive().on('pointerdown', () => {
if(isPlaying === false){
instructionAudio.play()
isPlaying = true
} else if(isPlaying === true) {
instructionAudio.stop();
isPlaying = false
}
})
}
retryButton.setInteractive().on('pointerdown', () => { retryButton.setInteractive().on('pointerdown', () => {
window.location.reload(); graphics.clear();
}) })
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); 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(window.innerWidth - submitWidth, window.innerHeight - submitHeight, "Submit", { // submitButton = this.add.text(window.innerWidth - submitWidth, window.innerHeight - submitHeight, "Submit", {
@@ -222,13 +354,20 @@ import Layout from '../../layouts/Layout.astro';
// backgroundColor: 'blue', // backgroundColor: 'blue',
// padding: { x: 20, y: 10 }, // padding: { x: 20, y: 10 },
// }); // });
// submitButton.setVisible(true); submitButton.setVisible(true);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
// submitButton.setVisible(false);
// windowLoad();
submitUserData(this); submitUserData(this);
}) showAnimation();
parentMainContainer.classList.remove('hidden');
if(isMobile){
colorContainer.style.display = 'none';
// parentMainContainer.classList.remove('hidden');
}
});
galleryButton.setInteractive().on('pointerdown', () => {
parentMainContainer.classList.remove('hidden');
gallerySliderId.classList.remove('hidden');
});
// const textStyle = {font: 'bold 40px quicksand', fill: '#05b3a4',}; // const textStyle = {font: 'bold 40px quicksand', fill: '#05b3a4',};
// if(!isMobile){ // if(!isMobile){
// this.add.text(customWidth / 10, 20, "Drawing", textStyle); // this.add.text(customWidth / 10, 20, "Drawing", textStyle);
@@ -245,7 +384,12 @@ import Layout from '../../layouts/Layout.astro';
outlineImage.setDepth(-1).setScale(1); outlineImage.setDepth(-1).setScale(1);
} }
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
const colorContainer = document.createElement('div'); const colorContainer = document.createElement('div');
colorContainer.style.position = 'absolute'; colorContainer.style.position = 'absolute';
colorContainer.style.top = '13%'; colorContainer.style.top = '13%';
@@ -259,13 +403,26 @@ import Layout from '../../layouts/Layout.astro';
if(isMobile){ if(isMobile){
colorContainer.style.display = 'none'; colorContainer.style.display = 'none';
colorContainer.style.flexDirection = 'row';
} }
let colorViewButton = this.add.image(window.innerWidth / 7, window.innerHeight / 1.25, 'colorButton'); let colorViewButton = this.add.image(window.innerWidth / 7, window.innerHeight / 1.25, 'colorButton');
if(!isMobile){ !isMobile ? colorViewButton.setVisible(false) : '';
colorViewButton.setVisible(false);
}
colorContainer.style.backgroundColor = '#FFFFFF';
colorContainer.style.padding = '30px 20px';
colorContainer.style.borderRadius = '80px';
colorContainer.style.boxShadow = '2px 6px 12.4px 4px #D2D1D170';
colorContainer.style.left = '0px';
colorContainer.style.top = '50%';
colorContainer.style.transform = 'translate(0, -50%)';
colorContainer.style.border = '1px solid #F9F9F9';
let colorEraserCont = document.createElement('div');
colorEraserCont.style.display = 'flex';
colorEraserCont.style.flexDirection = 'row';
colorContainer.appendChild(colorEraserCont);
colorViewButton.setInteractive().on('pointerdown', () => { colorViewButton.setInteractive().on('pointerdown', () => {
if(colorContainer.style.display === 'block') { if(colorContainer.style.display === 'block') {
colorContainer.style.display = 'none'; colorContainer.style.display = 'none';
@@ -302,7 +459,8 @@ import Layout from '../../layouts/Layout.astro';
} }
}); });
// Append the color picker to the color container data // Append the color picker to the color container data
colorContainer.appendChild(colorPicker);
// colorContainer.appendChild(colorPicker);
// const colors = data.colors; // const colors = data.colors;
// var colors = colorList; // var colors = colorList;
let colors = isMobile ? ['#0000FF', '#008000', '#A52A2A', '#800080', '#FFD700'] : ['#FF0000', '#FFFF00', '#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB']; let colors = isMobile ? ['#0000FF', '#008000', '#A52A2A', '#800080', '#FFD700'] : ['#FF0000', '#FFFF00', '#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB'];
@@ -526,39 +684,14 @@ import Layout from '../../layouts/Layout.astro';
// Create the Clear button // Create the Clear button
const clearButton = document.createElement('button'); const clearButton = document.createElement('button');
clearButton.innerHTML ='<img src="/assets/svg/clear.svg">'; clearButton.innerHTML ='<img src="/assets/svg/clear.svg">';
// clearButton.style.border = '3px solid blue'; clearButton.style.marginTop = !isMobile ? `-10px` :`0px`;
// clearButton.style.color = 'blue';
// clearButton.style.width = 'fit-content';
// clearButton.style.marginRight = '10px';
if(isMobile){
clearButton.style.padding = '2px 8px';
buttonsContainer.style.top = '100px';
buttonsContainer.style.marginLeft = '30px';
clearButton.style.marginTop = '-15px';
}else if(isTab){
clearButton.style.marginTop = '-100px';
} else {
clearButton.style.padding = '5px 10px';
clearButton.style.marginTop = '-115px';
}
// clearButton.style.fontWeight = 'bold';
// clearButton.style.borderRadius = '20%';
// clearButton.style.boxShadow = '5px 10px 30px #7c4c2390';
clearButton.addEventListener('click', () => { clearButton.addEventListener('click', () => {
clearDrawing(); clearDrawing();
}); });
if(isMobile){
clearButton.style.display = 'none';
}
colorViewButton.setInteractive().on('pointerdown', () => { colorViewButton.setInteractive().on('pointerdown', () => {
if(clearButton.style.display === 'block') { clearButton.style.display === 'block' ? clearButton.style.display = 'none' : clearButton.style.display = 'block';
clearButton.style.display = 'none';
}else{
clearButton.style.display = 'block';
}
}); });
// Create the Eraser button // Create the Eraser button
@@ -596,7 +729,8 @@ import Layout from '../../layouts/Layout.astro';
} }
}); });
// Add the Clear and Eraser buttons to the container // Add the Clear and Eraser buttons to the container
buttonsContainer.appendChild(clearButton); colorEraserCont.append(colorPicker);
colorEraserCont.append(clearButton);
// buttonsContainer.appendChild(eraserButton).setVisible; // buttonsContainer.appendChild(eraserButton).setVisible;
const sliderContainer = document.createElement('div'); const sliderContainer = document.createElement('div');
@@ -690,10 +824,17 @@ import Layout from '../../layouts/Layout.astro';
// snapNotice.setVisible(true); // snapNotice.setVisible(true);
snapshotButton.setVisible(false); snapshotButton.setVisible(false);
customCursor.setVisible(false); customCursor.setVisible(false);
muteIcon.setVisible(false);
retryButton.setVisible(false);
galleryButton.setVisible(false);
drawingZone.renderer.snapshot((image) => { drawingZone.renderer.snapshot((image) => {
submitButton.setVisible(true); submitButton.setVisible(true);
snapshotButton.setVisible(true); snapshotButton.setVisible(true);
customCursor.setVisible(true); customCursor.setVisible(true);
muteIcon.setVisible(true);
retryButton.setVisible(true);
galleryButton.setVisible(true);
image.style.width = '160px'; image.style.width = '160px';
image.style.height = '120px'; image.style.height = '120px';
image.style.paddingLeft = '2px'; image.style.paddingLeft = '2px';
@@ -747,12 +888,49 @@ import Layout from '../../layouts/Layout.astro';
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`; slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
}; };
const cursorSize = brushSize * cursorSizeMultiplier; const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear(); // Clear the previous frame customCursor.clear();
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color) customCursor.lineStyle(1.5, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize); customCursor.strokeCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x; customCursor.x = this.input.x;
customCursor.y = this.input.y; customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
if (erase === true) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
} else if (erase === false) {
customCursor.clear();
customCursor.lineStyle(3, 0x000000);
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
customCursor.x = this.input.x;
customCursor.y = this.input.y;
customCursor.moveTo(0, -cursorSize+3);
customCursor.lineTo(0, cursorSize-3);
customCursor.moveTo(-cursorSize + 3, 0);
customCursor.lineTo(cursorSize-3, 0);
customCursor.strokePath();
}
} }
// function update() { // function update() {
@@ -788,4 +966,40 @@ import Layout from '../../layouts/Layout.astro';
// this.customCursor.y = this.input.y; // this.customCursor.y = this.input.y;
// } // }
</script> </script>
<!-- <svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M11.4001 18.1612L11.4001 18.1612L18.796 10.7653C17.7894 10.3464 16.5972 9.6582 15.4697 8.53068C14.342 7.40298 13.6537 6.21058 13.2348 5.2039L5.83882 12.5999L5.83879 12.5999C5.26166 13.1771 4.97307 13.4657 4.7249 13.7838C4.43213 14.1592 4.18114 14.5653 3.97634 14.995C3.80273 15.3593 3.67368 15.7465 3.41556 16.5208L2.05445 20.6042C1.92743 20.9852 2.0266 21.4053 2.31063 21.6894C2.59466 21.9734 3.01478 22.0726 3.39584 21.9456L7.47918 20.5844C8.25351 20.3263 8.6407 20.1973 9.00498 20.0237C9.43469 19.8189 9.84082 19.5679 10.2162 19.2751C10.5343 19.0269 10.823 18.7383 11.4001 18.1612Z" fill="#1C274C"></path> <path d="M20.8482 8.71306C22.3839 7.17735 22.3839 4.68748 20.8482 3.15178C19.3125 1.61607 16.8226 1.61607 15.2869 3.15178L14.3999 4.03882C14.4121 4.0755 14.4246 4.11268 14.4377 4.15035C14.7628 5.0875 15.3763 6.31601 16.5303 7.47002C17.6843 8.62403 18.9128 9.23749 19.85 9.56262C19.8875 9.57563 19.9245 9.58817 19.961 9.60026L20.8482 8.71306Z" fill="#1C274C"></path> </g></svg> --> <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

@@ -3,14 +3,75 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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 isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = { const drawingZone = {
@@ -39,7 +100,7 @@ import Layout from "../../layouts/Layout.astro";
const game = new Phaser.Game(config); const game = new Phaser.Game(config);
const customWidth = window.innerWidth; const customWidth = window.innerWidth;
const customHeight = window.innerHeight; const customHeight = window.innerHeight;
let firstLayer, secondLayer, thirdLayer; let firstLayer;
let graphics; let graphics;
let isDrawing = false; let isDrawing = false;
let formattedDateTime; let formattedDateTime;
@@ -55,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;
@@ -70,23 +131,6 @@ import Layout from "../../layouts/Layout.astro";
tickIconWidth = 1.21; tickIconWidth = 1.21;
cancelIconWidth = 1.08; cancelIconWidth = 1.08;
galleryIconWidth = 2; 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;
}
if(isMobile){
submitWidth = 250; submitWidth = 250;
submitHeight = 110; submitHeight = 110;
noticeWidth = 100; noticeWidth = 100;
@@ -94,24 +138,7 @@ import Layout from "../../layouts/Layout.astro";
downloadWidth = 67; downloadWidth = 67;
downloadHeight = 200; downloadHeight = 200;
learningWidth = 200; learningWidth = 200;
learningHeight = 400 learningHeight = 400;
}else {
submitWidth = 380;
submitHeight = 95;
noticeWidth = 0;
noticeHeight = 0;
downloadWidth = 180;
downloadHeight = 70;
learningWidth = 450;
learningHeight = 400
}
if(isMobile){
cloudeSize = 200;
cloudHeight = 340;
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 30; letterHeight = 30;
letterScale = 1.8; letterScale = 1.8;
backgroundScale = 0.8; backgroundScale = 0.8;
@@ -130,11 +157,30 @@ import Layout from "../../layouts/Layout.astro";
submitHeight = customHeight / 1.1; submitHeight = customHeight / 1.1;
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){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
galleryIconWidth = 1.81;
}else{ }else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
galleryIconWidth = 1.345;
submitWidth = 380;
submitHeight = 95;
noticeWidth = 0;
noticeHeight = 0;
downloadWidth = 180;
downloadHeight = 70;
learningWidth = 450;
learningHeight = 400;
cloudeSize = 500; cloudeSize = 500;
cloudHeight = 250; cloudHeight = 250;
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 10; letterHeight = 10;
letterScale = 1.8; letterScale = 1.8;
backgroundScale = 1; backgroundScale = 1;
@@ -154,6 +200,7 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120; noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32; noticeHeight = window.innerHeight * 0.32;
} }
window.onload = function() { window.onload = function() {
currentDate = new Date(); currentDate = new Date();
formattedDateTime = currentDate.toLocaleString(); formattedDateTime = currentDate.toLocaleString();
@@ -201,24 +248,26 @@ import Layout from "../../layouts/Layout.astro";
borderBottom.lineTo(x + lineWidth, y); borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath(); borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { // submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand', // font: '900 24px Quicksand',
fill: '#05b3a4', // fill: '#05b3a4',
backgroundColor : '#7c4c23', // backgroundColor : '#7c4c23',
padding: {x: 10, y: 10}, // padding: {x: 10, y: 10},
shadow: { // shadow: {
offsetX : 2, // offsetX : 2,
offsetY : 2, // offsetY : 2,
color: '#000', // color: '#000',
blur: 5, // blur: 5,
fill: true // fill: true
} // }
}); // });
submitButton.setVisible(false); // submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => { submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked'); // console.log('Clicked');
submitUserData(this); submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
}) })
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9); // this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
@@ -249,6 +298,12 @@ import Layout from "../../layouts/Layout.astro";
// const baseFontSize = 16; // const baseFontSize = 16;
// const responsiveFontSize = (window.innerWidth / 550) * baseFontSize; // const responsiveFontSize = (window.innerWidth / 550) * baseFontSize;
retryButton.setInteractive().on('pointerdown', () => {
window.location.reload();
})
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32; let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 0', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5); this.add.text(window.innerWidth / 2, 80, 'Number: 0', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
@@ -307,6 +362,7 @@ import Layout from "../../layouts/Layout.astro";
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
// graphics.setMask(mask); // 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) {
@@ -324,20 +380,22 @@ import Layout from "../../layouts/Layout.astro";
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', document.getElementById('beforeStartBtn').addEventListener('click', function() {
fill: '#05b3a4', document.getElementById('blurDisplay').classList.add('hidden');
backgroundColor : '#7c4c23',
padding: {x: 20, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
})
audioOneAudio.play(); audioOneAudio.play();
gamestart = new Date();
gameStartTime = gamestart.toLocaleString();
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
graphics.setVisible(true);
demoButton.setVisible(true);
submitButton.setVisible(true);
})
// audioOneAudio.play();
// startButton.setInteractive().on('pointerdown', () => { // startButton.setInteractive().on('pointerdown', () => {
// audioOneAudio.play(); // audioOneAudio.play();
// // gmStartTime(); // // gmStartTime();
@@ -355,9 +413,49 @@ import Layout from "../../layouts/Layout.astro";
} }
// function beforeStartGame(){
// audioOneAudio.play();
// document.getElementById('blurDisplay').classList.add('hidden');
// }
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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,41 @@ 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 = "stat timr here"; let gameStartTime = "stat timr here";
let galleryIconWidth;
let noticeWidth;
let noticeHeight;
let muteIcon;
let retryButton;
let maxScore;
let cancelIcon;
let letterHeight;
let letterScale;
let animated1Height;
let animated1videoScale;
if(isMobile){ if(isMobile){
cloudeSize = 200;
cloudHeight = 340; submitWidth = 250;
canvasScale = 0.14 submitHeight = 110;
canvasHeight = 35; noticeWidth = 100;
letterHeight = 30; noticeHeight = 0;
letterScale = 1.1; downloadWidth = 67;
downloadHeight = 200;
learningWidth = 200;
learningHeight = 400;
letterHeight = 0;
letterScale = 1.8;
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;
animated1videoScale = 1;
animated1videoScale = 0.6;
animated1Height = 32; animated1Height = 32;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@@ -68,23 +148,33 @@ import Layout from "../../layouts/Layout.astro";
submitHeight = customHeight / 1.1; submitHeight = customHeight / 1.1;
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){
animated1videoScale = 1;
animated1Height = 32;
letterHeight = 0;
letterScale = 1.8;
}else{ }else{
submitWidth = 380;
submitHeight = 95;
noticeWidth = 0;
noticeHeight = 0;
downloadWidth = 180;
downloadHeight = 70;
learningWidth = 450;
learningHeight = 400;
cloudeSize = 500; cloudeSize = 500;
cloudHeight = 250; cloudHeight = 250;
canvasScale = 0.195; letterHeight = 0;
canvasHeight = 20; letterScale = 1.8;
letterHeight = 10;
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;
animated1videoScale = 0.70; animated1videoScale = 1;
animated1Height = 20; animated1Height = 20;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
startButtonHeight = customHeight / 2 - 20; startButtonHeight = customHeight / 2 - 20;
startButtonWidth = customWidth / 1.32; startButtonWidth = customWidth / 1.32;
submitWidth = customWidth / 1.32; submitWidth = customWidth / 1.32;
@@ -92,12 +182,35 @@ import Layout from "../../layouts/Layout.astro";
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();
// console.log("Page loaded on: " + formattedDateTime); // console.log("Page loaded on: " + formattedDateTime);
}; };
// let hideButton;
function preload() { function preload() {
this.load.video('animated1', '/assets/animated-letter/number_1.mp4'); this.load.video('animated1', '/assets/animated-letter/number_1.mp4');
@@ -112,135 +225,71 @@ import Layout from "../../layouts/Layout.astro";
this.load.image('cloud', '/assets/cloud.png'); this.load.image('cloud', '/assets/cloud.png');
this.load.image('canvas', '/assets/canvas4.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() {
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); 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');
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, "Number : 1", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9); // 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 - 10, customHeight / 2 + letterHeight, 'number1').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'number1').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'number1').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'number1').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated1').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated1').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale); // 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);
graphics.setVisible(true);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}
}); });
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write number : 1', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 1', {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 : 1', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated1Height, 'animated1').setDepth(2).setScale(animated1videoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated1Height, 'animated1').setDepth(2).setScale(animated1videoScale);
// Play the video // Play the video
@@ -256,11 +305,12 @@ import Layout from "../../layouts/Layout.astro";
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 10, 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 35px 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);
@@ -310,32 +360,44 @@ import Layout from "../../layouts/Layout.astro";
graphics.lineTo(pointer.x, pointer.y); graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath(); graphics.strokePath();
}); });
let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", { // let startButton = this.add.text(startButtonWidth, startButtonHeight, "Start", {
font: '900 24px Quicksand', // font: '900 24px Quicksand',
fill: '#05b3a4', // fill: '#05b3a4',
backgroundColor : '#7c4c23', // backgroundColor : '#7c4c23',
padding: {x: 20, y: 10}, // padding: {x: 20, y: 10},
shadow: { // shadow: {
offsetX : 2, // offsetX : 2,
offsetY : 2, // offsetY : 2,
color: '#000', // color: '#000',
blur: 5, // blur: 5,
fill: true // 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); gamestart = new Date();
gameStartTime = gamestart.toLocaleString();
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); demoButton.setVisible(true);
startButton.setVisible(false); submitButton.setVisible(true);
}) })
// 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);
// })
} }
@@ -345,3 +407,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,
@@ -43,21 +106,18 @@ import Layout from "../../layouts/Layout.astro";
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;
cloudHeight = 340;
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 58; letterHeight = 58;
letterScale = 1; letterScale = 1.5;
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;
animated2Scale = 0.55; animated2Scale = 0.85;
animated2Height = 32; animated2Height = 32;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@@ -69,18 +129,14 @@ let scoreTotal = 0; let isDrawing = false;
noticeWidth = window.innerWidth * 0.5 - 100; noticeWidth = window.innerWidth * 0.5 - 100;
noticeHeight = window.innerHeight * 0.38; noticeHeight = window.innerHeight * 0.38;
} else{ } else{
cloudeSize = 500;
cloudHeight = 250;
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 50; letterHeight = 50;
letterScale = 1; letterScale = 1.5;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animated2Scale = 0.55; animated2Scale = 0.85;
animated2Height = 20; animated2Height = 20;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@@ -91,158 +147,114 @@ 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();
// console.log("Page loaded on: " + formattedDateTime); // console.log("Page loaded on: " + formattedDateTime);
}; };
// let hideButton;
function preload() { function preload() {
this.load.video('animated2', '/assets/animated-letter/number_2.mp4'); this.load.video('animated2', '/assets/animated-letter/number_2.mp4');
this.load.svg('number2', '/assets/numeric/n2.svg'); this.load.svg('number2', '/assets/numeric/n2.svg');
this.load.svg('layer1', '/assets/numeric/n2.svg'); this.load.svg('layer1', '/assets/numeric/n2_l1.svg');
this.load.svg('layer2', '/assets/numeric/n2.svg'); this.load.svg('layer2', '/assets/numeric/n2_l2.svg');
this.load.audio('audioOne', '/assets/audio/roll-slant.mp3'); this.load.audio('audioOne', '/assets/audio/roll-slant.mp3');
this.load.audio('audioTwo', '/assets/audio/slide.mp3'); this.load.audio('audioTwo', '/assets/audio/slide.mp3');
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
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() {
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); 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");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { const borderBottom = this.add.graphics();
font: '900 24px Quicksand', const x = 0; const y = 54;
fill: '#05b3a4', const lineWidth = window.innerWidth;
backgroundColor : '#7c4c23', borderBottom.lineStyle(1, 0x0348A8);
padding: {x: 10, y: 10}, borderBottom.setAlpha(0.2);
shadow: { borderBottom.beginPath();
offsetX : 2, borderBottom.moveTo(x, y);
offsetY : 2, borderBottom.lineTo(x + lineWidth, y);
color: '#000', borderBottom.strokePath();
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, "Number : 2", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9); // 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 - 10, customHeight / 2 + letterHeight, 'number2').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'number2').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number2').setDepth(2).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number2').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number2').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated2').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated2').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
}); });
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write number : 2', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 1', {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 : 2', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated2Height, 'animated2').setDepth(2).setScale(animated2Scale); const animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated2Height, 'animated2').setDepth(2).setScale(animated2Scale);
// Play the video // Play the video
@@ -260,9 +272,8 @@ submitUserData(this);
let textX, textY; let textX, textY;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75; let stepTextSize = isMobile ? 12 : 16;
textY = isMobile ? customHeight / 5 : customHeight / 2.4; const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Roll Slant',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Roll Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@@ -271,7 +282,8 @@ submitUserData(this);
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 10, 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);
@@ -284,7 +296,6 @@ submitUserData(this);
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) => {
@@ -307,7 +318,6 @@ submitUserData(this);
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
@@ -346,36 +356,60 @@ submitUserData(this);
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); gamestart = new Date();
gameStartTime = gamestart.toLocaleString();
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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,25 @@ 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;
cloudHeight = 340; cloudHeight = 340;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 48; letterHeight = 48;
letterScale = 1; letterScale = 1.5;
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;
animated3Scale = 0.55; animated3Scale = 0.92;
animated3Height = 32; animated3Height = 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;
letterHeight = 30; letterHeight = 30;
letterScale = 1; letterScale = 1.5;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animated3Scale = 0.55; animated3Scale = 0.92;
animated3Height = 20; animated3Height = 20;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@@ -92,12 +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;
} }
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();
// console.log("Page loaded on: " + formattedDateTime); // console.log("Page loaded on: " + formattedDateTime);
}; };
// let hideButton;
function preload() { function preload() {
this.load.video('animated3', '/assets/animated-letter/number_3.mp4'); this.load.video('animated3', '/assets/animated-letter/number_3.mp4');
@@ -109,140 +194,76 @@ 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() {
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); 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");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { const borderBottom = this.add.graphics();
font: '900 24px Quicksand', const x = 0; const y = 54;
fill: '#05b3a4', const lineWidth = window.innerWidth;
backgroundColor : '#7c4c23', borderBottom.lineStyle(1, 0x0348A8);
padding: {x: 10, y: 10}, borderBottom.setAlpha(0.2);
shadow: { borderBottom.beginPath();
offsetX : 2, borderBottom.moveTo(x, y);
offsetY : 2, borderBottom.lineTo(x + lineWidth, y);
color: '#000', borderBottom.strokePath();
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, "Number : 3", { font: '700 40px quicksand', fill: '#05b3a4', });
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9); // 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 - 10, customHeight / 2 + letterHeight, 'number3').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'number3').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number3').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number3').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated3').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated3').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
}); });
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write number : 3', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 3', {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 : 3', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated3Height, 'animated3').setDepth(2).setScale(animated3Scale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated3Height, 'animated3').setDepth(2).setScale(animated3Scale);
// Play the video // Play the video
@@ -258,11 +279,11 @@ submitUserData(this);
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 10, 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. 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('audioOne'); const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play(); // audioOneAudio.play();
firstLayer.setDepth(1); firstLayer.setDepth(1);
@@ -271,7 +292,7 @@ submitUserData(this);
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 10, 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('audioOne'); const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@@ -307,7 +328,6 @@ submitUserData(this);
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
@@ -346,31 +366,14 @@ submitUserData(this);
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);
}) })
} }
@@ -379,3 +382,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
// let x = 100; // let x = 100;
// // Use x // // Use x
@@ -97,6 +162,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,138 +201,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('canvas', '/assets/canvas4.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('canvasStand', '/assets/stand2.png'); 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); 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, "Number : 4", { 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, 'number4').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number4').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number4').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number4').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated4').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated4').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
}); });
retryButton.setInteractive().on('pointerdown', () => {
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; window.location.reload();
const baseFontSize = 24; })
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; const maskGraphics = this.make.graphics();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write number : 4', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
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);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated4Height, 'animated4').setDepth(2).setScale(animated4Scale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated4Height, 'animated4').setDepth(2).setScale(animated4Scale);
// Play the video // Play the video
@@ -260,11 +283,12 @@ submitUserData(this);
}); });
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. Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. 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);
@@ -273,7 +297,7 @@ submitUserData(this);
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);
@@ -282,8 +306,9 @@ submitUserData(this);
secondLayer.setVisible(false); secondLayer.setVisible(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. Down', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioThreeAudio = this.sound.add('audioOne'); const audioThreeAudio = this.sound.add('audioOne');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@@ -378,31 +403,15 @@ submitUserData(this);
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);
}) })
} }
@@ -410,3 +419,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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);
@@ -54,7 +118,7 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 50; letterHeight = 50;
letterScale = 1; letterScale = 1.2;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
@@ -62,7 +126,7 @@ let scoreTotal = 0; let isDrawing = false;
sunHeight = 70; sunHeight = 70;
animated5Height = 35; animated5Height = 35;
animated5Scale = 0.55; animated5Scale = 0.7;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@@ -78,7 +142,7 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 40; letterHeight = 40;
letterScale = 1; letterScale = 1.2;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
@@ -86,7 +150,7 @@ let scoreTotal = 0; let isDrawing = false;
sunHeight = 100; sunHeight = 100;
animated5Height = 20; animated5Height = 20;
animated5Scale = 0.6; animated5Scale = 0.7;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@@ -97,6 +161,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();
@@ -115,138 +201,72 @@ 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("tickIcon", '/assets/svg/tick2.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('canvasStand', '/assets/stand2.png'); 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); 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'); // windowLoad();
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, "Number : 5", { 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, 'number5').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number5').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number5').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number5').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated5').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated5').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale); // 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write number : 5', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 5', {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 : 5', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated5Height, 'animated5').setDepth(2).setScale(animated5Scale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated5Height, 'animated5').setDepth(2).setScale(animated5Scale);
// Play the video // Play the video
@@ -261,11 +281,11 @@ submitUserData(this);
}); });
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. Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. 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);
@@ -274,7 +294,7 @@ submitUserData(this);
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. 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);
@@ -284,7 +304,7 @@ submitUserData(this);
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);
@@ -379,35 +399,56 @@ submitUserData(this);
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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 30; canvasHeight = 30;
letterHeight = 30; letterHeight = 30;
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;
animated6Scale = 0.55; animated6Scale = 0.7;
animated6Height = 32; animated6Height = 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 = 10; letterHeight = 10;
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;
animated6Scale = 0.55; animated6Scale = 0.7;
animated6Height = 20; animated6Height = 20;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@@ -93,12 +158,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;
} }
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();
// console.log("Page loaded on: " + formattedDateTime); // console.log("Page loaded on: " + formattedDateTime);
}; };
// let hideButton;
function preload() { function preload() {
this.load.video('animated6', '/assets/animated-letter/number_6.mp4'); this.load.video('animated6', '/assets/animated-letter/number_6.mp4');
@@ -111,159 +197,92 @@ 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() {
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); 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, "Number : 6", { 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 - 10, customHeight / 2 + letterHeight, 'number6').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'number6').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number6').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number6').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated6').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated6').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write number : 6', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 6', {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 : 6', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated6Height, 'animated6').setDepth(2).setScale(animated6Scale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated6Height, 'animated6').setDepth(2).setScale(animated6Scale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
// You can set additional properties for the video, such as loop and mute:
animatedLetter.setLoop(true); // Loop the video animatedLetter.setLoop(true); // Loop the video
animatedLetter.setMute(false); // Unmute the video animatedLetter.setMute(false); // Unmute the video
animatedLetter.on('complete', function () { animatedLetter.on('complete', function () {
// Video playback is complete
// You can add your code here for what to do when the video finishes. // You can add your code here for what to do when the video finishes.
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 10, 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. Curve Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Curve 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 +291,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 10, 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. Loop',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Loop',{ 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);
@@ -285,7 +304,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) => {
@@ -308,7 +326,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
@@ -347,30 +364,16 @@ 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);
}) })
} }
@@ -379,3 +382,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 30; canvasHeight = 30;
letterHeight = 30; letterHeight = 30;
letterScale = 1; letterScale = 1.5;
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;
animated7Scale = 0.55; animated7Scale = 0.75;
animated7Height = 32; animated7Height = 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 = 10; letterHeight = 10;
letterScale = 1.1; letterScale = 1.5;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animated7Scale = 0.55; animated7Scale = 0.75;
animated7Height = 20; animated7Height = 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,138 +198,76 @@ 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() {
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); 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, "Number : 7", { 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 - 10, customHeight / 2 + letterHeight, 'number7').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'number7').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number7').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number7').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated7').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated7').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale); // 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); 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 number : 7', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
retryButton.setInteractive().on('pointerdown', () => {
window.location.reload();
})
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 7', {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 : 7', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated7Height, 'animated7').setDepth(2).setScale(animated7Scale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated7Height, 'animated7').setDepth(2).setScale(animated7Scale);
// Play the video // Play the video
@@ -258,11 +283,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 10, 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. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slide',{ 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 +296,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 10, 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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant',{ 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 +309,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;
@@ -344,31 +367,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);
}) })
} }
@@ -377,3 +384,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14; canvasScale = 0.14;
canvasHeight = 30; canvasHeight = 30;
letterHeight = 30; letterHeight = 30;
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;
animated8Scale = 0.55; animated8Scale = 0.7;
animated8Height = 15; animated8Height = 15;
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 = 10; letterHeight = 10;
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;
animated8Scale = 0.55; animated8Scale = 0.7;
animated8Height = 0; animated8Height = 0;
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,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('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");
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); 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, "Number : 8", { 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 - 10, customHeight / 2 + letterHeight, 'number8').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'number8').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number8').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number8').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated8').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated8').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale); // 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write number : 8', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 8', {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 : 8', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated8Height, 'animated8').setDepth(2).setScale(animated8Scale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated8Height, 'animated8').setDepth(2).setScale(animated8Scale);
// Play the video // Play the video
@@ -258,11 +281,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 10, 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 Snake',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Snake',{ 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 +294,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 10, 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 Up',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Roll Up',{ 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);
@@ -345,31 +368,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);
}) })
} }
@@ -378,3 +385,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -50,14 +115,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 30; canvasHeight = 30;
letterHeight = 30; letterHeight = 30;
letterScale = 1; letterScale = 1.3;
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;
animated9Scale = 0.55; animated9Scale = 0.75;
animated9Height = 40; animated9Height = 40;
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 = 10; letterHeight = 10;
letterScale = 1; letterScale = 1.3;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
sunWidth = 200; sunWidth = 200;
sunHeight = 100; sunHeight = 100;
animated9Scale = 0.55; animated9Scale = 0.75;
animated9Height = 20; animated9Height = 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,139 +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('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() {
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); 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, "Number : 9", { 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 - 10, customHeight / 2 + letterHeight, 'number9').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'number9').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number9').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'number9').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated9').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animated9').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', () => {
graphics.setVisible(false);
animatedLetter.setCurrentTime(0); animatedLetter.setCurrentTime(0);
animatedLetter.play(true); animatedLetter.play(true);
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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write number : 9', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Number: 9', {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 : 9', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated9Height, 'animated9').setDepth(2).setScale(animated9Scale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated9Height, 'animated9').setDepth(2).setScale(animated9Scale);
// Play the video // Play the video
@@ -259,11 +281,12 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 8 : customWidth * 0.75; textX = isMobile ? customWidth / 8 : 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. Curve Around',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Curve 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 +295,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 10, 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('audioTwo'); const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false); secondTextLayer.setVisible(false);
secondLayer.setDepth(1); secondLayer.setDepth(1);
@@ -308,7 +331,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
@@ -347,31 +369,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);
}) })
} }
@@ -380,3 +386,40 @@ 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

@@ -3,14 +3,81 @@ import Layout from "../../layouts/Layout.astro";
--- ---
<Layout title="Guided Letter Tracing Game"> <Layout title="Guided Letter Tracing Game">
<main> <main>
<div id="blurDisplay" class="w-full min-h-screen absolute backdrop-blur-[5px] z-50">
<div class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</div>
</div>
<div> <div>
<div id="wsSavedImg" class="clip-art-container -z-10 absolute bottom-0 right-0">
<img src="/assets/svg/tracing-done.svg" alt="Clip Art" class="clip-art">
</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-3xl lg:max-w-4xl 2xl: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>
</div>
</div> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </main>
</Layout> </Layout>
<script src="/saveGameData.js" is:inline></script> <script src="/saveTracingGameData.js" is:inline></script>
<script is:inline> <script is:inline>
const findBuddies = JSON.parse(localStorage.getItem('userChildDetails') || '{}');
const buddiesName = findBuddies.metadata?.sprite || 'No sprite found'
console.log('buddName', buddiesName);
// fetch(`https://preschool-curriculum.in/api/one/v1//akademy/students/668ce00ae4714c0da8c17d4e`)
const jsonData = [
{
"src": "/assets/back.jpeg"
},
{
"src": "/assets/background.jpg"
},
{
"src": "/assets/backgroundImage.png"
},
{
"src": "/assets/beanieImage.png"
}
];
let currentSlide = 0;
function updateSlide(){
const slide = jsonData[currentSlide];
document.getElementById('slideImage').src = slide.src;
}
document.getElementById('nextButton').addEventListener('click', () => {
currentSlide = (currentSlide + 1) % jsonData.length;
console.log(currentSlide)
updateSlide();
})
document.getElementById('prevButton').addEventListener('click', () => {
currentSlide = (currentSlide - 1 + jsonData.length) % jsonData.length;
updateSlide();
})
updateSlide();
let parentMainContainer = document.getElementById('parentMainContainer');
let gallerySliderId = document.getElementById('gallerySliderId');
function closeGallery(){
gallerySliderId.classList.add('hidden');
}
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 +89,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,14 +107,13 @@ 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; let maxScore;
let galleryButton;
// // Use x
// console.log(x);
if(isMobile){ if(isMobile){
cloudeSize = 200; cloudeSize = 200;
@@ -55,14 +121,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 +144,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 +162,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,128 +202,77 @@ 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.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
this.load.image('canvas', '/assets/canvas4.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('canvasStand', '/assets/stand2.png'); 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); 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");
galleryButton = this.add.image(customWidth / galleryIconWidth, 30, "galleryIcons");
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();
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo'); // parentMainContainer.classList.remove('hidden');
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); galleryButton.setInteractive().on('pointerdown', () => {
cloud.setDepth(-1.8); // parentMainContainer.classList.remove('hidden');
const scrollSpeed = 0.5; gallerySliderId.classList.remove('hidden');
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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: A', {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 : A', { font: `900 ${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
@@ -250,11 +287,14 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
let finalMessage = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, 'Great job! You traced the letter perfectly!',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
finalMessage.setVisible(false);
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);
@@ -263,7 +303,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,10 +313,12 @@ 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);
// thirdLayer.setScale(1.15); // thirdLayer.setScale(1.15);
thirdLayer.setAlpha(0.5); thirdLayer.setAlpha(0.5);
thirdLayer.setInteractive({ draggable: true }); thirdLayer.setInteractive({ draggable: true });
@@ -287,8 +329,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;
@@ -343,6 +383,7 @@ let scoreTotal = 0; let isDrawing = false;
if (distance >= 100) { if (distance >= 100) {
thirdLayer.setAlpha(1); thirdLayer.setAlpha(1);
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
finalMessage.setVisible(true)
} else { } else {
thirdLayer.setAlpha(0.5); thirdLayer.setAlpha(0.5);
} }
@@ -369,31 +410,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);
}) })
} }
@@ -401,3 +425,37 @@ function update() {
} }
</script> </script>
<style href="https://fonts.googleapis.com/css?family=Quicksand&display=swap" rel="stylesheet">
* {
margin: 0;
padding: 0;
cursor: -webkit-grab; cursor: grab;
font-family: quicksand;
}
/* 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 */
}
</style>

View File

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,73 @@ 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");
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: B', {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 : B', { font: `900 ${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 +277,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 +290,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 +300,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 +314,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;
@@ -378,31 +397,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);
}) })
} }
@@ -411,3 +413,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,72 @@ 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() {
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedAHeight, 'animatedA').setDepth(2).setScale(animatedVideoScale); maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
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 +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, 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);
@@ -307,33 +327,16 @@ 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() {
@@ -341,3 +344,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,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('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");
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: D', {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 : D', { font: `900 ${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 +277,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 +290,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 +303,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;
@@ -341,30 +360,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);
}) })
} }
@@ -373,3 +377,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,70 @@ 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");
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: E', {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 : E', { font: `900 ${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 +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 - 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 +287,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 +297,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 +308,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);
@@ -407,31 +427,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);
}) })
} }
@@ -440,3 +443,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,69 @@ 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");
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); 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");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { const borderBottom = this.add.graphics();
font: '900 24px Quicksand', const x = 0; const y = 54;
fill: '#05b3a4', const lineWidth = window.innerWidth;
backgroundColor : '#7c4c23', borderBottom.lineStyle(1, 0x0348A8);
padding: {x: 10, y: 10}, borderBottom.setAlpha(0.2);
shadow: { borderBottom.beginPath();
offsetX : 2, borderBottom.moveTo(x, y);
offsetY : 2, borderBottom.lineTo(x + lineWidth, y);
color: '#000', borderBottom.strokePath();
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 : 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
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(animatedFScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedFHeight, 'animatedF').setDepth(2).setScale(animatedFScale);
// Play the video // Play the video
@@ -254,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, 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 +285,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 +295,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);
@@ -369,31 +387,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);
}) })
} }
@@ -401,3 +403,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,71 @@ 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");
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
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); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
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 +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, 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 +286,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);
@@ -333,31 +357,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);
}) })
} }
@@ -366,3 +374,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,71 @@ 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");
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: H', {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 : H', { font: `900 ${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 +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 + 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 +285,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 +295,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);
@@ -373,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); 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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();
@@ -112,135 +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('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");
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); 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 : 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); 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);
// 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
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(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);
@@ -372,31 +391,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);
}) })
} }
@@ -404,3 +406,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -107,137 +194,70 @@ 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");
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); 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");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { const borderBottom = this.add.graphics();
font: '900 24px Quicksand', const x = 0; const y = 54;
fill: '#05b3a4', const lineWidth = window.innerWidth;
backgroundColor : '#7c4c23', borderBottom.lineStyle(1, 0x0348A8);
padding: {x: 10, y: 10}, borderBottom.setAlpha(0.2);
shadow: { borderBottom.beginPath();
offsetX : 2, borderBottom.moveTo(x, y);
offsetY : 2, borderBottom.lineTo(x + lineWidth, y);
color: '#000', borderBottom.strokePath();
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 : J", { 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, 'letterJ').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterJ').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterJ').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterJ').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedJ').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedJ').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : J', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: J', {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 : J', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedJHeight, 'animatedJ').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedJHeight, 'animatedJ').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -251,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 Hook',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Hook',{ 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);
@@ -300,33 +320,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);
}) })
} }
function update() { function update() {
@@ -334,3 +336,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
// let x = 100; // let x = 100;
// // Use x // // Use x
@@ -95,6 +160,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 +199,71 @@ 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");
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); 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 : K", { 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 + 50, customHeight / 2 + letterHeight, 'letterK').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 50, customHeight / 2 + letterHeight, 'letterK').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterK').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterK').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedK').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedK').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : K', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: K', {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 : K', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedKHeight, 'animatedK').setDepth(2).setScale(animatedKScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedKHeight, 'animatedK').setDepth(2).setScale(animatedKScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -255,11 +276,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 50, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 50, 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 +289,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 50, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 50, 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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant',{ 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 +299,7 @@ let scoreTotal = 0; let isDrawing = false;
thirdLayer = this.add.image(customWidth / 2 + 50, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale); thirdLayer = this.add.image(customWidth / 2 + 50, 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. Slant', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slant',{ 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);
@@ -371,31 +392,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);
}) })
} }
@@ -403,3 +407,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -114,132 +201,70 @@ 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); 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 : L", { 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, 'letterL').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 30, customHeight / 2 + letterHeight, 'letterL').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterHeight, 'letterL').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterHeight, 'letterL').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedL').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedL').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : L', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: L', {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 : L', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedLHeight, 'animatedL').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedLHeight, 'animatedL').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -253,11 +278,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 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);
@@ -266,7 +291,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 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);
@@ -279,7 +304,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) => {
@@ -302,7 +326,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
@@ -341,30 +364,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);
}) })
} }
@@ -373,3 +381,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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,139 +196,71 @@ 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");
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); 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 : M", { 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, 'letterM').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterM').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterM').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterM').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedM').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedM').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : M', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: M', {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 : M', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedMHeight, 'animatedM').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedMHeight, 'animatedM').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -255,11 +274,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. 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 +288,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. 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 +298,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. Slant', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slant',{ 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);
@@ -289,7 +309,7 @@ let scoreTotal = 0; let isDrawing = false;
fourthLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer4').setScale(letterScale); fourthLayer = this.add.image(customWidth / 2, 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. Slant', { font: '700 40px quicksand', fill: '#05b3a4'}); const fourthTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '4. Slant',{ 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);
@@ -407,30 +427,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);
}) })
} }
@@ -439,3 +443,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
// let x = 100; // let x = 100;
// // Use x // // Use x
@@ -95,6 +160,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();
@@ -119,131 +206,71 @@ 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); 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 : N", { 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, 'letterN').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterN').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterN').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterN').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedN').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedN').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : N', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: N', {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 : N', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedNHeight, 'animatedN').setDepth(2).setScale(animatedNScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedNHeight, 'animatedN').setDepth(2).setScale(animatedNScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -256,11 +283,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 +296,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. 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);
@@ -279,7 +306,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. Slant', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slant',{ 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 +320,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;
@@ -374,30 +399,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);
}) })
} }
@@ -405,3 +414,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -113,133 +200,71 @@ 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); 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 : O", { 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, 'letterO').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterO').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterO').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterO').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedO').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedO').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : O', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: O', {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 : O', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedOHeight, 'animatedO').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedOHeight, 'animatedO').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -253,11 +278,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 / 12 : customWidth * 0.75; textX = isMobile ? customWidth / 12 : 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 Close',{ font: '700 35px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around Close',{ 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);
@@ -308,37 +334,53 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -115,133 +202,70 @@ 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); 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 : P", { 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, 'letterP').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 30, customHeight / 2 + letterHeight, 'letterP').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterP').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterP').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedP').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedP').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : P', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: P', {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 : P', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedPHeight, 'animatedP').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedPHeight, 'animatedP').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -255,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 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 +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 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);
@@ -342,31 +366,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);
}) })
} }
@@ -375,3 +382,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -103,145 +190,78 @@ let scoreTotal = 0; let isDrawing = false;
this.load.svg('letterQ', '/assets/capital-letter/q.svg'); this.load.svg('letterQ', '/assets/capital-letter/q.svg');
this.load.svg('layer1', '/assets/capital-letter/q_l1.svg'); this.load.svg('layer1', '/assets/capital-letter/q_l1.svg');
this.load.svg('layer2', '/assets/capital-letter/q_l2.svg'); this.load.svg('layer2', '/assets/capital-letter/q_l2.svg');
this.load.audio('audioOne', '/assets/audio/tall-down.mp3'); this.load.audio('audioOne', '/assets/audio/hook-around-close.mp3');
this.load.audio('audioTwo', '/assets/audio/slide-around.mp3'); this.load.audio('audioTwo', '/assets/audio/slant.mp3');
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
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");
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); 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 : Q", { 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, 'letterQ').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterQ').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterQ').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterQ').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedQ').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedQ').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : Q', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: Q', {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 : Q', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedQHeight, 'animatedQ').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedQHeight, 'animatedQ').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -255,11 +275,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 Close',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around Close',{ 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 +288,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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant',{ 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);
@@ -281,8 +301,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;
@@ -342,36 +360,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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
// let x = 100; // let x = 100;
// // Use x // // Use x
@@ -97,6 +162,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();
@@ -121,131 +208,70 @@ 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); 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 : R", { 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 + 10, customHeight / 2 + letterHeight, 'letterR').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 10, customHeight / 2 + letterHeight, 'letterR').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 10, customHeight / 2 + letterHeight, 'letterR').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 10, customHeight / 2 + letterHeight, 'letterR').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedR').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedR').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : R', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: R', {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 : R', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedRHeight, 'animatedR').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedRHeight, 'animatedR').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -258,11 +284,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 10, 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 +297,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 10, 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);
@@ -295,8 +321,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;
@@ -390,17 +414,13 @@ let scoreTotal = 0; let isDrawing = false;
} }
}) })
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);
}) })
} }
@@ -408,3 +428,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -107,139 +194,71 @@ 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");
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); 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 : S", { 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, 'letterS').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterS').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterS').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterS').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedS').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedS').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : S', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: S', {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 : S', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedSHeight, 'animatedS').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedSHeight, 'animatedS').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -253,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, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 12 : customWidth * 0.75; textX = isMobile ? customWidth / 12 : 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 Snake',{ font: '700 35px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around Snake',{ 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);
@@ -307,31 +326,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);
}) })
@@ -340,5 +343,41 @@ let scoreTotal = 0; let isDrawing = 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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,137 +196,70 @@ 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");
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); 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 : T", { 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, 'letterT').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterT').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterT').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterT').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedT').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedT').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : T', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: T', {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 : T', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedTHeight, 'animatedT').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedTHeight, 'animatedT').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -253,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, 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);
@@ -266,7 +286,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);
@@ -338,31 +358,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);
}) })
} }
@@ -371,3 +374,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -107,138 +194,70 @@ 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");
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); 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 : U", { 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, 'letterU').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterU').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterU').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterU').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedU').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedU').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : U', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: U', {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 : U', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedUHeight, 'animatedU').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedUHeight, 'animatedU').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -252,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 / 12 : customWidth * 0.75; textX = isMobile ? customWidth / 12 : 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 Curve Up',{ font: '700 35px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down Curve Up',{ 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);
@@ -308,30 +327,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);
}) })
@@ -342,3 +345,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -108,140 +195,72 @@ 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");
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); 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 : V", { 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, 'letterV').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterV').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterV').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterV').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedV').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedV').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : V', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: V', {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 : V', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedVHeight, 'animatedV').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedVHeight, 'animatedV').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -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, 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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant',{ 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, 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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant',{ 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);
@@ -281,8 +300,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;
@@ -304,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
@@ -343,30 +359,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);
}) })
} }
@@ -375,3 +375,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -108,139 +195,71 @@ 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");
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); 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 : W", { 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, 'letterW').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterW').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterW').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterW').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedW').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedW').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : W', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: W', {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 : W', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedWHeight, 'animatedW').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedWHeight, 'animatedW').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -254,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, 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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant',{ 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 +286,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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant',{ 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);
@@ -277,7 +296,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. Slant', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slant',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioThreeAudio = this.sound.add('audioOne'); const audioThreeAudio = this.sound.add('audioOne');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@@ -288,7 +307,7 @@ let scoreTotal = 0; let isDrawing = false;
fourthLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer4').setScale(letterScale); fourthLayer = this.add.image(customWidth / 2, 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. Slant', { font: '700 40px quicksand', fill: '#05b3a4'}); const fourthTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '4. Slant',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioFourthAudio = this.sound.add('audioOne'); const audioFourthAudio = this.sound.add('audioOne');
fourthTextLayer.setVisible(false); fourthTextLayer.setVisible(false);
fourthLayer.setDepth(1.1); fourthLayer.setDepth(1.1);
@@ -406,37 +425,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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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,138 +196,70 @@ 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");
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); 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 : X", { 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, 'letterX').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterX').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterX').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterX').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedX').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedX').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : X', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: X', {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 : X', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedXHeight, 'animatedX').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedXHeight, 'animatedX').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -254,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, 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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant',{ 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 +286,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. 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);
@@ -280,8 +299,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;
@@ -341,31 +358,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);
}) })
} }
@@ -374,3 +374,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
// let x = 100; // let x = 100;
// // Use x // // Use x
@@ -95,6 +160,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();
@@ -113,136 +200,70 @@ 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");
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); 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 : Y", { 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 - 10, customHeight / 2 + letterHeight, 'letterY').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'letterY').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'letterY').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'letterY').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedY').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedY').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : Y', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: Y', {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 : Y', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedYHeight, 'animatedY').setDepth(2).setScale(animatedYScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedYHeight, 'animatedY').setDepth(2).setScale(animatedYScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -255,12 +276,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 10, 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 Right',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant Right',{ 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);
@@ -268,7 +288,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 10, 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 Left',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant Left',{ 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 +298,7 @@ let scoreTotal = 0; let isDrawing = false;
thirdLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale); thirdLayer = this.add.image(customWidth / 2 - 10, 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. Down', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Down',{ 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);
@@ -292,8 +312,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;
@@ -373,31 +391,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);
}) })
} }
@@ -405,3 +406,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
// let x = 100; // let x = 100;
// // Use x // // Use x
@@ -95,6 +160,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,137 +198,71 @@ let scoreTotal = 0; let isDrawing = false;
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
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.image('backgroundImage', '/assets/bg6.png'); this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image('cloud', '/assets/cloud.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('canvas', '/assets/canvas4.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() {
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); 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 : Z", { 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, 'letterZ').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterZ').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterZ').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterZ').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedZ').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedZ').setDepth(2); canvasStand
firstScreen.setVisible(false); firstScreen.setVisible(false);
// this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale); retryButton.setInteractive().on('pointerdown', () => {
const canvas = this.add.image(customWidth / 2, customHeight / 2 + canvasHeight, 'canvas').setScale(canvasScale); window.location.reload();
// Set up a mask for the drawing area based on the canvas dimensions })
const maskGraphics = this.make.graphics() 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); maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask(); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; let responsiveFontSize = isMobile ? 16 : 32;
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; this.add.text(window.innerWidth / 2, 80, 'Letter: Z', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : Z', { font: `${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 letter : Z', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedZHeight, 'animatedZ').setDepth(2).setScale(animatedZScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedZHeight, 'animatedZ').setDepth(2).setScale(animatedZScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -254,11 +275,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. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slide',{ 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 +288,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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant',{ 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 +298,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('audioOne'); const audioThreeAudio = this.sound.add('audioOne');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@@ -291,8 +312,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;
@@ -354,6 +373,7 @@ let scoreTotal = 0; let isDrawing = false;
graphics = this.add.graphics(); graphics = this.add.graphics();
graphics.setMask(mask);
graphics.setMask(mask); 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) {
@@ -371,31 +391,16 @@ 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);
}) })
} }
@@ -403,3 +408,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -50,13 +115,13 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 30; letterHeight = 30;
letterScale = 1; 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;
animatedAHeight = 32; animatedAHeight = 32;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@@ -73,13 +138,13 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 20; letterHeight = 20;
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;
animatedAHeight = 20; animatedAHeight = 20;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@@ -91,12 +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;
} }
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();
// console.log("Page loaded on: " + formattedDateTime); // console.log("Page loaded on: " + formattedDateTime);
}; };
// let hideButton;
function preload() { function preload() {
this.load.video('animatedA', '/assets/animated-letter/small_a.mp4'); this.load.video('animatedA', '/assets/animated-letter/small_a.mp4');
@@ -109,139 +195,73 @@ 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'); let formattedDateTime; this.load.image("cancelIcon", '/assets/svg/cancel.svg');
let gameStartTime = "start time here"; 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); 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");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { const borderBottom = this.add.graphics();
font: '900 24px Quicksand', const x = 0; const y = 54;
fill: '#05b3a4', const lineWidth = window.innerWidth;
backgroundColor : '#7c4c23', borderBottom.lineStyle(1, 0x0348A8);
padding: {x: 10, y: 10}, borderBottom.setAlpha(0.2);
shadow: { borderBottom.beginPath();
offsetX : 2, borderBottom.moveTo(x, y);
offsetY : 2, borderBottom.lineTo(x + lineWidth, y);
color: '#000', borderBottom.strokePath();
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 : a", { 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, '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);
// 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', () => {
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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: a', {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 : a', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedAHeight, 'animatedA').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedAHeight, 'animatedA').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
@@ -257,11 +277,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 / 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);
@@ -270,7 +290,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. Small Down',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Small 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);
@@ -305,8 +325,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) => {
@@ -344,32 +362,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);
}) })
} }
@@ -378,3 +379,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,69 @@ 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");
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); 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");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { const borderBottom = this.add.graphics();
font: '900 24px Quicksand', const x = 0; const y = 54;
fill: '#05b3a4', const lineWidth = window.innerWidth;
backgroundColor : '#7c4c23', borderBottom.lineStyle(1, 0x0348A8);
padding: {x: 10, y: 10}, borderBottom.setAlpha(0.2);
shadow: { borderBottom.beginPath();
offsetX : 2, borderBottom.moveTo(x, y);
offsetY : 2, borderBottom.lineTo(x + lineWidth, y);
color: '#000', borderBottom.strokePath();
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: b', {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 : b', { font: `900 ${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 +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 / 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 +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. 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);
@@ -342,31 +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); 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,3 +375,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,73 @@ 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() {
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); 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");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { const borderBottom = this.add.graphics();
font: '900 24px Quicksand', const x = 0; const y = 54;
fill: '#05b3a4', const lineWidth = window.innerWidth;
backgroundColor : '#7c4c23', borderBottom.lineStyle(1, 0x0348A8);
padding: {x: 10, y: 10}, borderBottom.setAlpha(0.2);
shadow: { borderBottom.beginPath();
offsetX : 2, borderBottom.moveTo(x, y);
offsetY : 2, borderBottom.lineTo(x + lineWidth, y);
color: '#000', borderBottom.strokePath();
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, '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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
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); 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 +276,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 +292,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;
@@ -313,34 +330,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);
}) })
} }
function update() { function update() {
@@ -348,3 +346,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,80 @@ 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() {
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); 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; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: d', {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 : d', { font: `900 ${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 +285,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 +298,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);
@@ -343,30 +369,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);
}) })
} }
@@ -375,3 +385,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,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('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() {
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: e', {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 : e', { font: `900 ${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 +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 - 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 +292,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 +327,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
@@ -346,30 +365,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);
}) })
} }
@@ -378,3 +382,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,72 @@ 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() {
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
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); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
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 +275,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 +288,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 +300,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;
@@ -343,31 +359,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,3 +376,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,72 @@ 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() {
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); 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
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); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
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);
@@ -259,11 +277,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 +290,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 +324,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) => {
@@ -344,31 +361,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);
}) })
} }
@@ -377,3 +377,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,71 @@ 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");
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); 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', });
// 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
}); });
retryButton.setInteractive().on('pointerdown', () => {
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; window.location.reload();
const baseFontSize = 24; })
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; const maskGraphics = this.make.graphics();
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); maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: h', {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 : h', { font: `900 ${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 +278,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 +291,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 +303,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;
@@ -344,31 +362,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);
}) })
} }
@@ -377,3 +379,40 @@ 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

@@ -3,14 +3,76 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </main>
</Layout> <script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.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,70 @@ 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() {
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); 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");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { const borderBottom = this.add.graphics();
font: '900 24px Quicksand', const x = 0; const y = 54;
fill: '#05b3a4', const lineWidth = window.innerWidth;
backgroundColor : '#7c4c23', borderBottom.lineStyle(1, 0x0348A8);
padding: {x: 10, y: 10}, borderBottom.setAlpha(0.2);
shadow: { borderBottom.beginPath();
offsetX : 2, borderBottom.moveTo(x, y);
offsetY : 2, borderBottom.lineTo(x + lineWidth, y);
color: '#000', borderBottom.strokePath();
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 : 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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
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); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
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 +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 , 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 +287,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 +299,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;
@@ -345,30 +358,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);
}) })
} }
@@ -377,3 +374,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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,140 +198,71 @@ 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");
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); 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 : j", { 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 + letterJeight, 'letterJ').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 20, customHeight / 2 + letterJeight, 'letterJ').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 - 20 , customHeight / 2 + letterJeight, 'letterJ').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 - 20 , customHeight / 2 + letterJeight, 'letterJ').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterJeight, 'animatedJ').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterJeight, 'animatedJ').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : j', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: j', {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 : j', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedJHeight, 'animatedJ').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedJHeight, 'animatedJ').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -258,11 +276,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 + letterJeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterJeight, '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. Down Tail',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Down Tail',{ 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 +289,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterJeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterJeight, '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);
@@ -283,8 +301,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;
@@ -306,7 +322,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
@@ -345,30 +360,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);
}) })
} }
@@ -377,3 +376,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
// let x = 100; // let x = 100;
// // Use x // // Use x
@@ -96,6 +161,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,137 +201,71 @@ 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");
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); 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 : k", { 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, 'letterK').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'letterK').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterK').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterK').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedK').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedK').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); 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 : k', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); retryButton.setInteractive().on('pointerdown', () => {
window.location.reload();
})
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: k', {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 : k', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedKHeight, 'animatedK').setDepth(2).setScale(animatedKScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedKHeight, 'animatedK').setDepth(2).setScale(animatedKScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -257,11 +278,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 +291,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. Slant In',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant In',{ 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);
@@ -280,7 +301,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. Slant Out', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slant Out',{ 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);
@@ -294,8 +315,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;
@@ -375,30 +394,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);
}) })
} }
@@ -406,3 +409,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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,140 +196,70 @@ 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");
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); 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");
submitButton = this.add.text(submitWidth, submitHeight, "Submit", { const borderBottom = this.add.graphics();
font: '900 24px Quicksand', const x = 0; const y = 54;
fill: '#05b3a4', const lineWidth = window.innerWidth;
backgroundColor : '#7c4c23', borderBottom.lineStyle(1, 0x0348A8);
padding: {x: 10, y: 10}, borderBottom.setAlpha(0.2);
shadow: { borderBottom.beginPath();
offsetX : 2, borderBottom.moveTo(x, y);
offsetY : 2, borderBottom.lineTo(x + lineWidth, y);
color: '#000', borderBottom.strokePath();
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 : l", { 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 + 50, customHeight / 2 + letterHeight, 'letterL').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 50, customHeight / 2 + letterHeight, 'letterL').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 50, customHeight / 2 + letterHeight, 'letterL').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 50, customHeight / 2 + letterHeight, 'letterL').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedL').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedL').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : l', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: l', {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 : l', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedLHeight, 'animatedL').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedLHeight, 'animatedL').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -256,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 + 50, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 50, 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);
@@ -272,8 +289,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;
@@ -312,31 +327,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);
}) })
@@ -347,3 +345,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
// let x = 100; // let x = 100;
// // Use x // // Use x
@@ -54,14 +119,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.14 canvasScale = 0.14
canvasHeight = 35; canvasHeight = 35;
letterHeight = 50; letterHeight = 50;
letterScale = 1.1; 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;
animatedMHeight = 35; animatedMHeight = 35;
animatedMScale = 0.5; animatedMScale = 0.7;
helpButtonHeight = customHeight / 1.1; helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10; helpButtonWidth = customWidth / 2 + 10;
@@ -77,14 +142,14 @@ let scoreTotal = 0; let isDrawing = false;
canvasScale = 0.195; canvasScale = 0.195;
canvasHeight = 20; canvasHeight = 20;
letterHeight = 40; letterHeight = 40;
letterScale = 1.3; 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;
animatedMHeight = 20; animatedMHeight = 20;
animatedMScale = 0.6; animatedMScale = 0.8;
helpButtonHeight = customHeight / 2 + 40; helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32; helpButtonWidth = customWidth / 1.32;
@@ -95,6 +160,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 +199,70 @@ 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");
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); 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 : m", { 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, 'letterM').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterM').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterM').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterM').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedM').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedM').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); 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; retryButton.setInteractive().on('pointerdown', () => {
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : m', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); window.location.reload();
})
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: m', {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 : m', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedMHeight, 'animatedM').setDepth(2).setScale(animatedMScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedMHeight, 'animatedM').setDepth(2).setScale(animatedMScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -255,11 +275,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 / 5 : customWidth * 0.75; textX = isMobile ? customWidth / 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);
@@ -268,7 +288,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. 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);
@@ -278,7 +298,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. Roll Down', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Roll Down',{ 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);
@@ -373,30 +393,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);
}) })
} }
@@ -404,3 +409,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
letterNeight = 50; letterNeight = 50;
letterScale = 1.4; 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.63; animatedVideoScale = 0.7;
animatedNHeight = 32; animatedNHeight = 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;
letterNeight = 30; letterNeight = 30;
letterScale = 1.5; 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.65; animatedVideoScale = 0.7;
animatedNHeight = 20; animatedNHeight = 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,140 +198,71 @@ 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");
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); 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 : n", { 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 + 60, customHeight / 2 + letterNeight, 'letterN').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 60, customHeight / 2 + letterNeight, 'letterN').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 60, customHeight / 2 + letterNeight, 'letterN').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 60, customHeight / 2 + letterNeight, 'letterN').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterNeight, 'animatedN').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterNeight, 'animatedN').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : n', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: n', {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 : n', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedNHeight, 'animatedN').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedNHeight, 'animatedN').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -258,11 +276,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 60, customHeight / 2 + letterNeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 60, customHeight / 2 + letterNeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 5 : customWidth * 0.75; textX = isMobile ? customWidth / 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);
@@ -271,7 +289,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 60, customHeight / 2 + letterNeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 60, customHeight / 2 + letterNeight, '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 +301,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;
@@ -344,30 +360,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,3 +376,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -50,7 +115,7 @@ 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.6;
backgroundScale = 0.8; backgroundScale = 0.8;
sunScale = 0.1; sunScale = 0.1;
sunScalePlus = 0.15; sunScalePlus = 0.15;
@@ -73,7 +138,7 @@ 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.6;
backgroundScale = 1; backgroundScale = 1;
sunScale = 0.2; sunScale = 0.2;
sunScalePlus = 0.25; sunScalePlus = 0.25;
@@ -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();
@@ -107,141 +194,71 @@ 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() {
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); 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 : o", { 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, 'letterO').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterO').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterO').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterO').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedO').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedO').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
retryButton.setInteractive().on('pointerdown', () => {
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; window.location.reload();
const baseFontSize = 24; })
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; const maskGraphics = this.make.graphics();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : o', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: o', {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 : o', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedOHeight, 'animatedO').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedOHeight, 'animatedO').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -255,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, 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 Close',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around Close',{ 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,8 +288,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;
@@ -311,30 +326,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);
}) })
} }
@@ -343,3 +342,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,
@@ -21,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: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -39,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;
@@ -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();
@@ -108,140 +195,71 @@ 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");
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); 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 : p", { 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 + letterPeight, 'letterP').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 30, customHeight / 2 + letterPeight, 'letterP').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterPeight, 'letterP').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterPeight, 'letterP').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterPeight, 'animatedP').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterPeight, 'animatedP').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : p', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: p', {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 : p', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedPHeight, 'animatedP').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedPHeight, 'animatedP').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -255,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 + 30, customHeight / 2 + letterPeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterPeight, '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. Down Tail',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Down Tail',{ 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 +286,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterPeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterPeight, '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);
@@ -339,30 +357,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);
}) })
} }
@@ -371,3 +373,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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,
@@ -21,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: 0xebedea,
scale: { scale: {
mode: Phaser.Scale.FIT, mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY, autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -39,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;
@@ -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();
@@ -116,134 +203,70 @@ 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); 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 : q", { 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 - 45, customHeight / 2 + letterQeight, 'letterQ').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 45, customHeight / 2 + letterQeight, 'letterQ').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 - 45, customHeight / 2 + letterQeight, 'letterQ').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 - 45, customHeight / 2 + letterQeight, 'letterQ').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterQeight, 'animatedQ').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterQeight, 'animatedQ').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); 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 : p', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedQHeight, 'animatedQ').setDepth(2).setScale(animatedVideoScale);
}
})
retryButton.setInteractive().on('pointerdown', () => {
window.location.reload();
})
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: q', {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 : q', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedQHeight, 'animatedQ').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
animatedLetter.play(); animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -257,11 +280,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; - 35 let textX, textY; - 35
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 45, customHeight / 2 + letterQeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 45, customHeight / 2 + letterQeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 6.5 : customWidth * 0.75; textX = isMobile ? customWidth / 6.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. 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);
@@ -270,7 +293,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 45, customHeight / 2 + letterQeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 45, customHeight / 2 + letterQeight, '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 Hook',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Down Hook',{ 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 +305,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;
@@ -342,35 +363,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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
letterReight = 20; letterReight = 20;
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;
animatedRHeight = 32; animatedRHeight = 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;
letterReight = -10; letterReight = -10;
letterScale = 1.2; 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.6; animatedVideoScale = 0.7;
animatedRHeight = 20; animatedRHeight = 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,70 @@ 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() {
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); 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 : r", { 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 + 40, customHeight / 2 + letterReight, 'letterR').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 40, customHeight / 2 + letterReight, 'letterR').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterReight, 'letterR').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterReight, 'letterR').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterReight, 'animatedR').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterReight, 'animatedR').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : r', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: r', {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 : r', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedRHeight, 'animatedR').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedRHeight, 'animatedR').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -259,11 +275,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 + letterReight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterReight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 5 : customWidth * 0.75; textX = isMobile ? customWidth / 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 +288,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterReight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterReight, '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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Roll',{ 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 +300,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;
@@ -345,30 +359,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);
}) })
} }
@@ -377,3 +375,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -114,134 +201,71 @@ 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); 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 : s", { 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, 'letterS').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterS').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterS').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 90, customHeight / 2 + letterHeight, 'letterS').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedS').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedS').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : s', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: s', {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 : s', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedSHeight, 'animatedS').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedSHeight, 'animatedS').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -255,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, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 13 : customWidth * 0.75; textX = isMobile ? customWidth / 13 : 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 Snake',{ font: '700 35px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around Snake',{ 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);
@@ -307,30 +331,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);
}) })
@@ -341,3 +349,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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('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() {
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); 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();
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 : t", { 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 + letterTeight, 'letterR').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterTeight, 'letterR').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 , customHeight / 2 + letterTeight, 'letterR').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 , customHeight / 2 + letterTeight, 'letterR').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterTeight, 'animatedT').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterTeight, 'animatedT').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
}); });
retryButton.setInteractive().on('pointerdown', () => {
window.location.reload();
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; const maskGraphics = this.make.graphics();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : t', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: t', {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 : t', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedTHeight, 'animatedT').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedTHeight, 'animatedT').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 , customHeight / 2 + letterTeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterTeight, '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);
@@ -272,7 +286,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterTeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterTeight, '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);
@@ -344,30 +358,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', document.getElementById('beforeStartBtn').addEventListener('click', function() {
fill: '#05b3a4', document.getElementById('blurDisplay').classList.add('hidden');
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(); 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,3 +374,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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,140 +198,71 @@ 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");
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); 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 : u", { 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 + letterUeight, 'letterU').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 + 20, customHeight / 2 + letterUeight, 'letterU').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterUeight, 'letterU').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterUeight, 'letterU').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterUeight, 'animatedU').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterUeight, 'animatedU').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : u', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: u', {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 : u', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedUHeight, 'animatedU').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedUHeight, 'animatedU').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -258,11 +276,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 + letterUeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterUeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 25 : customWidth * 0.75; textX = isMobile ? customWidth / 25 : customWidth * 0.75;
textY = isMobile ? customHeight / 6 : customHeight / 2.3; textY = isMobile ? customHeight / 6 : customHeight / 2.3;
const firstTextLayer = this.add.text(textX, textY, '1. Small Down Curve Up',{ font: '700 35px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Small Down Curve Up',{ 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 +289,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterUeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterUeight, '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. Small Down',{ font: '700 35px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Small 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 +301,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;
@@ -344,30 +360,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,3 +376,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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();
@@ -110,140 +197,69 @@ 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() {
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); 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 : v", { 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 + letterVHeight, 'letterV').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterVHeight, 'letterV').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 , customHeight / 2 + letterVHeight, 'letterV').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 , customHeight / 2 + letterVHeight, 'letterV').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterVHeight, 'animatedV').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterVHeight, 'animatedV').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
}); });
retryButton.setInteractive().on('pointerdown', () => {
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; window.location.reload();
const baseFontSize = 24; })
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; const maskGraphics = this.make.graphics();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : v', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: v', {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 : v', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedVHeight, 'animatedV').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedVHeight, 'animatedV').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
@@ -259,11 +275,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 + letterVHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterVHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 + 30 : customWidth * 0.75; textX = isMobile ? customWidth / 4 + 30 : 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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant',{ 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 +288,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterVHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterVHeight, '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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant',{ 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);
@@ -284,8 +300,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;
@@ -345,30 +359,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);
}) })
} }
@@ -377,3 +375,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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,142 +196,69 @@ let scoreTotal = 0; let isDrawing = false;
this.load.image('topLogo', '/assets/top_logo.svg'); this.load.image('topLogo', '/assets/top_logo.svg');
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.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() {
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); 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 : w", { 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, 'letterW').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterW').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterW').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterW').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedW').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedW').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : w', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: w', {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 : w', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedWHeight, 'animatedW').setDepth(2).setScale(animatedVideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedWHeight, 'animatedW').setDepth(2).setScale(animatedVideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -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, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 + 40: customWidth * 0.75; textX = isMobile ? customWidth / 4 + 40: 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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant',{ 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, 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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant',{ 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);
@@ -281,7 +295,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. Slant', { font: '700 40px quicksand', fill: '#05b3a4'}); const thirdTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '3. Slant',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioThreeAudio = this.sound.add('audioOne'); const audioThreeAudio = this.sound.add('audioOne');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@@ -292,7 +306,7 @@ let scoreTotal = 0; let isDrawing = false;
fourthLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer4').setScale(letterScale); fourthLayer = this.add.image(customWidth / 2, 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. Slant', { font: '700 40px quicksand', fill: '#05b3a4'}); const fourthTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '4. Slant',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const audioFourthAudio = this.sound.add('audioOne'); const audioFourthAudio = this.sound.add('audioOne');
fourthTextLayer.setVisible(false); fourthTextLayer.setVisible(false);
fourthLayer.setDepth(1.1); fourthLayer.setDepth(1.1);
@@ -410,33 +424,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);
}) })
} }
function update() { function update() {
@@ -444,3 +440,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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,70 @@ 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() {
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); 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 : x", { 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 + letterXHeight, 'letterX').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2, customHeight / 2 + letterXHeight, 'letterX').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 , customHeight / 2 + letterXHeight, 'letterX').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 , customHeight / 2 + letterXHeight, 'letterX').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterXHeight, 'animatedX').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterXHeight, 'animatedX').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; })
const baseFontSize = 24; retryButton.setInteractive().on('pointerdown', () => {
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; window.location.reload();
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : x', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); })
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: x', {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 : x', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedXHeight, 'animatedX').setDepth(2).setScale(animatedXideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedXHeight, 'animatedX').setDepth(2).setScale(animatedXideoScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -259,11 +275,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 + letterXHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterXHeight, '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',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant',{ 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 +288,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterXHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterXHeight, '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);
@@ -284,8 +300,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;
@@ -345,30 +359,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);
}) })
} }
@@ -377,3 +376,40 @@ 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

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
@@ -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,70 @@ 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");
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); 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 : y", { 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 - 10, customHeight / 2 + letterYHeight, 'letterY').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 10, customHeight / 2 + letterYHeight, 'letterY').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterYHeight, 'letterY').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterYHeight, 'letterY').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterYHeight, 'animatedY').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterYHeight, 'animatedY').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); animatedLetter.setVisible(true);
}); firstScreen.setVisible(true);
}
})
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2; retryButton.setInteractive().on('pointerdown', () => {
const baseFontSize = 24; window.location.reload();
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize; })
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : y', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: y', {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 : y', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedYHeight, 'animatedY').setDepth(2).setScale(animatedYideoScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedYHeight, 'animatedY').setDepth(2).setScale(animatedYideoScale);
// Play the video // Play the video
@@ -258,11 +277,11 @@ let scoreTotal = 0; let isDrawing = false;
}); });
let textX, textY; let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterYHeight, 'layer1').setScale(letterScale); firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterYHeight, '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 Right',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant Right',{ 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 +290,7 @@ let scoreTotal = 0; let isDrawing = false;
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterYHeight, 'layer2').setScale(letterScale); secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterYHeight, '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 Tail',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant 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);
@@ -283,8 +302,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;
@@ -344,32 +361,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);
}) })
} }
function update() { function update() {
@@ -377,3 +377,40 @@ 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

@@ -0,0 +1,413 @@
---
import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<main>
<div>
</div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
const isMobile = window.innerWidth <= 768;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
width: isMobile ? window.innerWidth : window.innerWidth / 2,
height: window.innerHeight / 2,
};
const config = {
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
},
scene: {
preload: preload,
create: create,
update: update
}
};
// backgroundImage.png
const game = new Phaser.Game(config);
const customWidth = window.innerWidth;
const customHeight = window.innerHeight;
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
// let x = 100;
// // Use x
// console.log(x);
if(isMobile){
cloudeSize = 200;
cloudHeight = 340;
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 70;
letterScale = 0.92;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedZHeight = 35;
animatedZScale = 0.65;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
startButtonHeight = customHeight / 1.1;
startButtonWidth = customWidth / 2 - 100;
submitWidth = customWidth / 2 - 100;
submitHeight = customHeight / 1.1;
noticeWidth = window.innerWidth * 0.5 - 100;
noticeHeight = window.innerHeight * 0.38;
} else{
cloudeSize = 500;
cloudHeight = 250;
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 50;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedZHeight = 20;
animatedZScale = 0.73;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
startButtonHeight = customHeight / 2 - 20;
startButtonWidth = customWidth / 1.32;
submitWidth = customWidth / 1.32;
submitHeight = customHeight / 2 - 20;
noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32;
};
window.onload = function() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
// console.log("Page loaded on: " + formattedDateTime);
};
function preload() {
this.load.video('animatedZ', '/assets/animated-letter/capital_z.mp4');
this.load.svg('letterZ', '/assets/capital-letter/z.svg');
this.load.svg('layer1', '/assets/capital-letter/z_l1.svg');
this.load.svg('layer2', '/assets/capital-letter/z_l2.svg');
this.load.svg('layer3', '/assets/capital-letter/z_l3.svg');
this.load.audio('audioOne', '/assets/audio/slide.mp3');
this.load.audio('audioTwo', '/assets/audio/slant.mp3');
this.load.image('topLogo', '/assets/top_logo.svg');
this.load.svg('succesImage', '/assets/svg/tick.svg');
this.load.svg('hintImage', '/assets/svg/hint.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');
}
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);
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', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
submitUserData(this);
})
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : Z", { 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, 'letterZ').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterZ').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedZ').setDepth(2); canvasStand
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 width = customWidth; // Set your desired width
const height = customHeight;
const maskGraphics = this.make.graphics()
maskGraphics.fillRect(
customWidth / 2 - width / 2,
50, // Offset the rectangle to start 150px from the top
width,
height
);
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
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 : Z', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedZHeight, 'animatedZ').setDepth(2).setScale(animatedZScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
// You can set additional properties for the video, such as loop and mute:
animatedLetter.setLoop(true); // Loop the video
animatedLetter.setMute(false); // Unmute the video
animatedLetter.on('complete', function () {
// add function after end video;
});
let textX, textY;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
firstLayer.setAlpha(0.5);
firstLayer.setInteractive({ draggable: true });
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
const secondTextLayer = this.add.text(textX, textY, '2. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
secondLayer.setAlpha(0.5);
secondLayer.setInteractive({ draggable: true });
secondLayer.setVisible(false);
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
const thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioOne');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
// thirdLayer.setScale(1.15);
thirdLayer.setAlpha(0.5);
thirdLayer.setInteractive({ draggable: true });
thirdLayer.setVisible(false);
// Add these variables to keep track of start points
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
let thirdDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
firstDragStartPoint.y = pointer.y;
});
firstLayer.on('drag', (pointer) => {
const distance = Phaser.Math.Distance.Between(firstDragStartPoint.x, firstDragStartPoint.y, pointer.x, pointer.y);
if (distance >= 100) {
firstTextLayer.setVisible(false);
secondTextLayer.setVisible(true);
audioTwoAudio.play();
secondLayer.setVisible(true);
firstLayer.setAlpha(1);
secondLayer.setAlpha(0.5);
thirdLayer.setAlpha(0.5);
} else {
firstLayer.setAlpha(0.5);
}
});
secondLayer.on('dragstart', (pointer) => {
secondDragStartPoint.x = pointer.x;
secondDragStartPoint.y = pointer.y;
});
secondLayer.on('drag', (pointer) => {
const distance = Phaser.Math.Distance.Between(secondDragStartPoint.x, secondDragStartPoint.y, pointer.x, pointer.y);
if (distance >= 100) {
secondTextLayer.setVisible(false);
thirdTextLayer.setVisible(true);
audioThreeAudio.play();
thirdLayer.setVisible(true);
secondLayer.setAlpha(1);
thirdLayer.setAlpha(0.5);
} else {
secondLayer.setAlpha(0.5);
}
});
// Add this code for thirdLayer
thirdLayer.on('dragstart', (pointer) => {
thirdDragStartPoint.x = pointer.x;
thirdDragStartPoint.y = pointer.y;
});
thirdLayer.on('drag', (pointer) => {
const distance = Phaser.Math.Distance.Between(thirdDragStartPoint.x, thirdDragStartPoint.y, pointer.x, pointer.y);
if (distance >= 100) {
thirdLayer.setAlpha(1);
thirdTextLayer.setVisible(false);
} else {
thirdLayer.setAlpha(0.5);
}
});
graphics = this.add.graphics();
graphics.setMask(mask);
graphics.setMask(mask);
graphics.lineStyle(15, 0xFFFFFF, 2).setDepth(2); // Set line style (width, color, alpha)
this.input.on('pointerdown', function (pointer) {
isDrawing = true;
graphics.moveTo(pointer.x, pointer.y);
// console.log("Start Position", pointer.x, pointer.y)
});
this.input.on('pointerup', function () {
isDrawing = false;
});
this.input.on('pointermove', function (pointer) {
if (!isDrawing) return;
graphics.lineTo(pointer.x, pointer.y);
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);
})
}
function update() {
}
</script>

View File

@@ -3,14 +3,77 @@ 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 class="flex justify-center items-center h-screen ">
<button id="beforeStartBtn" class="bg-[#0348A8] px-10 py-2 rounded-[4px] text-[#FFFFFF] text-[32px] font-[700]">Start</button>
</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> </div>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script> <script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main> </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;
// let x = 100; // let x = 100;
// // Use x // // Use x
@@ -97,6 +162,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,139 +201,71 @@ 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("tickIcon", '/assets/svg/tick2.svg');
this.load.image('sun', '/assets/sun.png'); this.load.image("muteIcon", '/assets/svg/mute.svg');
this.load.image('bgMobile', '/assets/bgMobile.png'); this.load.image("cancelIcon", '/assets/svg/cancel.svg');
this.load.image('canvasStand', '/assets/stand2.png'); 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); 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 : z", { 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, 'letterZ').setAlpha(0.2).setDepth(0.5).setScale(letterScale); this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'letterZ').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterZ').setDepth(2).setScale(letterScale); const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterZ').setDepth(2).setScale(letterScale);
// const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedZ').setDepth(2); canvasStand // const firstScreen = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'animatedZ').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);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
animatedLetter.setVisible(true); 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 : z', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5); retryButton.setInteractive().on('pointerdown', () => {
window.location.reload();
})
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
const mask = maskGraphics.createGeometryMask();
let responsiveFontSize = isMobile ? 16 : 32;
this.add.text(window.innerWidth / 2, 80, 'Letter: z', {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 : z', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedZHeight, 'animatedZ').setDepth(2).setScale(animatedZScale); animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedZHeight, 'animatedZ').setDepth(2).setScale(animatedZScale);
// Play the video // Play the video
// animatedLetter.play(); // animatedLetter.play();
animatedLetter.setVisible(false); animatedLetter.setVisible(false);
@@ -259,11 +278,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 + 40 : customWidth * 0.75; textX = isMobile ? customWidth / 4 + 40 : 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. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'}); const firstTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slide',{ 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 +291,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. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'}); const secondTextLayer = this.add.text(window.innerWidth / 2, window.innerHeight / 1.2, '2. Slant',{ 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,7 +301,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('audioOne'); const audioThreeAudio = this.sound.add('audioOne');
thirdTextLayer.setVisible(false); thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1); thirdLayer.setDepth(1.1);
@@ -296,8 +315,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;
@@ -377,34 +394,54 @@ 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

@@ -11,10 +11,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause();" id="instructionButton"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4"> <div class="container mx-auto px-4">
<!-- <div class="flex flex-col"> <!-- <div class="flex flex-col">
<p id="LearningArea"></p> <p id="LearningArea"></p>
<p id="LearningSubArea_copy"></p> <p id="LearningSubArea"></p>
</div> --> </div> -->
<p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p> <p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p>
<form id="contactForm"> <form id="contactForm">
@@ -102,8 +102,8 @@ import Layout from "../../layouts/Layout.astro";
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -111,9 +111,31 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -173,7 +195,12 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
// console.log(gameData) let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(audioLink)
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){ if(gameData.label1){
document.getElementById("label1").innerHTML = gameData.label1; document.getElementById("label1").innerHTML = gameData.label1;
@@ -193,14 +220,13 @@ import Layout from "../../layouts/Layout.astro";
if(gameData.label6){ if(gameData.label6){
document.getElementById("label6").innerHTML = gameData.label6; document.getElementById("label6").innerHTML = gameData.label6;
} }
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/'; const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 6; i++) { for (let i = 1; i <= 6; i++) {
const imageId = `image${i}`; const imageId = `image${i}`;
document.getElementById(imageId).src = assetsURL + gameData[imageId]; document.getElementById(imageId).src = assetsURL + gameData[imageId];
} }
}); });
function checkResult2(id) { function checkResult2(id) {
@@ -324,7 +350,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -408,7 +434,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23; color: #7C4C23;
padding-top: 10px; padding-top: 10px;
} }
#LearningArea, #LearningSubArea_copy{ #LearningArea, #LearningSubArea{
font-size: 20px; font-size: 20px;
color: #7C4C23; color: #7C4C23;
font-weight: bold; font-weight: bold;

View File

@@ -11,10 +11,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4"> <div class="container mx-auto px-4">
<!-- <div class="flex flex-col"> <!-- <div class="flex flex-col">
<p id="LearningArea"></p> <p id="LearningArea"></p>
<p id="LearningSubArea_copy"></p> <p id="LearningSubArea"></p>
</div> --> </div> -->
<p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p> <p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p>
<form id="contactForm" class="flex flex-col justify-center"> <form id="contactForm" class="flex flex-col justify-center">
@@ -126,8 +126,8 @@ import Layout from "../../layouts/Layout.astro";
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -135,9 +135,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -196,6 +217,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){ if(gameData.label1){
@@ -226,7 +251,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label9").innerHTML = gameData.label9; document.getElementById("label9").innerHTML = gameData.label9;
} }
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea; // document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy; // document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/'; const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 9; i++) { for (let i = 1; i <= 9; i++) {
const imageId = `image${i}`; const imageId = `image${i}`;
@@ -353,7 +378,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -435,7 +460,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23; color: #7C4C23;
padding-top: 10px; padding-top: 10px;
} }
#LearningArea, #LearningSubArea_copy{ #LearningArea, #LearningSubArea{
font-size: 20px; font-size: 20px;
color: #7C4C23; color: #7C4C23;
font-weight: bold; font-weight: bold;

View File

@@ -12,11 +12,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
</div> </div>
@@ -84,8 +83,8 @@ import Layout from "../../layouts/Layout.astro";
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame();" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -93,9 +92,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -154,6 +174,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameLabel").innerHTML = gameData.label; document.getElementById("gameLabel").innerHTML = gameData.label;
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
@@ -276,7 +300,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.fontWeight = '600'; calculationText.style.fontWeight = '600';
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'

View File

@@ -11,10 +11,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
@@ -99,8 +99,8 @@ import Layout from "../../layouts/Layout.astro";
<p id="starFeedbackMessage" 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%);"></p> <p id="starFeedbackMessage" 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%);"></p>
</div> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame()" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -108,9 +108,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -131,6 +152,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){ if(gameData.label1){
@@ -152,7 +177,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label6").innerHTML = gameData.label6; document.getElementById("label6").innerHTML = gameData.label6;
} }
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea; // document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy; // document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/'; const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 6; i++) { for (let i = 1; i <= 6; i++) {
@@ -318,7 +343,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -396,7 +421,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23; color: #7C4C23;
padding-top: 10px; padding-top: 10px;
} }
#LearningArea, #LearningSubArea_copy{ #LearningArea, #LearningSubArea{
font-size: 20px; font-size: 20px;
color: #7C4C23; color: #7C4C23;
font-weight: bold; font-weight: bold;

View File

@@ -11,10 +11,10 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none"> <img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4"> <div class="container mx-auto px-4">
<!-- <div class="flex flex-col"> <!-- <div class="flex flex-col">
<p id="LearningArea"></p> <p id="LearningArea"></p>
<p id="LearningSubArea_copy"></p> <p id="LearningSubArea"></p>
</div> --> </div> -->
<p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p> <p class="sm:text-2xl md:text-3xl lg:text-4xl text-center font-[600] text-[#60C6CB] my-4 select-none" id="gameDescription"></p>
<form id="contactForm" class="flex flex-col justify-center"> <form id="contactForm" class="flex flex-col justify-center">
@@ -125,8 +125,8 @@ import Layout from "../../layouts/Layout.astro";
<img class="z-10" src="/assets/clip-art.svg" alt="" /> <img class="z-10" src="/assets/clip-art.svg" alt="" />
<p id="starFeedbackMessage" 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%);"></p> </div> <p id="starFeedbackMessage" 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%);"></p> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame()" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -134,9 +134,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -193,6 +214,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){ if(gameData.label1){
@@ -223,7 +248,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label9").innerHTML = gameData.label9; document.getElementById("label9").innerHTML = gameData.label9;
} }
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea; // document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy; // document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/'; const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 9; i++) { for (let i = 1; i <= 9; i++) {
const imageId = `image${i}`; const imageId = `image${i}`;
@@ -360,7 +385,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -437,7 +462,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23; color: #7C4C23;
padding-top: 10px; padding-top: 10px;
} }
#LearningArea, #LearningSubArea_copy{ #LearningArea, #LearningSubArea{
font-size: 20px; font-size: 20px;
color: #7C4C23; color: #7C4C23;
font-weight: bold; font-weight: bold;

View File

@@ -13,9 +13,9 @@ import Layout from "../../layouts/Layout.astro";
</div> </div>
<div class="flex flex-row space-x-1 pb-2"> <div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button> <button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button> <button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button> <button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button> <button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
</div> </div>
</div> </div>
<!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> --> <!-- <input onclick="saveUserData();" class="bg-blue-700 px-8 py-2 rounded-lg shadow-lg font-bold text-white cursor-pointer" type="submit" value="Submit"> -->
@@ -84,8 +84,8 @@ import Layout from "../../layouts/Layout.astro";
<img class="z-10" src="/assets/clip-art.svg" alt="" /> <img class="z-10" src="/assets/clip-art.svg" alt="" />
<p id="starFeedbackMessage" 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%);"></p> </div> <p id="starFeedbackMessage" 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%);"></p> </div>
<div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3"> <div class="flex flex-col w-full max-w-sm items-center justify-center mx-auto gap-3">
<button 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 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> <button onclick="retryGame()" class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div> </div>
</div> </div>
</div> </div>
@@ -93,9 +93,30 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art"> <img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</div> </div>
</div> </div>
<div>
<audio id="audioPlayer" controls class="hidden">
<source id="instrucAudio1" src="" type="audio/ogg">
<source id="instrucAudio2" src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</main> </main>
</Layout> </Layout>
<script is:inline> <script is:inline>
let isPlaying = false;
function audioPlayAndPause(){
if(isPlaying === false){
document.getElementById('audioPlayer').play();
isPlaying = true;
}else if(isPlaying === true){
document.getElementById('audioPlayer').pause();
document.getElementById('audioPlayer').currentTime = 0;
isPlaying = false;
}
}
function retryGame(){
window.location.reload();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const gameId = params.get('id'); const gameId = params.get('id');
const userId = params.get('userId'); const userId = params.get('userId');
@@ -121,6 +142,10 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
gameData = data.data; gameData = data.data;
let audioLink = `https://game-du.teachertrainingkolkata.in/assets/${gameData.instruction}.mp3`;
document.getElementById('instrucAudio1').src = audioLink;
document.getElementById('instrucAudio2').src = audioLink;
document.querySelector('audio').load();
// console.log(gameData) // console.log(gameData)
document.getElementById("gameLabel").innerHTML = gameData.label; document.getElementById("gameLabel").innerHTML = gameData.label;
document.getElementById("gameDescription").innerHTML = gameData.description; document.getElementById("gameDescription").innerHTML = gameData.description;
@@ -287,7 +312,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)'; calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText); containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, { fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'

View File

@@ -0,0 +1,28 @@
<div>
<audio controls>
<source src="horse.ogg" type="audio/ogg">
<source id="audioFile" src="horse.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
<script is:inline>
fetch('https://game-du.teachertrainingkolkata.in/items/game_drag/19')
.then(response => response.json())
.then(responseData => {
console.log(responseData); // Log the full response
// Check if the data contains the 'instruction' field
const instructionId = responseData.data.instruction;
// Assuming you need to build the full URL from this instruction ID
const audioUrl = `https://game-du.teachertrainingkolkata.in/assets/${instructionId}.mp3`;
console.log(audioUrl)
// Set the audio source dynamically
document.getElementById('audioFile').src = audioUrl;
})
.catch(error => {
console.error('Error fetching audio source:', error);
});
</script>

2
task/27.11.2024.txt Normal file
View File

@@ -0,0 +1,2 @@
Gallery Implement in all drawing games?
The new design for Buzzboard is hard to achieve so its need to develope from base lavel

Some files were not shown because too many files have changed in this diff Show More