9 Commits

101 changed files with 13130 additions and 25278 deletions

8141
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -1,4 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 285 B

View File

@@ -1,6 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 477 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 31 KiB

View File

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

View File

@@ -6,7 +6,7 @@ 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 gameId;
let submitNotic;
console.log(userId);
@@ -194,7 +194,7 @@ function submitUserData(drawingZone) {
'gameStar' : starValue
};
console.log(userData);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'

View File

@@ -1,128 +0,0 @@
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();
});
};

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">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4">
<!-- <div class="flex flex-col">
<p id="LearningArea"></p>
<p id="LearningSubArea"></p>
<p id="LearningSubArea_copy"></p>
</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>
<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>
</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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -99,30 +99,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -143,10 +122,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){
@@ -168,7 +143,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label6").innerHTML = gameData.label6;
}
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 6; i++) {
@@ -336,7 +311,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -455,7 +430,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23;
padding-top: 10px;
}
#LearningArea, #LearningSubArea{
#LearningArea, #LearningSubArea_copy{
font-size: 20px;
color: #7C4C23;
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">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4">
<!-- <div class="flex flex-col">
<p id="LearningArea"></p>
<p id="LearningSubArea"></p>
<p id="LearningSubArea_copy"></p>
</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>
<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>
</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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -117,30 +117,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -160,10 +139,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){
@@ -194,7 +169,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label9").innerHTML = gameData.label9;
}
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 9; i++) {
const imageId = `image${i}`;
@@ -370,7 +345,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -489,7 +464,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23;
padding-top: 10px;
}
#LearningArea, #LearningSubArea{
#LearningArea, #LearningSubArea_copy{
font-size: 20px;
color: #7C4C23;
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">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4">
<!-- <div class="flex flex-col">
<p id="LearningArea"></p>
<p id="LearningSubArea"></p>
<p id="LearningSubArea_copy"></p>
</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>
<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>
</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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -99,30 +99,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -144,10 +123,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){
@@ -169,7 +144,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label6").innerHTML = gameData.label6;
}
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 6; i++) {
@@ -337,7 +312,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
// console.log(userData);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -456,7 +431,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23;
padding-top: 10px;
}
#LearningArea, #LearningSubArea{
#LearningArea, #LearningSubArea_copy{
font-size: 20px;
color: #7C4C23;
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">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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>
</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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -112,30 +112,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -156,10 +135,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){
@@ -356,7 +331,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -476,7 +451,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23;
padding-top: 10px;
}
#LearningArea, #LearningSubArea{
#LearningArea, #LearningSubArea_copy{
font-size: 20px;
color: #7C4C23;
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">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
@@ -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>
</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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -87,30 +87,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -130,10 +109,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameLabel").innerHTML = gameData.label;
document.getElementById("gameDescription").innerHTML = gameData.description;
@@ -307,7 +282,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
// console.log(userData);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'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>
</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="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>
@@ -56,9 +56,6 @@ import Layout from '../../layouts/Layout.astro';
let cancelIconWidth;
let retryButton;
let blockMatches;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){
topLogoWidth = 4.5;
@@ -145,10 +142,6 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drag_drop_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.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;
if(isMobile){
imageCustomWidth = "?width=80";
@@ -246,9 +239,6 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) {
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('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -420,10 +410,10 @@ import Layout from '../../layouts/Layout.astro';
// window.load
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale();
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", {
@@ -442,19 +432,7 @@ import Layout from '../../layouts/Layout.astro';
showAnimation();
})
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){
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>
</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="" 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>
@@ -59,9 +59,6 @@ const numberOfTimes = starNumberOfTime;
let resetIconWidth;
let tickIconWidth;
let cancelIconWidth;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){
topLogoWidth = 4.5;
@@ -171,11 +168,6 @@ const numberOfTimes = starNumberOfTime;
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.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;
if(isMobile){
imageCustomWidth = "?width=100";
@@ -272,9 +264,6 @@ const numberOfTimes = starNumberOfTime;
for (var i = 0; i < 5; i++) {
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('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -351,7 +340,7 @@ const numberOfTimes = starNumberOfTime;
},
];
// this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea, {font: `19px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea_copy, {font: `19px`}).setTint(0x7c4c23);
// Left Image Name
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);
@@ -408,11 +397,18 @@ const numberOfTimes = starNumberOfTime;
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);
// 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();
let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale();
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-32, 340, "target2");
@@ -421,20 +417,6 @@ const numberOfTimes = starNumberOfTime;
// 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-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 = [
{
@@ -483,7 +465,7 @@ const numberOfTimes = starNumberOfTime;
counter++;
return 'borderCorrect';
} else {
// console.log(`Score Total: ${scoreTotal}`);
console.log(`Score Total: ${scoreTotal}`);
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>
</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="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>
@@ -55,9 +55,6 @@ import Layout from '../../layouts/Layout.astro';
let resetIconWidth;
let tickIconWidth;
let cancelIconWidth;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){
topLogoWidth = 4.5;
@@ -150,10 +147,6 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drag_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.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;
if(isMobile){
imageCustomWidth = "?width=100";
@@ -250,9 +243,6 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) {
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('topLogo', '/assets/top_logo.svg');
this.load.image("tick", '/assets/tick.png');
@@ -337,7 +327,7 @@ import Layout from '../../layouts/Layout.astro';
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);
// this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea, {font: `19px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea_copy, {font: `19px`}).setTint(0x7c4c23);
// Left Image Name
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);
@@ -382,10 +372,10 @@ import Layout from '../../layouts/Layout.astro';
// });
// };
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale();
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-32, 340, "target2");
@@ -395,19 +385,6 @@ import Layout from '../../layouts/Layout.astro';
this.add.image(displayW * 0.9-32, 680, "target4");
// 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 x = 0; const y = 54;

View File

@@ -365,7 +365,7 @@ import Layout from '../../layouts/Layout.astro';
fill: '#7c4c23',
}).setOrigin(0.5);
// this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea, {font: `19px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea_copy, {font: `19px`}).setTint(0x7c4c23);
// Left Image Name
this.add.text(leftTargetZoneW - 45, 240, data.left_image1_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>
</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="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>
@@ -56,10 +56,6 @@ import Layout from '../../layouts/Layout.astro';
let tickIconWidth;
let cancelIconWidth;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.8;
@@ -151,11 +147,6 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag_v2/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.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;
if(isMobile){
imageCustomWidth = "?width=100";
@@ -252,9 +243,6 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) {
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('topLogo', '/assets/top_logo.svg');
this.load.image("tick", '/assets/tick.png');
@@ -339,7 +327,7 @@ import Layout from '../../layouts/Layout.astro';
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);
// this.add.text(displayW / 14 - 15, 50, data.LearningArea, {font: `20px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea, {font: `19px`}).setTint(0x7c4c23);
// this.add.text(displayW / 14 - 15, 70, data.LearningSubArea_copy, {font: `19px`}).setTint(0x7c4c23);
// Left Image Name
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);
@@ -384,10 +372,10 @@ import Layout from '../../layouts/Layout.astro';
// });
// };
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale();
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-32, 340, "target2");
@@ -396,19 +384,7 @@ 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-32, 680, "target4");
// 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 x = 0; const y = 54;

View File

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

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>
</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="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>
@@ -59,9 +59,6 @@ import Layout from '../../layouts/Layout.astro';
let blockMatches;
let retryButtonWidth;
let leftTargetZoneW;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){
topLogoWidth = 4.5;
@@ -182,10 +179,6 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag_v3/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.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;
if(isMobile){
imageCustomWidth = "?width=100";
@@ -281,9 +274,6 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) {
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('topLogo', '/assets/top_logo.svg');
this.load.image("tick", '/assets/tick.png');
@@ -432,25 +422,12 @@ import Layout from '../../layouts/Layout.astro';
graphics.strokePath();
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").setScale();
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale().setInteractive().on('pointerdown', () => {history.back()});
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale();
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", {
// font: '600 30px Quicksand',
// 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>
</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="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>
@@ -59,9 +59,6 @@ import Layout from '../../layouts/Layout.astro';
let leftTargetZoneW;
let rightTargetZoneW;
let retryButtonWidth;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){
topLogoWidth = 4.5;
@@ -148,10 +145,6 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag_v4/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.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;
if(isMobile){imageCustomWidth = "?width=100";} else{imageCustomWidth = "?width=100";};
const assetsURL = "https://game-du.teachertrainingkolkata.in/assets/"
@@ -245,9 +238,6 @@ import Layout from '../../layouts/Layout.astro';
for (var i = 0; i < 5; i++) {
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('topLogo', '/assets/top_logo.svg');
// this.load.image("tick", '/assets/tick.png');
@@ -259,6 +249,8 @@ import Layout from '../../layouts/Layout.astro';
// this.load.image("retryIcon", "/assets/svg/retry.svg")
this.load.image("border", '/assets/squar.png');
this.load.spritesheet("blocks1", assetsList.element5,{
frameWidth: 100,
frameHeight: 100,
@@ -413,23 +405,10 @@ import Layout from '../../layouts/Layout.astro';
graphics.strokePath();
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
let soundButton = this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
this.add.image(displayW / muteIconWidth, 30, "muteIcon").setScale();
const retryButton = this.add.image(displayW / resetIconWidth, 30, "resetIcon").setScale();
submitButton = this.add.image(displayW / tickIconWidth, 30, "tickIcon").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
}
})
}
this.add.image(displayW / cancelIconWidth, 30, "cancelIcon").setScale();
// submitButton = this.add.text(window.innerWidth / 2 - buttonWidth, window.innerHeight / 2 - buttonHeight, "Submit", {
// font: '600 30px Quicksand',
// fill: '#fff',

View File

@@ -3,102 +3,14 @@ import Layout from '../../layouts/Layout.astro';
---
<Layout title='Drawing Game'>
<main>
<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>
<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>
<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>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<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 isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
@@ -120,34 +32,24 @@ import Layout from '../../layouts/Layout.astro';
let shortUniqueID;
let scoreTotal = 0;
let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
let galleryIconWidth;
let galleryButton;
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.8;
resetIconWidth = 1.47;
tickIconWidth = 1.24;
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;
}
if(isMobile){
submitWidth = 250;
@@ -192,10 +94,6 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drawing_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
// console.log(data)
// colorList = data.colors;
const {image} = data;
@@ -235,9 +133,6 @@ import Layout from '../../layouts/Layout.astro';
let colorList;
function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('outline', assetsList.image);
this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -247,7 +142,6 @@ import Layout from '../../layouts/Layout.astro';
this.load.svg('buttonIcons', '/assets/svg/button-icon.svg');
this.load.svg('cursorImage', '/assets/svg/pencil.svg');
this.load.image('colorButton', '/assets/color_button.png');
this.load.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
}
function create() {
@@ -281,34 +175,15 @@ import Layout from '../../layouts/Layout.astro';
borderBottom.lineTo(x + lineWidth, y);
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");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
const retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
galleryButton = this.add.image(customWidth / galleryIconWidth, 30, "galleryIcons");
retryButton.setInteractive().on('pointerdown', () => {
graphics.clear();
window.location.reload();
});
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);
// submitButton = this.add.text(window.innerWidth - submitWidth, window.innerHeight - submitHeight, "Submit", {
// font: '600 30px Quicksand',
@@ -318,17 +193,8 @@ import Layout from '../../layouts/Layout.astro';
// });
submitButton.setVisible(true);
submitButton.setInteractive().on('pointerdown', () => {
// windowLoad();
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',};
@@ -350,12 +216,7 @@ import Layout from '../../layouts/Layout.astro';
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.setMask(mask);
const colorContainer = document.createElement('div');
colorContainer.style.position = 'absolute';
colorContainer.style.top = '13%';
@@ -368,16 +229,7 @@ import Layout from '../../layouts/Layout.astro';
}
if(isMobile){
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');
if(!isMobile){
@@ -393,14 +245,6 @@ import Layout from '../../layouts/Layout.astro';
// 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');
colorPicker.type = 'color';
colorPicker.value = selectedColor;
@@ -427,10 +271,7 @@ import Layout from '../../layouts/Layout.astro';
}
});
// Append the color picker to the color container data
colorAndClearContainer.appendChild(colorPicker)
colorAndClearContainer.appendChild(clearButton)
colorContainer.appendChild(colorAndClearContainer);
colorContainer.appendChild(colorPicker);
// const colors = data.colors;
// var colors = colorList;
var colors = isMobile ? ['#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB', '#FFD700'] : ['#FF0000', '#FFFF00', '#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB'];
@@ -658,19 +499,20 @@ import Layout from '../../layouts/Layout.astro';
// buttonsContainer.style.left = `${window.innerWidth * 0.03}px`; // Position 5% from the left edge
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';
// }
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.borderRadius = '20%';
// clearButton.style.boxShadow = '5px 10px 30px #7c4c2390';
@@ -719,7 +561,7 @@ import Layout from '../../layouts/Layout.astro';
}
});
// Add the Clear and Eraser buttons to the container
// buttonsContainer.appendChild(clearButton);
buttonsContainer.appendChild(clearButton);
// colorPicker.appendChild(clearButton);
// buttonsContainer.appendChild(eraserButton).setVisible;
@@ -813,17 +655,10 @@ import Layout from '../../layouts/Layout.astro';
submitButton.setVisible(false);
snapshotButton.setVisible(false);
customCursor.setVisible(false);
muteIcon.setVisible(false);
retryButton.setVisible(false);
galleryButton.setVisible(false);
drawingZone.renderer.snapshot((image) => {
submitButton.setVisible(true);
snapshotButton.setVisible(true);
customCursor.setVisible(true);
muteIcon.setVisible(true);
retryButton.setVisible(true);
galleryButton.setVisible(true);
image.style.width = '160px';
image.style.height = '120px';
image.style.paddingLeft = '2px';
@@ -955,49 +790,12 @@ import Layout from '../../layouts/Layout.astro';
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
};
const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear();
customCursor.lineStyle(1.5, 0x000000);
customCursor.clear(); // Clear the previous frame
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color)
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates
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();
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() {
@@ -1037,30 +835,5 @@ import Layout from '../../layouts/Layout.astro';
.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 */
}
</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,102 +3,14 @@ import Layout from '../../layouts/Layout.astro';
---
<Layout title='Drawing Game'>
<main>
<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>
<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>
<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>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<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 isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
@@ -120,34 +32,24 @@ import Layout from '../../layouts/Layout.astro';
let shortUniqueID;
let scoreTotal = 0;
let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
let galleryIconWidth;
let galleryButton;
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.8;
resetIconWidth = 1.47;
tickIconWidth = 1.24;
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;
}
if(isMobile){
@@ -193,10 +95,6 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/drawing_writo/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
// console.log(data)
// colorList = data.colors;
const {image} = data;
@@ -236,9 +134,6 @@ import Layout from '../../layouts/Layout.astro';
let colorList;
function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('outline', assetsList.image);
this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -248,7 +143,6 @@ import Layout from '../../layouts/Layout.astro';
this.load.svg('buttonIcons', '/assets/svg/button-icon.svg');
this.load.svg('cursorImage', '/assets/svg/pencil.svg');
this.load.image('colorButton', '/assets/color_button.png');
this.load.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
}
function create() {
@@ -272,8 +166,6 @@ import Layout from '../../layouts/Layout.astro';
});
// window.load
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
@@ -284,33 +176,14 @@ import Layout from '../../layouts/Layout.astro';
borderBottom.lineTo(x + lineWidth, y);
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");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
const 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', () => {
graphics.clear();
window.location.reload();
});
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);
@@ -322,18 +195,8 @@ import Layout from '../../layouts/Layout.astro';
// });
submitButton.setVisible(true);
submitButton.setInteractive().on('pointerdown', () => {
// windowLoad();
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',};
@@ -363,12 +226,7 @@ import Layout from '../../layouts/Layout.astro';
// } else{
// 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.setMask(mask);
const colorContainer = document.createElement('div');
colorContainer.style.position = 'absolute';
colorContainer.style.top = '13%';
@@ -381,16 +239,7 @@ import Layout from '../../layouts/Layout.astro';
}
if(isMobile){
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');
if(!isMobile){
@@ -404,14 +253,6 @@ 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
const colorPicker = document.createElement('input');
@@ -440,9 +281,7 @@ import Layout from '../../layouts/Layout.astro';
}
});
// Append the color picker to the color container data
colorAndClearContainer.appendChild(colorPicker)
colorAndClearContainer.appendChild(clearButton)
colorContainer.appendChild(colorAndClearContainer);
colorContainer.appendChild(colorPicker);
// const colors = data.colors;
// var colors = colorList;
var colors = isMobile ? ['#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB', '#FFD700'] : ['#FF0000', '#FFFF00', '#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB'];
@@ -669,6 +508,21 @@ import Layout from '../../layouts/Layout.astro';
buttonsContainer.style.left = '20px';
// buttonsContainer.style.left = `${window.innerWidth * 0.03}px`; // Position 5% from the left edge
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.borderRadius = '20%';
// clearButton.style.boxShadow = '5px 10px 30px #7c4c2390';
@@ -717,7 +571,7 @@ import Layout from '../../layouts/Layout.astro';
}
});
// Add the Clear and Eraser buttons to the container
// buttonsContainer.appendChild(clearButton);
buttonsContainer.appendChild(clearButton);
// colorPicker.appendChild(clearButton);
// buttonsContainer.appendChild(eraserButton).setVisible;
@@ -811,18 +665,10 @@ import Layout from '../../layouts/Layout.astro';
submitButton.setVisible(false);
snapshotButton.setVisible(false);
customCursor.setVisible(false);
muteIcon.setVisible(false);
retryButton.setVisible(false);
galleryButton.setVisible(false);
drawingZone.renderer.snapshot((image) => {
submitButton.setVisible(true);
snapshotButton.setVisible(true);
customCursor.setVisible(true);
muteIcon.setVisible(true);
retryButton.setVisible(true);
galleryButton.setVisible(true);
image.style.width = '160px';
image.style.height = '120px';
image.style.paddingLeft = '2px';
@@ -954,76 +800,50 @@ import Layout from '../../layouts/Layout.astro';
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
};
const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear();
customCursor.lineStyle(1.5, 0x000000);
customCursor.clear(); // Clear the previous frame
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color)
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates
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();
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>
<style>
/* 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 */
.clear-button {
background-color: blue;
}
</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 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>
<button class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -39,7 +39,7 @@ import Layout from '../../layouts/Layout.astro';
</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="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>
@@ -49,6 +49,11 @@ 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="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>
@@ -56,35 +61,38 @@ 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" />
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
<!-- http://localhost:2022/drawing/?id=525&userId=6746c2e9cd3b551fae55cb67&gameName=birdWS1 -->
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<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 = [
{
"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;
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;
@@ -134,10 +142,6 @@ const parsedObject = JSON.parse(retrievedData);
let muteIcon;
let retryButton;
let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.65;
@@ -204,10 +208,6 @@ const parsedObject = JSON.parse(retrievedData);
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drawing/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
// console.log(data)
// colorList = data.colors;
const {image} = data;
@@ -248,9 +248,6 @@ const parsedObject = JSON.parse(retrievedData);
let colorList;
function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('outline', assetsList.image);
this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -300,19 +297,6 @@ const parsedObject = JSON.parse(retrievedData);
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', () => {
// window.location.reload();
@@ -361,14 +345,7 @@ const parsedObject = JSON.parse(retrievedData);
} else{
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.setMask(mask);
const colorContainer = document.createElement('div');
colorContainer.style.zIndex = '1';
colorContainer.style.position = 'absolute';
@@ -724,17 +701,13 @@ const parsedObject = JSON.parse(retrievedData);
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';
eraserButton.style.border = '2px solid #0348A8';
} 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';
}
});
// Add the Clear and Eraser buttons to the container
@@ -863,6 +836,85 @@ const parsedObject = JSON.parse(retrievedData);
});
}
// 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) {
if (!isErasing) {
graphics.lineStyle(brushSize * 2, Phaser.Display.Color.HexStringToColor(selectedColor).color);
@@ -900,49 +952,12 @@ const parsedObject = JSON.parse(retrievedData);
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
};
const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear();
customCursor.lineStyle(1.5, 0x000000);
customCursor.clear(); // Clear the previous frame
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color)
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates
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();
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() {
@@ -1015,3 +1030,4 @@ const parsedObject = JSON.parse(retrievedData);
display: block;
}
</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,98 +3,35 @@ import Layout from '../../layouts/Layout.astro';
---
<Layout title='Drawing Game'>
<main>
<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="loadingMainContainer" class="w-full h-screen bg-[#00000070] absolute" 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 id="scoreBoard" class="z-10 w-full h-screen bg-[#00000070] absolute" style="display: none;">
</div>
<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 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;" />
<img class="z-10" src="/assets/clip-art.svg" alt="" />
<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>
<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 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 class="clip-art-container absolute bottom-0 right-0">
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<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');
@@ -128,34 +65,24 @@ import Layout from '../../layouts/Layout.astro';
let noticeWidth;
let noticeHeight;
let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
let galleryIconWidth;
let galleryButton;
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.8;
resetIconWidth = 1.47;
tickIconWidth = 1.24;
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;
}
if(isMobile){
submitWidth = 250;
@@ -210,10 +137,6 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drawing_v2/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
colorList = data.colors;
defaultColor = colorList[0];
const {image1, image2} = data;
@@ -254,9 +177,6 @@ import Layout from '../../layouts/Layout.astro';
let colorList;
function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('image1', assetsList.image1);
this.load.image('image2', assetsList.image2);
this.load.image('topLogo', '/assets/top_logo.svg');
@@ -268,7 +188,6 @@ import Layout from '../../layouts/Layout.astro';
this.load.svg('cursorImage', '/assets/svg/pencil.svg');
this.load.image('waxTexture', '/assets/texture.png');
this.load.image('colorButton', '/assets/color_button.png');
this.load.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
}
function create() {
@@ -335,32 +254,12 @@ import Layout from '../../layouts/Layout.astro';
const outlineImage1 = this.add.image(customWidth / image1Width, customHeight / image1Height, 'image1');
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");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
const 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', ()=>{
graphics.clear();
window.location.reload();
})
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", {
@@ -369,21 +268,21 @@ import Layout from '../../layouts/Layout.astro';
// backgroundColor: 'blue',
// padding: { x: 20, y: 10 },
// });
submitButton.setVisible(true);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
// windowLoad();
// submitUserData();
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',};
if(!isMobile){
// this.add.text(customWidth / 10, 20, "Drawing", textStyle);
// 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');
}
if(isMobile){
outlineImage1.setDepth(-5).setScale(0.28);
@@ -395,46 +294,29 @@ import Layout from '../../layouts/Layout.astro';
outlineImage1.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.setMask(mask);
const colorContainer = document.createElement('div');
colorContainer.style.zIndex = '1';
colorContainer.style.position = 'absolute';
colorContainer.style.top = '13%';
if(isMobile){
colorContainer.style.marginTop = '13%';
}
colorContainer.style.left = '10px';
colorContainer.style.display = 'flex';
colorContainer.style.marginBottom = '0';
colorContainer.style.marginBottom = '15px';
if(!isMobile){
colorContainer.style.top = '10%';
colorContainer.style.top = '25%';
colorContainer.style.flexDirection = 'column';
}
if(isMobile){
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 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);}
if(!isMobile){
colorViewButton.setVisible(false);
}
colorViewButton.setInteractive().on('pointerdown', () => {
if(colorContainer.style.display === 'block') {
@@ -451,47 +333,17 @@ import Layout from '../../layouts/Layout.astro';
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;
const buttonSize = 60;
const buttonSpacing = 15;
const clearEraserContainer = document.createElement('div');
clearEraserContainer.style.display = 'flex';
clearEraserContainer.style.flexDirection = 'row';
isMobile ? clearEraserContainer.style.marginTop = '-60px' : clearEraserContainer.style.marginTop = '40px';
if(isMobile){
clearEraserContainer.style.marginTop = '-60px';
}else{
clearEraserContainer.style.marginTop = '40px';
}
const colorButtonsContainer = document.createElement('div');
colorButtonsContainer.style.display = 'flex';
colorButtonsContainer.style.flexDirection = 'column';
@@ -696,15 +548,51 @@ import Layout from '../../layouts/Layout.astro';
// Create the Clear button
const clearButton = document.createElement('button');
clearButton.innerHTML ='<img src="/assets/svg/clear.svg">';
clearButton.style.marginTop = !isMobile ? `-10px` :`0px`;
// // clearButton.style.border = '3px solid blue';
// 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', () => {
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';
colorEraserCont.append(eraserButton);
colorEraserCont.append(clearButton);
// buttonsContainer.appendChild(clearEraserContainer);
eraserButton.style.fontWeight = 'bold';
eraserButton.style.borderRadius = '20%';
eraserButton.style.boxShadow = '5px 10px 15px #7c4c2390';
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');
sliderContainer.className = 'slider-container';
@@ -781,17 +669,10 @@ import Layout from '../../layouts/Layout.astro';
submitButton.setVisible(false);
snapshotButton.setVisible(false);
customCursor.setVisible(false);
muteIcon.setVisible(false);
retryButton.setVisible(false);
galleryButton.setVisible(false);
drawingZone.renderer.snapshot((image) => {
submitButton.setVisible(true);
snapshotButton.setVisible(true);
customCursor.setVisible(true);
muteIcon.setVisible(true);
retryButton.setVisible(true);
galleryButton.setVisible(true);
image.style.width = '160px';
image.style.height = '120px';
image.style.paddingLeft = '2px';
@@ -843,49 +724,12 @@ import Layout from '../../layouts/Layout.astro';
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
};
const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear();
customCursor.lineStyle(1.5, 0x000000);
customCursor.clear(); // Clear the previous frame
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color)
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(defaultColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates
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();
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>
<style>

View File

@@ -3,107 +3,14 @@ import Layout from '../../layouts/Layout.astro';
---
<Layout title='Drawing Game'>
<main>
<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>
<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>
<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>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<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 isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
@@ -125,12 +32,6 @@ import Layout from '../../layouts/Layout.astro';
let tickIconWidth;
let cancelIconWidth;
let maxScore;
let erase;
let audioData;
let audioFileId = false;
let isPlaying = false;
let galleryIconWidth;
let galleryButton;
if(isMobile){
topLogoWidth = 4.5;
@@ -138,21 +39,18 @@ import Layout from '../../layouts/Layout.astro';
resetIconWidth = 1.47;
tickIconWidth = 1.24;
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;
}
if(isMobile){
@@ -198,10 +96,6 @@ import Layout from '../../layouts/Layout.astro';
const data = fetch(`https://game-du.teachertrainingkolkata.in/items/game_drawing_v3/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.then(({data}) => {
if(data.instruction){
audioFileId = true;
}
audioData = `https://game-du.teachertrainingkolkata.in/assets/${data.instruction}.mp3`;
// console.log(data)
// colorList = data.colors;
const {image} = data;
@@ -241,9 +135,6 @@ import Layout from '../../layouts/Layout.astro';
let colorList;
function preload() {
if(audioFileId === true){
this.load.audio('instructAudio', audioData)
}
this.load.image('outline', assetsList.image);
this.load.image('topLogo', '/assets/top_logo.svg');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
@@ -253,7 +144,6 @@ import Layout from '../../layouts/Layout.astro';
this.load.svg('buttonIcons', '/assets/svg/button-icon.svg');
this.load.svg('cursorImage', '/assets/svg/pencil.svg');
this.load.image('colorButton', '/assets/color_button.png');
this.load.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
}
function create() {
@@ -318,34 +208,12 @@ import Layout from '../../layouts/Layout.astro';
borderBottom.strokePath();
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");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
const 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', () => {
graphics.clear();
window.location.reload();
})
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", {
@@ -354,20 +222,13 @@ import Layout from '../../layouts/Layout.astro';
// backgroundColor: 'blue',
// padding: { x: 20, y: 10 },
// });
submitButton.setVisible(true);
// submitButton.setVisible(true);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
// submitButton.setVisible(false);
// windowLoad();
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',};
// if(!isMobile){
// this.add.text(customWidth / 10, 20, "Drawing", textStyle);
@@ -384,12 +245,7 @@ import Layout from '../../layouts/Layout.astro';
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.setMask(mask);
const colorContainer = document.createElement('div');
colorContainer.style.position = 'absolute';
colorContainer.style.top = '13%';
@@ -403,26 +259,13 @@ import Layout from '../../layouts/Layout.astro';
if(isMobile){
colorContainer.style.display = 'none';
colorContainer.style.flexDirection = 'row';
}
let colorViewButton = this.add.image(window.innerWidth / 7, window.innerHeight / 1.25, 'colorButton');
!isMobile ? colorViewButton.setVisible(false) : '';
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);
colorViewButton.setInteractive().on('pointerdown', () => {
if(colorContainer.style.display === 'block') {
colorContainer.style.display = 'none';
@@ -459,8 +302,7 @@ import Layout from '../../layouts/Layout.astro';
}
});
// Append the color picker to the color container data
// colorContainer.appendChild(colorPicker);
colorContainer.appendChild(colorPicker);
// const colors = data.colors;
// var colors = colorList;
let colors = isMobile ? ['#0000FF', '#008000', '#A52A2A', '#800080', '#FFD700'] : ['#FF0000', '#FFFF00', '#0000FF', '#008000', '#A52A2A', '#800080', '#FFC0CB'];
@@ -684,14 +526,39 @@ import Layout from '../../layouts/Layout.astro';
// Create the Clear button
const clearButton = document.createElement('button');
clearButton.innerHTML ='<img src="/assets/svg/clear.svg">';
clearButton.style.marginTop = !isMobile ? `-10px` :`0px`;
// 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';
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', () => {
clearDrawing();
});
if(isMobile){
clearButton.style.display = 'none';
}
colorViewButton.setInteractive().on('pointerdown', () => {
clearButton.style.display === 'block' ? clearButton.style.display = 'none' : clearButton.style.display = 'block';
if(clearButton.style.display === 'block') {
clearButton.style.display = 'none';
}else{
clearButton.style.display = 'block';
}
});
// Create the Eraser button
@@ -729,8 +596,7 @@ import Layout from '../../layouts/Layout.astro';
}
});
// Add the Clear and Eraser buttons to the container
colorEraserCont.append(colorPicker);
colorEraserCont.append(clearButton);
buttonsContainer.appendChild(clearButton);
// buttonsContainer.appendChild(eraserButton).setVisible;
const sliderContainer = document.createElement('div');
@@ -824,17 +690,10 @@ import Layout from '../../layouts/Layout.astro';
// snapNotice.setVisible(true);
snapshotButton.setVisible(false);
customCursor.setVisible(false);
muteIcon.setVisible(false);
retryButton.setVisible(false);
galleryButton.setVisible(false);
drawingZone.renderer.snapshot((image) => {
submitButton.setVisible(true);
snapshotButton.setVisible(true);
customCursor.setVisible(true);
muteIcon.setVisible(true);
retryButton.setVisible(true);
galleryButton.setVisible(true);
image.style.width = '160px';
image.style.height = '120px';
image.style.paddingLeft = '2px';
@@ -888,49 +747,12 @@ import Layout from '../../layouts/Layout.astro';
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
};
const cursorSize = brushSize * cursorSizeMultiplier;
customCursor.clear();
customCursor.lineStyle(1.5, 0x000000);
customCursor.clear(); // Clear the previous frame
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color)
customCursor.strokeCircle(0, 0, cursorSize);
customCursor.fillStyle(Phaser.Display.Color.HexStringToColor(selectedColor).color, 1);
customCursor.fillCircle(0, 0, cursorSize);
// Position the cursor at the current mouse pointer coordinates
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();
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() {
@@ -966,40 +788,4 @@ import Layout from '../../layouts/Layout.astro';
// this.customCursor.y = this.input.y;
// }
</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>
<!-- <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,75 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
@@ -100,7 +39,7 @@ import Layout from "../../layouts/Layout.astro";
const game = new Phaser.Game(config);
const customWidth = window.innerWidth;
const customHeight = window.innerHeight;
let firstLayer;
let firstLayer, secondLayer, thirdLayer;
let graphics;
let isDrawing = false;
let formattedDateTime;
@@ -116,7 +55,7 @@ import Layout from "../../layouts/Layout.astro";
var assetsList = {}
var snapshotButton;
let submitButton;
let demoButton;
let demoButtonButton;
let shortUniqueID;
let noticeWidth;
let noticeHeight;
@@ -131,6 +70,23 @@ import Layout from "../../layouts/Layout.astro";
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;
}
if(isMobile){
submitWidth = 250;
submitHeight = 110;
noticeWidth = 100;
@@ -138,7 +94,24 @@ import Layout from "../../layouts/Layout.astro";
downloadWidth = 67;
downloadHeight = 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;
letterScale = 1.8;
backgroundScale = 0.8;
@@ -157,30 +130,11 @@ import Layout from "../../layouts/Layout.astro";
submitHeight = customHeight / 1.1;
noticeWidth = window.innerWidth * 0.5 - 100;
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{
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;
cloudHeight = 250;
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 10;
letterScale = 1.8;
backgroundScale = 1;
@@ -200,7 +154,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
noticeHeight = window.innerHeight * 0.32;
}
window.onload = function() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -248,26 +201,24 @@ import Layout from "../../layouts/Layout.astro";
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 = 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.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitUserData(this);
showAnimation();
parentMainContainer.classList.remove('hidden');
})
// this.add.image(customWidth / 2, 50, 'cloud').setDepth(1.9);
@@ -298,12 +249,6 @@ import Layout from "../../layouts/Layout.astro";
// const baseFontSize = 16;
// 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;
this.add.text(window.innerWidth / 2, 80, 'Number: 0', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
@@ -362,7 +307,6 @@ const maskGraphics = this.make.graphics();
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) {
@@ -380,22 +324,20 @@ graphics.setMask(mask);
graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath();
});
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
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
}
})
// audioOneAudio.play();
audioOneAudio.play();
// startButton.setInteractive().on('pointerdown', () => {
// audioOneAudio.play();
// // gmStartTime();
@@ -413,49 +355,9 @@ graphics.setMask(mask);
}
// function beforeStartGame(){
// audioOneAudio.play();
// document.getElementById('blurDisplay').classList.add('hidden');
// }
function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,41 +40,24 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
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){
submitWidth = 250;
submitHeight = 110;
noticeWidth = 100;
noticeHeight = 0;
downloadWidth = 67;
downloadHeight = 200;
learningWidth = 200;
learningHeight = 400;
letterHeight = 0;
letterScale = 1.8;
cloudeSize = 200;
cloudHeight = 340;
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 30;
letterScale = 1.1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animated1videoScale = 1;
animated1videoScale = 0.6;
animated1Height = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -148,33 +68,23 @@ import Layout from "../../layouts/Layout.astro";
submitHeight = customHeight / 1.1;
noticeWidth = window.innerWidth * 0.5 - 100;
noticeHeight = window.innerHeight * 0.38;
}else if(isTab){
animated1videoScale = 1;
animated1Height = 32;
letterHeight = 0;
letterScale = 1.8;
} else{
submitWidth = 380;
submitHeight = 95;
noticeWidth = 0;
noticeHeight = 0;
downloadWidth = 180;
downloadHeight = 70;
learningWidth = 450;
learningHeight = 400;
cloudeSize = 500;
cloudHeight = 250;
letterHeight = 0;
letterScale = 1.8;
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 10;
letterScale = 1.2;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animated1videoScale = 1;
animated1videoScale = 0.70;
animated1Height = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
startButtonHeight = customHeight / 2 - 20;
startButtonWidth = customWidth / 1.32;
submitWidth = customWidth / 1.32;
@@ -182,35 +92,12 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
// console.log("Page loaded on: " + formattedDateTime);
};
// let hideButton;
function preload() {
this.load.video('animated1', '/assets/animated-letter/number_1.mp4');
@@ -225,71 +112,135 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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');
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
}
});
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: 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);
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 : 1', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated1Height, 'animated1').setDepth(2).setScale(animated1videoScale);
// Play the video
@@ -305,12 +256,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 35px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -360,44 +310,32 @@ graphics.setMask(mask);
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
// }
// })
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
gamestart = new Date();
gameStartTime = gamestart.toLocaleString();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
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);
startButton.setVisible(false);
// })
})
}
@@ -407,40 +345,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -106,18 +43,21 @@ import Layout from "../../layouts/Layout.astro";
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
cloudHeight = 340;
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 58;
letterScale = 1.5;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animated2Scale = 0.85;
animated2Scale = 0.55;
animated2Height = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -129,14 +69,18 @@ import Layout from "../../layouts/Layout.astro";
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.5;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animated2Scale = 0.85;
animated2Scale = 0.55;
animated2Height = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -147,114 +91,158 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
// console.log("Page loaded on: " + formattedDateTime);
};
// let hideButton;
function preload() {
this.load.video('animated2', '/assets/animated-letter/number_2.mp4');
this.load.svg('number2', '/assets/numeric/n2.svg');
this.load.svg('layer1', '/assets/numeric/n2_l1.svg');
this.load.svg('layer2', '/assets/numeric/n2_l2.svg');
this.load.svg('layer1', '/assets/numeric/n2.svg');
this.load.svg('layer2', '/assets/numeric/n2.svg');
this.load.audio('audioOne', '/assets/audio/roll-slant.mp3');
this.load.audio('audioTwo', '/assets/audio/slide.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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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);
// 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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
});
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: 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 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 : 2', { font: `${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);
// Play the video
@@ -272,8 +260,9 @@ const maskGraphics = this.make.graphics();
let textX, textY;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
let stepTextSize = isMobile ? 12 : 16;
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);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
const firstTextLayer = this.add.text(textX, textY, '1. Roll Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -282,8 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -296,6 +284,7 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
@@ -318,6 +307,7 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
``
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
@@ -356,60 +346,36 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
gamestart = new Date();
gameStartTime = gamestart.toLocaleString();
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>
<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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,25 +40,24 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
cloudHeight = 340;
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 48;
letterScale = 1.5;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animated3Scale = 0.92;
animated3Scale = 0.55;
animated3Height = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -138,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 30;
letterScale = 1.5;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animated3Scale = 0.92;
animated3Scale = 0.55;
animated3Height = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -156,33 +92,12 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
// console.log("Page loaded on: " + formattedDateTime);
};
// let hideButton;
function preload() {
this.load.video('animated3', '/assets/animated-letter/number_3.mp4');
@@ -194,76 +109,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
});
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: 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);
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 : 3', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated3Height, 'animated3').setDepth(2).setScale(animated3Scale);
// Play the video
@@ -279,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Roll Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Roll Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -292,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Roll Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -328,6 +307,7 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
``
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
@@ -366,14 +346,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -382,40 +379,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
@@ -162,28 +97,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -201,74 +114,138 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
});
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: 4', {fill: '#60C6CB', font: `900 ${responsiveFontSize}px quicksand`}).setOrigin(0.5);
const descrptText = this.add.text(window.innerWidth/2, 125, 'Let`s learn how to write number : 4', { font: `900 ${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
const 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 : 4', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated4Height, 'animated4').setDepth(2).setScale(animated4Scale);
// Play the video
@@ -283,12 +260,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -297,7 +273,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -306,9 +282,8 @@ const maskGraphics = this.make.graphics();
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(window.innerWidth / 2, window.innerHeight / 1.2, '3. Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const thirdTextLayer = this.add.text(textX, textY, '3. Down', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioOne');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -403,15 +378,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -419,40 +410,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,10 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
// console.log(x);
@@ -118,7 +54,7 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 50;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
@@ -126,7 +62,7 @@ import Layout from "../../layouts/Layout.astro";
sunHeight = 70;
animated5Height = 35;
animated5Scale = 0.7;
animated5Scale = 0.55;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -142,7 +78,7 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 40;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
@@ -150,7 +86,7 @@ import Layout from "../../layouts/Layout.astro";
sunHeight = 100;
animated5Height = 20;
animated5Scale = 0.7;
animated5Scale = 0.6;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -161,28 +97,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -201,72 +115,138 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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'); // windowLoad();
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
});
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: 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);
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 : 5', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated5Height, 'animated5').setDepth(2).setScale(animated5Scale);
// Play the video
@@ -281,11 +261,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -294,7 +274,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Roll Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -304,7 +284,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioThree');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -399,56 +379,35 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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>
<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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 30;
letterHeight = 30;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animated6Scale = 0.7;
animated6Scale = 0.55;
animated6Height = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 10;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animated6Scale = 0.7;
animated6Scale = 0.55;
animated6Height = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,33 +93,12 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
// console.log("Page loaded on: " + formattedDateTime);
};
// let hideButton;
function preload() {
this.load.video('animated6', '/assets/animated-letter/number_6.mp4');
@@ -197,92 +111,159 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
});
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: 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);
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 : 6', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated6Height, 'animated6').setDepth(2).setScale(animated6Scale);
// 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 () {
// Video playback is complete
// You can add your code here for what to do when the video finishes.
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Curve Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Curve Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -291,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Loop',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -304,6 +285,7 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
@@ -326,6 +308,7 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
``
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
@@ -364,16 +347,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -382,40 +379,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 30;
letterHeight = 30;
letterScale = 1.5;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animated7Scale = 0.75;
animated7Scale = 0.55;
animated7Height = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 10;
letterScale = 1.5;
letterScale = 1.1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animated7Scale = 0.75;
animated7Scale = 0.55;
animated7Height = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,76 +111,138 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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);
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);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated7Height, 'animated7').setDepth(2).setScale(animated7Scale);
// Play the video
@@ -283,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
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);
@@ -296,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 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);
@@ -309,6 +284,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -367,15 +344,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -384,40 +377,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14;
canvasHeight = 30;
letterHeight = 30;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animated8Scale = 0.7;
animated8Scale = 0.55;
animated8Height = 15;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 10;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animated8Scale = 0.7;
animated8Scale = 0.55;
animated8Height = 0;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,74 +111,138 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
});
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: 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);
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 : 8', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated8Height, 'animated8').setDepth(2).setScale(animated8Scale);
// Play the video
@@ -281,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Snake',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Hook Snake',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -294,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Roll Up',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -368,15 +345,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -385,40 +378,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 30;
letterHeight = 30;
letterScale = 1.3;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animated9Scale = 0.75;
animated9Scale = 0.55;
animated9Height = 40;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 10;
letterScale = 1.3;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animated9Scale = 0.75;
animated9Scale = 0.55;
animated9Height = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,74 +111,139 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
graphics.setVisible(false);
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
});
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: 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);
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 : 9', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animated9Height, 'animated9').setDepth(2).setScale(animated9Scale);
// Play the video
@@ -281,12 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 8 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Curve Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -295,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -331,6 +308,7 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
``
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
@@ -369,15 +347,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -386,40 +380,3 @@ function update() {
}
</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,81 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
</main>
</Layout>
<script src="/saveTracingGameData.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<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 isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -89,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -107,13 +40,14 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
let maxScore;
let galleryButton;
// let x = 100;
// // Use x
// console.log(x);
if(isMobile){
cloudeSize = 200;
@@ -121,14 +55,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 70;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedAHeight = 35;
animatedAScale = 0.8;
animatedAScale = 0.65;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -144,14 +78,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 50;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedAHeight = 0;
animatedAScale = 0.8;
animatedAHeight = 20;
animatedAScale = 0.73;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -162,28 +96,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -202,77 +114,128 @@ import Layout from "../../layouts/Layout.astro";
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.svg('galleryIcons', '/assets/svg/gallery-icon.svg');
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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
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', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
submitUserData(this);
showAnimation();
// parentMainContainer.classList.remove('hidden');
});
galleryButton.setInteractive().on('pointerdown', () => {
// parentMainContainer.classList.remove('hidden');
gallerySliderId.classList.remove('hidden');
})
this.add.image(customWidth / 2 * 1.6 - 0.5, 50, 'topLogo');
this.add.text(customWidth / 10, 20, "Letter : A", { font: '700 40px quicksand', fill: '#05b3a4', });
const cloud = this.add.tileSprite(customWidth / 2, customHeight / 2 - cloudHeight, customWidth, cloudeSize, 'cloud').setAlpha(0.9);
cloud.setDepth(-1.8);
const scrollSpeed = 0.5;
this.time.addEvent({
loop: true,
callback: () => {
cloud.tilePositionX += scrollSpeed;
},
delay: 16, // Adjust the delay for the desired scrolling speed
});
const sun = this.add.sprite(customWidth - sunWidth, sunHeight, 'sun').setScale(sunScale).setDepth(-1.9);
const backgroundImages = this.add.image(customWidth / 2, customHeight /2, 'backgroundImage').setDepth(-2).setScale(backgroundScale);
this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'letterA').setAlpha(0.2).setDepth(0.5).setScale(letterScale);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : A', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedAHeight, 'animatedA').setDepth(2).setScale(animatedAScale);
// Play the video
@@ -287,14 +250,11 @@ import Layout from "../../layouts/Layout.astro";
});
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);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Slant Left',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -303,7 +263,7 @@ import Layout from "../../layouts/Layout.astro";
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slant Right',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -313,12 +273,10 @@ import Layout from "../../layouts/Layout.astro";
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioThree');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
// thirdLayer.setScale(1.15);
thirdLayer.setAlpha(0.5);
thirdLayer.setInteractive({ draggable: true });
@@ -329,6 +287,8 @@ import Layout from "../../layouts/Layout.astro";
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;
@@ -383,7 +343,6 @@ import Layout from "../../layouts/Layout.astro";
if (distance >= 100) {
thirdLayer.setAlpha(1);
thirdTextLayer.setVisible(false);
finalMessage.setVisible(true)
} else {
thirdLayer.setAlpha(0.5);
}
@@ -410,14 +369,31 @@ import Layout from "../../layouts/Layout.astro";
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -425,37 +401,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 58;
letterScale = 1.2;
letterScale = 0.85;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.8;
animatedBHeight = 22;
animatedVideoScale = 0.6;
animatedBHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -138,14 +73,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 50;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.8;
animatedBHeight = 10;
animatedVideoScale = 0.70;
animatedBHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -197,73 +110,139 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : B', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedBHeight, 'animatedB').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -277,11 +256,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -290,7 +269,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -300,7 +279,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slide Around', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioTHreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -314,6 +293,8 @@ const maskGraphics = this.make.graphics();
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;
@@ -397,14 +378,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -413,40 +411,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -122,7 +57,7 @@ import Layout from "../../layouts/Layout.astro";
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.59;
animatedCHeight = 32;
animatedAHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
startButtonHeight = customHeight / 1.1;
@@ -144,7 +79,7 @@ import Layout from "../../layouts/Layout.astro";
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.70;
animatedCHeight = 20;
animatedAHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -155,28 +90,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -185,7 +98,7 @@ import Layout from "../../layouts/Layout.astro";
// let hideButton;
function preload() {
this.load.video('animatedC', '/assets/animated-letter/capital_c.mp4');
this.load.video('animatedA', '/assets/animated-letter/capital_c.mp4');
this.load.svg('letterC', '/assets/capital-letter/c.svg');
this.load.svg('layer1', '/assets/capital-letter/c.svg');
this.load.audio('audioOne', '/assets/audio/hook-around.mp3');
@@ -193,72 +106,139 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('backgroundImage', '/assets/bg6.png');
this.load.image('cloud', '/assets/cloud.png');
this.load.image('canvas', '/assets/canvas4.png');
this.load.image('beanie', '/assets/beanieImage.png');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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, 'animatedA').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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : C', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedAHeight, 'animatedA').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -272,11 +252,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -327,16 +307,33 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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() {
@@ -344,40 +341,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 58;
letterScale = 1.2;
letterScale = 0.85;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.8;
animatedDHeight = 22;
animatedVideoScale = 0.6;
animatedDHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -138,14 +73,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 50;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.8;
animatedDHeight = 10;
animatedVideoScale = 0.70;
animatedDHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -196,74 +109,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
submitNotic.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -277,11 +256,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 15, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -290,7 +269,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -303,6 +282,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -360,15 +341,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -377,40 +373,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer, fourthLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -154,28 +89,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -195,70 +108,137 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : E', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedEHeight, 'animatedE').setDepth(2).setScale(0.73);
// Play the video
@@ -274,11 +254,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 20, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -287,7 +267,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -297,7 +277,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -308,7 +288,7 @@ const maskGraphics = this.make.graphics();
fourthLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer4').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 fourthTextLayer = this.add.text(textX, textY, '4. Slide', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioFourthAudio = this.sound.add('audioTwo');
fourthTextLayer.setVisible(false);
fourthLayer.setDepth(1.1);
@@ -427,14 +407,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -443,40 +440,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,26 +40,28 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
// console.log(x);
if(isMobile){
cloudeSize = 200;
cloudHeight = 340;
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 35;
letterScale = 1.08;
letterHeight = 70;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedFHeight = 0;
animatedFScale = 0.8;
animatedFHeight = 35;
animatedFScale = 0.65;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -138,14 +77,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 50;
letterScale = 1.1;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedFHeight = 10;
animatedFScale = 0.8;
animatedFHeight = 20;
animatedFScale = 0.73;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -156,28 +95,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -195,69 +112,134 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : F', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedFHeight, 'animatedF').setDepth(2).setScale(animatedFScale);
// Play the video
@@ -272,11 +254,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -285,7 +267,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -295,7 +277,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -387,15 +369,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -403,40 +401,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,26 +40,24 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
cloudHeight = 340;
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 30;
letterScale = 1;
letterHeight = 58;
letterScale = 0.85;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.7;
animatedGHeight = 0;
animatedVideoScale = 0.60;
animatedGHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -156,33 +91,7 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
// console.log("Page loaded on: " + formattedDateTime);
};
// let hideButton;
function preload() {
this.load.video('animatedG', '/assets/animated-letter/capital_g.mp4');
@@ -195,71 +104,138 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : G', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedGHeight, 'animatedG').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -273,11 +249,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
audioOneAudio.play();
firstLayer.setDepth(1);
@@ -286,7 +262,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -357,15 +333,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -374,40 +366,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,13 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
// console.log(x);
if(isMobile){
cloudeSize = 200;
@@ -115,14 +54,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 70;
letterScale = 1.2;
letterScale = 0.9;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedHHeight = 30;
animatedHScale = 0.78;
animatedHHeight = 45;
animatedHScale = 0.6;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -138,14 +77,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 50;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedHHeight = 10;
animatedHScale = 0.78;
animatedHHeight = 20;
animatedHScale = 0.70;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -156,28 +95,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -195,71 +112,137 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : H', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedHHeight, 'animatedH').setDepth(2).setScale(animatedHScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -272,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 20, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -285,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -295,7 +278,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -390,55 +373,35 @@ graphics.setMask(mask);
graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath();
});
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);
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>
<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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,10 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
// console.log(x);
@@ -159,28 +95,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,68 +112,135 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
const baseFontSize = 24;
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : I', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedIHeight, 'animatedI').setDepth(2).setScale(animatedIScale);
// Play the video
@@ -274,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 40, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -287,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -297,7 +278,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slide', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -391,14 +372,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -406,40 +404,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -194,70 +107,137 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : J', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedJHeight, 'animatedJ').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -271,11 +251,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Hook',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Hook',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -320,15 +300,33 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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() {
@@ -336,40 +334,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
@@ -160,28 +95,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -199,71 +112,137 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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);
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);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedKHeight, 'animatedK').setDepth(2).setScale(animatedKScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -276,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 50, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -289,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 50, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 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);
@@ -299,7 +278,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2 + 50, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slant', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -392,14 +371,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -407,40 +403,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -155,28 +90,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -201,70 +114,132 @@ import Layout from "../../layouts/Layout.astro";
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image("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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : L', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedLHeight, 'animatedL').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -278,11 +253,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 30, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -291,7 +266,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -304,6 +279,7 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
@@ -326,6 +302,7 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
``
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
@@ -364,15 +341,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -381,40 +373,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer, fourthLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -196,71 +109,139 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : M', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedMHeight, 'animatedM').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -274,12 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -288,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -298,7 +278,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slant', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -309,7 +289,7 @@ const maskGraphics = this.make.graphics();
fourthLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer4').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 fourthTextLayer = this.add.text(textX, textY, '4. Slant', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioFourthAudio = this.sound.add('audioTwo');
fourthTextLayer.setVisible(false);
fourthLayer.setDepth(1.1);
@@ -427,14 +407,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -443,40 +439,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
@@ -160,28 +95,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -206,71 +119,131 @@ import Layout from "../../layouts/Layout.astro";
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image("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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : N', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedNHeight, 'animatedN').setDepth(2).setScale(animatedNScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -283,11 +256,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -296,7 +269,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -306,7 +279,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slant', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -320,6 +293,8 @@ const maskGraphics = this.make.graphics();
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;
@@ -399,14 +374,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -414,40 +405,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -200,71 +113,133 @@ import Layout from "../../layouts/Layout.astro";
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image("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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : O', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedOHeight, 'animatedO').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -278,12 +253,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 12 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Hook Around Close',{ font: '700 35px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -334,53 +308,37 @@ graphics.setMask(mask);
graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath();
});
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);
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() {
}
function update() {}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -202,70 +115,133 @@ import Layout from "../../layouts/Layout.astro";
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image("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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedPHeight, 'animatedP').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -279,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 30, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -292,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -366,14 +342,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -382,40 +375,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -190,78 +103,145 @@ import Layout from "../../layouts/Layout.astro";
this.load.svg('letterQ', '/assets/capital-letter/q.svg');
this.load.svg('layer1', '/assets/capital-letter/q_l1.svg');
this.load.svg('layer2', '/assets/capital-letter/q_l2.svg');
this.load.audio('audioOne', '/assets/audio/hook-around-close.mp3');
this.load.audio('audioTwo', '/assets/audio/slant.mp3');
this.load.audio('audioOne', '/assets/audio/tall-down.mp3');
this.load.audio('audioTwo', '/assets/audio/slide-around.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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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);
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 : Q', { font: `${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
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -275,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around Close',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Hook Around Close',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -288,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 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);
@@ -301,6 +281,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -360,55 +342,36 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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>
<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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
@@ -162,28 +97,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -208,70 +121,131 @@ import Layout from "../../layouts/Layout.astro";
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image("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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : R', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedRHeight, 'animatedR').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -284,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 10, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -297,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -321,6 +295,8 @@ const maskGraphics = this.make.graphics();
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;
@@ -414,13 +390,17 @@ graphics.setMask(mask);
}
})
firstTextLayer.setVisible(false);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -428,40 +408,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -194,71 +107,139 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : S', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedSHeight, 'animatedS').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -272,11 +253,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 12 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Hook Around Snake',{ font: '700 35px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -326,15 +307,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
@@ -343,41 +340,5 @@ graphics.setMask(mask);
function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -196,70 +109,137 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : T', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedTHeight, 'animatedT').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -273,11 +253,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -286,7 +266,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -358,14 +338,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -374,40 +371,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -194,70 +107,138 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : U', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedUHeight, 'animatedU').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -271,11 +252,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 12 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Tall Down Curve Up',{ font: '700 35px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -327,14 +308,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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,40 +342,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -195,72 +108,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
submitNotic.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : V', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedVHeight, 'animatedV').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -274,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -287,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -300,6 +281,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -321,6 +304,7 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
``
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
@@ -359,14 +343,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -375,40 +375,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer, fourthLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -195,71 +108,139 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : W', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedWHeight, 'animatedW').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -273,11 +254,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -286,7 +267,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -296,7 +277,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slant', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioOne');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -307,7 +288,7 @@ const maskGraphics = this.make.graphics();
fourthLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer4').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 fourthTextLayer = this.add.text(textX, textY, '4. Slant', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioFourthAudio = this.sound.add('audioOne');
fourthTextLayer.setVisible(false);
fourthLayer.setDepth(1.1);
@@ -425,55 +406,37 @@ graphics.setMask(mask);
graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath();
});
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);
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>
<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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -196,70 +109,138 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : X', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedXHeight, 'animatedX').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -273,11 +254,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slant',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -286,7 +267,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Cross',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -299,6 +280,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -358,14 +341,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -374,40 +374,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
@@ -160,28 +95,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -200,70 +113,136 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : Y', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedYHeight, 'animatedY').setDepth(2).setScale(animatedYScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -276,11 +255,12 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, 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(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 firstTextLayer = this.add.text(textX, textY, '1. Slant Right',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
firstLayer.setAlpha(0.5);
@@ -288,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slant Left',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -298,7 +278,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Down', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioThree');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -312,6 +292,8 @@ const maskGraphics = this.make.graphics();
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;
@@ -391,14 +373,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -406,40 +405,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
@@ -160,28 +95,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,71 +111,137 @@ import Layout from "../../layouts/Layout.astro";
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.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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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);
retryButton.setInteractive().on('pointerdown', () => {
window.location.reload();
})
const maskGraphics = this.make.graphics();
maskGraphics.fillRect(customWidth / 2 - customWidth / 2, 55, customWidth, customHeight);
// 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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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);
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);
@@ -275,11 +254,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Slide',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
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);
@@ -288,7 +267,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 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);
@@ -298,7 +277,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 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);
@@ -312,6 +291,8 @@ const maskGraphics = this.make.graphics();
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;
@@ -373,7 +354,6 @@ const maskGraphics = this.make.graphics();
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) {
@@ -391,16 +371,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -408,40 +403,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,13 +50,13 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 30;
letterScale = 1.7;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.75;
animatedVideoScale = 0.6;
animatedAHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -138,13 +73,13 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 20;
letterScale = 1.7;
letterScale = 1.5;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.75;
animatedVideoScale = 0.7;
animatedAHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -156,33 +91,12 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
// console.log("Page loaded on: " + formattedDateTime);
};
// let hideButton;
function preload() {
this.load.video('animatedA', '/assets/animated-letter/small_a.mp4');
@@ -195,73 +109,139 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png'); let formattedDateTime;
let gameStartTime = "start time here";
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : a', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedAHeight, 'animatedA').setDepth(2).setScale(animatedVideoScale);
// Play the video
@@ -277,11 +257,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 6 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -290,7 +270,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Small Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -325,6 +305,8 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
``
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
secondLayer.on('dragstart', (pointer) => {
@@ -362,15 +344,32 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -379,40 +378,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xeaeae8,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -157,28 +92,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -197,69 +110,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
});
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: 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);
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 : b', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedBHeight, 'animatedB').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -273,11 +257,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 20, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -286,7 +270,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Roll Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -358,15 +342,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -375,40 +375,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 40;
letterScale = 1.7;
letterScale = 1.3;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.75;
animatedVideoScale = 0.6;
animatedCHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 30;
letterScale = 1.7;
letterScale = 1.5;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.75;
animatedVideoScale = 0.7;
animatedCHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -196,73 +109,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : c', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedCHeight, 'animatedC').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -276,11 +257,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 7 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -292,6 +273,8 @@ const maskGraphics = this.make.graphics();
// Add these variables to keep track of start points
let firstDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -330,15 +313,34 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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() {
@@ -346,40 +348,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,80 +111,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
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);
});
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: 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);
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);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -285,11 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 secondTextLayer = this.add.text(textX, textY, '2. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -298,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 30, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 firstTextLayer = this.add.text(textX, textY, '1. Roll Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -369,14 +343,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -385,40 +375,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xeaeae8,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 30;
letterScale = 1.9;
letterScale = 1.4;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.78;
animatedVideoScale = 0.57;
animatedEHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 20;
letterScale = 1.9;
letterScale = 1.75;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.78;
animatedVideoScale = 0.7;
animatedEHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,74 +111,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
});
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: 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);
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 : e', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedEHeight, 'animatedE').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -279,11 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 6 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -292,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slide',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -327,6 +307,7 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
``
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
@@ -365,15 +346,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -382,40 +378,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xeaeae8,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = -10;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.70;
animatedFHeight = 38;
animatedVideoScale = 0.57;
animatedFHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -138,14 +73,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = -20;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.69;
animatedFHeight = 40;
animatedVideoScale = 0.65;
animatedFHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -196,72 +109,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : f', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedFHeight, 'animatedF').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -275,11 +257,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 6 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Hook Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -288,7 +270,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 15, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Cross',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -300,6 +282,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -359,15 +343,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -376,40 +376,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,15 +50,15 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 8;
letterScale = 1.2;
letterScale = 0.95;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.75;
animatedGHeight = 45;
animatedVideoScale = 0.62;
animatedGHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = -20;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.8;
animatedVideoScale = 0.65;
animatedGHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,72 +111,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : g', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedGHeight, 'animatedG').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -277,11 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 6 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
audioOneAudio.play();
firstLayer.setDepth(1);
@@ -290,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Down Tail',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -324,6 +306,7 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
secondLayer.on('dragstart', (pointer) => {
@@ -361,14 +344,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -377,40 +377,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xeaeae8,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 70;
letterScale = 1.2;
letterScale = 0.95;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.75;
animatedVideoScale = 0.6;
animatedHHeight = 35;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,15 +74,15 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 70;
letterScale = 1.2;
letterScale = 1;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.75;
animatedHHeight = 35;
animatedVideoScale = 0.63;
animatedHHeight = 42;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,71 +111,138 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
});
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: 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);
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 : h', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedHHeight, 'animatedH').setDepth(2).setScale(animatedVideoScale);
// Play the video
@@ -278,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 25, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
audioOneAudio.play();
firstLayer.setDepth(1);
@@ -291,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 25, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Roll Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -303,6 +283,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -362,15 +344,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -379,40 +377,3 @@ function update() {
}
</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,76 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
<script src="/saveGameAI.js" is:inline></script>
</Layout>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -84,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xecedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -102,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -114,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterIeight = 50;
letterScale = 1.6;
letterScale = 1.2;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.7;
animatedVideoScale = 0.5;
animatedIHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -138,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterIeight = 30;
letterScale = 1.6;
letterScale = 1.3;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.7;
animatedVideoScale = 0.55;
animatedIHeight = 10;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -157,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -197,70 +111,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
const baseFontSize = 24;
const responsiveFontSize = (window.innerWidth / 480) * baseFontSize;
const descrptText = this.add.text(screenCenterX, 90, 'Let`s learn how to write letter : i', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedIHeight, 'animatedI').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -274,11 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 5.5 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Small Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -287,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterIeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Dot',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -299,6 +284,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -358,14 +345,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -374,40 +377,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,71 +111,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : j', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedJHeight, 'animatedJ').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -276,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterJeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Down Tail',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -289,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterJeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Dot',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -301,6 +283,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -322,6 +306,7 @@ const maskGraphics = this.make.graphics();
firstLayer.setAlpha(0.5);
}
});
``
// Repeat the above code for secondLayer and thirdLayer
// Add this code for secondLayer
@@ -360,14 +345,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
startButton.setInteractive().on('pointerdown', () => {
audioOneAudio.play();
submitButton.setVisible(true);
firstTextLayer.setVisible(true);
animatedLetter.setVisible(false);
firstScreen.setVisible(false);
animatedLetter.setVisible(false); firstScreen.setVisible(false);
graphics.setVisible(true);
hideButton.setVisible(false);
demoButton.setVisible(true);
startButton.setVisible(false);
})
}
@@ -376,40 +377,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xeaeae8,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
@@ -161,28 +96,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -201,71 +114,137 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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);
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);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedKHeight, 'animatedK').setDepth(2).setScale(animatedKScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -278,11 +257,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 20, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -291,7 +270,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slant In',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -301,7 +280,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slant Out', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioThree');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -315,6 +294,8 @@ const maskGraphics = this.make.graphics();
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;
@@ -394,14 +375,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -409,40 +406,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -196,70 +109,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : l', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedLHeight, 'animatedL').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -273,11 +256,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 50, 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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Tall Down',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -289,6 +272,8 @@ const maskGraphics = this.make.graphics();
// Add these variables to keep track of start points
let firstDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -327,14 +312,31 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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,40 +347,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xeaeae8,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
@@ -119,14 +54,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 50;
letterScale = 1.7;
letterScale = 1.1;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedMHeight = 35;
animatedMScale = 0.7;
animatedMScale = 0.5;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -142,14 +77,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 40;
letterScale = 1.7;
letterScale = 1.3;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedMHeight = 20;
animatedMScale = 0.8;
animatedMScale = 0.6;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -160,28 +95,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -199,70 +112,137 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : m', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedMHeight, 'animatedM').setDepth(2).setScale(animatedMScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -275,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 5 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Small Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -288,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Roll Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -298,7 +278,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Roll Down', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioTwo');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -393,15 +373,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -409,40 +404,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xeaeae8,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterNeight = 50;
letterScale = 1.6;
letterScale = 1.4;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.7;
animatedVideoScale = 0.63;
animatedNHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterNeight = 30;
letterScale = 1.6;
letterScale = 1.5;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.7;
animatedVideoScale = 0.65;
animatedNHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,71 +111,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : n', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedNHeight, 'animatedN').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -276,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 60, customHeight / 2 + letterNeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 5 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Small Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -289,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 60, customHeight / 2 + letterNeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Roll Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -301,6 +283,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -360,14 +344,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -376,40 +376,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,7 +50,7 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterHeight = 40;
letterScale = 1.6;
letterScale = 1.3;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
@@ -138,7 +73,7 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterHeight = 30;
letterScale = 1.6;
letterScale = 1.5;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
@@ -156,28 +91,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -194,71 +107,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
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);
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
})
});
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: 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);
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 : o', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedOHeight, 'animatedO').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -272,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
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(window.innerWidth / 2, window.innerHeight / 1.2, '1. Hook Around Close',{ font: `600 ${stepTextSize}px quicksand`, fill: '#000000'}).setOrigin(0.5);
const firstTextLayer = this.add.text(textX, textY, '1. Hook Around Close',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -288,6 +271,8 @@ const maskGraphics = this.make.graphics();
// Add these variables to keep track of start points
let firstDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -326,14 +311,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -342,40 +343,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -84,7 +21,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -102,11 +39,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -155,28 +90,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -195,71 +108,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedPHeight, 'animatedP').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -273,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterPeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Down Tail',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -286,7 +268,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 30, customHeight / 2 + letterPeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Roll Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -357,14 +339,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -373,40 +371,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -84,7 +21,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -102,11 +39,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -157,28 +92,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -203,70 +116,134 @@ import Layout from "../../layouts/Layout.astro";
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image("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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
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
animatedLetter.play();
animatedLetter.setVisible(false);
@@ -280,11 +257,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY; - 35
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 45, customHeight / 2 + letterQeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 6.5 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Hook Around',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -293,7 +270,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 45, customHeight / 2 + letterQeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Down Hook',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -305,6 +282,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -363,56 +342,35 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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>
<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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -115,14 +50,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.14
canvasHeight = 35;
letterReight = 20;
letterScale = 1.6;
letterScale = 1.2;
backgroundScale = 0.8;
sunScale = 0.1;
sunScalePlus = 0.15;
sunWidth = 70;
sunHeight = 70;
animatedVideoScale = 0.7;
animatedVideoScale = 0.5;
animatedRHeight = 32;
helpButtonHeight = customHeight / 1.1;
helpButtonWidth = customWidth / 2 + 10;
@@ -139,14 +74,14 @@ import Layout from "../../layouts/Layout.astro";
canvasScale = 0.195;
canvasHeight = 20;
letterReight = -10;
letterScale = 1.6;
letterScale = 1.2;
backgroundScale = 1;
sunScale = 0.2;
sunScalePlus = 0.25;
sunWidth = 200;
sunHeight = 100;
animatedVideoScale = 0.7;
animatedVideoScale = 0.6;
animatedRHeight = 20;
helpButtonHeight = customHeight / 2 + 40;
helpButtonWidth = customWidth / 1.32;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,70 +111,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : r', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedRHeight, 'animatedR').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -275,11 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterReight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 5 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Small Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -288,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 40, customHeight / 2 + letterReight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Roll',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -300,6 +284,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -359,14 +345,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -375,40 +377,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -201,71 +114,134 @@ import Layout from "../../layouts/Layout.astro";
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
this.load.image("tickIcon", '/assets/svg/tick2.svg');
this.load.image("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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : s', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedSHeight, 'animatedS').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -279,11 +255,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 13 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Hook Around Snake',{ font: '700 35px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -331,14 +307,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
@@ -349,40 +341,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,68 +111,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
});
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: 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);
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 : t', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedTHeight, 'animatedT').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -273,11 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterTeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Tall Down',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -286,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterTeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Cross',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -358,14 +344,30 @@ graphics.setMask(mask);
graphics.lineTo(pointer.x, pointer.y);
graphics.strokePath();
});
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -374,40 +376,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,71 +111,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
submitNotic.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : u', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedUHeight, 'animatedU').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -276,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterUeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 25 : customWidth * 0.75;
textY = isMobile ? customHeight / 6 : customHeight / 2.3;
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 firstTextLayer = this.add.text(textX, textY, '1. Small Down Curve Up',{ font: '700 35px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -289,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 + 20, customHeight / 2 + letterUeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Small Down',{ font: '700 35px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -301,6 +283,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -360,14 +344,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -376,40 +376,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -197,69 +110,140 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
submitNotic.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
}
});
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: 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);
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 : v', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedVHeight, 'animatedV').setDepth(2).setScale(animatedVideoScale);
// Play the video
@@ -275,11 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterVHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 + 30 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -288,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterVHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -300,6 +284,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -359,14 +345,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -375,40 +377,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer, fourthLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -196,69 +109,142 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : w', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedWHeight, 'animatedW').setDepth(2).setScale(animatedVideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -272,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 + 40: customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -285,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioOne');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -295,7 +281,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 thirdTextLayer = this.add.text(textX, textY, '3. Slant', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioThreeAudio = this.sound.add('audioOne');
thirdTextLayer.setVisible(false);
thirdLayer.setDepth(1.1);
@@ -306,7 +292,7 @@ const maskGraphics = this.make.graphics();
fourthLayer = this.add.image(customWidth / 2, customHeight / 2 + letterHeight, 'layer4').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 fourthTextLayer = this.add.text(textX, textY, '4. Slant', { font: '700 40px quicksand', fill: '#05b3a4'});
const audioFourthAudio = this.sound.add('audioOne');
fourthTextLayer.setVisible(false);
fourthLayer.setDepth(1.1);
@@ -424,15 +410,33 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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() {
@@ -440,40 +444,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,70 +111,141 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : x', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedXHeight, 'animatedX').setDepth(2).setScale(animatedXideoScale);
// Play the video
// animatedLetter.play();
animatedLetter.setVisible(false);
@@ -275,11 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterXHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Slant',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -288,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 , customHeight / 2 + letterXHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Cross',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -300,6 +284,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -359,15 +345,30 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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);
})
}
@@ -376,40 +377,3 @@ function update() {
}
</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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
if(isMobile){
cloudeSize = 200;
@@ -158,28 +93,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -198,70 +111,138 @@ import Layout from "../../layouts/Layout.astro";
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("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');
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() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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
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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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: 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);
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 : y', { font: `${responsiveFontSize}px quicksand`, fill: '#7c4c23', fontWeight : 'bold'}).setOrigin(0.5);
animatedLetter = this.add.video(customWidth / 2 , customHeight / 2 + animatedYHeight, 'animatedY').setDepth(2).setScale(animatedYideoScale);
// Play the video
@@ -277,11 +258,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterYHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 firstTextLayer = this.add.text(textX, textY, '1. Slant Right',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioOneAudio = this.sound.add('audioOne');
// audioOneAudio.play();
firstLayer.setDepth(1);
@@ -290,7 +271,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 10, customHeight / 2 + letterYHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 secondTextLayer = this.add.text(textX, textY, '2. Slant Tail',{ font: '700 40px quicksand', fill: '#05b3a4'});
const audioTwoAudio = this.sound.add('audioTwo');
secondTextLayer.setVisible(false);
secondLayer.setDepth(1);
@@ -302,6 +283,8 @@ const maskGraphics = this.make.graphics();
let firstDragStartPoint = { x: 0, y: 0 };
let secondDragStartPoint = { x: 0, y: 0 };
// ...
// Add this code for firstLayer
firstLayer.on('dragstart', (pointer) => {
firstDragStartPoint.x = pointer.x;
@@ -361,15 +344,32 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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() {
@@ -377,40 +377,3 @@ function update() {
}
</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

@@ -1,413 +0,0 @@
---
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,77 +3,14 @@ import Layout from "../../layouts/Layout.astro";
---
<Layout title="Guided Letter Tracing Game">
<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 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>
</main>
</Layout>
<script src="/saveGameAI.js" is:inline></script>
<script src="/saveGameData.js" is:inline></script>
<script is:inline>
function showAnimation() {
const clipArt = document.querySelector('.clip-art');
clipArt.classList.add('show');
}
const isMobile = window.innerWidth <= 768;
const isTab = window.innerWidth > 768 && window.innerWidth <= 1416;
const drawingZone = {
x: isMobile ? 0 : window.innerWidth / 4,
y: window.innerHeight / 4,
@@ -85,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0xebedea,
backgroundColor: 0xFFFFFF,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
@@ -103,11 +40,9 @@ import Layout from "../../layouts/Layout.astro";
let firstLayer, secondLayer, thirdLayer;
let graphics;
let animatedLetter;
let scoreTotal = 0;
let isDrawing = false;
let scoreTotal = 0; let isDrawing = false;
let formattedDateTime;
let gameStartTime = "start time here";
let demoButton;
// let x = 100;
// // Use x
@@ -162,28 +97,6 @@ import Layout from "../../layouts/Layout.astro";
noticeWidth = window.innerWidth * 0.5 - 120;
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() {
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
@@ -201,71 +114,139 @@ import Layout from "../../layouts/Layout.astro";
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("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');
this.load.image('sun', '/assets/sun.png');
this.load.image('bgMobile', '/assets/bgMobile.png');
this.load.image('canvasStand', '/assets/stand2.png');
}
function create() {
this.add.image(customWidth / topLogoWidth, 30, "topLogo");
muteIcon = this.add.image(customWidth / muteIconWidth, 30, "muteIcon");
retryButton = this.add.image(customWidth / resetIconWidth, 30, "resetIcon");
submitButton = this.add.image(customWidth / tickIconWidth, 30, "tickIcon");
demoButton = this.add.image(customWidth / galleryIconWidth, 30, "helpIcons");
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
cancelIcon = this.add.image(customWidth / cancelIconWidth, 30, "cancelIcon");
const borderBottom = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
borderBottom.lineStyle(1, 0x0348A8);
borderBottom.setAlpha(0.2);
borderBottom.beginPath();
borderBottom.moveTo(x, y);
borderBottom.lineTo(x + lineWidth, y);
borderBottom.strokePath();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - noticeHeight, 'Submitted Successfully', {font: '600 20px Quicksand', fill: '#FFFFFF', backgroundColor: '#004aad',padding: {left: 20,right: 20,top: 10,bottom: 10}}).setDepth(3).setVisible(false);
submitButton = this.add.text(submitWidth, submitHeight, "Submit", {
font: '900 24px Quicksand',
fill: '#05b3a4',
backgroundColor : '#7c4c23',
padding: {x: 10, y: 10},
shadow: {
offsetX : 2,
offsetY : 2,
color: '#000',
blur: 5,
fill: true
}
});
submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
submitButton.setVisible(false);
// windowLoad();
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);
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 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', () => {
animatedLetter.setCurrentTime(0);
animatedLetter.play(true);
graphics.setVisible(false);
firstScreen.setVisible(true);
if(animatedLetter.visible){
animatedLetter.setVisible(false);
graphics.setVisible(true);
firstScreen.setVisible(false);
} else{
graphics.setVisible(false);
demoButton.setVisible(false); // Hide the "Demo" button
hideButton.setVisible(true); // Show the "Hide" button
animatedLetter.setVisible(true);
firstScreen.setVisible(true);
});
}
})
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);
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);
@@ -278,11 +259,11 @@ const maskGraphics = this.make.graphics();
});
let textX, textY;
let stepTextSize = isMobile ? 12 : 16;
firstLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer1').setScale(letterScale);
textX = isMobile ? customWidth / 4 + 40 : customWidth * 0.75;
textY = isMobile ? customHeight / 5 : customHeight / 2.4;
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 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);
@@ -291,7 +272,7 @@ const maskGraphics = this.make.graphics();
secondLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer2').setScale(letterScale);
textX = isMobile ? customWidth / 4 : customWidth * 0.75;
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 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);
@@ -301,7 +282,7 @@ const maskGraphics = this.make.graphics();
thirdLayer = this.add.image(customWidth / 2 - 20, customHeight / 2 + letterHeight, 'layer3').setScale(letterScale);
textX = isMobile ? customWidth / 3 : customWidth * 0.75;
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 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);
@@ -315,6 +296,8 @@ const maskGraphics = this.make.graphics();
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;
@@ -394,54 +377,34 @@ graphics.setMask(mask);
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);
document.getElementById('beforeStartBtn').addEventListener('click', function() {
document.getElementById('blurDisplay').classList.add('hidden');
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>
<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">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause();" id="instructionButton"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4">
<!-- <div class="flex flex-col">
<p id="LearningArea"></p>
<p id="LearningSubArea"></p>
<p id="LearningSubArea_copy"></p>
</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>
<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>
</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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -111,31 +111,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -195,12 +173,7 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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(audioLink)
// console.log(gameData)
document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){
document.getElementById("label1").innerHTML = gameData.label1;
@@ -220,13 +193,14 @@ import Layout from "../../layouts/Layout.astro";
if(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/';
for (let i = 1; i <= 6; i++) {
const imageId = `image${i}`;
document.getElementById(imageId).src = assetsURL + gameData[imageId];
}
});
function checkResult2(id) {
@@ -350,7 +324,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -434,7 +408,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23;
padding-top: 10px;
}
#LearningArea, #LearningSubArea{
#LearningArea, #LearningSubArea_copy{
font-size: 20px;
color: #7C4C23;
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">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4">
<!-- <div class="flex flex-col">
<p id="LearningArea"></p>
<p id="LearningSubArea"></p>
<p id="LearningSubArea_copy"></p>
</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>
<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>
</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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -135,30 +135,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -217,10 +196,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){
@@ -251,7 +226,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label9").innerHTML = gameData.label9;
}
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 9; i++) {
const imageId = `image${i}`;
@@ -378,7 +353,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -460,7 +435,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23;
padding-top: 10px;
}
#LearningArea, #LearningSubArea{
#LearningArea, #LearningSubArea_copy{
font-size: 20px;
color: #7C4C23;
font-weight: bold;

View File

@@ -12,10 +12,11 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/top_logo.svg" alt="" draggable="false" class="select-none">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
</div>
@@ -83,8 +84,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>
</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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -92,30 +93,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -174,10 +154,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameLabel").innerHTML = gameData.label;
document.getElementById("gameDescription").innerHTML = gameData.description;
@@ -300,7 +276,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.fontWeight = '600';
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'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">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
@@ -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>
</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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -108,30 +108,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -152,10 +131,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){
@@ -177,7 +152,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label6").innerHTML = gameData.label6;
}
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 6; i++) {
@@ -343,7 +318,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -421,7 +396,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23;
padding-top: 10px;
}
#LearningArea, #LearningSubArea{
#LearningArea, #LearningSubArea_copy{
font-size: 20px;
color: #7C4C23;
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">
</div>
<div class="flex flex-row space-x-1 pb-2">
<button onclick="audioPlayAndPause()"><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
@@ -22,7 +22,7 @@ import Layout from "../../layouts/Layout.astro";
<div class="container mx-auto px-4">
<!-- <div class="flex flex-col">
<p id="LearningArea"></p>
<p id="LearningSubArea"></p>
<p id="LearningSubArea_copy"></p>
</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>
<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="" />
<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">
<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 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>
@@ -134,30 +134,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -214,10 +193,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameDescription").innerHTML = gameData.description;
if(gameData.label1){
@@ -248,7 +223,7 @@ import Layout from "../../layouts/Layout.astro";
document.getElementById("label9").innerHTML = gameData.label9;
}
// document.getElementById('LearningArea').innerHTML = gameData.LearningArea;
// document.getElementById('LearningSubArea').innerHTML = gameData.LearningSubArea;
// document.getElementById('LearningSubArea_copy').innerHTML = gameData.LearningSubArea_copy;
const assetsURL = 'https://game-du.teachertrainingkolkata.in/assets/';
for (let i = 1; i <= 9; i++) {
const imageId = `image${i}`;
@@ -385,7 +360,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -462,7 +437,7 @@ import Layout from "../../layouts/Layout.astro";
color: #7C4C23;
padding-top: 10px;
}
#LearningArea, #LearningSubArea{
#LearningArea, #LearningSubArea_copy{
font-size: 20px;
color: #7C4C23;
font-weight: bold;

View File

@@ -13,9 +13,9 @@ import Layout from "../../layouts/Layout.astro";
</div>
<div class="flex flex-row space-x-1 pb-2">
<button><img src="/assets/svg/mute.svg" alt=""></button>
<button onclick="retryGame()"><img src="/assets/svg/reset.svg" alt=""></button>
<button><img src="/assets/svg/reset.svg" alt=""></button>
<button onclick="saveUserData();"><img src="/assets/svg/tick2.svg" alt=""></button>
<button onclick="history.back();"><img src="/assets/svg/cancel.svg" alt=""></button>
<button><img src="/assets/svg/cancel.svg" alt=""></button>
</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"> -->
@@ -84,8 +84,8 @@ import Layout from "../../layouts/Layout.astro";
<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>
<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>
<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 class="border-[1px] border-[#0348A8] p-2.5 rounded-[4px] text-[#0348A8] w-full">Try Again</button>
</div>
</div>
</div>
@@ -93,30 +93,9 @@ import Layout from "../../layouts/Layout.astro";
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
</Layout>
<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 gameId = params.get('id');
const userId = params.get('userId');
@@ -142,10 +121,6 @@ import Layout from "../../layouts/Layout.astro";
.then(res => res.json())
.then(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)
document.getElementById("gameLabel").innerHTML = gameData.label;
document.getElementById("gameDescription").innerHTML = gameData.description;
@@ -312,7 +287,7 @@ import Layout from "../../layouts/Layout.astro";
calculationText.style.color = 'rgba(0, 0, 0, 0.38)';
containerDiv.appendChild(calculationText);
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore2`, {
fetch(`https://api.teachertrainingkolkata.in/api/saveGameScore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'

View File

@@ -1,28 +0,0 @@
<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>

View File

@@ -1,2 +0,0 @@
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