Making a Multiplayer WEB RPG - Part 3: - Updating the interface
Tags: babylonjs, colyseus
Published: 2023-05-18 04:50:41

Hi all,

Having focused mostly on gameplay element and the core structure of the game, I've never spent any time into making a decent UI. The last few days, I've done a full refactorig of the UI including code & design. It is now much more tidy and organized (it was a mess!).

FYI, I'm using exclusively the **BABYLON GUI** system  (no html / css)

**NOTE**: *Be aware, I still very new at coding in typescript and javascript on a project of this scale, so please jump in if I say something silly.*

GITHUB: [https://github.com/oriongunning/t5c](https://github.com/oriongunning/t5c)

### Current design

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v33axptbdl5r2cuscg6t.png)

### Design
A few hours on Affinity Designer (great alternative to Photoshop btw) was enough to get a rough idea of what I wanted the UI to look like, admitedly it is very generic but should be easily expandable in the future.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfri77au75o5bd3olfje.png)

### Interface Elements
I've restructured every UI element into it's own class, with a much more meaninful naming convention:
- AbilityBar.ts
- Chatbox.ts
- ExperienceBar.ts
- RessurectBox.ts
- Tooltip.ts
- MainMenu.ts
- CastingBar.ts

Additionally, all the code is now following a similar structure.

### Moveable panels

All the moveable panels have their own class extended from Panel.ts, which makes creating a new panel a breeze:  

```javascript
import { Rectangle } from "@babylonjs/gui/2D/controls/rectangle";
import { Panel } from "./Panel";
export class Panel_Inventory extends Panel {

    private panel: Rectangle;

    constructor(_UI, _currentPlayer, options) {
        super(_UI, _currentPlayer, options);
        this.createContent();
    }
 
    public open() {
        super.open(); // I did not know this was possible until only recently.
        this.refresh();
    }

    private createContent() {
        // use this._panelContent as the container;
        // content here
    }

    public refresh() {
        // any update to the UI should be done here
    }
}
```

and then initialize the panel like this: 

```javascript
this.panelInventory = new Panel_Inventory(this, currentPlayer, {
    name: "Inventory",
    width: "246px;",
    height: "300px;",
    top: "-30px;",
    left: "-15px;",
    horizontal_position: Control.HORIZONTAL_ALIGNMENT_RIGHT,
    vertical_position: Control.VERTICAL_ALIGNMENT_BOTTOM,
});
```

I then added a very basic drag and drop system to Panel.ts
```
// drag and drop events
panelHeader.onPointerDownObservable.add((e) => {
    this._isPointerDown = true;
    this._pointerDownPosition = { x: e.x, y: e.y };
});
panelHeader.onPointerUpObservable.add((e) => {
    this._isPointerDown = false;
});
panelHeader.onPointerMoveObservable.add((event) => {
    if (this._isPointerDown) {
        var deltaX = event.x - this._pointerDownPosition.x;
        var deltaY = event.y - this._pointerDownPosition.y;
        this._panel.leftInPixels += deltaX;
        this._panel.topInPixels += deltaY;
        this._pointerDownPosition.x = event.x;
        this._pointerDownPosition.y = event.y;
    }
});
```

I'm sure I'm probably boring you guys by this point, as this is all pretty standard stuff. If any of the code if of interest, just check out the github repository.

### Theming
Still plenty of work to do on this part, however I've started working on having one file responsible of all the appearance (font-family, color, background, borderColor, etc..), more to come in the future once I figure how the best way to tackle this.
  
### Result

Anyway, without further ado, here's the result:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8z0e3ns2uapyqajmq5mo.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nouw5b7ajjl9nzi98uoi.png)

Alot to improve here, but as a first iteration, I'm rather happy with the result.

What do you guys think? Any suggestions?