Forum Archive

Help with SpriteNode with image from ui.Path

pedroagb

Hey everyone,

Can someone help me understand what I'm doing wrong with this I Ching app I'm working on? This is supposed to display six stacked lines (an hexagram), each line responsive to touch, but I didn't want to bother you with a long script, so I created a minimal example that replicates my current problem.

I would like to present a line (rectangle), that is inclosed in a bigger area (because it will be a button). So I want the shape of the SpriteNode to be bigger than the actual content (drawn with Path). In my example, the rectangle should fill 1/3rd of the total sprite area, centered vertically.

At first I was using ShapeNode to draw the rectangle, but although I managed to get the graphics right, I couldn't get the positioning right when I draw other lines above, because the shape size is determined using the actual Path, and would end up smaller than the total shape (which should be width x height in my example below). I could get the positioning right manipulating the anchor_point, but then I ended up with negative Node.shape values, and I think that messed with the touch detection.

So I switched to SpriteNode, and although it now reponds correctly to touch, I can't figure what is wrong with the graphic, because it fills the whole sprite size, not just a 1/3rd centered vertically. I also don't understand the rounded corners.

Also if I print line.frame, it gives me (60, 100, 201, 61). Maybe not a big problem, but why not (60, 100, 200, 60)?

Thanks in advance for any help you can provide. Here's my code:

import scene, ui

class LineButton(scene.SpriteNode):
    def __init__(self, w, h, **kwargs):
        ctx=ui.ImageContext(w, h)
        with ctx:
            path=ui.Path()
            path.line_width = 1
            path.move_to(0, h/3)
            path.line_to(w, h/3)
            path.line_to(w, 2*h/3)
            path.line_to(0, 2*h/3)
            path.close()             
            path.fill()            
        super().__init__(scene.Texture(ctx.get_image()), size=(w,h), **kwargs)

class ShowHexagram(scene.Scene):
    def setup(self):
        footer=100
        width=200
        height=60         
        y = footer+height/2
        line=LineButton(width, height, position=(self.size.w/2, y), parent=self)
        #print("frame=", line.frame)

scene.run(ShowHexagram())
JonB

Rounded corners come from the path line_cap_style. Try the butt option .

When paths get converted to images in shapenode, I think the frame is auto computed, so will be tight to the drawn area. You might try creating an ImageContext of the desired size, and draw the path, and then get the ui.image -- you may have more control.

pedroagb

Thanks for replying, I actually solved the problem myself just minutes after I posted, that's why I deleted my post.
I'm sure I'll have plenty more doubts for future posts, though :)
Cheers