phaser-game-bs/src/pages/drag/index.astro

641 lines
24 KiB
Plaintext

---
import Layout from '../../layouts/Layout.astro';
let starNumberOfTime = localStorage.getItem('starValue');
console.log(starNumberOfTime);
const numberOfTimes = starNumberOfTime;
---
<Layout title="Drag Game">
<main>
<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>
<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;" />
<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>
</div>
</div>
</div>
<div id="wsSavedImg" class="clip-art-container -z-10 absolute bottom-0 right-0">
<img src="/assets/svg/clip-art2.svg" alt="Clip Art" class="clip-art">
</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>
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 = {
x: isMobile ? 0 : window.innerWidth / 4, // Set x to 0 on mobile, else 1/4 of screen width
y: window.innerHeight / 4,
width: isMobile ? window.innerWidth : window.innerWidth / 2, // Full width on mobile, else 1/2 of screen width
height: window.innerHeight / 2,
};
let submitButton;
let formattedDateTime;
let shortUniqueID;
let scoreTotal = 0;
let maxScore = 4;
let resultView;
let topLogoWidth;
let muteIconWidth;
let resetIconWidth;
let tickIconWidth;
let cancelIconWidth;
let audioData;
let audioFileId = false;
let isPlaying = false;
if(isMobile){
topLogoWidth = 4.5;
muteIconWidth = 1.8;
resetIconWidth = 1.47;
tickIconWidth = 1.24;
cancelIconWidth = 1.08;
}else if(isTab){
topLogoWidth = 4.5;
muteIconWidth = 1.6;
resetIconWidth = 1.43;
tickIconWidth = 1.29;
cancelIconWidth = 1.18;
}else{
topLogoWidth = 6;
muteIconWidth = 1.3;
resetIconWidth = 1.26;
tickIconWidth = 1.222;
cancelIconWidth = 1.185;
}
if(isMobile){
noticeWidth = 100;
noticeHeight = 0;
buttonWidth = 67;
buttonHeight = 0;
retryButtonWidth = window.innerWidth / 2 - 50;
retryButtonHeight = window.innerHeight - 70;
} else {
noticeWidth = 100;
noticeHeight = 0;
buttonWidth = 100;
buttonHeight = 0;
retryButtonWidth = window.innerWidth / 2 - 50;
retryButtonHeight = window.innerHeight - 70;
}
gameResult = [];
window.onload = function() {
// Get the current date and time
currentDate = new Date();
// Format the date and time as a string
formattedDateTime = currentDate.toLocaleString();
// Log the formatted date and time to the console
// // console.log("Page loaded on: " + formattedDateTime);
};
function generateShortUniqueID(length) {14
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
result += characters.charAt(randomIndex);
}
return result;
};
shortUniqueID = generateShortUniqueID(10); // Change 10 to the desired length
let blockMatches;
const targetZones = [
{
x: 0,
y: 170,
name: "target1",
block: null,
},
{
x: 0,
y: 340,
name: "target2",
block: null,
},
{
x: 0,
y: 510,
name: "target3",
block: null,
},
{
x: 0,
y: 680,
name: "target4",
block: null,
},
];
// const blockMatches = [
// {
// blockName: "blocks1",
// targetName: "target1",
// },
// {
// blockName: "blocks2",
// targetName: "target2",
// },
// {
// blockName: "blocks3",
// targetName: "target3",
// },
// {
// blockName: "blocks4",
// targetName: "target4",
// },
// ];
// console.log(blockMatches.blockName, blockMatches.targetName)
var assetsList = {}
const params = new URLSearchParams(window.location.search);
const paramsID = params.get('id');
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";
} else{
imageCustomWidth = "?width=100";
}
const assetsURL = "https://game-du.teachertrainingkolkata.in/assets/"
assetsList.left_image1 = assetsURL + left_image1 + imageCustomWidth;
assetsList.left_image2 = assetsURL + left_image2 + imageCustomWidth;
assetsList.left_image3 = assetsURL + left_image3 + imageCustomWidth;
assetsList.left_image4 = assetsURL + left_image4 + imageCustomWidth;
assetsList.right_image1 = assetsURL + right_image1 + imageCustomWidth;
assetsList.right_image2 = assetsURL + right_image2 + imageCustomWidth;
assetsList.right_image3 = assetsURL + right_image3 + imageCustomWidth;
assetsList.right_image4 = assetsURL + right_image4 + imageCustomWidth;
const config = {
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: '#ffffff',
parent: "phaser-example",
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
},
scene: MyGame,
};
const game = new Phaser.Game(config);
})
.catch(error => {
console.error('Error fetching initial data:', error);
});
class MyGame extends Phaser.Scene {
constructor() {
super();
}
preload() {
var progressBar = this.add.graphics();
var progressBox = this.add.graphics();
progressBox.fillStyle(0x222222, 0.8);
progressBox.fillRect(240, 270, 320, 50);
var width = this.cameras.main.width;
var height = this.cameras.main.height;
var loadingText = this.make.text({
x: width / 2,
y: height / 2 - 50,
text: 'Loading...',
style: {
font: '20px monospace',
fill: '#ffffff'
}
});
loadingText.setOrigin(0.5, 0.5);
var percentText = this.make.text({
x: width / 2,
y: height / 2 - 5,
text: '0%',
style: {
font: '18px monospace',
fill: '#ffffff'
}
});
percentText.setOrigin(0.5, 0.5);
var assetText = this.make.text({
x: width / 2,
y: height / 2 + 50,
text: '',
style: {
font: '18px monospace',
fill: '#ffffff'
}
});
assetText.setOrigin(0.5, 0.5);
this.load.on('progress', function (value) {
percentText.setText(parseInt(value * 100) + '%');
progressBar.clear();
progressBar.fillStyle(0xffffff, 1);
progressBar.fillRect(250, 280, 300 * value, 30);
});
this.load.on('fileprogress', function (file) {
assetText.setText('Loading asset: ' + file.key);
});
this.load.on('complete', function () {
progressBar.destroy();
progressBox.destroy();
loadingText.destroy();
percentText.destroy();
assetText.destroy();
});
// this.load.image('logo', 'zenvalogo.png');
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');
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.image("border", '/assets/svg/border.svg');
this.load.image("borderCorrect", '/assets/svg/border-correct.svg');
this.load.image("borderWrong", '/assets/svg/border-wrong.svg');
this.load.spritesheet("target1", assetsList.right_image1,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("target2", assetsList.right_image2,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("target3", assetsList.right_image3,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("target4", assetsList.right_image4,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks1", assetsList.left_image1,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks2", assetsList.left_image2, {
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks3", assetsList.left_image3, {
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks4", assetsList.left_image4, {
frameWidth: 100,
frameHeight: 100,
});
}
create() {
const params = new URLSearchParams(window.location.search);
const paramsID = params.get('id');
fetch(`https://game-du.teachertrainingkolkata.in/items/game_drag/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.then(({ data }) => {
// console.log(data)
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
const baseFontSize = 24;
let textSizeScale; if(isMobile){textSizeScale = 540}else{textSizeScale = 940};
const responsiveFontSize = (window.innerWidth / textSizeScale) * baseFontSize;
let wrapWidth;
if(isMobile){wrapWidth = 10;} else{wrapWidth = 200;}
const descrptText = this.add.text(screenCenterX, 90, data.description, { font: `${responsiveFontSize}px quicksand`, fill: '#60C6CB', align: "center", wordWrap: {width: window.innerWidth-wrapWidth}}, ).setOrigin(0.5);
blockMatches = [
{
blockName: "blocks1",
targetName: `target${data.right_match1}`,
},
{
blockName: "blocks2",
targetName: `target${data.right_match2}`,
},
{
blockName: "blocks3",
targetName: `target${data.right_match3}`,
},
{
blockName: "blocks4",
targetName: `target${data.right_match4}`,
},
];
// 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);
// 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);
this.add.text(displayW / 14 - 15, 579, data.left_image3_name).setTint(0x7c4c23);
this.add.text(displayW / 14 - 15, 750, data.left_image4_name).setTint(0x7c4c23);
//Right Image Name
this.add.text(displayW * 0.9-80, 240, data.right_image1_name).setTint(0x7c4c23);
this.add.text(displayW * 0.9-80, 409, data.right_image2_name).setTint(0x7c4c23);
this.add.text(displayW * 0.9-80, 579, data.right_image3_name).setTint(0x7c4c23);
this.add.text(displayW * 0.9-80, 750, data.right_image4_name).setTint(0x7c4c23);
})
.catch(error => {
console.error('Error fetching initial data:', error);
});
const displayW = window.innerWidth;
// const URL = window.location.href;
// const gameName = URL.split('/');
// let userData = {
// 'user': 'drawing@beanstalkedu.com',
// 'game_name': gameName[3],
// 'starts': formattedDateTime,
// // 'game_start' : gameStartTime,
// };
// function submitUserData() {
// fetch(`https://2016.dev2-cs.siliconpin.com/save/`, {
// 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)
// });
// };
// window.load
const graphics = this.add.graphics();
const x = 0; const y = 54;
const lineWidth = window.innerWidth;
graphics.lineStyle(1, 0x0348A8);
graphics.setAlpha(0.2);
graphics.beginPath();
graphics.moveTo(x, y);
graphics.lineTo(x + lineWidth, y);
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);
this.add.image(displayW / topLogoWidth, 30, "topLogo").setScale();
let soundButton = 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 * 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");
// this.add.image(displayW * 0.9-33, 340, "border").setAlpha(1).setScale(1).setDepth(-1);
this.add.image(displayW * 0.9-32, 510, "target3");
// 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 = [
{
x: displayW / 15 - 15,
y: 120,
textureKey: "blocks1",
id: "block1",
},
{
x: displayW / 15 - 15,
y: 280,
textureKey: "blocks2",
id: "block2",
},
{
x: displayW / 15 - 15,
y: 460,
textureKey: "blocks3",
id: "block3",
},
{
x: displayW / 15 - 15,
y: 640,
textureKey: "blocks4",
id: "block4",
},
];
// submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// submitButton.setVisible(false);
// window.location.reload();
// windowLoad();
submitUserData(this);
showAnimation();
});
let counter = 0;
const droppedBlocks = [];
const targetZoneBorders = [];
const isMatch = (blockName, targetName) => {
const match = blockMatches.find((m) => m.blockName === blockName && m.targetName === targetName);
if (match !== undefined) {
scoreTotal++;
counter++;
return 'borderCorrect';
} else {
// console.log(`Score Total: ${scoreTotal}`);
return 'borderWrong';
}
};
// Create target zones and their borders
targetZones.forEach((targetZone) => {
const targetImage = this.add.image(targetZone.x, targetZone.y, targetZone.name).setAlpha(0);
const targetBorder = this.add.image(targetZone.x = displayW * 0.9 - 172, targetZone.y, 'border');
targetZoneBorders.push(targetBorder);
targetZone.block = null;
});
// Add interactive blocks and handle drag events
blocks.forEach((block) => {
const newBlock = this.add
.sprite(block.x, block.y, block.textureKey, 1)
.setOrigin(0, 0)
.setInteractive({ draggable: true });
this.add.sprite(block.x, block.y, block.textureKey, 1).setOrigin(0, 0).setAlpha(0.3);
newBlock.on("drag", (pointer, dragX, dragY) => {
newBlock.setScale(1.3);
newBlock.x = dragX;
newBlock.y = dragY;
});
newBlock.on("dragend", () => {
newBlock.setScale(1.0);
let droppedOnTargetZone = false;
targetZones.forEach((targetZone, targetIndex) => {
if (
Phaser.Geom.Intersects.RectangleToRectangle(
newBlock.getBounds(),
new Phaser.Geom.Rectangle(targetZone.x, targetZone.y, 200, 100)
)
) {
if (targetZone.block === null) {
newBlock.setPosition(targetZone.x - 50, targetZone.y - 50);
newBlock.disableInteractive();
targetZone.block = newBlock;
droppedBlocks.push(newBlock);
// Check if the block matches the target and update the specific border
const borderCondition = isMatch(newBlock.texture.key, targetZone.name);
targetZoneBorders[targetIndex].setTexture(borderCondition); // Update only the matched border
if (counter === 4) {
submitButton.setVisible(true); // Show submit button if required counter reached
}
} else {
newBlock.setPosition(block.x, block.y);
}
droppedOnTargetZone = true;
targetZoneBorders[targetIndex].setVisible(true); // Make the border visible
targetZoneBorders[targetIndex].setAlpha(1); // Set border to fully visible
return;
}
});
if (!droppedOnTargetZone) {
newBlock.setPosition(block.x, block.y); // Reset position if not dropped on any target zone
}
if (droppedBlocks.length === targetZones.length) {
displayResult(droppedBlocks); // Display results when all blocks are dropped
}
});
});
retryButton.setInteractive().on('pointerdown', () => {
window.location.reload();
})
// const footerBorder = this.add.graphics();
// const footerX = 0; const footerY = window.innerHeight / 1.07;
// const footerLineWidth = window.innerWidth;
// footerBorder.lineStyle(1, 0x0348A8);
// footerBorder.setAlpha(0.2);
// footerBorder.beginPath();
// footerBorder.moveTo(footerX, footerY);
// footerBorder.lineTo(footerX + footerLineWidth, footerY);
// footerBorder.strokePath();
// let textSize;
// if(isMobile){
// textSize = 10;
// }else{
// textSize = 20;
// }
// this.add.text(displayW / 20, window.innerHeight / 1.05, 'All rights reserved. Copyright@akademy.interakto2024', {font: ` ${textSize}px Quicksand`, fill: '#002C6970',});
// this.add.text(displayW / 1.36, window.innerHeight / 1.05, 'Privacy • Terms of use', {font: ` ${textSize}px Quicksand`, fill: '#002C6970',});
}
}
// 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 displayResult = (droppedBlocks) => {
// const overlap = document.getElementById("overlap");
// overlap.style.display = "block";
// let finalDom;
droppedBlocks.forEach((block) => {
const targetZone = targetZones.find((zone) => zone.name === block.texture.key);
});
};
</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>