amirGi Posted August 12, 2021 Share Posted August 12, 2021 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? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.