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

640 lines
25 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
import Layout from '../../layouts/Layout.astro';
---
<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/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 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-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 = 8;
let resultView;
let topLogoWidth;
let muteIconWidth;
let resetIconWidth;
let tickIconWidth;
let cancelIconWidth;
let retryButton;
let blockMatches;
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 - 140;
retryButtonHeight = window.innerHeight - 50;
leftTargetZoneW = window.innerWidth / 6;
rightTargetZoneW = window.innerWidth * 0.9 - 40;
} else {
noticeWidth = 100;
noticeHeight = 0;
buttonWidth = 100;
buttonHeight = 0;
retryButtonWidth = window.innerWidth / 2 - 50;
retryButtonHeight = window.innerHeight - 70;
leftTargetZoneW = window.innerWidth / 6;
rightTargetZoneW = window.innerWidth * 0.9 - 172;
}
gameResult = [];
window.onload = function() {
// Get the current date and time
currentDate = new Date();
formattedDateTime = currentDate.toLocaleString();
};
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 * 0.9 - 172
const leftTargetZones = [
{
x: leftTargetZoneW + 30,
y: window.innerHeight / 2.5,
name: "target1",
block: null,
},
// Add more left target zones as needed
];
const rightTargetZones = [
{
x: rightTargetZoneW - 30,
y: window.innerHeight / 2.5,
name: "target2",
block: null,
},
// Add more right target zones as needed
];
const targetZones = [...leftTargetZones, ...rightTargetZones];
// 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/drag_drop_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.then(({data}) => {
const {image1, image2, image3, image4, image5, image6, image7, image8} = data;
if(isMobile){
imageCustomWidth = "?width=80";
} else{
imageCustomWidth = "?width=100";
}
const assetsURL = "https://game-du.teachertrainingkolkata.in/assets/"
assetsList.element1 = assetsURL + image1 + imageCustomWidth;
assetsList.element2 = assetsURL + image2 + imageCustomWidth;
assetsList.element3 = assetsURL + image3 + imageCustomWidth;
assetsList.element4 = assetsURL + image4 + imageCustomWidth;
assetsList.element5 = assetsURL + image5 + imageCustomWidth;
assetsList.element6 = assetsURL + image6 + imageCustomWidth;
assetsList.element7 = assetsURL + image7 + imageCustomWidth;
assetsList.element8 = assetsURL + image8 + imageCustomWidth;
// console.log(assetsList.left_image1)
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');
}
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/squar.png');
this.load.spritesheet("blocks1", assetsList.element5,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks2", assetsList.element6,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks3", assetsList.element7,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks4", assetsList.element8,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks5", assetsList.element1,{
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks6", assetsList.element2, {
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks7", assetsList.element3, {
frameWidth: 100,
frameHeight: 100,
});
this.load.spritesheet("blocks8", assetsList.element4, {
frameWidth: 100,
frameHeight: 100,
});
}
create() {
// const borderGraphics = this.add.graphics();
// const borderThickness = 6;
// borderGraphics.lineStyle(borderThickness, 0x7c4c23); // Border color: 0x000000 (black), Border thickness: 2
// const borderX = window.innerWidth / 2 - borderThickness / 2; // Center the border on the screen
// borderGraphics.beginPath();
// borderGraphics.moveTo(borderX, 130);
// borderGraphics.lineTo(borderX, window.innerHeight - 260);
// borderGraphics.strokePath();
// borderGraphics.closePath();
// const borderGraphicsX = this.add.graphics();
// const borderThicknessX = 6;
// borderGraphicsX.lineStyle(borderThicknessX, 0x7c4c23); // Border color: 0x7c4c23, Border thickness: 6
// const borderY = window.innerHeight / 5 - borderThickness / 2; // Center the border vertically on the screen
// borderGraphicsX.beginPath();
// borderGraphicsX.moveTo(0, borderY);
// borderGraphicsX.lineTo(window.innerWidth, borderY);
// borderGraphicsX.strokePath();
// borderGraphicsX.closePath();
const params = new URLSearchParams(window.location.search);
const paramsID = params.get('id');
fetch(`https://game-du.teachertrainingkolkata.in/items/drag_drop_phonics/${encodeURIComponent(paramsID)}?filter[status][_eq]=published`)
.then(response => response.json())
.then(({ data }) => {
blockMatches = [
{
blockName: "blocks1",
targetName: `target${data.match1}`,
},
{
blockName: "blocks2",
targetName: `target${data.match2}`,
},
{
blockName: "blocks3",
targetName: `target${data.match3}`,
},
{
blockName: "blocks4",
targetName: `target${data.match4}`,
},
{
blockName: "blocks5",
targetName: `target${data.match5}`,
},
{
blockName: "blocks6",
targetName: `target${data.match6}`,
},
{
blockName: "blocks7",
targetName: `target${data.match7}`,
},
{
blockName: "blocks8",
targetName: `target${data.match8}`,
}
];
// console.log(data)
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();
if(data.label1, data.label2, data.label3, data.label4, data.label5, data.label6, data.label7, data.label8){
this.add.text(window.innerWidth / 2 - 170, window.innerHeight - 55, data.label1, {font:`15px`, fill: `#7c4c23`})
this.add.text(window.innerWidth / 2 - 80, window.innerHeight - 55, data.label2, {font:`15px`, fill: `#7c4c23`})
this.add.text(window.innerWidth / 2 + 15, window.innerHeight - 55, data.label3, {font:`15px`, fill: `#7c4c23`})
this.add.text(window.innerWidth / 2 + 105, window.innerHeight - 55, data.label4, {font:`15px`, fill: `#7c4c23`})
this.add.text(window.innerWidth / 2 - 170, window.innerHeight - 185, data.label5, {font:`15px`, fill: `#7c4c23`})
this.add.text(window.innerWidth / 2 - 80, window.innerHeight - 185, data.label6, {font:`15px`, fill: `#7c4c23`})
this.add.text(window.innerWidth / 2 + 20, window.innerHeight - 185, data.label7, {font:`15px`, fill: `#7c4c23`})
this.add.text(window.innerWidth / 2 + 105, window.innerHeight - 185, data.label8, {font:`15px`, fill: `#7c4c23`})
}
if(isMobile){
this.add.text(leftTargetZoneW - 20, window.innerHeight / 4.5, data.left_label, {font:`10px`, fill: `#60C6CB`});
this.add.text(rightTargetZoneW - 100, window.innerHeight / 4.5, data.right_label, {font:`10px`, fill: `#60C6CB`});
} else{
this.add.text(leftTargetZoneW - 100, window.innerHeight / 6, data.left_label, {font: `20px`, fill: `#60C6CB`});
this.add.text(rightTargetZoneW - 165, window.innerHeight / 6, data.right_label, {font: `20px`, fill: `#60C6CB`});
}
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
const baseFontSize = 24;
const responsiveFontSize = (window.innerWidth / 940) * baseFontSize;
let wrapWidth;
if(isMobile){wrapWidth = 10;} else{wrapWidth = 200;}
const descrptText = this.add.text(screenCenterX, 100, data.description, { font: `${responsiveFontSize}px quicksand`, fill: '#60C6CB', align: "center", wordWrap: {width: window.innerWidth-wrapWidth}}, ).setOrigin(0.5);
})
.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
this.add.image(displayW / topLogoWidth, 30, "topLogo").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();
submitNotic = this.add.text(window.innerWidth / 2 - noticeWidth, window.innerHeight / 2 - 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);
// submitButton.setVisible(false);
submitButton.setInteractive().on('pointerdown', () => {
// console.log('Clicked');
// submitButton.setVisible(false);
// window.location.reload();
// windowLoad();
submitUserData(this);
showAnimation();
})
let blocks1Width1, blocks1Width2, blocks1Width3, blocks1Width4, blocks1Width5, blocks1Width6, blocks1Width7, blocks1Width8;
if(isMobile){
blocks1Width1 = 180;
blocks1Width2 = 90;
blocks1Width3 = 2;
blocks1Width4 = 90;
blocks1Width5 = 180;
blocks1Width6 = 90;
blocks1Width7 = 2;
blocks1Width8 = 90;
} else{
blocks1Width1 = 200;
blocks1Width2 = 100;
blocks1Width3 = 2;
blocks1Width4 = 100;
blocks1Width5 = 200;
blocks1Width6 = 100;
blocks1Width7 = 2;
blocks1Width8 = 100;
}
const blocks = [
{
x: displayW / 2 - blocks1Width1,
y: window.innerHeight - 290,
textureKey: "blocks1",
id: "block1",
},
{
x: displayW / 2 - blocks1Width2,
y: window.innerHeight - 290,
textureKey: "blocks2",
id: "block2",
},
{
x: displayW / blocks1Width3,
y: window.innerHeight - 290,
textureKey: "blocks3",
id: "block3",
},
{
x: displayW / 2 + blocks1Width4,
y: window.innerHeight - 290,
textureKey: "blocks4",
id: "block4",
},
{
x: displayW / 2 - blocks1Width5,
y: window.innerHeight - 160,
textureKey: "blocks5",
id: "block5",
},
{
x: displayW / 2 - blocks1Width6,
y: window.innerHeight - 160,
textureKey: "blocks6",
id: "block6",
},
{
x: displayW / blocks1Width7,
y: window.innerHeight - 160,
textureKey: "blocks7",
id: "block7",
},
{
x: displayW / 2 + blocks1Width8,
y: window.innerHeight - 160,
textureKey: "blocks8",
id: "block8",
},
];
// console.log('test blocks',blocks[0])
let borderScale; if(isMobile){borderScale = 0.9;} else{borderScale = 1.5;}
const droppedBlocks = [];
const targetZoneBorders = [];
targetZones.forEach((targetZone) => {
const targetImage = this.add.image(targetZone.x, targetZone.y, targetZone.name).setAlpha(0);
const targetBorder = this.add.image(targetZone.x, targetZone.y-20, "border").setAlpha(0.05).setScale(borderScale);
targetZoneBorders.push(targetBorder);
targetZone.block = null;
}),
blocks.forEach((block, index) => {
const newBlock = this.add.sprite(block.x, block.y, block.textureKey, 0).setOrigin(0, 0).setInteractive({ draggable: true }).setScale(1);
// 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).setDepth(-2);
let droppedOnTargetZone = false;
targetZones.forEach((targetZone, targetIndex) => {
if (
Phaser.Geom.Intersects.RectangleToRectangle(
newBlock.getBounds(),
new Phaser.Geom.Rectangle(targetZone.x, targetZone.y, 100, 50)
)
) {
// newBlock.setPosition(targetZone.x - 50, targetZone.y - 50); //backgroundColor:`#FF0000`
const col = counter % 2;
const row = Math.floor(counter / 2);
newBlock.setPosition(targetZone.x - 50, targetZone.y -50);
newBlock.disableInteractive();
targetZone.block = newBlock;
droppedBlocks.push(newBlock);
// Adjust isMatch function based on your requirements
if (isMatch(newBlock.texture.key, targetZone.name)) {
// Handle match logic if needed
}
droppedOnTargetZone = true;
targetZoneBorders[targetIndex].setVisible(true);
targetZoneBorders[targetIndex].setAlpha(0.5);
return;
}
});
if (!droppedOnTargetZone) {
newBlock.setPosition(newBlock.input.dragStartX, newBlock.input.dragStartY);
};
// Check if all blocks have been dropped on target zones
if (droppedBlocks.length === targetZones.length) {
displayResult(droppedBlocks);
newBlock.setVisible(false);
}
});
});
// retryButton = this.add.image(retryButtonWidth, retryButtonHeight, 'retryIcon')
retryButton.setInteractive().on('pointerdown', () => {
window.location.reload();
})
// retryButton.setVisible(false);
let score = 0;
let counter = 0;
const isMatch = (blockName, targetName) => {
if(isMatch){
counter++;
// console.log(counter)
}
const match = blockMatches.find((m) => m.blockName === blockName && m.targetName === targetName);
// console.log(match)
if(match !== undefined){
scoreTotal++;
// console.log("Score Total", scoreTotal)
}
if(counter === 8){
// resultView = this.add.text(window.innerWidth / 2 - 100, window.innerHeight / 2 - 100, `Your Score: ${scoreTotal}`, {font: `24px`, fill: `#7c4c23`}).setVisible(false);
// console.log(counter)
submitButton.setVisible(true);
retryButton.setVisible(true);
// resultView.setVisible(true);
}
};
}
}
const displayResult = (droppedBlocks) => {
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>