Merge pull request #692 from thecodingmachine/develop
Deploy 2021-02-01
This commit is contained in:
commit
cc1e3bbe0e
29
.github/workflows/build-and-deploy.yml
vendored
29
.github/workflows/build-and-deploy.yml
vendored
@ -161,32 +161,3 @@ jobs:
|
||||
with:
|
||||
msg: Environment deployed at https://${{ env.GITHUB_REF_SLUG }}.workadventure.test.thecodingmachine.com
|
||||
check_for_duplicate_msg: true
|
||||
|
||||
- name: Run Cypress tests
|
||||
uses: cypress-io/github-action@v2
|
||||
if: ${{ env.GITHUB_REF_SLUG != 'master' }}
|
||||
env:
|
||||
CYPRESS_BASE_URL: https://play.${{ env.GITHUB_REF_SLUG }}.workadventure.test.thecodingmachine.com
|
||||
with:
|
||||
env: host=play.${{ env.GITHUB_REF_SLUG }}.workadventure.test.thecodingmachine.com,port=80
|
||||
spec: cypress/integration/spec.js
|
||||
wait-on: https://play.${{ env.GITHUB_REF_SLUG }}.workadventure.test.thecodingmachine.com
|
||||
working-directory: e2e
|
||||
|
||||
- name: Run Cypress tests in prod
|
||||
uses: cypress-io/github-action@v2
|
||||
if: ${{ env.GITHUB_REF_SLUG == 'master' }}
|
||||
env:
|
||||
CYPRESS_BASE_URL: https://play.workadventu.re
|
||||
with:
|
||||
env: host=play.workadventu.re
|
||||
spec: cypress/integration/spec.js
|
||||
wait-on: https://workadventu.re
|
||||
working-directory: e2e
|
||||
|
||||
- name: "Upload the screenshot on test failure"
|
||||
uses: actions/upload-artifact@v1
|
||||
if: failure()
|
||||
with:
|
||||
name: "screenshot"
|
||||
path: "./e2e/cypress/screenshots/spec.js/WorkAdventureGame -- loads (failed).png"
|
||||
|
@ -3,7 +3,8 @@
|
||||
local namespace = env.GITHUB_REF_SLUG,
|
||||
local tag = namespace,
|
||||
local url = if namespace == "master" then "workadventu.re" else namespace+".workadventure.test.thecodingmachine.com",
|
||||
local adminUrl = if namespace == "master" || namespace == "develop" || std.startsWith(namespace, "admin") then "https://"+url else null,
|
||||
// develop branch does not use admin because of issue with SSL certificate of admin as of now.
|
||||
local adminUrl = if namespace == "master" /*|| namespace == "develop"*/ || std.startsWith(namespace, "admin") then "https://"+url else null,
|
||||
"$schema": "https://raw.githubusercontent.com/thecodingmachine/deeployer/master/deeployer.schema.json",
|
||||
"version": "1.0",
|
||||
"containers": {
|
||||
|
@ -1,20 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
|
||||
wait_app:
|
||||
image: dadarek/wait-for-dependencies
|
||||
depends_on:
|
||||
- reverse-proxy
|
||||
command: front:8080
|
||||
cypress:
|
||||
# the Docker image to use from https://github.com/cypress-io/cypress-docker-images
|
||||
image: "cypress/included:3.8.3"
|
||||
depends_on:
|
||||
- reverse-proxy
|
||||
environment:
|
||||
# pass base url to test pointing at the web application
|
||||
- CYPRESS_baseUrl=http://front:8080
|
||||
working_dir: /e2e
|
||||
volumes:
|
||||
- ./e2e/:/e2e
|
3
e2e/.gitignore
vendored
3
e2e/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
screenshots/
|
||||
videos/
|
||||
node_modules/
|
@ -1,36 +0,0 @@
|
||||
# Testing with cypress
|
||||
|
||||
This project use [cypress](https://www.cypress.io/) to do functional testing of the website.
|
||||
Unfortunately we cannot integrate it with docker-compose for the moment, so you will need to install some packages locally on your pc.
|
||||
|
||||
## Getting Started
|
||||
|
||||
You will need to install theses dependancies on linux (don't know about mac):
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install libgtk2.0-0 libgtk-3-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
|
||||
```
|
||||
|
||||
Cypress can be installed locally in the e2e directory
|
||||
```bash
|
||||
cd e2e
|
||||
npm install
|
||||
```
|
||||
|
||||
|
||||
How to use:
|
||||
```bash
|
||||
npm run cy:run
|
||||
npm run cy:open
|
||||
```
|
||||
|
||||
The first command will run all tests in the terminal, while the second will open the interactive task runner which allow you to easily manage the test workflow
|
||||
|
||||
[More details here](https://docs.cypress.io/guides/getting-started/testing-your-app.html#Step-1-Start-your-server)
|
||||
|
||||
## How to test a game
|
||||
|
||||
Cypress cannot "see" and so cannot directly manipulate the canva created by Phaser.
|
||||
|
||||
This means we have to do workarounds such as exposing core objects in the window so that cypress can manipulate them or doing console that cypress can catch.
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"baseUrl": "http://workadventure.localhost",
|
||||
"video": false,
|
||||
"defaultCommandTimeout": 20000,
|
||||
"pluginsFile": false,
|
||||
"supportFile": false
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
Cypress.on('window:before:load', (win) => {
|
||||
// because this is called before any scripts
|
||||
// have loaded - the ga function is undefined
|
||||
// so we need to create it.
|
||||
win.cypressAsserter = cy.stub().as('ca')
|
||||
})
|
||||
|
||||
describe('WorkAdventureGame', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/', {
|
||||
onBeforeLoad (win) {
|
||||
cy.spy(win.console, 'log').as('console.log')
|
||||
},
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
it('loads', () => {
|
||||
cy.get('@console.log').should('be.calledWith', 'Started the game')
|
||||
cy.get('@console.log').should('be.calledWith', 'Preloading')
|
||||
cy.get('@console.log').should('be.calledWith', 'Preloading done')
|
||||
cy.get('@console.log').should('be.calledWith', 'startInit')
|
||||
cy.get('@console.log').should('be.calledWith', 'startInit done')
|
||||
});
|
||||
});
|
1406
e2e/package-lock.json
generated
1406
e2e/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"cypress": "^3.8.3"
|
||||
},
|
||||
"scripts": {
|
||||
"cy:run": "cypress run",
|
||||
"cy:open": "cypress open"
|
||||
}
|
||||
}
|
1
front/dist/.gitignore
vendored
Normal file
1
front/dist/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
index.html
|
@ -26,7 +26,7 @@
|
||||
"axios": "^0.21.1",
|
||||
"generic-type-guard": "^3.2.0",
|
||||
"google-protobuf": "^3.13.0",
|
||||
"phaser": "^3.52.0",
|
||||
"phaser": "3.24.1",
|
||||
"queue-typescript": "^1.0.1",
|
||||
"quill": "^1.3.7",
|
||||
"simple-peer": "^9.6.2",
|
||||
|
@ -1,5 +1,8 @@
|
||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
||||
import * as TypeMessages from "./TypeMessage";
|
||||
import List = Phaser.Structs.List;
|
||||
import {UpdatedLocalStreamCallback} from "../WebRtc/MediaManager";
|
||||
import {Banned} from "./TypeMessage";
|
||||
|
||||
export interface TypeMessageInterface {
|
||||
showMessage(message: string): void;
|
||||
@ -8,6 +11,7 @@ export interface TypeMessageInterface {
|
||||
export class UserMessageManager {
|
||||
|
||||
typeMessages: Map<string, TypeMessageInterface> = new Map<string, TypeMessageInterface>();
|
||||
receiveBannedMessageListener: Set<Function> = new Set<UpdatedLocalStreamCallback>();
|
||||
|
||||
constructor(private Connection: RoomConnection) {
|
||||
const valueTypeMessageTab = Object.values(TypeMessages);
|
||||
@ -21,7 +25,14 @@ export class UserMessageManager {
|
||||
initialise() {
|
||||
//receive signal to show message
|
||||
this.Connection.receiveUserMessage((type: string, message: string) => {
|
||||
this.showMessage(type, message);
|
||||
const typeMessage = this.showMessage(type, message);
|
||||
|
||||
//listener on banned receive message
|
||||
if(typeMessage instanceof Banned) {
|
||||
for (const callback of this.receiveBannedMessageListener) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -32,5 +43,10 @@ export class UserMessageManager {
|
||||
return;
|
||||
}
|
||||
classTypeMessage.showMessage(message);
|
||||
return classTypeMessage;
|
||||
}
|
||||
|
||||
setReceiveBanListener(callback: Function){
|
||||
this.receiveBannedMessageListener.add(callback);
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
declare let window:WindowWithCypressAsserter;
|
||||
|
||||
interface WindowWithCypressAsserter extends Window {
|
||||
cypressAsserter: CypressAsserter;
|
||||
}
|
||||
|
||||
//this class is used to communicate with cypress, our e2e testing client
|
||||
//Since cypress cannot manipulate canvas, we notified it with console logs
|
||||
class CypressAsserter {
|
||||
|
||||
constructor() {
|
||||
window.cypressAsserter = this
|
||||
}
|
||||
|
||||
gameStarted() {
|
||||
console.log('Started the game')
|
||||
}
|
||||
|
||||
preloadStarted() {
|
||||
console.log('Preloading')
|
||||
}
|
||||
|
||||
preloadFinished() {
|
||||
console.log('Preloading done')
|
||||
}
|
||||
|
||||
initStarted() {
|
||||
console.log('startInit')
|
||||
}
|
||||
|
||||
initFinished() {
|
||||
console.log('startInit done')
|
||||
}
|
||||
}
|
||||
|
||||
export const cypressAsserter = new CypressAsserter()
|
@ -6,7 +6,8 @@ export interface BodyResourceDescriptionListInterface {
|
||||
|
||||
export interface BodyResourceDescriptionInterface {
|
||||
name: string,
|
||||
img: string
|
||||
img: string,
|
||||
level?: number
|
||||
}
|
||||
|
||||
export const PLAYER_RESOURCES: BodyResourceDescriptionListInterface = {
|
||||
|
@ -23,21 +23,26 @@ export const loadAllDefaultModels = (load: LoaderPlugin): BodyResourceDescriptio
|
||||
});
|
||||
return returnArray;
|
||||
}
|
||||
export const loadCustomTexture = (load: LoaderPlugin, texture: CharacterTexture) => {
|
||||
|
||||
export const loadCustomTexture = (loaderPlugin: LoaderPlugin, texture: CharacterTexture) : Promise<BodyResourceDescriptionInterface> => {
|
||||
const name = 'customCharacterTexture'+texture.id;
|
||||
load.spritesheet(name,texture.url,{frameWidth: 32, frameHeight: 32});
|
||||
return name;
|
||||
const playerResourceDescriptor: BodyResourceDescriptionInterface = {name, img: texture.url, level: texture.level}
|
||||
return createLoadingPromise(loaderPlugin, playerResourceDescriptor);
|
||||
}
|
||||
|
||||
export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturePlugin: TextureManager, texturekeys:Array<string|BodyResourceDescriptionInterface>): Promise<string[]> => {
|
||||
const promisesList:Promise<void>[] = [];
|
||||
export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturekeys:Array<string|BodyResourceDescriptionInterface>): Promise<string[]> => {
|
||||
const promisesList:Promise<unknown>[] = [];
|
||||
texturekeys.forEach((textureKey: string|BodyResourceDescriptionInterface) => {
|
||||
const playerResourceDescriptor = getRessourceDescriptor(textureKey);
|
||||
if(!texturePlugin.exists(playerResourceDescriptor.name)) {
|
||||
console.log('Loading '+playerResourceDescriptor.name)
|
||||
promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor));
|
||||
try {
|
||||
//TODO refactor
|
||||
const playerResourceDescriptor = getRessourceDescriptor(textureKey);
|
||||
if (playerResourceDescriptor && !loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
|
||||
promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor));
|
||||
}
|
||||
}catch (err){
|
||||
console.error(err);
|
||||
}
|
||||
})
|
||||
});
|
||||
let returnPromise:Promise<Array<string|BodyResourceDescriptionInterface>>;
|
||||
if (promisesList.length > 0) {
|
||||
loadPlugin.start();
|
||||
@ -66,8 +71,14 @@ export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptio
|
||||
}
|
||||
|
||||
const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface) => {
|
||||
return new Promise<void>((res, rej) => {
|
||||
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, {frameWidth: 32, frameHeight: 32});
|
||||
loadPlugin.once('filecomplete-spritesheet-'+playerResourceDescriptor.name, () => res());
|
||||
return new Promise<BodyResourceDescriptionInterface>((res) => {
|
||||
if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
|
||||
return res(playerResourceDescriptor);
|
||||
}
|
||||
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, {
|
||||
frameWidth: 32,
|
||||
frameHeight: 32
|
||||
});
|
||||
loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, () => res(playerResourceDescriptor));
|
||||
});
|
||||
}
|
@ -30,7 +30,7 @@ import {RemotePlayer} from "../Entity/RemotePlayer";
|
||||
import {Queue} from 'queue-typescript';
|
||||
import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer";
|
||||
import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
||||
import {lazyLoadPlayerCharacterTextures} from "../Entity/PlayerTexturesLoadingManager";
|
||||
import {lazyLoadPlayerCharacterTextures, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
|
||||
import {
|
||||
CenterListener,
|
||||
layoutManager,
|
||||
@ -67,6 +67,8 @@ import {SelectCharacterScene, SelectCharacterSceneName} from "../Login/SelectCha
|
||||
import {TextureError} from "../../Exception/TextureError";
|
||||
import {addLoader} from "../Components/Loader";
|
||||
import {ErrorSceneName} from "../Reconnecting/ErrorScene";
|
||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||
|
||||
export interface GameSceneInitInterface {
|
||||
initPosition: PointInterface|null,
|
||||
@ -111,7 +113,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
MapPlayers!: Phaser.Physics.Arcade.Group;
|
||||
MapPlayersByKey : Map<number, RemotePlayer> = new Map<number, RemotePlayer>();
|
||||
Map!: Phaser.Tilemaps.Tilemap;
|
||||
Layers!: Array<Phaser.Tilemaps.TilemapLayer>;
|
||||
Layers!: Array<Phaser.Tilemaps.StaticTilemapLayer>;
|
||||
Objects!: Array<Phaser.Physics.Arcade.Sprite>;
|
||||
mapFile!: ITiledMap;
|
||||
groups: Map<number, Sprite>;
|
||||
@ -183,6 +185,14 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
preload(): void {
|
||||
addLoader(this);
|
||||
|
||||
const localUser = localUserStore.getLocalUser();
|
||||
const textures = localUser?.textures;
|
||||
if (textures) {
|
||||
for (const texture of textures) {
|
||||
loadCustomTexture(this.load, texture);
|
||||
}
|
||||
}
|
||||
|
||||
this.load.image(openChatIconName, 'resources/objects/talk.png');
|
||||
this.load.on(FILE_LOAD_ERROR, (file: {src: string}) => {
|
||||
this.scene.start(ErrorSceneName, {
|
||||
@ -339,11 +349,11 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
this.physics.world.setBounds(0, 0, this.Map.widthInPixels, this.Map.heightInPixels);
|
||||
|
||||
//add layer on map
|
||||
this.Layers = new Array<Phaser.Tilemaps.TilemapLayer>();
|
||||
this.Layers = new Array<Phaser.Tilemaps.StaticTilemapLayer>();
|
||||
let depth = -2;
|
||||
for (const layer of this.mapFile.layers) {
|
||||
if (layer.type === 'tilelayer') {
|
||||
this.addLayer(this.Map.createLayer(layer.name, this.Terrains, 0, 0).setDepth(depth));
|
||||
this.addLayer(this.Map.createStaticLayer(layer.name, this.Terrains, 0, 0).setDepth(depth));
|
||||
|
||||
const exitSceneUrl = this.getExitSceneUrl(layer);
|
||||
if (exitSceneUrl !== undefined) {
|
||||
@ -524,6 +534,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic, this.playerName);
|
||||
this.GlobalMessageManager = new GlobalMessageManager(this.connection);
|
||||
this.UserMessageManager = new UserMessageManager(this.connection);
|
||||
this.UserMessageManager.setReceiveBanListener(this.bannedUser.bind(this));
|
||||
|
||||
const self = this;
|
||||
this.simplePeer.registerPeerConnectionListener({
|
||||
@ -848,13 +859,13 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
this.cameras.main.setZoom(ZOOM_LEVEL);
|
||||
}
|
||||
|
||||
addLayer(Layer : Phaser.Tilemaps.TilemapLayer){
|
||||
addLayer(Layer : Phaser.Tilemaps.StaticTilemapLayer){
|
||||
this.Layers.push(Layer);
|
||||
}
|
||||
|
||||
createCollisionWithPlayer() {
|
||||
//add collision layer
|
||||
this.Layers.forEach((Layer: Phaser.Tilemaps.TilemapLayer) => {
|
||||
this.Layers.forEach((Layer: Phaser.Tilemaps.StaticTilemapLayer) => {
|
||||
this.physics.add.collider(this.CurrentPlayer, Layer, (object1: GameObject, object2: GameObject) => {
|
||||
//this.CurrentPlayer.say("Collision with layer : "+ (object2 as Tile).layer.name)
|
||||
});
|
||||
@ -872,7 +883,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
|
||||
createCurrentPlayer(){
|
||||
//TODO create animation moving between exit and start
|
||||
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.textures, this.characterLayers);
|
||||
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.characterLayers);
|
||||
try {
|
||||
this.CurrentPlayer = new Player(
|
||||
this,
|
||||
@ -1066,7 +1077,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
return;
|
||||
}
|
||||
|
||||
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.textures, addPlayerData.characterLayers);
|
||||
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, addPlayerData.characterLayers);
|
||||
const player = new RemotePlayer(
|
||||
addPlayerData.userId,
|
||||
this,
|
||||
@ -1235,5 +1246,14 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||
mediaManager.removeTriggerCloseJitsiFrameButton('close-jisi');
|
||||
}
|
||||
|
||||
private bannedUser(){
|
||||
this.cleanupClosingScene();
|
||||
this.userInputManager.clearAllInputKeyboard();
|
||||
this.scene.start(ErrorSceneName, {
|
||||
title: 'Banned',
|
||||
subTitle: 'You was banned of WorkAdventure',
|
||||
message: 'If you want more information, you can contact us: workadventure@thecodingmachine.com'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,8 +43,9 @@ export class ActionableItem {
|
||||
}
|
||||
this.isSelectable = true;
|
||||
if (this.sprite.pipeline) {
|
||||
this.sprite.setPipeline(OutlinePipeline.KEY);
|
||||
this.sprite.pipeline.set2f('uTextureSize', this.sprite.texture.getSourceImage().width, this.sprite.texture.getSourceImage().height);
|
||||
// Commented out to try to fix MacOS issue
|
||||
/*this.sprite.setPipeline(OutlinePipeline.KEY);
|
||||
this.sprite.pipeline.set2f('uTextureSize', this.sprite.texture.getSourceImage().width, this.sprite.texture.getSourceImage().height);*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +57,8 @@ export class ActionableItem {
|
||||
return;
|
||||
}
|
||||
this.isSelectable = false;
|
||||
this.sprite.resetPipeline();
|
||||
// Commented out to try to fix MacOS issue
|
||||
//this.sprite.resetPipeline();
|
||||
}
|
||||
|
||||
/**
|
||||
|
41
front/src/Phaser/Login/AbstractCharacterScene.ts
Normal file
41
front/src/Phaser/Login/AbstractCharacterScene.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import {ResizableScene} from "./ResizableScene";
|
||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||
import {loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
|
||||
import {CharacterTexture} from "../../Connexion/LocalUser";
|
||||
|
||||
export abstract class AbstractCharacterScene extends ResizableScene {
|
||||
|
||||
loadCustomSceneSelectCharacters() : Promise<BodyResourceDescriptionInterface[]> {
|
||||
const textures = this.getTextures();
|
||||
const promises : Promise<BodyResourceDescriptionInterface>[] = [];
|
||||
if (textures) {
|
||||
for (const texture of textures) {
|
||||
if (texture.level === -1) {
|
||||
continue;
|
||||
}
|
||||
promises.push(loadCustomTexture(this.load, texture));
|
||||
}
|
||||
}
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
loadSelectSceneCharacters() : Promise<BodyResourceDescriptionInterface[]> {
|
||||
const textures = this.getTextures();
|
||||
const promises: Promise<BodyResourceDescriptionInterface>[] = [];
|
||||
if (textures) {
|
||||
for (const texture of textures) {
|
||||
if (texture.level !== -1) {
|
||||
continue;
|
||||
}
|
||||
promises.push(loadCustomTexture(this.load, texture));
|
||||
}
|
||||
}
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
private getTextures() : CharacterTexture[]|undefined{
|
||||
const localUser = localUserStore.getLocalUser();
|
||||
return localUser?.textures;
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import {ResizableScene} from "./ResizableScene";
|
||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {addLoader} from "../Components/Loader";
|
||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
||||
|
||||
export const CustomizeSceneName = "CustomizeScene";
|
||||
|
||||
@ -20,7 +21,7 @@ enum CustomizeTextures{
|
||||
arrowUp = "arrow_up",
|
||||
}
|
||||
|
||||
export class CustomizeScene extends ResizableScene {
|
||||
export class CustomizeScene extends AbstractCharacterScene {
|
||||
|
||||
private textField!: TextField;
|
||||
private enterField!: TextField;
|
||||
@ -48,29 +49,21 @@ export class CustomizeScene extends ResizableScene {
|
||||
|
||||
preload() {
|
||||
addLoader(this);
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
this.load.image(CustomizeTextures.arrowRight, "resources/objects/arrow_right.png");
|
||||
this.load.image(CustomizeTextures.icon, "resources/logos/tcm_full.png");
|
||||
this.load.image(CustomizeTextures.arrowUp, "resources/objects/arrow_up.png");
|
||||
this.load.bitmapFont(CustomizeTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||
|
||||
this.layers = loadAllLayers(this.load);
|
||||
|
||||
const localUser = localUserStore.getLocalUser();
|
||||
|
||||
const textures = localUser?.textures;
|
||||
if (textures) {
|
||||
for (const texture of textures) {
|
||||
if(texture.level === -1){
|
||||
continue;
|
||||
}
|
||||
loadCustomTexture(this.load, texture);
|
||||
const name = 'customCharacterTexture'+texture.id;
|
||||
this.layers[texture.level].unshift({
|
||||
name,
|
||||
img: texture.url
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create() {
|
||||
|
@ -2,7 +2,6 @@ import {gameManager} from "../Game/GameManager";
|
||||
import {TextField} from "../Components/TextField";
|
||||
import {TextInput} from "../Components/TextInput";
|
||||
import Image = Phaser.GameObjects.Image;
|
||||
import {cypressAsserter} from "../../Cypress/CypressAsserter";
|
||||
import {SelectCharacterSceneName} from "./SelectCharacterScene";
|
||||
import {ResizableScene} from "./ResizableScene";
|
||||
|
||||
@ -29,16 +28,13 @@ export class LoginScene extends ResizableScene {
|
||||
}
|
||||
|
||||
preload() {
|
||||
cypressAsserter.preloadStarted();
|
||||
//this.load.image(LoginTextures.playButton, "resources/objects/play_button.png");
|
||||
this.load.image(LoginTextures.icon, "resources/logos/tcm_full.png");
|
||||
// Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap
|
||||
this.load.bitmapFont(LoginTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||
cypressAsserter.preloadFinished();
|
||||
}
|
||||
|
||||
create() {
|
||||
cypressAsserter.initStarted();
|
||||
|
||||
this.textField = new TextField(this, this.game.renderer.width / 2, 50, 'Enter your name:');
|
||||
this.nameInput = new TextInput(this, this.game.renderer.width / 2, 70, 8, this.name,(text: string) => {
|
||||
@ -59,8 +55,6 @@ export class LoginScene extends ResizableScene {
|
||||
}
|
||||
this.login(this.name);
|
||||
});
|
||||
|
||||
cypressAsserter.initFinished();
|
||||
}
|
||||
|
||||
update(time: number, delta: number): void {
|
||||
|
@ -9,6 +9,7 @@ import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {loadAllDefaultModels, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
|
||||
import {addLoader} from "../Components/Loader";
|
||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
||||
|
||||
|
||||
//todo: put this constants in a dedicated file
|
||||
@ -21,7 +22,7 @@ enum LoginTextures {
|
||||
customizeButtonSelected = "customize_button_selected"
|
||||
}
|
||||
|
||||
export class SelectCharacterScene extends ResizableScene {
|
||||
export class SelectCharacterScene extends AbstractCharacterScene {
|
||||
private readonly nbCharactersPerRow = 6;
|
||||
private textField!: TextField;
|
||||
private pressReturnField!: TextField;
|
||||
@ -44,6 +45,13 @@ export class SelectCharacterScene extends ResizableScene {
|
||||
|
||||
preload() {
|
||||
addLoader(this);
|
||||
|
||||
this.loadSelectSceneCharacters().then((bodyResourceDescriptions) => {
|
||||
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
|
||||
this.playerModels.push(bodyResourceDescription);
|
||||
});
|
||||
})
|
||||
|
||||
this.load.image(LoginTextures.playButton, "resources/objects/play_button.png");
|
||||
this.load.image(LoginTextures.icon, "resources/logos/tcm_full.png");
|
||||
// Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap
|
||||
@ -51,18 +59,6 @@ export class SelectCharacterScene extends ResizableScene {
|
||||
this.playerModels = loadAllDefaultModels(this.load);
|
||||
this.load.image(LoginTextures.customizeButton, 'resources/objects/customize.png');
|
||||
this.load.image(LoginTextures.customizeButtonSelected, 'resources/objects/customize_selected.png');
|
||||
|
||||
const localUser = localUserStore.getLocalUser();
|
||||
const textures = localUser?.textures;
|
||||
if (textures) {
|
||||
for (const texture of textures) {
|
||||
if(texture.level !== -1){
|
||||
continue;
|
||||
}
|
||||
const name = loadCustomTexture(this.load, texture);
|
||||
this.playerModels.push({name: name, img: texture.url});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
export class OutlinePipeline extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline {
|
||||
export class OutlinePipeline extends Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline {
|
||||
|
||||
// the unique id of this pipeline
|
||||
public static readonly KEY = 'Outline';
|
||||
|
@ -60,7 +60,7 @@ export class UserInputManager {
|
||||
}
|
||||
|
||||
clearAllInputKeyboard(){
|
||||
this.Scene.input.keyboard.removeAllKeys();
|
||||
this.Scene.input.keyboard.removeAllListeners();
|
||||
}
|
||||
|
||||
getEventListForGameTick(): ActiveEventList {
|
||||
|
@ -1,21 +1,19 @@
|
||||
export class HtmlUtils {
|
||||
public static getElementByIdOrFail<T extends HTMLElement>(id: string): T {
|
||||
const elem = document.getElementById(id);
|
||||
if (elem === null) {
|
||||
throw new Error("Cannot find HTML element with id '"+id+"'");
|
||||
if (HtmlUtils.isHtmlElement<T>(elem)) {
|
||||
return elem;
|
||||
}
|
||||
// FIXME: does not check the type of the returned type
|
||||
return elem as T;
|
||||
throw new Error("Cannot find HTML element with id '"+id+"'");
|
||||
}
|
||||
|
||||
public static removeElementByIdOrFail<T extends HTMLElement>(id: string): T {
|
||||
const elem = document.getElementById(id);
|
||||
if (elem === null) {
|
||||
throw new Error("Cannot find HTML element with id '"+id+"'");
|
||||
if (HtmlUtils.isHtmlElement<T>(elem)) {
|
||||
elem.remove();
|
||||
return elem;
|
||||
}
|
||||
// FIXME: does not check the type of the returned type
|
||||
elem.remove();
|
||||
return elem as T;
|
||||
throw new Error("Cannot find HTML element with id '"+id+"'");
|
||||
}
|
||||
|
||||
public static urlify(text: string): string {
|
||||
@ -24,4 +22,8 @@ export class HtmlUtils {
|
||||
return '<a href="' + url + '" target="_blank" style=":visited {color: white}">' + url + '</a>';
|
||||
})
|
||||
}
|
||||
|
||||
private static isHtmlElement<T extends HTMLElement>(elem: HTMLElement | null): elem is T {
|
||||
return elem !== null;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'phaser';
|
||||
import GameConfig = Phaser.Types.Core.GameConfig;
|
||||
import {DEBUG_MODE, JITSI_URL, RESOLUTION} from "./Enum/EnvironmentVariable";
|
||||
import {cypressAsserter} from "./Cypress/CypressAsserter";
|
||||
import {LoginScene} from "./Phaser/Login/LoginScene";
|
||||
import {ReconnectingScene} from "./Phaser/Reconnecting/ReconnectingScene";
|
||||
import {SelectCharacterScene} from "./Phaser/Login/SelectCharacterScene";
|
||||
@ -93,16 +92,15 @@ const config: GameConfig = {
|
||||
},
|
||||
callbacks: {
|
||||
postBoot: game => {
|
||||
const renderer = game.renderer;
|
||||
// Commented out to try to fix MacOS bug
|
||||
/*const renderer = game.renderer;
|
||||
if (renderer instanceof WebGLRenderer) {
|
||||
renderer.pipelines.add(OutlinePipeline.KEY, new OutlinePipeline(game));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cypressAsserter.gameStarted();
|
||||
|
||||
const game = new Phaser.Game(config);
|
||||
|
||||
window.addEventListener('resize', function (event) {
|
||||
|
@ -1771,7 +1771,7 @@ eventemitter3@^2.0.3:
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba"
|
||||
integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=
|
||||
|
||||
eventemitter3@^4.0.0, eventemitter3@^4.0.7:
|
||||
eventemitter3@^4.0.0, eventemitter3@^4.0.4:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
@ -1829,7 +1829,7 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2:
|
||||
dependencies:
|
||||
homedir-polyfill "^1.0.1"
|
||||
|
||||
exports-loader@^1.1.1:
|
||||
exports-loader@^1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-1.1.1.tgz#88c9a6877ee6a5519d7c41a016bdd99148421e69"
|
||||
integrity sha512-CmyhIR2sJ3KOfVsHjsR0Yvo+0lhRhRMAevCbB8dhTVLHsZPs0lCQTvRmR9YNvBXDBxUuhmCE2f54KqEjZUaFrg==
|
||||
@ -2528,7 +2528,7 @@ import-local@^2.0.0:
|
||||
pkg-dir "^3.0.0"
|
||||
resolve-cwd "^2.0.0"
|
||||
|
||||
imports-loader@^1.2.0:
|
||||
imports-loader@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-1.2.0.tgz#b06823d0bb42e6f5ff89bc893829000eda46693f"
|
||||
integrity sha512-zPvangKEgrrPeqeUqH0Uhc59YqK07JqZBi9a9cQ3v/EKUIqrbJHY4CvUrDus2lgQa5AmPyXuGrWP8JJTqzE5RQ==
|
||||
@ -3663,14 +3663,14 @@ pbkdf2@^3.0.3:
|
||||
safe-buffer "^5.0.1"
|
||||
sha.js "^2.4.8"
|
||||
|
||||
phaser@^3.52.0:
|
||||
version "3.52.0"
|
||||
resolved "https://registry.yarnpkg.com/phaser/-/phaser-3.52.0.tgz#834dd7a7717308c2576d2450d0806317cf3d1ea8"
|
||||
integrity sha512-oH39AUXR+cletB3GIvLnVO2J7/M6xs0D0LamVdCrbCDO3jckQOVBcqR6SJ2wam+4D5iJTCXv8K+FmxFzcTUWuA==
|
||||
phaser@3.24.1:
|
||||
version "3.24.1"
|
||||
resolved "https://registry.yarnpkg.com/phaser/-/phaser-3.24.1.tgz#376e0c965d2a35af37c06ee78627dafbde5be017"
|
||||
integrity sha512-WbrRMkbpEzarkfrq83akeauc6b8xNxsOTpDygyW7wrU2G2ne6kOYu3hji4UAaGnZaOLrVuj8ycYPjX9P1LxcDw==
|
||||
dependencies:
|
||||
eventemitter3 "^4.0.7"
|
||||
exports-loader "^1.1.1"
|
||||
imports-loader "^1.2.0"
|
||||
eventemitter3 "^4.0.4"
|
||||
exports-loader "^1.1.0"
|
||||
imports-loader "^1.1.0"
|
||||
path "^0.12.7"
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1:
|
||||
|
Loading…
Reference in New Issue
Block a user