Jump to content

Re-using a line graphics


Recommended Posts

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 .

image.png.06011c259dc0151ae51da855afb3d06d.png

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 by zlobul
Link to post
Share on other sites
Posted (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 by zlobul
Link to post
Share on other sites
Posted (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 by zlobul
Link to post
Share on other sites
Posted (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 by zlobul
Link to post
Share on other sites

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 :)

Link to post
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...
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...