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.


    Sprite animation linked with an action

    Pythonista
    animation game
    3
    16
    5914
    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.
    • jackattack
      jackattack last edited by

      
      from scene import *
      import sound
      import random
      import math
      A = Action
      
      sprite_sheet=[Texture('scene_practice/new_sprites/IMG_3039.JPG').subtexture(Rect(0,0.5,0.33,0.25)),Texture('scene_practice/new_sprites/IMG_3039.JPG').subtexture(Rect(0.33,0.5,0.33,0.25)),Texture('scene_practice/new_sprites/IMG_3039.JPG').subtexture(Rect(0.66,0.5,0.33,0.25))]
      
      class MyScene (Scene):
      	def setup(self):
      		 self.screen="game"
      		 self.background_color = 'black'
      		
      		 self.Sprite = SpriteNode(sprite_sheet[0],scale = 4, position = (self.size.x/2,self.size.y/1.1), parent = self)
      		 self.add_child(self.Sprite)
      		 self.n = -1
      		 
      		 self.button = SpriteNode('shp:Circle',scale=2,position=(self.size.x/1.5,self.size.y/3))
      		 self.add_child(self.button)
      			
      		
      	def did_change_size(self):
      		pass
      	
      	def update(self):
      		
      		step1 = int(self.Sprite.position.y / 15) % 3
      		if step1 != self.n:
      			self.Sprite.texture = sprite_sheet[step1]
      	
      	def touch_began(self, touch):
      		moveaction = Action.move_by(0,-46)
      		
      		if touch.location in self.button.bbox:
      			self.Sprite.run_action(moveaction)
      
      if __name__ == '__main__':
      	run(MyScene(), show_fps=False)
      
      

      Okay so here is a basic version of what I have been doing.

      So in my Update method I’m using the y coordinate of my sprite to return an integer 0 or 1 or 2, then I’m using this as a reference To set the texture from my spritesheet, basically just what was being done in the game tutorial.

      The thing I’m stuck with is how I can expand this idea to another direction, so for instance if I wanted to go up instead of down I would need to use an entirely different sprite sheet but I don’t know how to do that

      What I would really like to do if possible is tie the whole animation process to the button press so I could animate a more diverse range of things not just relying on position? Does that make sense?

      I’m so grateful for you guys taking time to read my stuff and help, gives me real motivation to keep learning, so thanks again everyone

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

        @jackattack
        Any chance we can get the sprite sheet your using?

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

          Sure can do, what format can I post it on here? I basically just cropped one from online to make it easier to work with

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

            @jackattack said:

            Sure can do, what format can I post it on here?

            You will have to upload somewhere then hyperlink it. I personally use Imgur

            @jackattack said:

            I basically just cropped one from online to make it easier to work with

            no problem its just to help replicate the same execution you have 😎

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

              my sprite sheet
              Just using one row of this in my code for a basic walk forward animation

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

                @jackattack

                here is my script example. sorry it took a while lol. its not very clean but i think it should be easy to follow. let me know if you have any questions. you should benable to use thenSprite class to create other objects and as you will see this approach doesnt use the update method at all or depend on position.

                
                from scene import *
                from time import sleep
                import sound
                import random
                import math
                
                A = Action
                
                Character_Male='IMG_3039.jpg'
                
                def get_texture(sheet, x, y, w, h):
                    '''
                    for cleaner Code
                    '''
                    return Texture(sheet).subtexture(Rect(x, y, w, h))
                
                
                class Direction:
                    '''
                    simple Constants
                    '''
                    NORTH="north"
                    SOUTH="south"
                    EAST="east"
                    WEST="west"
                
                class Sprite(SpriteNode):
                    '''
                    Use this class for game objects
                    '''
                    def __init__(self,sprite_sheet, *args, **kwargs):
                        self.sprite_sheet=sprite_sheet
                        self.animations=dict(
                            {"idle":get_texture(self.sprite_sheet, 0.00, 0.75, 0.33, 0.25)})
                        SpriteNode.__init__(self, texture=self.animations["idle"], *args, **kwargs)
                        
                        self.movement_speed=50
                        self.active_direction=Direction.SOUTH
                        self.Texture_Group(
                            "move-north", 
                            [
                                get_texture(self.sprite_sheet, 0.00, 0.75, 0.33, 0.25),
                                get_texture(self.sprite_sheet, 0.33, 0.75, 0.33, 0.25),   
                                get_texture(self.sprite_sheet, 0.66, 0.75, 0.33, 0.25)
                            ])
                        self.Texture_Group(
                            "move-south", 
                            [
                                get_texture(self.sprite_sheet, 0.00, 0.50, 0.33, 0.25),
                                get_texture(self.sprite_sheet, 0.33, 0.50, 0.33, 0.25),
                                get_texture(self.sprite_sheet, 0.66, 0.50, 0.33, 0.25)
                            ])
                        self.Texture_Group(
                            "move-east", 
                            [
                                get_texture(self.sprite_sheet, 0.00, 0.25, 0.33, 0.25),
                                get_texture(self.sprite_sheet, 0.33, 0.25, 0.33, 0.25),
                                get_texture(self.sprite_sheet, 0.66, 0.25, 0.33, 0.25)
                            ])
                        self.Texture_Group(
                            "move-west", 
                            [
                                get_texture(self.sprite_sheet, 0.00, 0.00, 0.33, 0.25),
                                get_texture(self.sprite_sheet, 0.33, 0.00, 0.33, 0.25),
                                get_texture(self.sprite_sheet, 0.66, 0.00, 0.33, 0.25)
                            ])
                        
                        
                    # decorator alows the use of time.sleep() without blocking     
                    @ui.in_background
                    def Run_Animation(self, tag):
                        for x in self.animations[f"{tag}-{self.active_direction}"]:
                            self.texture = x
                            sleep(0.2)
                        self.texture=self.animations[f"{tag}-{self.active_direction}"][0]
                    
                    def Texture_Group(self, tag, texture_list):
                        self.animations[tag]=texture_list
                    
                    def Change_Direction(self, direction):
                        self.active_direction=direction
                        if direction == Direction.SOUTH:
                            self.velocity=(0.0, -self.movement_speed)
                        elif direction == Direction.NORTH:
                            self.velocity=(0.0, self.movement_speed)
                        elif direction == Direction.EAST:
                            self.velocity=(-self.movement_speed, 0.0)
                        elif direction == Direction.WEST:
                            self.velocity=(self.movement_speed, 0.0)
                
                
                class Button(SpriteNode):
                    '''
                    Simple Button Object
                    '''
                    def __init__(self, text, meta, action=None, *args, **kwargs):
                        SpriteNode.__init__(self, Texture('pzl:Gray7'), *args, **kwargs)
                        self.texture=Texture('pzl:Gray7')
                        self.action=action
                        self.text=LabelNode(text, anchor_point=(0.5, 0.5), color="yellow", parent=self)
                
                        self.meta=meta
                    
                    # Not used in this example but can be lol
                    def Pressed(self):
                        self.action(self)
                
                class MyScene (Scene):
                    def setup(self):
                        self.screen="game"
                        self.background_color='black'
                        self.buttons=[]
                        
                        self.player=Sprite(Character_Male, position=self.size/2, scale=4, parent=self)
                        
                        self.n = -1
                        
                        
                        self.up_button=Button(
                            "↑",
                            Direction.NORTH,
                            position=Point(get_screen_size()[0]/4*3, 270),
                            scale=2,
                            parent=self)
                        self.buttons.append(self.up_button)
                        
                        self.down_button=Button(
                            "↓",
                            Direction.SOUTH,
                            position=Point(get_screen_size()[0]/4*3, 130),
                            scale=2,
                            parent=self)
                        self.buttons.append(self.down_button)
                        
                        self.right_button=Button(
                            "→",
                            Direction.WEST,
                            position=Point(get_screen_size()[0]/4*3+70, 200),
                            scale=2,
                            parent=self)
                        self.buttons.append(self.right_button)
                        
                        self.left_button=Button(
                            "←",
                            Direction.EAST,
                            position=Point(get_screen_size()[0]/4*3-70, 200),
                            scale=2,
                            parent=self)
                        self.buttons.append(self.left_button)
                        
                    def touch_began(self, touch):
                        for btn in self.buttons:
                            if touch.location in btn.bbox:
                                self.player.Change_Direction(btn.meta)
                                self.player.run_action(
                                    Action.move_by(
                                        self.player.velocity[0],
                                        self.player.velocity[1]))
                                self.player.Run_Animation("move")
                        
                    def touch_ended(self, touch):
                        pass
                        
                        
                if __name__ == '__main__':
                    run(MyScene(), show_fps=True)
                
                1 Reply Last reply Reply Quote 0
                • jackattack
                  jackattack last edited by

                  Wow this works perfectly thank you so much, I’m going to take some time to study it and try to learn how to recreate it with some other effects. Thanks for taking the time out 😌

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

                    @stephen

                    I’ve learnt so much reading your code, love the way you’ve done so many things, spent ages going through it all. Could you give me any insight into the order you went about writing it?

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

                      Also the only bit I didn’t really understand was when you set up the button class you used init, but then you did spritenode.init what is this for?

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

                        @jackattack said:

                        Also the only bit I didn’t really understand was when you set up the button class you used init, but then you did spritenode.init what is this for?

                        when you subclass an object that has __init__ paramiters you must either call the Parent class __init__ as i did here or you can use super(). if you do not call the parent's __init__ then the new object will not inherit the dirived.


                        @jackattack said:

                        I’ve learnt so much reading your code, love the way you’ve done so many things, spent ages going through it all. Could you give me any insight into the order you went about writing it?

                        I usually start with utility classes. in my Example game this would be stuff like Screen() and EventManager(), then visual testing. at this point i woud start my ButtonNode() and Animations().. now i create my Player(), GUI() and o on. the order on the script itself doesnt matter with Object Orientated Programing (OOP) just remember the Interpreter exec the scripts top down. so in order to Dirive from from Class A it must exist before Class B.


                        @jackattack said:

                        Wow this works perfectly thank you so much, I’m going to take some time to study it and try to learn how to recreate it with some other effects. Thanks for taking the time out 😌

                        Not a problem at all! 🥂💯 i enjoy helping others if you have any equestions please dont hesitate!;

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