Jump to content

Camera from JSON map (mapeditor)


amirGi
 Share

Recommended Posts

Hi everyone, 

I'm trying to build a camera for a large exported JSON map. Currently, what I'm doing is pivoting the movement around the player to give the illusion of movement like this in the game loop

``` 

 this.playerOffsetX -= this.sprite.vx;
 this.playerOffsetY -= this.sprite.vy;

 this.player.x += this.sprite.vx; //NOTE, this does not actually move the sprite, this.player is just a Javascript object with an x and y property
 this.player.y += this.sprite.vy;
 this.staticBackground.pivot.set(this.player.x, this.player.y);

```

Now after the player has moved a number of pixels = the length of my file, I re-draw the map by adjusting the row and column of the original map and re-draw everything again (inefficient, I know for now until I get it working correctly)

```

 renderMap(initial = false) {
        //move the camera to give illusion of movement
        // if (newLeftX === this.leftX && newLeftY === this.leftY && !initial) return;
        const layers = this.map.layers;
        //camera spans 10 tiles to right and down
        const mapWidth = this.map.width;
        const mapHeight = this.map.height;
        var updateMap = initial;
        if (!initial) {
            // this.staticBackground.position.set(this.sprite.x, this.sprite.y);
            if (this.playerOffsetX !== 0) {
                if (this.playerOffsetX % SQUARELENGTH === 0) {
                    this.staticBackground.removeChildren();
                    const step = Math.floor(this.playerOffsetX / SQUARELENGTH);
                    this.leftX -= step;
                    if (this.leftX <= 0) {
                        this.leftX = 0;
                    }
                    this.playerOffsetX = this.sprite.width / 2;
                    updateMap = true;
                }
            } 
            if (this.playerOffsetY !== 0) {
                if (this.playerOffsetY % SQUARELENGTH === 0) {
                    this.staticBackground.removeChildren();
                    //TODO: fix this
                    const step = Math.floor(this.playerOffsetY / SQUARELENGTH);
                    this.leftY -= step;
                    console.log("step: ", step," new y:", this.leftY);
                    if (this.leftY <= 0) {
                        this.leftY = 0;
                    }
                    this.playerOffsetY = this.sprite.height / 2;
                    updateMap = true;
                    console.log("refresh y: ", this.leftY);
                }             
            } 

            if (!updateMap) {
                return ;
            }
        } else {
            this.staticBackground.position.set(0, 0);
        }
        console.log("ran: ", this.leftX, this.leftY);
        for (let layer = 0; layer < layers.length; layer++) {
            const currLayerData = layers[layer].data;
            //calculate exact window we need to iterate, since window is square
            //but data is a 1D array, we will still encounter some elements outside window
            //still a 4x improvement
            const start = (this.leftY * mapWidth - 1) + this.leftX;
            const end = start + WINDOW_WIDTH + (WINDOW_HEIGHT * mapWidth) + 1;
            console.log(this.leftX, this.leftY, start, end, currLayerData.length);
            for (let i = start; i < end; i++) {
                //position on our screen
                //data is stored as one very long string, representing a 2D grid
                //y and x are in terms of rows and cols of tiles not raw pixels
                const y = i / mapHeight| 0;
                const x = i % mapWidth | 0;
                //choose tile
                if (currLayerData[i] !== 0 && currLayerData[i] < 100) {
                    //only continue if in window of map
                    const yOffset = y - this.leftY;
                    const xOffset = x - this.leftX
                    //tile window is WINDOW_WIDTH x WINDOW_HEIGHT
                    if (yOffset >= -5 && yOffset <= WINDOW_HEIGHT + 5 && xOffset >= -5 && xOffset <= WINDOW_WIDTH + 5) {
                        //elements are stored corresponding to sequential ids, that map back
                        //to the tileset - 20 = # of tiles in each row in our tileset
                        const tileRow = Math.floor(currLayerData[i] / 20);
                        const tileCol = ((currLayerData[i] - 1) % 20);
                        const sprite = new PIXI.Texture(TextureCache["/static/img/rpg.png"]);
                        sprite.frame = new PIXI.Rectangle(tileCol * SQUARELENGTH, tileRow * SQUARELENGTH, SQUARELENGTH, SQUARELENGTH);
                        const layer = new PIXI.Sprite(sprite);
                        layer.x = xOffset * SQUARELENGTH;
                        layer.y = yOffset * SQUARELENGTH;
                        this.staticBackground.addChild(layer);
                    }
                }
            }
        }
    }

```

The problem is that I'm getting some weird tearing issues - I think the problem is to do with pivoting - I pivot the map around the player coordinates (which keeps increasing or decreasing) but when I redraw the map in the given area, the pivot is not adjusted for that offset, but I'm not sure which offset that is. 

 

Anybody have an idea of why this is not working correctly? Is there an easier/better approach?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...