omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    [SPACE ESCAPE]-Game example to help with Game dev

    Pythonista
    game dev
    6
    133
    43807
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • stephen
      stephen @Karina last edited by

      @Karina said:

      @stephen I tried to do like an arrow here

      class ButtonNode(SpriteNode):
      	def __init__(self, img, action=None, text=None, parent=None, *args, **kwargs):
      		super().__init__(self, img, *args, **kwargs)
      			
      

      But he tells me that in super().init should be 2 numbers. I don't understand what he means at all🤷‍♀️

      when used in a classbdeffenition, in this case __init__, super will gather the needed data from the current environment that it needs to define the instance. so here you dont pass self and super for SpriteNode is expecting a string for texture(string is a sequence of characters) and not self. this automatic defining is why super is used. its called Cooperative Inheritance. as long as there is a super call in all base classes it allows for multiple inheritance without having to bother with explicitly defining who the parent or base class is. for example it would be more practical to made a button a ShapeNode that way you can add a border to the button without adding another sprite in the background by using path. now if we had put super().__init__(*args, **kwargs) and insured the correct args are passed we would just need to change the base class fom ButtonNode(SpriteNode): to ButtonNode(ShapeNode): and super would handle the rest. 😎😀

      1 Reply Last reply Reply Quote 0
      • Karina
        Karina last edited by

        @stephen So here better to put ShapeNode instead of SpriteNode?

        stephen 1 Reply Last reply Reply Quote 0
        • stephen
          stephen @Karina last edited by

          @Karina said:

          @stephen So here better to put ShapeNode instead of SpriteNode?

          i would personally. But there's nothing wrong with using SpriteNode. Check out this one I made not long ago.

          Karina 1 Reply Last reply Reply Quote 0
          • Karina
            Karina last edited by Karina

            @stephen Yes, I know, I copied it to my pythonista when you showed it. But there a lot of things, don't know from where to begin it. I just used to write more linear, so it's difficult for me to understand. But it goes slowly

            stephen 1 Reply Last reply Reply Quote 0
            • Karina
              Karina @stephen last edited by

              @stephen said:

              @Karina said:

              @stephen So here better to put ShapeNode instead of SpriteNode?

              i would personally. But there's nothing wrong with using SpriteNode. Check out this one I made not long ago.

              Can you explain why, what ShapeNode has that we need?

              stephen 1 Reply Last reply Reply Quote 0
              • Karina
                Karina last edited by

                class ButtonNode(SpriteNode):
                	def __init__(self, img, action=None, text=None, parent=None, *args, **kwargs):
                		super().__init__(img, *args, **kwargs)
                			
                		
                	def setup(self):
                		bg = ui.Path.rounded_rect(0, 0, 200, 200, 8) 
                		bg.line_width = 7
                		self.bg = ShapeNode(bg, stroke_color='blue', parent=self)
                		self.add_child(self.bg)
                

                @stephen here he tells me line_width is invalid arg, but Path obj has it, and in example they do the same. Why I can't do that?

                stephen 1 Reply Last reply Reply Quote 0
                • stephen
                  stephen @Karina last edited by

                  @Karina said:

                  class ButtonNode(SpriteNode):
                  	def __init__(self, img, action=None, text=None, parent=None, *args, **kwargs):
                  		super().__init__(img, *args, **kwargs)
                  			
                  		
                  	def setup(self):
                  		bg = ui.Path.rounded_rect(0, 0, 200, 200, 8) 
                  		bg.line_width = 7
                  		self.bg = ShapeNode(bg, stroke_color='blue', parent=self)
                  		self.add_child(self.bg)
                  

                  @stephen here he tells me line_width is invalid arg, but Path obj has it, and in example they do the same. Why I can't do that?

                  To start, im not too sure how your executing setup you dont make any calls to it. the code inside setup Is functional but I would like to point out that you are adding 2 children of this ShapeNode to self.. When you pass parent in any subclass of Node it will add that instance to the list of children for self. i would remove self.add_child(self.bg) since we know and who the parent will be at construction time 😎.

                  as for you question here i had zero issues with bg.line_width when i ran this setup method inside my Scene subclass. ill need to see how you cal calling your setup here

                  1 Reply Last reply Reply Quote 0
                  • stephen
                    stephen @Karina last edited by

                    @Karina said:

                    @stephen said:

                    @Karina said:

                    @stephen So here better to put ShapeNode instead of SpriteNode?

                    i would personally. But there's nothing wrong with using SpriteNode. Check out this one I made not long ago.

                    Can you explain why, what ShapeNode has that we need?

                    you defenently do not need ShapeNode but there is no reason not to. I probably should of mentioned this earlier lol im sorry..

                    ShapeNode is a subclass of SpriteNode! 😃😃😃 So you have everything a SpriteNode has including texture as well as path. this means you can use a image for the background and use a Path for your Border..

                    
                    
                    # Just to show using Borders with a image Background
                    class ButtonNode(ShapeNode):
                        def __init__(self, rect=(0, 0, 150, 75), corner_radius=6, *args, **kwargs):
                            super().__init__(*args, **kwargs)
                            x, y, width, height = rect
                            
                            if corner_radius > 0:
                                self.path = ui.Path.rounded_rect(x, y, width, height, corner_radius)
                            else:
                                self.path = ui.Path.rect(x, y, width, height)
                            
                            lw=self.line_width=10
                            self.fill_color=None
                            self.stroke_color='blue'
                            
                            self.bg_texture=SpriteNode(
                                texture=Texture('pzl:Blue8'),
                                size=self.size-(lw, lw),
                                parent=self)
                    

                    If you were to try and do this with a normal SpriteNode you can never have path borders with a image background without covering the edges of your image. Also by using a SpriteNode as base class only the ShapeNode child has corner_radius so your texture images corners will show outside your rounded edges.

                    1 Reply Last reply Reply Quote 0
                    • stephen
                      stephen @Karina last edited by stephen

                      @Karina said:

                      @stephen Yes, I know, I copied it to my pythonista when you showed it. But there a lot of things, don't know from where to begin it. I just used to write more linear, so it's difficult for me to understand. But it goes slowly

                      I shortened my ButtonNode and removed rhe Event Manage. there is some short comments on this one too.. hopfully it will help you understand better?

                      
                      import scene
                      
                      class ButtonNode(scene.ShapeNode):
                          def __init__(self,
                                          action,
                                          name=f'ButtonNode',
                                          bg_color='lightgray',
                                          accessoryColor='red',
                                          icon=None,
                                          accessory='emj:Exclamation_Mark_2',
                                          anchor_point=(0.5, 0.5),
                                          font_family='<system>',
                                          font_size=16,
                                          parent=None,
                                          position=(0, 0),
                                          size=(120, 45),
                                          corner_radius=8,
                                          border_size=20,
                                          borderColor='black',
                                          text='',
                                          text_color='black',
                                          enabled=True,
                                          *args, **kwargs):
                      
                              # these mainly for call to super()
                              self.x, self.y = position
                              self.w, self.h = size
                              super().__init__(
                                      path=scene.ui.Path.rounded_rect(
                                          self.x, self.y, self.w, self.h, corner_radius),
                                      fill_color=bg_color,
                                      stroke_color=borderColor,
                                      shadow=None,
                                      parent=parent,
                                      *args, **kwargs)
                              
                              # Normal Properties for Instance()
                              self.enabled=enabled
                              self.button_action=action
                              self.name=name
                              self.position=position
                              self.size=size
                              self.anchor_point=anchor_point
                              self.icon=self._init_textures(icon)
                              
                              # for border
                              self.border_size=border_size
                              self.borderColor=borderColor
                              self.corner_radius=corner_radius
                              
                              # for accessory
                              self.accessory=self._init_textures(accessory)
                              self.showAccesory=False
                              self.accessoryColor=accessoryColor
                              
                              # for Label
                              self.text=text if text != '' else self.name
                              self.text_color=text_color
                              self.font_family=font_family
                              self.font_size=font_size
                              
                              # Container to hold each component. 
                              # is just a dict version of self.children but specific.
                              self.components=dict({
                                      'accessory':None,
                                      'icon':None,
                                      'label':None})
                              
                              self._setup(self.icon, self.accessory, self.components)
                      
                          # Type Check to make sure img is a string or ui.Image
                          def _init_textures(self, img):
                              if type(img) == str or type(img) == scene.ui.Image:
                                  return scene.Texture(img)
                              else:
                                  return None
                      
                          # setup our Components
                          def _setup(self, i, a, c):
                              if a != None:
                                  # small indicator image in top left corner
                                  # if its enabled it will disable and hide when pressed
                                  # intended for stuff like new item in inventory...
                                  c['accessory']=scene.SpriteNode(
                                          texture=a,
                                          size=(self.size[1]/4, self.size[1]/5*1.5),
                                          position=scene.Point(-self.size[0]/2+7, self.size[1]/2-10),
                                          parent=self,
                                          z_position=4,
                                          color=self.accessoryColor)
                              
                              if i != None:
                                  # button image
                                  c['icon']=scene.SpriteNode(
                                          texture=i,
                                          size=scene.Size(self.size[1]/2, self.size[1]/2),
                                          position=scene.Point(self.w/2 - self.size[1]/3 , 0),
                                          parent=self,
                                          z_position=9)
                      
                              if self.text:
                                  # button text..
                                  c['label']=scene.LabelNode(
                                          text=self.text,
                                          font=(self.font_family, self.font_size),
                                          position=scene.Point(0 , 0),
                                          anchor_point=(0.5, 0.5),
                                          color=self.text_color,
                                          parent=self,
                                          z_position=10)
                          
                          # called when you tap the button
                          def Button_Tapped(self):
                              if self.components['accessory'].alpha > 0:
                                  self.components['accessory'].alpha = 0
                              if self.enabled:
                                  self.button_action(self)
                      
                      # custom action
                      def my_button_action(sender):
                          print(f'{sender.name}: {sender.text}..')
                      
                      class main(scene.Scene):
                          def setup(self):
                              self.buttons=list([])
                              self.background_color='lightgray'
                              self.my_button=ButtonNode(
                                  text='My Button', parent=self, action=my_button_action,
                                  position=scene.Point(self.size[0]/2, self.size[1]/2+100))
                              self.buttons.append(self.my_button)
                      
                          def touch_began(self, touch):
                              for btn in self.buttons:
                                  if self.point_from_scene(touch.location) in btn.frame:
                                      btn.Button_Tapped()
                      
                      scene.run(main())
                      
                      1 Reply Last reply Reply Quote 0
                      • Karina
                        Karina last edited by Karina

                        ShapeNode is a subclass of SpriteNode!

                        Yeah, they say it in docs, I just forgot🤦‍♀️. Then it's more clever to make ShapeNode base class

                        1 Reply Last reply Reply Quote 1
                        • Karina
                          Karina last edited by

                           lw=self.line_width=10
                          

                          Here why you're lw and self.line_width? One is not enough? And it seems it should be self.path.line_width cause Path has that attr.

                          self.bg_texture=SpriteNode(
                                      texture=Texture('pzl:Blue8'),
                                      size=self.size-(lw, lw),
                                      parent=self)
                          

                          You're trying make here the form of Blue8, but with rounded angles?

                          stephen 2 Replies Last reply Reply Quote 0
                          • Karina
                            Karina last edited by Karina

                            @stephen in built in examples sometimes there are with pyui files. Do you use them?

                            1 Reply Last reply Reply Quote 0
                            • stephen
                              stephen @Karina last edited by

                              @Karina said:

                               lw=self.line_width=10
                              

                              Here why you're lw and self.line_width? One is not enough? And it seems it should be self.path.line_width cause Path has that attr.

                              ShapeNode has a few setting for path so that you dont need to set them for every path. when you pass a new path object to your ShapeNode it doesva check on the follwing Properties and if the value is not None it applies this to your new Path object.

                              with that said if you have say ShapeNode().line_width set to 3 and for just the next path object you want the width set to 6. you would need to set ShapeNode().path to the new path object and then set ShapeNode().path.line_width = 6 otherwise your ShapeNode().line_width will overide the path's predefined value. Only reason not to just change ShapeNode().line_width before creating the path is in this example you want it to only change once and would hate to forget to change it back lol.

                              ShapeNode Path Properties:

                              ShapeNode().line_width
                              ShapeNode().fill_color
                              ShapeNode().path
                              ShapeNode().shadow
                              ShapeNode().stroke_color
                              
                              1 Reply Last reply Reply Quote 0
                              • stephen
                                stephen @Karina last edited by

                                @Karina said:

                                Here why you're lw and self.line_width? One is not enough?

                                Yes one is more than enough. I do this at times to shorten line length

                                1 Reply Last reply Reply Quote 0
                                • Karina
                                  Karina last edited by ccc

                                  as for you question here i had zero issues with bg.line_width when i ran this setup method inside my Scene subclass. ill need to see how you cal calling your setup here

                                  @stephen here's the full code though I've changed a little reading your advices

                                  from scene import *
                                  import ui
                                  
                                  def sw(): return get_screen_size()[0]
                                  def sh(): return get_screen_size()[1]
                                  def bw(): return 150
                                  def bh(): return 140
                                  
                                  
                                  class ButtonNode(ShapeNode):
                                  	def __init__(self, rect=(0, 0, 150, 75), corner_radius=7, *args, **kwargs):
                                  		super().__init__(img, *args, **kwargs)
                                  		x, y, width, height = rect
                                  			
                                  		
                                  	def setup(self):
                                  		bg = ui.Path.rounded_rect(0, 0, 200, 200, 8) 
                                  		bg.line_width = 7
                                  		self.bg = ShapeNode(bg, stroke_color='blue', parent=self)
                                  		self.add_child(self.bg)		
                                  	
                                  	
                                  
                                  		
                                  def button_tapped(sender):
                                  	print(sender.text)
                                  
                                  
                                  
                                  class Main(Scene):
                                  	def setup(self):
                                  		self.background_color = '#eaeaea'
                                  		down = ButtonNode('iob:arrow_right_b_256', size=Size(bw(), bh()), 
                                  		                        line_width=7, position=Point(sw()-70, sh()/2))
                                  		down.make_button()
                                  		self.add_child(down)
                                  
                                  
                                  run(Main(), LANDSCAPE)
                                  
                                  1 Reply Last reply Reply Quote 0
                                  • Karina
                                    Karina last edited by

                                    Do you know how to make it in portrait orientation? No matter which attr I pass, it's still in landscape. Or that's just because of version,of my iPad?

                                    stephen 2 Replies Last reply Reply Quote 0
                                    • stephen
                                      stephen @Karina last edited by

                                      @Karina said:

                                      Do you know how to make it in portrait orientation? No matter which attr I pass, it's still in landscape. Or that's just because of version,of my iPad?

                                      Heres the script back. i did a few corrections. you were ading the new code but not using it. lol but thats ok. this stuff can make you pull your hair out from time to time. Af for your error message for line_width, it's not part of the constructor parameters so this must be set after calling the super's Init. Interpreter didn't know the property existed yet. I'm assuming it has to do with execution inside ShapeNode itself.

                                      Also you need to remove your fill color to see your texture. But we are getting there!

                                      At the moment we can not control our Orientation on iPad. It has to do with ios13 and multi-tasking support for Pythonista. But a few of us are working on that

                                      from scene import *
                                      import ui
                                      
                                      def sw(): return get_screen_size()[0]
                                      def sh(): return get_screen_size()[1]
                                      def bw(): return 150
                                      def bh(): return 140
                                      
                                      
                                      class ButtonNode(ShapeNode):
                                          def __init__(self,
                                                  rect=(0, 0, 150, 75),
                                                  corner_radius=8,
                                                  bakground_color='lightgreen',
                                                  line_width=0,
                                                  *args, **kwargs):
                                                      
                                              super().__init__(*args, **kwargs)
                                              self.tint = bakground_color
                                              x, y, width, height = rect
                                              self.position, self.size = get_screen_size()/2, (rect[2], rect[3])
                                              
                                      #    def setup(self):
                                              bg = ui.Path.rounded_rect(x, y, width, height, corner_radius) 
                                              bg.line_width = line_width
                                          
                                              self.bg = ShapeNode(bg, stroke_color='blue', fill_color='clear',parent=self)
                                      #        self.add_child(self.bg)     
                                          
                                          
                                      
                                              
                                      def button_tapped(sender):
                                          print(sender.text)
                                      
                                      
                                      
                                      class Main(Scene):
                                          def setup(self):
                                              self.background_color = '#b7b7b7'
                                              down = ButtonNode(
                                                  texture=Texture('iob:arrow_right_b_256'),
                                                  size=Size(bw(), bh()), 
                                                  line_width=5, 
                                                  position=Point(sw()/2, sh()/2),
                                                  parent=self)
                                              
                                      #        self.add_child(down)
                                      
                                      
                                      run(Main(), LANDSCAPE)
                                      
                                      
                                      
                                      1 Reply Last reply Reply Quote 0
                                      • stephen
                                        stephen @Karina last edited by stephen

                                        @Karina said:

                                        Do you know how to make it in portrait orientation? No matter which attr I pass, it's still in landscape. Or that's just because of version,of my iPad?

                                        i made a note on last post but i wanted to add that it sounds like your orientation lock is on

                                        1 Reply Last reply Reply Quote 0
                                        • Karina
                                          Karina last edited by

                                          @stephen Yes it was so. But when it's off, orientation changes when I tint. And I want it to be just portrait

                                          stephen 1 Reply Last reply Reply Quote 0
                                          • Karina
                                            Karina last edited by

                                            @stephen I generally understood your code, but how do you count those positions, of icon, accessory, button? Cause size[1]/5*1.5 seems quite confusing
                                            I changed a little your code, now the icon is music, and when you tap plays random sounds. But the button is in the corner, you even can't see it fully😓

                                            stephen 2 Replies Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors