Saqirm Posted May 10, 2020 Share Posted May 10, 2020 (edited) Hello pixijs forum and devs. I´m currently working on a multiplayer 2d Game. Problem: I'm using pivot for main game scene to follow the Player (in center) everything works okay when i have resolution at 1. -- Thanks for every reply, my english is not very well so ill try to explain throu the photos &code I'll attach some photos to show u my problem PIXIJS Inspector: - Pivot point does not scale properly with resolution. My code for resize and App I have my app declared here as static export class Game { //Create a Pixi Application public static app:any = new PIXI.Application({ antialias: false, // default: false transparent: false, // default: false autoDensity: true, autoResize: true, resolution: window.devicePixelRatio, }); // Resolution & Camera public static WIDTH:number = 728; public static HEIGHT:number = 540; I have own container which contain Game (everything expect UI) dynamic content Game.scene /** Game -> Dynamic container */ public static scene:any = new PIXI.Container(); public static init():void { // Initialize Display.Stage (Layers support) Game.app.stage = new PIXI.display.Stage(); Game.app.stage.addChild(Game.scene); Game.resize(); // call resize funct. .... Game.app.renderer.render(Game.app.stage); } // i took those function from Pixi Forum /* Helper function to resize the game to fit the full screen */ public static resize():void { const WIDTH:number = Game.WIDTH; const HEIGHT:number = Game.HEIGHT; const vpw:number = window.innerWidth; // Width of the viewport const vph:number = window.innerHeight; // Height of the viewport let nvw:number; // New game width let nvh:number; // New game height // The aspect ratio is the ratio of the screen's sizes in different dimensions. // The height-to-width aspect ratio of the game is HEIGHT / WIDTH. if (vph / vpw < HEIGHT / WIDTH) { // If height-to-width ratio of the viewport is less than the height-to-width ratio // of the game, then the height will be equal to the height of the viewport, and // the width will be scaled. nvh = vph; nvw = (nvh * WIDTH) / HEIGHT; } else { // In the else case, the opposite is happening. nvw = vpw; nvh = (nvw * HEIGHT) / WIDTH; } // Set the game screen size to the new values. // This command only makes the screen bigger --- it does not scale the contents of the Game. // There will be a lot of extra room --- or missing room --- if we don't scale the scene. Game.app.renderer.resize(vpw, vph); // This command scales the scene to fit the new size of the Game. let zoom = Camera.activeCamera ? Camera.activeCamera.zoom : 1; Game.scene.scale.set(zoom * (nvw / WIDTH), zoom * (nvh / HEIGHT)); Game.scene.filterArea = new PIXI.Rectangle(0,0, vpw, vph) } export class Camera { .... public static updateView() { if (Camera.activeCamera) Game.scene.pivot.set(Camera.activeCamera.position.x, Camera.activeCamera.position.y); } public setFocus(obj:any):void { this._cameraFocus = obj.position; } // On Update / GameLoop Camera.activeCamera.setPosition(Camera.activeCamera._cameraFocus.x, Camera.activeCamera._cameraFocus.y); ... } Camera.activeCamera._cameraFocus.x is bounded to (referenced) container position - For some reason pivoting player position (container) is not centering container to the middle if resolution is higher. in PlayerInit i have Game.camera.setFocus(this.container) -- My HTML Viewport is: <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui" /> Edited May 10, 2020 by Saqirm phongit and ivan.popelyshev 2 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 10, 2020 Share Posted May 10, 2020 > For some reason pivoting player position (container) is not centering container to the middle if resolution is higher. It looks like despite all the CSS-ing canvas is actually 2 times bigger in CSS size. Code looks fine and `autoDensity` i there, but can you please check that canvas css is correct? Quote Link to comment Share on other sites More sharing options...
Saqirm Posted May 10, 2020 Author Share Posted May 10, 2020 (edited) @ivan.popelyshev Oh i'm sorry to disturb you, i already find the problem I used Game.app.renderer.width instead of screen I'm abit confused with Game.app.screen/view/renderer widths/heights Renderer and View returns twice more than screen ... view is returning width/height based on <canvas> element i guess screen seems to be updatable with resolution while view and renderer are fixed for resolution 1. by changing it to screen it works well Game.scene.position.x = Game.app.screen.width / 2 + Game.offsetX; Game.scene.position.y = Game.app.screen.height / 2 + Game.offsetY; Edited May 10, 2020 by Saqirm Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 10, 2020 Share Posted May 10, 2020 (edited) Ye, that's why i recommend people to use "screen" (i added that property). Handling resolution is always trouble. Btw, I recommend to look in "pivot" prop too, usually its how i do it: camera.position.set(screen.width/2, screen.height/2); camera.pivot.set(lookAt.x, lookAt.y); camera.scale.set(...); basicaly, you are pinning "lookAt" local coords to position on screen, which is half of screen. It works regardless of scale or rotation, you have guarantee that position in global is pinned to local pivot. Edited May 10, 2020 by ivan.popelyshev Saqirm 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 10, 2020 Share Posted May 10, 2020 Usually people who start to use resolution mess it up at least one time even with all the explanation on forums. Now you're part of our club, Welcome to the forums! Saqirm 1 Quote Link to comment Share on other sites More sharing options...
Saqirm Posted May 10, 2020 Author Share Posted May 10, 2020 (edited) export class Camera { public static cameras:Camera[] = []; private _cameraFocus:any; public static activeCamera:Camera; private id:number = 0; private _pos:any = { x: 0, y: 0 } public zoom:number = 1; public canZoom:boolean = true; public zoomSpeed:number = 0; /** * Create a new camera for game * @param id - ID of Camera (Unique ID) * @param x - Position of camera * @param y - Position of Camera * @param scale - Scale of FOV (Zoom) * @param active - If camera is Active * @param follow - If camera should follow spirite/Obj */ constructor(id:number, x:number, y:number, scale:number, active?:boolean, follow?:any) { this.id = id; if (active) Camera.setActiveCamera(this); this.setZoom(scale, true); this.setPosition(x,y); if (follow) this.setFocus(follow); Camera.cameras[this.id] = this; return this; } /** * * @param camera - Camera Object (Optional) * @param id - ID param */ public static setActiveCamera(camera?:Camera, id?:number):any { if (camera) Camera.activeCamera = camera; if (id) Camera.activeCamera = Camera.cameras[id]; if (!Camera.activeCamera) { console.warn("Warining: Camera.setActiveCamrea - Cannot find active camera..."); return; } // Set View for camera Camera.updateZoom(); Camera.updateView(); return Camera.activeCamera; } public static updateView() { // change view only for active camera if (Camera.activeCamera) Game.scene.pivot.set(Camera.activeCamera.position.x, Camera.activeCamera.position.y); } /**** Camera */ /** * SetCameraView (Position X/Y) * @param x - X coords / global * @param y - Y coords / global */ public setPosition(x:number, y:number):void { this.position = {x: x, y: y}; if (Camera.activeCamera && this.id == Camera.activeCamera.id) Camera.updateView(); } /** Set position of camera * @param val -> Object with properities (x, y) */ public set position(val:any) { this._pos.x = val.x; this._pos.y = val.y; } /** * Get method for position */ public get position():any { return this._pos; } /** setFocus (focusing spirite/object) * @param obj - Object which are focused in camera FOV */ public setFocus(obj:any):void { this._cameraFocus = obj.position; } /** Remove focus */ public clearFocus():void { this._cameraFocus = null; this.setPosition(this.position.x, this.position.y); } /** * Update zoom of camera (FOV) * @param value - Value (Scale value) * @param update - force update screen */ public setZoom(value:number, update?:boolean):void { this.zoom = value; if (update) Camera.updateZoom(); } /** * call to Game.resize to correct values */ public static updateZoom():void { if (Camera.activeCamera) Game.resize() else throw new Error("ERROR: Can't update zoom because active camera does not exists!"); } public static update(delta:number, deltaTime:number):void { if (Camera.activeCamera._cameraFocus && Camera.activeCamera) { // Update camera position //this.activeCamera.position = {x: this.scene.pivot.x, y: this.scene.pivot.y}; } // Smooth zoom test if (Camera.activeCamera.zoomSpeed != 0) { let zoomSpeed = Camera.activeCamera.zoomSpeed > 1 ? 1 : Camera.activeCamera.zoomSpeed; Camera.activeCamera.zoomSpeed += zoomSpeed > 0 ? -(zoomSpeed * 0.15) : Math.abs(zoomSpeed* 0.15); if (Math.abs(Camera.activeCamera.zoomSpeed) < 0.2) Camera.activeCamera.zoomSpeed = 0; if (Camera.activeCamera.zoomSpeed > 0) { if (Camera.activeCamera.zoom < 2.5) Camera.activeCamera.setZoom(Camera.activeCamera.zoom + Math.abs(Camera.activeCamera.zoom * 0.01 * zoomSpeed), true); } else if (Camera.activeCamera.zoom > 1) Camera.activeCamera.setZoom(Camera.activeCamera.zoom - Math.abs(Camera.activeCamera.zoom * 0.01 * zoomSpeed), true); } } } This is my whole Camera class im using (it is only very basis) ill expand it later, maybe someone will use it. Thanks for the answer. Have a nice day. PS> Should be re-named to Viewport (camera does not exists in 2d i know :-D) Edited May 10, 2020 by Saqirm phongit and ivan.popelyshev 2 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 10, 2020 Share Posted May 10, 2020 (edited) Well it exist in 2d we just dont have it on low-level in pixi I made camera several times but i dont know how to make a good plugin. Technically its separation of projection and world transforms, and in pixi projection is just thing that converts pixels to webgl coords, it can be moved only with "renderer.render(... matrix as fourth param)" but the support is limited. That's the best we've got: https://github.com/davidfig/pixi-viewport more plugins: https://github.com/pixijs/pixi.js/wiki/v5-Resources Edited May 10, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
Saqirm Posted May 12, 2020 Author Share Posted May 12, 2020 (edited) @ivan.popelyshev Well, I found plugin Tiled for pixijs, when i already did it by myself ? I also checked viewport plugin but id like to build my own, actually for my game i do not need anything complex. Viewport in 2D is just about pivoting and positioning of the main scene which is actually view. For 3D projection or 2.5d it is much harder. It is not very hard to make own viewport for 2d projection with full support. But there is lot of super cool plugins that i will definitely use like Pixi-Tilemap which is superfast and cool. I'm using it with tiled editor Edited May 12, 2020 by Saqirm ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 12, 2020 Share Posted May 12, 2020 > Well, I found plugin Tiled for pixijs, when i already did it by myself ? > i will definitely use like Pixi-Tilemap which is superfast and cool Yes, usually people do that, its better if you know how that importer works, writing it yourself is the best way to ensure that Yes, pixi-tilemap helps with it, it doesnt care of particular format, you can use whatever you want with it. Btw, people asked and I added tile rotations/flips there some time ago. Quote Link to comment Share on other sites More sharing options...
Saqirm Posted May 12, 2020 Author Share Posted May 12, 2020 (edited) @ivan.popelyshev This is my code for rotation, it might not be the best way to do it but it works. /** * rotate single tile * @param data - Tile Data Id ((Taken from JSON) */ private checkTileRotation(data:number):number { let rotation = 0; if (data & Env.FLIPPED_DIAGONALLY_FLAG) rotation += 4; if (data & Env.FLIPPED_VERTICALLY_FLAG && data & Env.FLIPPED_HORIZONTALLY_FLAG) rotation += 4; else { if (data & Env.FLIPPED_VERTICALLY_FLAG) rotation -= 2; if (data & Env.FLIPPED_HORIZONTALLY_FLAG) rotation += 2; } return rotation; } // In LOOP (drawing) // now remove last 3 bits data &= ~(Env.FLIPPED_HORIZONTALLY_FLAG | Env.FLIPPED_VERTICALLY_FLAG | Env.FLIPPED_DIAGONALLY_FLAG); export enum Environments { // Flags for map -> Tiles (Rotation) FLIPPED_HORIZONTALLY_FLAG = 0x80000000, FLIPPED_VERTICALLY_FLAG = 0x40000000, FLIPPED_DIAGONALLY_FLAG = 0x20000000, Edited May 12, 2020 by Saqirm ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 12, 2020 Share Posted May 12, 2020 (edited) https://pixijs.io/examples/#/textures/texture-rotate.js 0,2,4,6 rotations 8,10,12,14 flip-y then rotate you flips are below 8, that isn't correc on its own, vertical is 8, diagonal is 10, horizontal is 12. just make three IF's for flags and set rotation to one of those . There shouldn't be two flags active at the same time, right? Edited May 12, 2020 by ivan.popelyshev Saqirm 1 Quote Link to comment Share on other sites More sharing options...
Saqirm Posted May 12, 2020 Author Share Posted May 12, 2020 (edited) @ivan.popelyshev You're right i will re-write it Edited May 12, 2020 by Saqirm Quote Link to comment Share on other sites More sharing options...
Saqirm Posted May 12, 2020 Author Share Posted May 12, 2020 (edited) @ivan.popelyshev Last 4 bites are: 1.-> Once right 1010 -> 6 2 -> Twice right 1100 -> 4 3 -> 3 times Right 0110 -> 2 4 -> Flipped Y 1000 -> 12 5 -> Flipped Y & Once right 1110 -> 14 6 -> Flipped Y & twice right 0100 -> 8 7 -> Flipped Y & 3times right 0010 -> 10 8 -> Flipped X 0100 -> 8 9 -> Flipped X & once Right 0010 -> 10 10 -> Flipped X & twice right 1000 -> 12 11 -> Flipped X & 3times right 1110 -> 14 32th bit => Flipped Y 31th bit => Flipped X 30th bit => Flipped Diagonaly There can be set up 3 flags at once. My final code for it. (Data) parm is Data taken from JSON. This is JSON Tiled export private checkTileRotation(data:number):number { if (data & Env.FLIPPED_VERTICALLY_FLAG && data & Env.FLIPPED_HORIZONTALLY_FLAG && data & Env.FLIPPED_DIAGONALLY_FLAG) return 14; else if (data & Env.FLIPPED_VERTICALLY_FLAG && data & Env.FLIPPED_HORIZONTALLY_FLAG) return 4; else if (data & Env.FLIPPED_VERTICALLY_FLAG && data & Env.FLIPPED_DIAGONALLY_FLAG) return 2; else if (data & Env.FLIPPED_HORIZONTALLY_FLAG && data & Env.FLIPPED_DIAGONALLY_FLAG) return 6; else if (data & Env.FLIPPED_HORIZONTALLY_FLAG) return 12; else if (data & Env.FLIPPED_VERTICALLY_FLAG) return 8; else if (data & Env.FLIPPED_DIAGONALLY_FLAG) return 10; return 0; } I tested it with all possible rotations and it works Edited May 12, 2020 by Saqirm phongit and ivan.popelyshev 2 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.