Merge pull request #807 from thecodingmachine/improvePlayerAnims

FIX: player anims correctly stop on the idle frame
This commit is contained in:
Kharhamel 2021-03-11 16:34:20 +01:00 committed by GitHub
commit 18fa1e6153
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 75 additions and 128 deletions

View File

@ -3,7 +3,6 @@ const GROUP_RADIUS = process.env.GROUP_RADIUS ? Number(process.env.GROUP_RADIUS)
const ALLOW_ARTILLERY = process.env.ALLOW_ARTILLERY ? process.env.ALLOW_ARTILLERY == 'true' : false; const ALLOW_ARTILLERY = process.env.ALLOW_ARTILLERY ? process.env.ALLOW_ARTILLERY == 'true' : false;
const ADMIN_API_URL = process.env.ADMIN_API_URL || ''; const ADMIN_API_URL = process.env.ADMIN_API_URL || '';
const ADMIN_API_TOKEN = process.env.ADMIN_API_TOKEN || 'myapitoken'; const ADMIN_API_TOKEN = process.env.ADMIN_API_TOKEN || 'myapitoken';
const MAX_USERS_PER_ROOM = parseInt(process.env.MAX_USERS_PER_ROOM || '') || 600;
const CPU_OVERHEAT_THRESHOLD = Number(process.env.CPU_OVERHEAT_THRESHOLD) || 80; const CPU_OVERHEAT_THRESHOLD = Number(process.env.CPU_OVERHEAT_THRESHOLD) || 80;
const JITSI_URL : string|undefined = (process.env.JITSI_URL === '') ? undefined : process.env.JITSI_URL; const JITSI_URL : string|undefined = (process.env.JITSI_URL === '') ? undefined : process.env.JITSI_URL;
const JITSI_ISS = process.env.JITSI_ISS || ''; const JITSI_ISS = process.env.JITSI_ISS || '';
@ -19,7 +18,6 @@ export {
ADMIN_API_TOKEN, ADMIN_API_TOKEN,
HTTP_PORT, HTTP_PORT,
GRPC_PORT, GRPC_PORT,
MAX_USERS_PER_ROOM,
GROUP_RADIUS, GROUP_RADIUS,
ALLOW_ARTILLERY, ALLOW_ARTILLERY,
CPU_OVERHEAT_THRESHOLD, CPU_OVERHEAT_THRESHOLD,

View File

@ -7,7 +7,6 @@ import {PositionNotifier} from "./PositionNotifier";
import {Movable} from "_Model/Movable"; import {Movable} from "_Model/Movable";
import {extractDataFromPrivateRoomId, extractRoomSlugPublicRoomId, isRoomAnonymous} from "./RoomIdentifier"; import {extractDataFromPrivateRoomId, extractRoomSlugPublicRoomId, isRoomAnonymous} from "./RoomIdentifier";
import {arrayIntersect} from "../Services/ArrayHelper"; import {arrayIntersect} from "../Services/ArrayHelper";
import {MAX_USERS_PER_ROOM} from "../Enum/EnvironmentVariable";
import {JoinRoomMessage} from "../Messages/generated/messages_pb"; import {JoinRoomMessage} from "../Messages/generated/messages_pb";
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils"; import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
import {ZoneSocket} from "src/RoomManager"; import {ZoneSocket} from "src/RoomManager";
@ -116,8 +115,6 @@ export class GameRoom {
this.nextUserId++; this.nextUserId++;
this.users.set(user.id, user); this.users.set(user.id, user);
this.usersByUuid.set(user.uuid, user); this.usersByUuid.set(user.uuid, user);
// Let's call update position to trigger the join / leave room
//this.updatePosition(socket, userPosition);
this.updateUserGroup(user); this.updateUserGroup(user);
// Notify admins // Notify admins
@ -149,10 +146,6 @@ export class GameRoom {
} }
} }
get isFull(): boolean {
return this.users.size >= MAX_USERS_PER_ROOM;
}
public isEmpty(): boolean { public isEmpty(): boolean {
return this.users.size === 0 && this.admins.size === 0; return this.users.size === 0 && this.admins.size === 0;
} }

View File

@ -1,4 +1,4 @@
import {PlayerAnimationNames} from "../Phaser/Player/Animation"; import {PlayerAnimationDirections} from "../Phaser/Player/Animation";
import {UserSimplePeerInterface} from "../WebRtc/SimplePeer"; import {UserSimplePeerInterface} from "../WebRtc/SimplePeer";
import {SignalData} from "simple-peer"; import {SignalData} from "simple-peer";
import {RoomConnection} from "./RoomConnection"; import {RoomConnection} from "./RoomConnection";

View File

@ -1,4 +1,4 @@
import {PlayerAnimationNames} from "../Player/Animation"; import {PlayerAnimationDirections, PlayerAnimationTypes} from "../Player/Animation";
import {SpeechBubble} from "./SpeechBubble"; import {SpeechBubble} from "./SpeechBubble";
import BitmapText = Phaser.GameObjects.BitmapText; import BitmapText = Phaser.GameObjects.BitmapText;
import Container = Phaser.GameObjects.Container; import Container = Phaser.GameObjects.Container;
@ -10,8 +10,7 @@ interface AnimationData {
frameRate: number; frameRate: number;
repeat: number; repeat: number;
frameModel: string; //todo use an enum frameModel: string; //todo use an enum
frameStart: number; frames : number[]
frameEnd: number;
} }
export abstract class Character extends Container { export abstract class Character extends Container {
@ -19,7 +18,7 @@ export abstract class Character extends Container {
private readonly playerName: BitmapText; private readonly playerName: BitmapText;
public PlayerValue: string; public PlayerValue: string;
public sprites: Map<string, Sprite>; public sprites: Map<string, Sprite>;
private lastDirection: string = PlayerAnimationNames.WalkDown; private lastDirection: PlayerAnimationDirections = PlayerAnimationDirections.Down;
//private teleportation: Sprite; //private teleportation: Sprite;
private invisible: boolean; private invisible: boolean;
@ -28,7 +27,7 @@ export abstract class Character extends Container {
y: number, y: number,
texturesPromise: Promise<string[]>, texturesPromise: Promise<string[]>,
name: string, name: string,
direction: string, direction: PlayerAnimationDirections,
moving: boolean, moving: boolean,
frame?: string | number frame?: string | number
) { ) {
@ -81,7 +80,7 @@ export abstract class Character extends Container {
this.getPlayerAnimations(texture).forEach(d => { this.getPlayerAnimations(texture).forEach(d => {
this.scene.anims.create({ this.scene.anims.create({
key: d.key, key: d.key,
frames: this.scene.anims.generateFrameNumbers(d.frameModel, {start: d.frameStart, end: d.frameEnd}), frames: this.scene.anims.generateFrameNumbers(d.frameModel, {frames: d.frames}),
frameRate: d.frameRate, frameRate: d.frameRate,
repeat: d.repeat repeat: d.repeat
}); });
@ -96,37 +95,57 @@ export abstract class Character extends Container {
private getPlayerAnimations(name: string): AnimationData[] { private getPlayerAnimations(name: string): AnimationData[] {
return [{ return [{
key: `${name}-${PlayerAnimationNames.WalkDown}`, key: `${name}-${PlayerAnimationDirections.Down}-${PlayerAnimationTypes.Walk}`,
frameModel: name, frameModel: name,
frameStart: 0, frames: [0, 1, 2, 1],
frameEnd: 2,
frameRate: 10, frameRate: 10,
repeat: -1 repeat: -1
}, { }, {
key: `${name}-${PlayerAnimationNames.WalkLeft}`, key: `${name}-${PlayerAnimationDirections.Left}-${PlayerAnimationTypes.Walk}`,
frameModel: name, frameModel: name,
frameStart: 3, frames: [3, 4, 5, 4],
frameEnd: 5,
frameRate: 10, frameRate: 10,
repeat: -1 repeat: -1
}, { }, {
key: `${name}-${PlayerAnimationNames.WalkRight}`, key: `${name}-${PlayerAnimationDirections.Right}-${PlayerAnimationTypes.Walk}`,
frameModel: name, frameModel: name,
frameStart: 6, frames: [6, 7, 8, 7],
frameEnd: 8,
frameRate: 10, frameRate: 10,
repeat: -1 repeat: -1
}, { }, {
key: `${name}-${PlayerAnimationNames.WalkUp}`, key: `${name}-${PlayerAnimationDirections.Up}-${PlayerAnimationTypes.Walk}`,
frameModel: name, frameModel: name,
frameStart: 9, frames: [9, 10, 11, 10],
frameEnd: 11,
frameRate: 10, frameRate: 10,
repeat: -1 repeat: -1
},{
key: `${name}-${PlayerAnimationDirections.Down}-${PlayerAnimationTypes.Idle}`,
frameModel: name,
frames: [1],
frameRate: 10,
repeat: 1
}, {
key: `${name}-${PlayerAnimationDirections.Left}-${PlayerAnimationTypes.Idle}`,
frameModel: name,
frames: [4],
frameRate: 10,
repeat: 1
}, {
key: `${name}-${PlayerAnimationDirections.Right}-${PlayerAnimationTypes.Idle}`,
frameModel: name,
frames: [7],
frameRate: 10,
repeat: 1
}, {
key: `${name}-${PlayerAnimationDirections.Up}-${PlayerAnimationTypes.Idle}`,
frameModel: name,
frames: [10],
frameRate: 10,
repeat: 1
}]; }];
} }
protected playAnimation(direction : string, moving: boolean): void { protected playAnimation(direction : PlayerAnimationDirections, moving: boolean): void {
if (this.invisible) return; if (this.invisible) return;
for (const [texture, sprite] of this.sprites.entries()) { for (const [texture, sprite] of this.sprites.entries()) {
if (!sprite.anims) { if (!sprite.anims) {
@ -134,10 +153,9 @@ export abstract class Character extends Container {
return; return;
} }
if (moving && (!sprite.anims.currentAnim || sprite.anims.currentAnim.key !== direction)) { if (moving && (!sprite.anims.currentAnim || sprite.anims.currentAnim.key !== direction)) {
sprite.play(texture+'-'+direction, true); sprite.play(texture+'-'+direction+'-'+PlayerAnimationTypes.Walk, true);
} else if (!moving) { } else if (!moving) {
sprite.anims.play(texture + '-' + direction, true); sprite.anims.play(texture + '-' + direction + '-'+PlayerAnimationTypes.Idle, true);
sprite.anims.stop();
} }
} }
} }
@ -157,17 +175,17 @@ export abstract class Character extends Container {
// up or down animations are prioritized over left and right // up or down animations are prioritized over left and right
if (body.velocity.y < 0) { //moving up if (body.velocity.y < 0) { //moving up
this.lastDirection = PlayerAnimationNames.WalkUp; this.lastDirection = PlayerAnimationDirections.Up;
this.playAnimation(PlayerAnimationNames.WalkUp, true); this.playAnimation(PlayerAnimationDirections.Up, true);
} else if (body.velocity.y > 0) { //moving down } else if (body.velocity.y > 0) { //moving down
this.lastDirection = PlayerAnimationNames.WalkDown; this.lastDirection = PlayerAnimationDirections.Down;
this.playAnimation(PlayerAnimationNames.WalkDown, true); this.playAnimation(PlayerAnimationDirections.Down, true);
} else if (body.velocity.x > 0) { //moving right } else if (body.velocity.x > 0) { //moving right
this.lastDirection = PlayerAnimationNames.WalkRight; this.lastDirection = PlayerAnimationDirections.Right;
this.playAnimation(PlayerAnimationNames.WalkRight, true); this.playAnimation(PlayerAnimationDirections.Right, true);
} else if (body.velocity.x < 0) { //moving left } else if (body.velocity.x < 0) { //moving left
this.lastDirection = PlayerAnimationNames.WalkLeft; this.lastDirection = PlayerAnimationDirections.Left;
this.playAnimation(PlayerAnimationNames.WalkLeft, true); this.playAnimation(PlayerAnimationDirections.Left, true);
} }
this.setDepth(this.y); this.setDepth(this.y);

View File

@ -1,6 +1,7 @@
import {GameScene} from "../Game/GameScene"; import {GameScene} from "../Game/GameScene";
import {PointInterface} from "../../Connexion/ConnexionModels"; import {PointInterface} from "../../Connexion/ConnexionModels";
import {Character} from "../Entity/Character"; import {Character} from "../Entity/Character";
import {PlayerAnimationDirections} from "../Player/Animation";
/** /**
* Class representing the sprite of a remote player (a player that plays on another computer) * Class representing the sprite of a remote player (a player that plays on another computer)
@ -15,22 +16,17 @@ export class RemotePlayer extends Character {
y: number, y: number,
name: string, name: string,
texturesPromise: Promise<string[]>, texturesPromise: Promise<string[]>,
direction: string, direction: PlayerAnimationDirections,
moving: boolean moving: boolean
) { ) {
super(Scene, x, y, texturesPromise, name, direction, moving, 1); super(Scene, x, y, texturesPromise, name, direction, moving, 1);
//set data //set data
this.userId = userId; this.userId = userId;
//todo: implement on click action
/*this.playerName.setInteractive();
this.playerName.on('pointerup', () => {
});*/
} }
updatePosition(position: PointInterface): void { updatePosition(position: PointInterface): void {
this.playAnimation(position.direction, position.moving); this.playAnimation(position.direction as PlayerAnimationDirections, position.moving);
this.setX(position.x); this.setX(position.x);
this.setY(position.y); this.setY(position.y);

View File

@ -13,7 +13,7 @@ import {CurrentGamerInterface, hasMovedEventName, Player} from "../Player/Player
import {DEBUG_MODE, JITSI_PRIVATE_MODE, POSITION_DELAY, RESOLUTION, ZOOM_LEVEL} from "../../Enum/EnvironmentVariable"; import {DEBUG_MODE, JITSI_PRIVATE_MODE, POSITION_DELAY, RESOLUTION, ZOOM_LEVEL} from "../../Enum/EnvironmentVariable";
import {ITiledMap, ITiledMapLayer, ITiledMapLayerProperty, ITiledMapObject, ITiledTileSet} from "../Map/ITiledMap"; import {ITiledMap, ITiledMapLayer, ITiledMapLayerProperty, ITiledMapObject, ITiledTileSet} from "../Map/ITiledMap";
import {AddPlayerInterface} from "./AddPlayerInterface"; import {AddPlayerInterface} from "./AddPlayerInterface";
import {PlayerAnimationNames} from "../Player/Animation"; import {PlayerAnimationDirections} from "../Player/Animation";
import {PlayerMovement} from "./PlayerMovement"; import {PlayerMovement} from "./PlayerMovement";
import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator"; import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator";
import {RemotePlayer} from "../Entity/RemotePlayer"; import {RemotePlayer} from "../Entity/RemotePlayer";
@ -865,7 +865,7 @@ export class GameScene extends ResizableScene implements CenterListener {
this.startY, this.startY,
this.playerName, this.playerName,
texturesPromise, texturesPromise,
PlayerAnimationNames.WalkDown, PlayerAnimationDirections.Down,
false, false,
this.userInputManager this.userInputManager
); );
@ -914,16 +914,16 @@ export class GameScene extends ResizableScene implements CenterListener {
let x = event.x; let x = event.x;
let y = event.y; let y = event.y;
switch (event.direction) { switch (event.direction) {
case PlayerAnimationNames.WalkUp: case PlayerAnimationDirections.Up:
y -= 32; y -= 32;
break; break;
case PlayerAnimationNames.WalkDown: case PlayerAnimationDirections.Down:
y += 32; y += 32;
break; break;
case PlayerAnimationNames.WalkLeft: case PlayerAnimationDirections.Left:
x -= 32; x -= 32;
break; break;
case PlayerAnimationNames.WalkRight: case PlayerAnimationDirections.Right:
x += 32; x += 32;
break; break;
default: default:
@ -1059,7 +1059,7 @@ export class GameScene extends ResizableScene implements CenterListener {
addPlayerData.position.y, addPlayerData.position.y,
addPlayerData.name, addPlayerData.name,
texturesPromise, texturesPromise,
addPlayerData.position.direction, addPlayerData.position.direction as PlayerAnimationDirections,
addPlayerData.position.moving addPlayerData.position.moving
); );
this.MapPlayers.add(player); this.MapPlayers.add(player);

View File

@ -1,9 +1,13 @@
export enum PlayerAnimationNames { export enum PlayerAnimationDirections {
WalkDown = 'down', Down = 'down',
WalkLeft = 'left', Left = 'left',
WalkUp = 'up', Up = 'up',
WalkRight = 'right', Right = 'right',
}
export enum PlayerAnimationTypes {
Walk = 'walk',
Idle = 'idle',
} }

View File

@ -1,4 +1,4 @@
import {PlayerAnimationNames} from "./Animation"; import {PlayerAnimationDirections} from "./Animation";
import {GameScene} from "../Game/GameScene"; import {GameScene} from "../Game/GameScene";
import {UserInputEvent, UserInputManager} from "../UserInput/UserInputManager"; import {UserInputEvent, UserInputManager} from "../UserInput/UserInputManager";
import {Character} from "../Entity/Character"; import {Character} from "../Entity/Character";
@ -11,7 +11,7 @@ export interface CurrentGamerInterface extends Character{
} }
export class Player extends Character implements CurrentGamerInterface { export class Player extends Character implements CurrentGamerInterface {
private previousDirection: string = PlayerAnimationNames.WalkDown; private previousDirection: string = PlayerAnimationDirections.Down;
private wasMoving: boolean = false; private wasMoving: boolean = false;
constructor( constructor(
@ -20,7 +20,7 @@ export class Player extends Character implements CurrentGamerInterface {
y: number, y: number,
name: string, name: string,
texturesPromise: Promise<string[]>, texturesPromise: Promise<string[]>,
direction: string, direction: PlayerAnimationDirections,
moving: boolean, moving: boolean,
private userInputManager: UserInputManager private userInputManager: UserInputManager
) { ) {
@ -43,20 +43,20 @@ export class Player extends Character implements CurrentGamerInterface {
let y = 0; let y = 0;
if (activeEvents.get(UserInputEvent.MoveUp)) { if (activeEvents.get(UserInputEvent.MoveUp)) {
y = - moveAmount; y = - moveAmount;
direction = PlayerAnimationNames.WalkUp; direction = PlayerAnimationDirections.Up;
moving = true; moving = true;
} else if (activeEvents.get(UserInputEvent.MoveDown)) { } else if (activeEvents.get(UserInputEvent.MoveDown)) {
y = moveAmount; y = moveAmount;
direction = PlayerAnimationNames.WalkDown; direction = PlayerAnimationDirections.Down;
moving = true; moving = true;
} }
if (activeEvents.get(UserInputEvent.MoveLeft)) { if (activeEvents.get(UserInputEvent.MoveLeft)) {
x = -moveAmount; x = -moveAmount;
direction = PlayerAnimationNames.WalkLeft; direction = PlayerAnimationDirections.Left;
moving = true; moving = true;
} else if (activeEvents.get(UserInputEvent.MoveRight)) { } else if (activeEvents.get(UserInputEvent.MoveRight)) {
x = moveAmount; x = moveAmount;
direction = PlayerAnimationNames.WalkRight; direction = PlayerAnimationDirections.Right;
moving = true; moving = true;
} }
if (x !== 0 || y !== 0) { if (x !== 0 || y !== 0) {

View File

@ -264,31 +264,6 @@ export class SocketManager implements ZoneEventListener {
pusherToBackMessage.setItemeventmessage(itemEventMessage); pusherToBackMessage.setItemeventmessage(itemEventMessage);
client.backConnection.write(pusherToBackMessage); client.backConnection.write(pusherToBackMessage);
/*const itemEvent = ProtobufUtils.toItemEvent(itemEventMessage);
try {
const world = this.Worlds.get(ws.roomId);
if (!world) {
console.error("Could not find world with id '", ws.roomId, "'");
return;
}
const subMessage = new SubMessage();
subMessage.setItemeventmessage(itemEventMessage);
// Let's send the event without using the SocketIO room.
for (const user of world.getUsers().values()) {
const client = this.searchClientByIdOrFail(user.id);
//client.emit(SocketIoEvent.ITEM_EVENT, itemEvent);
emitInBatch(client, subMessage);
}
world.setItemState(itemEvent.itemId, itemEvent.state);
} catch (e) {
console.error('An error occurred on "item_event"');
console.error(e);
}*/
} }
async handleReportMessage(client: ExSocketInterface, reportPlayerMessage: ReportPlayerMessage) { async handleReportMessage(client: ExSocketInterface, reportPlayerMessage: ReportPlayerMessage) {
@ -310,25 +285,6 @@ export class SocketManager implements ZoneEventListener {
pusherToBackMessage.setWebrtcsignaltoservermessage(data); pusherToBackMessage.setWebrtcsignaltoservermessage(data);
socket.backConnection.write(pusherToBackMessage); socket.backConnection.write(pusherToBackMessage);
//send only at user
/*const client = this.sockets.get(data.getReceiverid());
if (client === undefined) {
console.warn("While exchanging a WebRTC signal: client with id ", data.getReceiverid(), " does not exist. This might be a race condition.");
return;
}
const webrtcSignalToClient = new WebRtcSignalToClientMessage();
webrtcSignalToClient.setUserid(socket.userId);
webrtcSignalToClient.setSignal(data.getSignal());
const serverToClientMessage = new ServerToClientMessage();
serverToClientMessage.setWebrtcsignaltoclientmessage(webrtcSignalToClient);
if (!client.disconnecting) {
client.send(serverToClientMessage.serializeBinary().buffer, true);
}*/
} }
emitScreenSharing(socket: ExSocketInterface, data: WebRtcSignalToServerMessage): void { emitScreenSharing(socket: ExSocketInterface, data: WebRtcSignalToServerMessage): void {
@ -336,24 +292,6 @@ export class SocketManager implements ZoneEventListener {
pusherToBackMessage.setWebrtcscreensharingsignaltoservermessage(data); pusherToBackMessage.setWebrtcscreensharingsignaltoservermessage(data);
socket.backConnection.write(pusherToBackMessage); socket.backConnection.write(pusherToBackMessage);
//send only at user
/*const client = this.sockets.get(data.getReceiverid());
if (client === undefined) {
console.warn("While exchanging a WEBRTC_SCREEN_SHARING signal: client with id ", data.getReceiverid(), " does not exist. This might be a race condition.");
return;
}
const webrtcSignalToClient = new WebRtcSignalToClientMessage();
webrtcSignalToClient.setUserid(socket.userId);
webrtcSignalToClient.setSignal(data.getSignal());
const serverToClientMessage = new ServerToClientMessage();
serverToClientMessage.setWebrtcscreensharingsignaltoclientmessage(webrtcSignalToClient);
if (!client.disconnecting) {
client.send(serverToClientMessage.serializeBinary().buffer, true);
}*/
} }
private searchClientByIdOrFail(userId: number): ExSocketInterface { private searchClientByIdOrFail(userId: number): ExSocketInterface {