zlobul Posted April 28, 2021 Share Posted April 28, 2021 (edited) Hi , I'm new to PIXI and I'm trying to create a dynamically changing column of lines using PIXI v5 . Lets say I would like to have 4 lines that will be placed in 10 vertically aligned positions. The 4 line types have different colors and length . The bottom position ( pos 0 ) should change on event, lets say on click and push the others up , the last position (10) should disappear from the group. As I dont think drawing 10 lines is optimal , I'm trying to find a way to re-use a single line Graphics. Not sure what the best approach should be - use line images and create sprites from them then position them in the canvas ? Or create a single line and clone it every time , then change its color , length , position ? Also should it be a graphic , sprite or texture ? So far I have tried : Created a function to draw lines , but it blueLine = new PIXI.Graphics() purpleLine = new PIXI.Graphics() pinkLine = new PIXI.Graphics() cyanLine = new PIXI.Graphics() this.drawLine(this.blueLine,2, 0x008aff, {x:400, y:470},{x:260, y:0},{x:300, y:0}) this.drawLine(this.purpleLine,2, 0x991bfa, {x:400, y:480},{x:240, y:0},{x:300, y:0}) this.drawLine(this.pinkLine,2, 0xf55497, {x:400, y:500},{x:220, y:0},{x:300, y:0}) this.drawLine(this.cyanLine,2, 0x17c3b2, {x:400, y:490},{x:200, y:0},{x:300, y:0}) drawLine(newLine,thickness: number, color: number, position: {x:number,y:number}, moveTo: {x:number,y:number},lineTo: {x:number,y:number} ) { this.app.stage.addChild(newLine) newLine.lineStyle(thickness, color) .moveTo(moveTo.x, moveTo.y) .lineTo(lineTo.x,lineTo.y) newLine.position.set(position.x,position.y) } This works for 4 lines , but then how to create clones to continue drawing them on the screen ? Should I create a Texture or Sprite from each of them and re-use it by creating new line ? I have also tried to create a Sprite : this.drawLine(this.line,10, 0x008aff, {x:0, y:470},{x:260, y:0},{x:300, y:0}) let lineTexture = this.app.renderer.generateTexture(this.line) let lineSprite = new PIXI.Sprite(lineTexture) lineSprite.x = 110 lineSprite.y = 200 this.lineContainer.addChild(lineSprite) this.app.stage.addChild(this.lineContainer) But it doesn't appear on the app stage , what am I doing wrong ? Thanks Edited April 28, 2021 by zlobul Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted April 28, 2021 Share Posted April 28, 2021 strange, it should work. can you make minimal demo in pixi-playground or any kind of jsfiddle sites? Quote Link to comment Share on other sites More sharing options...
zlobul Posted April 29, 2021 Author Share Posted April 29, 2021 (edited) Sure - https://www.pixiplayground.com/#/edit/aj27y5c_43_nRiQoOGvIv or this one : https://www.pixiplayground.com/#/edit/WLgv1hHjxtRPEUsbtr1_L Also which method will be faster , to draw the lines or to load them as Sprites from image files ? I know the amount of operations is low here - only 10 lines , but in theory loading them from .png files looks to me the faster method. Edited April 29, 2021 by zlobul Quote Link to comment Share on other sites More sharing options...
zlobul Posted April 29, 2021 Author Share Posted April 29, 2021 (edited) I think I managed to do it with image files: wheelContainer = new PIXI.Container() blueLine = new PIXI.Texture.from('img/Blue_line.png') purpleLine = new PIXI.Texture.from('img/Purple_line.png') pinkLine = new PIXI.Texture.from('img/Pink_line.png') cyanLine = new PIXI.Texture.from('img/Cyan_line.png') const lines = [this.blueLine, this.purpleLine, this.pinkLine, this.cyanLine] for (let i = 0; i < 40; i++) { let texture = lines[Math.floor(Math.random() * lines.length)] let newLineSprite = new PIXI.Sprite(texture) newLineSprite.anchor.set(1) newLineSprite.y = -10 - (i * 10) this.lineContainer.addChild(newLineSprite) } this.lineContainer.position.set(800, 510) this.app.stage.addChild(this.lineContainer) The question remains , which approach will be faster - drawing the lines or load them as Textures from PNG files ? Edited April 29, 2021 by zlobul Quote Link to comment Share on other sites More sharing options...
zlobul Posted April 29, 2021 Author Share Posted April 29, 2021 (edited) Here is the final code I wrote to make it work , not sure if there is a better way .... blueLine = new PIXI.Texture.from('img/Blue_line.png') purpleLine = new PIXI.Texture.from('img/Purple_line.png') pinkLine = new PIXI.Texture.from('img/Pink_line.png') cyanLine = new PIXI.Texture.from('img/Cyan_line.png') lastWins = new Map() // just generating random line type sprites and position them in the container const lines = [this.blueLine, this.purpleLine, this.pinkLine, this.cyanLine] for (let linePos = 0; linePos < 40; linePos++) { let texture = lines[Math.floor(Math.random() * lines.length)] let newLineSprite = new PIXI.Sprite(texture) newLineSprite.anchor.set(1) newLineSprite.y = -10 - (linePos * 10) this.lastWins.set(linePos, newLineSprite ) this.lineContainer.addChild(newLineSprite) } this.lineContainer.position.set(800, 510) this.app.stage.addChild(this.lineContainer) .... onComplete: () => { this.drawWiningLine(number) } drawWiningLine(sector: number){ let texture if (this.isEven(sector)){ texture = this.blueLine } else if (gameConfig.sectorNumbersPink.includes(sector)) { texture = this.pinkLine } else if (gameConfig.sectorNumbersPurple.includes(sector)) { texture = this.purpleLine } else { texture = this.cyanLine } this.addToLineMap(this.lastWins, texture) } addToLineMap(map, texture){ map.forEach((value, key) => { if ( key == 39 ) { let newLineSprite = new PIXI.Sprite(texture) this.positionLine(key,newLineSprite) map.set(key, newLineSprite ) } else if (key == 0) { this.lineContainer.removeChild(map.get(key)) let nextPosValue = map.get(key+1) map.set(key,nextPosValue) } else { let nextPosValue = map.get(key+1) map.set(key,nextPosValue) } }) this.drawLineMap(map) } drawLineMap(map) { map.forEach((value, key) => { this.positionLine(key,value) this.lineContainer.addChild(value) }) } positionLine(position,sprite){ sprite.anchor.set(1) sprite.y = -(position * 10) } Edited April 29, 2021 by zlobul Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted April 29, 2021 Share Posted April 29, 2021 > Also which method will be faster , to draw the lines or to load them as Sprites from image files ? I know the amount of operations is low here - only 10 lines , but in theory loading them from .png files looks to me the faster method. I dont think there's a difference on 10 lines karlbot and zlobul 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.