Page 1 of 1

Seeing weird issues with canvas.line, anything better to use

Posted: Fri Jun 03, 2016 1:26 am
by octacon100
Hi All,

I'm trying to animate a line, and I'm seeing strange things happening with the canvas.line method. Looks like when the x end point is less than the x start point, the y start and end points get flipped around. Here's an example render method that I'm using.

Code: Select all

def render(self, width, height, st, at):
                render = renpy.Render(self.width, self.height)
                canvas = render.canvas()

                canvas.line("#000", (500,500), (0,0), 20) #flips the line around
                canvas.line("#000", (500,500), (1000,1000), 20)
                canvas.line("#000", (500,500), (0,1000), 20) #flips the line around
                canvas.line("#000", (500,500), (1000,0), 20) 
                canvas.line("#000", (500,500), (500,1000), 20)
                canvas.line("#000", (500,500), (1000,500), 20)
                canvas.line("#000", (500,500), (500,0), 20)
                canvas.line("#000", (500,500), (0,500), 20)
Any way to fix this, or is there something better to use? Otherwise animating a flowing line is impossible in certain directions.

Thanks in advance!

Re: Seeing weird issues with canvas.line, anything better to

Posted: Fri Jun 03, 2016 6:43 pm
by octacon100
Ended up fixing this by flipping the start and end points around if the end x position is less than the start x position. Seems to work just as well. Might have a UDD up here if I can get around to it.

Re: Seeing weird issues with canvas.line, anything better to

Posted: Sat Jun 04, 2016 6:01 am
by octacon100
Ok, made a hopefully helpful UDD for anyone who wants animated lines or just lines in general, here's the code dump and testing scripts.

Code: Select all

init python:

    class Line(renpy.Displayable):

        def __init__(self,  baseColor, startPos, endPos, lineWidth=20, animatedOn=False, animatedColor=Color("000000"), baseOn=True, **kwargs):
            # Pass additional properties on to the renpy.Displayable
            # constructor.
            super(Line, self).__init__(**kwargs)

            self.width = config.screen_width
            self.height = config.screen_height
            self.startPos = startPos
            self.endPos = endPos
            self.lineWidth = lineWidth
            self.baseColor = baseColor
            self.baseOn = baseOn
            self.animatedOn = animatedOn
            self.animatedColor = animatedColor

            self.drawFrames = 20.0 #Must have a decimal point/be a float to work
            self.startPosX = startPos[0]
            self.startPosY = startPos[1]
            self.currentPosX = self.startPosX
            self.currentPosY = self.startPosY
            self.endPosX = endPos[0]
            self.endPosY = endPos[1]

            self.distanceX = (self.endPosX - self.startPosX)
            self.distanceY = (self.endPosY - self.startPosY)
            self.steps = 0


        def render(self, width, height, st, at):
                render = renpy.Render(self.width, self.height)
                canvas = render.canvas()

                self.drawLine(canvas)

                renpy.redraw(self, 0)

                return render

        def drawLine(self, canvas):
            if self.steps <= (self.drawFrames):
                self.steps = self.steps + 1
                self.currentPosX = self.startPosX + (self.distanceX * ( self.steps / (self.drawFrames)))
                self.currentPosY = self.startPosY + (self.distanceY * ( self.steps / (self.drawFrames)))

            currentEndPos = (self.currentPosX, self.currentPosY)

            #Handle xstart being more than xend.
            if self.endPosX < self.startPosX:
                #flip the start and end around so that it draws properly.
                if self.baseOn:
                    canvas.line(self.baseColor, start_pos=self.endPos, end_pos=self.startPos, width=self.lineWidth - 5)
                if self.animatedOn:
                    canvas.line(self.animatedColor, start_pos=currentEndPos, end_pos=self.startPos, width=self.lineWidth)
            else:
                if self.baseOn:
                    canvas.line(self.baseColor, start_pos=self.startPos, end_pos=self.endPos, width=self.lineWidth - 5)
                if self.animatedOn:
                    canvas.line(self.animatedColor, start_pos=self.startPos, end_pos=currentEndPos, width=self.lineWidth)


    class LineRender(renpy.Displayable):

        def __init__(self,  **kwargs):
            # Pass additional properties on to the renpy.Displayable
            # constructor.
            super(LineRender, self).__init__(**kwargs)

            self.width = config.screen_width
            self.height = config.screen_height
            self.lines = [
            Line(Color("000000"), (300, 300), (300, 600), 20, True, Color("FF0000"))
            ,Line(Color("000000"), (300, 300), (600, 300), 20, True, Color("FF0000"))
            ,Line(Color("000000"), (300, 300), (0, 300), 20)
             ,Line(Color("000000"), (300, 300), (300, 0), 20)
             ,Line(Color("000000"), (300, 300), (600, 600), 20, True, Color("FF0000"))
             ,Line(Color("000000"), (300, 300), (0, 600), 20, True, Color("FF0000"))
             ,Line(Color("000000"), (300, 300), (0, 0), 20)
             ,Line(Color("000000"), (300, 300), (600, 0), 20)]

        def render(self, width, height, st, at):
            render = renpy.Render(self.width, self.height)
            canvas = render.canvas()

            for line in self.lines:
                line.drawLine(canvas)

            renpy.redraw(self, 0)

            return render

screen lineRenderTest:
    add LineRender()

screen lineTest:
    add Line(Color("000000"), (300, 300), (300, 600), 20, True, Color("FF0000"))
    add Line(Color("000000"), (300, 300), (600, 300), 20, True, Color("FF0000"))
    add Line(Color("000000"), (300, 300), (0, 300), 20)
    add Line(Color("000000"), (300, 300), (300, 0), 20)
    add Line(Color("000000"), (300, 300), (600, 600), 20, True, Color("FF0000"))
    add Line(Color("000000"), (300, 300), (0, 600), 20, True, Color("FF0000"))
    add Line(Color("000000"), (300, 300), (0, 0), 20)
    add Line(Color("000000"), (300, 300), (600, 0), 20)

label lineTest:
    show screen lineTest

    "" "This is running the line UDD by adding multiple versions to a screen."

    hide screen lineTest

    show screen lineRenderTest

    "" "This is running the line UDD by adding multiple versions to a UDD, then adding the UDD. You'll see that it's much faster."

    hide screen lineRenderTest