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
-
Also can you post the code you are using just in case it's just a small mishap? Make sure to put the code inside two
```
so that it is formatted properlyCheckout the *** COMPOSE *** on top right when your writing a post 😀
-
Hey thanks so much for getting back to me, I’ll take a look at the examples, I’m a bit busy myself at the moment but I’ll try to get the code I’m using to you ASAP. Be warned it’s a hot mess cause I’m just practicing some ideas at the moment, and I’m also very bad at this 😂
-
@jackattack, one idea:
- In your touch handler, set a variable with up/down/left/right based on the main direction of movement, then use an Action to move the SpriteNode
- In update, select the right set of textures based on the up/down/left/right variable, then the actual image based on ”coordinate modulo number of images”. You can scale dividing the coordinate value first. So, for example, if moving up and you want the image to change every 10 points, you can set the sprite texture with
up_images[node.position.y // 10 % len(up_images)]
.
-
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
-
@jackattack
Any chance we can get the sprite sheet your using? -
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
-
@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 😎
-
my sprite sheet
Just using one row of this in my code for a basic walk forward animation -
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)
-
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 😌
-
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?
-
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?
-
@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 usesuper()
. 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()
andEventManager()
, then visual testing. at this point i woud start myButtonNode()
andAnimations()
.. now i create myPlayer()
,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!;