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.


    How to get a SpriteNode to change image / colour on screen-touching another Sprite?

    Pythonista
    4
    7
    3252
    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.
    • themusicman
      themusicman last edited by themusicman

      So, as the title states, I would like to find out how I am able to amend an existing sprite to a new colour/image, when I touch another Sprite on the iPad screen.

      Specifically - this is part of the Connect-4 script I am trying to create. The way I have chosen to do the 'how to choose ones move' is comprised of an area with left and right arrows, and in between these arrows is the button that says 'make move'. So, as one presses the left or right arrows, another sprite moves one column at a time to the respective column in the space above the board where the player wishes to make the move. Once the player is happy with the column to move, they press the separate 'make move' sprite.

      This then calls the code that fills the next empty space on the board for that column, and also calls a 'check if winning line' function.

      However. what I also wish to do is once the 'make move' sprite has been pressed, the colour of the sprite in the space above the board changes to match the colour of the next player to go. I believe I have the logic sorted for this, but I can't for the life of me figure out how to change the sprites colour.

      In the def setup(self) function I have defined the sprite as this;

      		# this will show current player above row selected
      		self.player = SpriteNode(self.turn_colour)
      		self.player.position = (player_x, player_y)
      		self.player.scale = 1.8
      		self.add_child(self.player)
      

      and then in the def touch_began(self, touch) function, I have this;

      		if self.turn == 0:
      			self.turn_colour = ('emj:Red_Circle')
      		else:
      			self.turn_colour = ('emj:Blue_Circle')
      
      		self.player = SpriteNode(self.turn_colour)
      
      		# left button pressed, so insert code to move disc to left here
      		
      		# right button pressed so insert code to move disc to right here
      		
      

      But unfortunately, this does not seem to amend the self.player sprite at all. Could someone advise please;

      1 - if this is possible, and if so
      2 - what is the correct syntax I should use, and
      3 - which Pythonista game function I should place the code to do that

      Any help greatly appreciated. More than happy to elaborate if needed. Many thanks.

      mikael 2 Replies Last reply Reply Quote 0
      • mikael
        mikael @themusicman last edited by

        @themusicman, I would suggest that your game would be easier to implement using plain ui Views instead of the scene module. For example, you can implement direct touch handlers on Views.

        1 Reply Last reply Reply Quote 0
        • mikael
          mikael @themusicman last edited by

          @themusicman, but to answer your question, if I understand correctly, you are just changing the value of the self.player valiable to a new SpriteNode, which is not added to the scene at all.

          Instead, change the texture of the existing SpriteNode:

          self.player.texture = Texture('emj:something')
          

          Or you can set the color attribute to tint the texture with different colors.

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

            I managed to write some alternate (but yes, very ugly) code to do this. Just not too sure where the best place is to locate it,.

            		for fill_board in range(COLUMN_COUNT):
            			for rows2 in range(ROW_COUNT):
            				if self.board[rows2][fill_board] != 0:
            
            					if self.board[rows2][fill_board] == 1:
            						self.fill_circle = SpriteNode('emj:Red_Circle')
            					else:
            						self.fill_circle = SpriteNode('emj:Blue_Circle')
            
            					#				self.fill_circle = SpriteNode(self.turn_colour)
            					self.fill_circle.scale = 1.8
            					self.fill_circle.position = (
            					(fill_board * (768 - 68) / COLUMN_COUNT) + 80, (rows2 * (768 - 68) / COLUMN_COUNT) + 68)
            					self.add_child(self.fill_circle)
            
            

            It works when this code is inserted in the

            def update(self): 
            

            function, though it is a very poor 'brute force' method of checking an array and filling a Sprite on the screen depending on the content of the item in the array.

            When I inserted this code into the

            def touch_began(self, touch):

            function, I have a few placement issues so need to do some further investigation as to the best location to place that code.

            I really do need to write a more efficient way of doing this... maybe by just inserting one piece on the board per turn instead of filling every space with its corresponding array item!

            That's noobies to coding for you, eh haha

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

              Okay so I learnt that you can get the frame of a SpriteNode. Say that your sprite is moving in random directions like an AI finding paths. Now take the frame of the SpriteNode:
              E.g:

              def setup(self):
                  trap = SpriteNode('sprite', position=self.size/2)
                  AI = SpriteNode('sprite', position=self.size/3
                  trap_location = trap.frame
                  self.add_child(AI)
                  self.add_child(trap)
              

              Now in the update function, check if the location of the AI is in the location of the trap:
              E.g:

              def update(self):
                  if (self.AI.frame.x and self.AI.frame.y) in trap_location:
                      # Do the rest of your code here.
              
              1 Reply Last reply Reply Quote 1
              • JonB
                JonB last edited by

                Another option is to create a totally new Sprite. Presumably for connect 4 you would have a Sprite for red and one for black, and you could just hide one when you show the other.

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

                  Absolutely loving the help and support from experts on here, thanks so much guys and gals.

                  @Splefix - that's an awesome idea, thanks for the suggestion.

                  @JonB - yep, this is exactly what I ended up doing, Jon. Once I had my head around the logic and syntax, even this old chap managed to code this section in a few mins.

                  Still a few things to iron out in the code, but all in all, for my first real attempt at a slightly longer Python script than Print("Hello World:), I am pretty pleased with myself.

                  Connect4 coded in Pythonista and running (albeit with a few glitches) on my iPad. Who'd have thunk it!! haha

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post
                  Powered by NodeBB Forums | Contributors