workadventure/front/src/Phaser/Login/CustomizeScene.ts

321 lines
12 KiB
TypeScript
Raw Normal View History

2020-07-28 11:06:08 +02:00
import {EnableCameraSceneName} from "./EnableCameraScene";
import Rectangle = Phaser.GameObjects.Rectangle;
import {loadAllLayers} from "../Entity/PlayerTexturesLoadingManager";
2020-07-28 11:06:08 +02:00
import Sprite = Phaser.GameObjects.Sprite;
import Container = Phaser.GameObjects.Container;
2020-07-28 15:53:44 +02:00
import {gameManager} from "../Game/GameManager";
import {localUserStore} from "../../Connexion/LocalUserStore";
import {addLoader} from "../Components/Loader";
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
import {AbstractCharacterScene} from "./AbstractCharacterScene";
import {areCharacterLayersValid} from "../../Connexion/LocalUser";
import { MenuScene } from "../Menu/MenuScene";
import { SelectCharacterSceneName } from "./SelectCharacterScene";
import { RESOLUTION } from "../../Enum/EnvironmentVariable";
2020-07-28 11:06:08 +02:00
export const CustomizeSceneName = "CustomizeScene";
export const CustomizeSceneKey = "CustomizeScene";
const customizeSceneKey = 'customizeScene';
2020-07-28 11:06:08 +02:00
export class CustomizeScene extends AbstractCharacterScene {
private Rectangle!: Rectangle;
2020-07-28 11:06:08 +02:00
private selectedLayers: number[] = [0];
private containersRow: Container[][] = [];
private activeRow:number = 0;
2020-10-20 16:39:23 +02:00
private layers: BodyResourceDescriptionInterface[][] = [];
2020-07-28 11:06:08 +02:00
private customizeSceneElement!: Phaser.GameObjects.DOMElement;
2020-07-28 11:06:08 +02:00
constructor() {
super({
key: CustomizeSceneName
});
}
preload() {
addLoader(this);
this.load.html(customizeSceneKey, 'resources/html/CustomCharacterScene.html');
this.layers = loadAllLayers(this.load);
this.loadCustomSceneSelectCharacters().then((bodyResourceDescriptions) => {
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
if(!bodyResourceDescription.level){
throw 'Texture level is null';
}
this.layers[bodyResourceDescription.level].unshift(bodyResourceDescription);
});
});
2020-07-28 11:06:08 +02:00
}
create() {
const middleX = this.getMiddleX();
this.customizeSceneElement = this.add.dom(middleX, 0).createFromCache(customizeSceneKey);
MenuScene.revealMenusAfterInit(this.customizeSceneElement, customizeSceneKey);
this.customizeSceneElement.addListener('click');
this.customizeSceneElement.on('click', (event:MouseEvent) => {
event.preventDefault();
if((event?.target as HTMLInputElement).id === 'customizeSceneButtonLeft') {
this.moveCursorHorizontally(-1);
}else if((event?.target as HTMLInputElement).id === 'customizeSceneButtonRight') {
this.moveCursorHorizontally(1);
}else if((event?.target as HTMLInputElement).id === 'customizeSceneButtonDown') {
this.moveCursorVertically(1);
}else if((event?.target as HTMLInputElement).id === 'customizeSceneButtonUp') {
this.moveCursorVertically(-1);
}else if((event?.target as HTMLInputElement).id === 'customizeSceneFormBack') {
if(this.activeRow > 0){
this.moveCursorVertically(-1);
}else{
this.backToPreviousScene();
}
}else if((event?.target as HTMLButtonElement).id === 'customizeSceneFormSubmit') {
if(this.activeRow < 5){
this.moveCursorVertically(1);
}else{
this.nextSceneToCamera();
}
}
});
this.Rectangle = this.add.rectangle(this.cameras.main.worldView.x + this.cameras.main.width / 2, this.cameras.main.worldView.y + this.cameras.main.height / 3, 32, 33)
2020-07-28 11:06:08 +02:00
this.Rectangle.setStrokeStyle(2, 0xFFFFFF);
this.add.existing(this.Rectangle);
this.createCustomizeLayer(0, 0, 0);
this.createCustomizeLayer(0, 0, 1);
this.createCustomizeLayer(0, 0, 2);
this.createCustomizeLayer(0, 0, 3);
this.createCustomizeLayer(0, 0, 4);
this.createCustomizeLayer(0, 0, 5);
this.moveLayers();
this.input.keyboard.on('keyup-ENTER', () => {
this.nextSceneToCamera();
});
this.input.keyboard.on('keyup-BACKSPACE', () => {
this.backToPreviousScene();
2020-07-28 11:06:08 +02:00
});
this.input.keyboard.on('keyup-RIGHT', () => this.moveCursorHorizontally(1));
this.input.keyboard.on('keyup-LEFT', () => this.moveCursorHorizontally(-1));
this.input.keyboard.on('keyup-DOWN', () => this.moveCursorVertically(1));
this.input.keyboard.on('keyup-UP', () => this.moveCursorVertically(-1));
2020-10-20 16:39:23 +02:00
2020-10-20 17:22:32 +02:00
const customCursorPosition = localUserStore.getCustomCursorPosition();
if (customCursorPosition) {
2020-10-20 17:22:32 +02:00
this.activeRow = customCursorPosition.activeRow;
this.selectedLayers = customCursorPosition.selectedLayers;
2020-10-20 17:22:32 +02:00
this.moveLayers();
this.updateSelectedLayer();
}
}
2020-10-20 16:39:23 +02:00
private moveCursorHorizontally(index: number): void {
2020-10-20 17:22:32 +02:00
this.selectedLayers[this.activeRow] += index;
if (this.selectedLayers[this.activeRow] < 0) {
this.selectedLayers[this.activeRow] = 0
2020-10-20 16:39:23 +02:00
} else if(this.selectedLayers[this.activeRow] > this.layers[this.activeRow].length - 1) {
this.selectedLayers[this.activeRow] = this.layers[this.activeRow].length - 1
}
this.moveLayers();
this.updateSelectedLayer();
2020-10-20 17:22:32 +02:00
this.saveInLocalStorage();
}
2020-10-20 16:39:23 +02:00
private moveCursorVertically(index:number): void {
if(index === -1 && this.activeRow === 5){
const button = this.customizeSceneElement.getChildByID('customizeSceneFormSubmit') as HTMLButtonElement;
2021-04-23 19:29:43 +02:00
button.innerHTML = `Next <img src="resources/objects/arrow_up.png"/>`;
}
if(index === 1 && this.activeRow === 4){
const button = this.customizeSceneElement.getChildByID('customizeSceneFormSubmit') as HTMLButtonElement;
button.innerText = 'Finish';
}
2021-04-23 19:29:43 +02:00
if(index === -1 && this.activeRow === 1){
const button = this.customizeSceneElement.getChildByID('customizeSceneFormBack') as HTMLButtonElement;
button.innerText = `Return`;
2021-04-23 19:29:43 +02:00
}
if(index === 1 && this.activeRow === 0){
const button = this.customizeSceneElement.getChildByID('customizeSceneFormBack') as HTMLButtonElement;
button.innerHTML = `Back <img src="resources/objects/arrow_up.png"/>`;
}
this.activeRow += index;
if (this.activeRow < 0) {
this.activeRow = 0
2020-10-20 16:39:23 +02:00
} else if (this.activeRow > this.layers.length - 1) {
this.activeRow = this.layers.length - 1
}
this.moveLayers();
2020-10-20 17:22:32 +02:00
this.saveInLocalStorage();
2020-07-28 11:06:08 +02:00
}
2020-10-20 16:39:23 +02:00
2020-10-20 17:22:32 +02:00
private saveInLocalStorage() {
localUserStore.setCustomCursorPosition(this.activeRow, this.selectedLayers);
}
2020-10-20 16:39:23 +02:00
2020-07-28 11:06:08 +02:00
/**
* @param x, the layer's vertical position
* @param y, the layer's horizontal position
2020-10-20 16:39:23 +02:00
* @param layerNumber, index of the this.layers array
2020-07-28 11:06:08 +02:00
* create the layer and display it on the scene
*/
private createCustomizeLayer(x: number, y: number, layerNumber: number): void {
this.containersRow[layerNumber] = [];
2020-10-20 17:22:32 +02:00
this.selectedLayers[layerNumber] = 0;
2020-07-28 11:06:08 +02:00
let alpha = 0;
let layerPosX = 0;
2020-10-20 16:39:23 +02:00
for (let i = 0; i < this.layers[layerNumber].length; i++) {
2020-07-28 11:06:08 +02:00
const container = this.generateCharacter(300 + x + layerPosX, y, layerNumber, i);
this.containersRow[layerNumber][i] = container;
this.add.existing(container);
layerPosX += 30;
alpha += 0.1;
}
}
/**
* Generates a character from the current selected items BUT replaces
* one layer item with an item we pass in parameter.
*
* Current selected items are fetched from this.selectedLayers
*
* @param x,
* @param y,
* @param layerNumber, The selected layer number (0 for body...)
* @param selectedItem, The number of the item select (0 for black body...)
*/
private generateCharacter(x: number, y: number, layerNumber: number, selectedItem: number) {
return new Container(this, x, y,this.getContainerChildren(layerNumber,selectedItem));
}
private getContainerChildren(layerNumber: number, selectedItem: number): Array<Sprite> {
const children: Array<Sprite> = new Array<Sprite>();
for (let j = 0; j <= layerNumber; j++) {
if (j === layerNumber) {
2020-10-20 16:39:23 +02:00
children.push(this.generateLayers(0, 0, this.layers[j][selectedItem].name));
2020-07-28 11:06:08 +02:00
} else {
const layer = this.selectedLayers[j];
if (layer === undefined) {
continue;
}
2020-10-20 16:39:23 +02:00
children.push(this.generateLayers(0, 0, this.layers[j][layer].name));
2020-07-28 11:06:08 +02:00
}
}
return children;
}
/**
* Move the layer left, right, up and down and update the selected layer
*/
private moveLayers(): void {
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
const screenCenterY = this.cameras.main.worldView.y + this.cameras.main.height / 3;
2020-07-28 11:06:08 +02:00
const screenWidth = this.game.renderer.width;
const screenHeight = this.game.renderer.height;
for (let i = 0; i < this.containersRow.length; i++) {
for (let j = 0; j < this.containersRow[i].length; j++) {
let selectedX = this.selectedLayers[i];
if (selectedX === undefined) {
selectedX = 0;
}
this.containersRow[i][j].x = screenCenterX + (j - selectedX) * 40;
this.containersRow[i][j].y = screenCenterY + (i - this.activeRow) * 40;
const alpha1 = Math.abs(selectedX - j)*47*2/screenWidth;
const alpha2 = Math.abs(this.activeRow - i)*49*2/screenHeight;
this.containersRow[i][j].setAlpha((1 -alpha1)*(1 - alpha2));
}
}
}
/**
* @param x, the sprite's vertical position
* @param y, the sprites's horizontal position
* @param name, the sprite's name
* @return a new sprite
*/
private generateLayers(x: number, y: number, name: string): Sprite {
return new Sprite(this, x, y, name);
}
private updateSelectedLayer() {
for(let i = 0; i < this.containersRow.length; i++){
for(let j = 0; j < this.containersRow[i].length; j++){
const children = this.getContainerChildren(i, j);
this.containersRow[i][j].removeAll(true);
this.containersRow[i][j].add(children);
}
}
}
update(time: number, delta: number): void {
const middleX = this.getMiddleX();
this.tweens.add({
targets: this.customizeSceneElement,
x: middleX,
duration: 1000,
ease: 'Power3'
});
}
public onResize(): void {
2020-07-28 11:06:08 +02:00
this.moveLayers();
this.Rectangle.x = this.cameras.main.worldView.x + this.cameras.main.width / 2;
this.Rectangle.y = this.cameras.main.worldView.y + this.cameras.main.height / 3;
const middleX = this.getMiddleX();
this.tweens.add({
targets: this.customizeSceneElement,
x: middleX,
duration: 1000,
ease: 'Power3'
});
}
2020-07-28 11:06:08 +02:00
protected getMiddleX() : number{
return (this.game.renderer.width / RESOLUTION) -
(
this.customizeSceneElement
&& this.customizeSceneElement.node
&& this.customizeSceneElement.node.getBoundingClientRect().width > 0
? (this.customizeSceneElement.node.getBoundingClientRect().width / (2*RESOLUTION))
: 150
);
}
2020-07-28 11:06:08 +02:00
private nextSceneToCamera(){
const layers: string[] = [];
let i = 0;
for (const layerItem of this.selectedLayers) {
if (layerItem !== undefined) {
layers.push(this.layers[i][layerItem].name);
}
i++;
}
if (!areCharacterLayersValid(layers)) {
return;
}
gameManager.setCharacterLayers(layers);
this.scene.sleep(CustomizeSceneName);
this.scene.remove(SelectCharacterSceneName);
gameManager.tryResumingGame(this, EnableCameraSceneName);
}
private backToPreviousScene(){
this.scene.sleep(CustomizeSceneName);
this.scene.run(SelectCharacterSceneName);
}
2020-07-28 15:53:44 +02:00
}