Animated sprite from few images
You could try modifying your sprite so that it swaps out its image for a different one inside update
. That way, when the sprite is rendered, it'll look animated.
Edit:
Here's a quick example I drew up:
import pygame
import sys
def load_image(name):
image = pygame.image.load(name)
return image
class TestSprite(pygame.sprite.Sprite):
def __init__(self):
super(TestSprite, self).__init__()
self.images = []
self.images.append(load_image('image1.png'))
self.images.append(load_image('image2.png'))
# assuming both images are 64x64 pixels
self.index = 0
self.image = self.images[self.index]
self.rect = pygame.Rect(5, 5, 64, 64)
def update(self):
'''This method iterates through the elements inside self.images and
displays the next one each tick. For a slower animation, you may want to
consider using a timer of some sort so it updates slower.'''
self.index += 1
if self.index >= len(self.images):
self.index = 0
self.image = self.images[self.index]
def main():
pygame.init()
screen = pygame.display.set_mode((250, 250))
my_sprite = TestSprite()
my_group = pygame.sprite.Group(my_sprite)
while True:
event = pygame.event.poll()
if event.type == pygame.QUIT:
pygame.quit()
sys.exit(0)
# Calling the 'my_group.update' function calls the 'update' function of all
# its member sprites. Calling the 'my_group.draw' function uses the 'image'
# and 'rect' attributes of its member sprites to draw the sprite.
my_group.update()
my_group.draw(screen)
pygame.display.flip()
if __name__ == '__main__':
main()
It assumes that you have two images called image1.png
and image2.png
inside the same folder the code is in.
how to animate the sprite?
Create a sprite class with a list of images. Add an attribute that counts the frames. Get image from image list in the update
method based on number of frames:
class MySprite(pygame.sprite.Sprite):
def __init__(self, x, y, image_list):
super().__init__()
self.frame = 0
self.image_list = image_list
self.image = self.image_list[0]
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def update(self, event_list):
animation_interval = 20
self.frame += 1
if self.frame // animation_interval >= len(self.image_list):
self.frame = 0
self.image = self.image_list[self.frame // animation_interval]
for event in event_list:
if event.type == pygame.MOUSEBUTTONDOWN:
mouse = event.pos
print(mouse[:])
However, instead of constantly creating and kill
ing the sprite every frame, you need to create the sprite once before the application loop. Change the position of the sprite and update the sprite in the application loop:
file_list = ['crossHair.png', 'crossHair_2.png', 'crossHair_3.png']
image_list = []
for name in file_list:
image = pygame.image.load(name)
image.set_colorkey(WHITE)
image_list.append(image)
# create sprite
sprite1 = MySprite(0, 0, image_list)
placeSP_group = pygame.sprite.OrderedUpdates()
placeSP_group.add([sprite1])
clock = pygame.time.Clock()
running = True
while running:
# handle events
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
running = False
# update sprite
x, y = pygame.mouse.get_pos()
placeSP_group.sprites()[0].rect.center = (x, y)
placeSP_group.update(event_list)
# draw scene
window_game.fill('white')
window_game.blit(backGround,(0,0)).size
placeSP_group.draw(window_game)
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
exit()
See also:
- how to create an illusion of animations in pygame
- Animated sprite from few images
- How do I create animated sprites using Sprite Sheets in Pygame?
Infinitely animating sprite in pygame
Make a list of the images for animation:
image_list = [pos1, pos2, pos3, pos4, pos5]
Add a variable that will store an index of the image list:
current_image = 0
Increment the index in the application loop and reset the index if it is equal to the length of the list:
run = True
while run:
# [...]
current_image += 1
if current_image == len(image_list):
current_image = 0
# [...]
Get the current image by subscription:
screen.blit(image_list[current_image], x, y)
Unity Sprite two images animation at runtime
You can do this with the Animator in Unity but doing with code gives you more control. Coroutines is one of the best ways to do this.
1.Create a script called SpriteAnimator
. Copy everything from below to it.
using UnityEngine;
using System.Collections;
public class SpriteAnimator : MonoBehaviour
{
bool continueAnimation = false;
SpriteRenderer displaySprite;
Sprite sprite1;
Sprite sprite2;
public void setupSprites(SpriteRenderer displaySprite, string animSprite1, string animSprite2)
{
//Set where the animated sprite will be updated
this.displaySprite = displaySprite;
//Load Sprite 1
Texture2D tex = Resources.Load<Texture2D>(animSprite1) as Texture2D;
sprite1 = Sprite.Create(tex, new Rect(0, 0, 250, 150), new Vector2(0.5f, 0.5f), 40);
//Load Sprite 2
Texture2D tex2 = Resources.Load<Texture2D>(animSprite2) as Texture2D;
sprite2 = Sprite.Create(tex2, new Rect(0, 0, 250, 150), new Vector2(0.5f, 0.5f), 40);
}
private IEnumerator startAnimationCRT(float time)
{
if (continueAnimation)
{
yield break;
}
continueAnimation = true;
WaitForSeconds waitTime = new WaitForSeconds(time);
while (continueAnimation)
{
//Change to Sprite1
displaySprite.sprite = sprite1;
//Wait for `time` amount
yield return waitTime;
//Change Sprite
displaySprite.sprite = sprite2;
//Wait for `time` amount
yield return waitTime;
}
continueAnimation = false;
}
public void startAnimation(float time)
{
StartCoroutine(startAnimationCRT(time));
}
public void stopAnimation()
{
continueAnimation = false;
}
public void removeAnimation()
{
Destroy(this.gameObject);
}
}
2.Create another script called SpriteAnimation
. Copy everything from below to it. Also remove ": MonoBehaviour
" after the class name. You must do this! It can't derive from MonoBehaviour
so remove it.
using UnityEngine;
using System.Collections;
public class SpriteAnimation
{
SpriteAnimator spriteAnimator;
GameObject gameObj;
public void setupSprites(string animationName, SpriteRenderer displaySprite, string animSprite1, string animSprite2)
{
gameObj = new GameObject(animationName);
gameObj.AddComponent<SpriteAnimator>();
spriteAnimator = gameObj.GetComponent<SpriteAnimator>();
spriteAnimator.setupSprites(displaySprite, animSprite1, animSprite2);
}
public void startAnimation(float time = 0.5f)
{
spriteAnimator.startAnimation(time);
}
public void stopAnimation()
{
spriteAnimator.stopAnimation();
}
public void Destroy()
{
spriteAnimator.removeAnimation();
}
}
Done. How to use:
public SpriteRenderer SR;
SpriteAnimation dogAnimation;
void Start()
{
dogAnimation = new SpriteAnimation();
dogAnimation.setupSprites("DogAnimation", SR, "dog", "dog2");
dogAnimation.startAnimation(0.2f);
}
Call dogAnimation.stopAnimation();
to stop the animation.
You can create many SpriteAnimations
as you want. The line of code dogAnimation.setupSprites("DogAnimation", SR, "dog", "dog2");
will setup animation. It will create a new GameObject
named DogAnimation
. It will then load two images called dog
and dog2
from the Resources
folder so make sure those exist. SR
is the texture on the screen that will be changed with dog2
and dog
images. dogAnimation.startAnimation(0.2f);
will start the animation and you can pass in the animation transition time inside.
How do I get my images to work as an animation in pygame?
- Load the images and put them into lists.
- Add an index, a timer and an
images
(the current image list/animation) attribute to the class. - When the user presses one of the movement keys, swap the image list.
- To animate the
images
, first pass thedt
(delta time) to the player'supdate
method and subsequently to the other methods that need it. Increment the timer attribute and, after the desired time interval, increment the index and use it to swap the image.
That's basically all you need to do, but maybe you have to adjust a few things.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
# Load images once when the program starts. Put them into lists, so that
# you can easily swap them out when the player changes the direction.
STICKMAN_IDLE = [pg.image.load(
'Images/Animations/PlayerRun/Stickman_stand_still.png').convert_alpha()]
# You could use a list comprehension here (look it up).
STICKMAN_RUN = [
pg.image.load('Images/Animations/PlayerRun/Stickman_run_1.png').convert_alpha(),
pg.image.load('Images/Animations/PlayerRun/Stickman_run_2.png').convert_alpha(),
pg.image.load('Images/Animations/PlayerRun/Stickman_run_3.png').convert_alpha(),
pg.image.load('Images/Animations/PlayerRun/Stickman_run_4.png').convert_alpha(),
]
class Player:
def __init__(self, x, y):
self.pos_x = x
self.pos_y = y
self.images = STICKMAN_IDLE
self.image = self.images[0]
self.rect = self.image.get_rect(center=(x, y))
self.anim_index = 0
self.anim_timer = 0
def move_player(self, dt):
"""Move the player."""
self.pressed = pg.key.get_pressed()
if self.pressed[pg.K_a]:
self.pos_x -= 5 # Move left.
self.images = STICKMAN_RUN_RIGHT # Change the animation.
if self.pressed[pg.K_d]:
self.pos_x += 5 # Move right.
self.images = STICKMAN_RUN_RIGHT # Change the animation.
if not self.pressed[pg.K_d] and not self.pressed[pg.K_a]:
self.images = STICKMAN_IDLE # Change the animation.
# Update the rect because it's used to blit the image.
self.rect.center = self.pos_x, self.pos_y
def animate(self, dt):
# Add the delta time to the anim_timer and increment the
# index after 70 ms.
self.anim_timer += dt
if self.anim_timer > .07: # After 70 ms.
self.anim_timer = 0 # Reset the timer.
self.anim_index += 1 # Increment the index.
self.anim_index %= len(self.images) # Modulo to cycle the index.
self.image = self.images[self.anim_index] # And switch the image.
def update(self, dt):
self.move_player(dt)
self.animate(dt)
def draw(self, screen):
screen.blit(self.image, self.rect)
def main():
clock = pg.time.Clock()
player = Player(100, 300)
done = False
while not done:
# dt (delta time) = time in ms since previous tick.
dt = clock.tick(30) / 1000
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
player.update(dt) # Pass the delta time to the player.
screen.fill((30, 30, 30))
player.draw(screen)
pg.display.flip()
if __name__ == '__main__':
main()
pg.quit()
Related Topics
Running a Bash Script from Python
Unicode Box Drawing Characters Not Printed in Ruby
Why Aren't Python Nested Functions Called Closures
How to Access Variables from Different Classes in Tkinter
Why Is the Pygame Animation Is Flickering
How to Urlencode a Querystring in Python
Replace Values in a Pandas Series via Dictionary Efficiently
Is There a Simple Way to Delete a List Element by Value
How to Return Two Values from a Function in Python
Python Multiprocessing + Subprocess Issues
Python Threading with Queue: How to Avoid to Use Join
Unix Socket Credential Passing in Python
How to Emulate a Do-While Loop
How to Convert a String to a Number If It Has Commas in It as Thousands Separators
What Are "Named Tuples" in Python