Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Animation Styles/AnimatedSprite.py
blob: 67966006a580a504894e1f3f0b5c49befe85ded7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import pygame

class Spritesheet:
    """
    Class from http://www.scriptedfun.com/transcript-2-using-sprite-sheets-and-drawing-the-background/

    This class can be used to seporate images from the sprite sheet
    """
    def __init__(self, filename):
        self.sheet = pygame.image.load(filename)#.convert()

    def imgat(self, rect):
        rect = pygame.Rect(rect)
        image = pygame.Surface(rect.size)#.convert()
        image.blit(self.sheet, (0, 0), rect)
        return image

    def imgsat(self, rects):
        imgs = []
        for rect in rects:
            imgs.append(self.imgat(rect))
        return imgs

    def img_extract( self, cols, rows, width, height ):
        rect_list = []
        for y in range(0, rows):
            for x in range(0, cols):
                rect_list.append( (width*x, height*y, width, height) )
        return self.imgsat( rect_list)


class AnimatedSprite(pygame.sprite.Sprite):
    """
    http://shinylittlething.com/2009/07/21/pygame-and-animated-sprites/
    """

    def __init__(self,images,textfileName,fps = 10):
        pygame.sprite.Sprite.__init__(self)
        self._images = images

        # Track the time we started, and the time between updates.
        # Then we can figure out when we have to switch the image.
        self._start = pygame.time.get_ticks()
        self._delay = 1000 / fps
        self._last_update = 0
        self._frame = 0
        self.animations = {}
        
        if textfileName != '':
           f = open(textfileName, 'r')
           currentLine = f.readline()
           while currentLine != '':
             animValues = currentLine.split(",")
             #This is a list called animations that at each position contains a list of two values. the first value is the start position
             #of the given animation and the second is the end position of the given animation
             self.animations[animValues[0]] =  [int(animValues[1]), int(animValues[2])]
             currentLine = f.readline()

        # Call update to set our first image.
        #self.update(pygame.time.get_ticks())

    def addImages(self, images):

        self._images.extend(images)

    def update(self, t):
        # This method updates the animation in a situation where there is only one animation contained within the object.

        #calculates the amount of time that has passed since the last update
        timePassed = t - self._last_update
        #checks if enough time has passed that it would need to update the frame of the animation
        if timePassed > self._delay:
            #since enough time has passed, it will determine how many times the frame was supposed to change since the last update
            frameChanges = int(timePassed/self._delay)
            #goes to the frame that it should be at right now and skips any frames that would have already been over and done with
            self._frame += frameChanges
            #checks if the current frame is past the final frame and continues to check over and over until it is not
            while self._frame >= len(self._images):
              #since we are past the final frame it is now figuring out how many frames past the final frame we have actually gone
              framesPast = self._frame - len(self._images)
              #sets the current frame to the frame it should be at
              self._frame = framesPast - 1
            #sets the current image to the image associated with the current frame
            self.image = self._images[self._frame]
            #sets the last update value to the current time so that at the next update the time change is accurate
            self._last_update = t

    def updateAnimation(self, t, animName):
        # This method updates the animation based on the start and end frame of the specific animation you are on.
        #This means that if your object contains multiple animations, you can use this method to reference the exact
        #animation that you are using.

        #calculates the amount of time that has passed since the last update
        timePassed = t - self._last_update
        #checks if enough time has passed that it would need to update the frame of the animation
        if timePassed > self._delay:
            #Checks to make sure that the current frame is actually set to a position within the animation
            if self._frame < self.animations.get(animName)[0] or self._frame > self.animations.get(animName)[1]:
              #corrects the position of the current frame
              self._frame = self.animations.get(animName)[0]
            #since enough time has passed, it will determine how many times the frame was supposed to change since the last update
            frameChanges = int(timePassed/self._delay)
            #goes to the frame that it should be at right now and skips any frames that would have already been over and done with
            self._frame += frameChanges
            #checks if the current frame is past the final frame of the current animation and continues to check over and over
            #until it is not
            while self._frame >= self.animations.get(animName)[1]:
              #Determines how many frames past the final frame of the animation it is
              framesPast = self._frame - self.animations.get(animName)[1]
              #Sets the current frame to the frame it should be at
              self._frame = framesPast - 1 + self.animations.get(animName)[0]
            #sets the current image to the image associated with the current frame
            self.image = self._images[self._frame]
            #sets the last update value to the current time so that at the next update the time change is accurate
            self._last_update = t

    def nextFrame(self):
        # This definition is designed to simply move to the next frame.
        # All of the other definitions only move to the nex frame if
        # enough time has passed based on the framerate. With this
        # definition I can go right to the next frame allowing me to
        # see how fast a framerate I can get to and not be limited by 
        # what I define.

        self._frame += 1
        if self._frame >= len(self._images):
            framesPast = self._frame - len(self._images)
            self._frame = framesPast
        self.image = self._images[self._frame]
        
    def nextAnimFrame(self, animName):
        # This definition is designed to simply move to the next frame of the specified animation.
        if self._frame < self.animations[animName][0]:
            self._frame = self.animations[animName][0]

        self._frame += 1
        if self._frame > self.animations[animName][1]:
            framesPast = self._frame - self.animations[animName][1]
            self._frame = framesPast - 1 + self.animations[animName][0]
        self.image = self._images[self._frame]