Phaser 3 - Saving and Loading dynamic maps (tilemaps)
Tags: javascript, beginners, postgres
Published: 2020-03-10 12:01:05

__About Me__: I've been programming for just over 3 years and I'm currently looking for a job in web development/game design.

__About the topic__: I have seen many phaser 3 developers attempting to create dynamic maps, which could be saved and exported but they couldn't find the solution, so I decided to attempt and solve this problem.

__About the Tools used__: SQL (Postgres), ruby on rails for back-end API, Phaser3 and Reg-ex for basic security.

__About the Level__: This tutorial is meant for a complete beginner so everybody could understand! but remember in this tutorial I don't show a way to secure user route or use and authorization methods.

__Example of usage__ : <a href="https://lastresort.pw" target="_blank">LastResort.pw</a>

{% vimeo: 396294350 %}

<center> End Result map saved to the current user <center/>

Our first step is creating a rails app and setting up a Relational database:

I am using ruby on rails for this tutorial but this method could work on any other web framework.

> Rails part starts here, setting new rails app with webpacker and Postgres DB

to create a new rails app with webpacker and Postgres DB

`rails new $yourappname --webpack --database=postgresql`

![Database photo](https://i.imgur.com/ISU8NHE.png)

<center>In this database each user has base_commands column which will be an array of commands, we will touch this later.
The structure table contains two columns, placed and amount both being integer, which will represent the number of structures owned and the number of structures placed on the tilemap.
User_structures is a join table containing user structures.

We will start by generating all of our models :
structure, user and user_structures

`rails g model structure amount:integer placed:integer`
`rails g model user`
`rails g model user_structure structure:references user:references`

inside User migration file
`t.string :base_commands, array:true, default: []`

Then run the following commands
`rails db:create`
`rails db:migrate`

Now after we finished setting up our database will start working on models

In the User and Structure model, we add `has_many :user_structure`
In UserStructure model we add the following lines:
`belongs_to :structure`
`belongs_to :user`

Our next step now is to create Get and Patch routes so we could access our base_commands column.

`rails g controller game`

then in routes.rb (inside config folder) we add the following routes
  `get 'base/:id', to: "game#showbase"`
  `patch 'base/:id', to: "game#updatebase"`
in our game controller we add basic checking , and responding with JSON containing user base_commands.
see code in <a href="https://github.com/matannahmani/phaser3tutorial" target="_blank">github</a>

after creating all of our API endpoints we can finally start working inside our Phaser javascript file!</center>

we will start by using the basic Phaser3 template:
`const config = {
  type: Phaser.WEBGL,
  width: 375,
  height: 812,
  scale: {
    mode: Phaser.Scale.RESIZE,
  },
  // parent  : 'phaser-app',
  scene: {
    preload: preload,
    create: create,
    update: update,
  }
}`

after finishing our basic template we need to load our tileset to the phaser3 canvas.
we will create preload function:
`function preload() {
      this.load.image('tiles', 'url/tileimg.png');
      this.load.tilemapTiledJSON('tilemap', 'url/tilemapjson.json');
`
tiles is the key for the image and tilemap is the key for the json

now will move to the create and update function:
`function create() {
      const map = this.make.tilemap({ key: 'tilemap' });
      const tiles = map.addTilesetImage('16x16s', 'tiles');
      const layer = map.createStaticLayer(1, tiles);
            layer2 = map.createDynamicLayer(2, tiles);
`
`function update() {}`
Nice ! now will should have our map running on the canvas
![Base Photo](https://i.imgur.com/yj936sf.png)

Our next step is to create our Fetch calls, We will create two functions, first the loadBase that will give us the current user draw commands,
Second, the updateBase which will add our draw command to the user database.
you could also find improved version of functions in <a href="https://github.com/matannahmani/phaser3tutorial/blob/master/app/javascript/plugins/game.js" target="_blank">github<a/>
`
function loadBase() {
  fetch('../base/1') // will get first user base
    .then((response) => {
      return response.json();
    })
    .then((commands) => {
      commands.msg.forEach((command) =>{ // iterate over commands
        eval(command); }) // execute each draw command
    });
} `

`function updateBase(data) {
    // Default options are marked with *
    fetch('../base', {
      method: 'PATCH', // *GET, POST, PUT, DELETE, etc.
      mode: 'cors', // no-cors, *cors, same-origin
      cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
      credentials: 'same-origin', // include, *same-origin, omit
      headers: {
        'Content-Type': 'application/json'
        // 'Content-Type': 'application/x-www-form-urlencoded',
      },
      redirect: 'follow', // manual, *follow, error
      referrerPolicy: 'no-referrer', // no-referrer, *client
      body: JSON.stringify(data) // body data type must match "Content-Type" header
    }).then((response) => {
    return response.json().then((data) => {
      if(data['response'] == '500')
        location.reload(); // reload page if failed placing
    }) // parses JSON response into native JavaScript objects
  });
}`

You could see full example <a href="https://lastresort.pw" target="_blank">game</a>
Or here at Lastresort.pw