Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/api/SuperSprite.py
diff options
context:
space:
mode:
authorAlan Aguiar <alanjas@hotmail.com>2012-02-26 23:21:30 (GMT)
committer Alan Aguiar <alanjas@hotmail.com>2012-02-26 23:21:30 (GMT)
commit02de66e7d3403af17113b7d7e674eb4bcb96278d (patch)
tree1ae053e2bbd1a15cf5c2381c9ac4adc276259724 /src/api/SuperSprite.py
parent54e57e7ba5ad7ae0508e6005c798db0a497e6578 (diff)
rename files of class - add losed permissions
Diffstat (limited to 'src/api/SuperSprite.py')
-rwxr-xr-xsrc/api/SuperSprite.py427
1 files changed, 427 insertions, 0 deletions
diff --git a/src/api/SuperSprite.py b/src/api/SuperSprite.py
new file mode 100755
index 0000000..6105541
--- /dev/null
+++ b/src/api/SuperSprite.py
@@ -0,0 +1,427 @@
+import pygame
+import math
+
+class CSuperSprite(pygame.sprite.Sprite):
+ """ An enhanced Sprite class
+ expects a gameEngine.Scene class as its one parameter
+ Use methods to change image, direction, speed
+ Will automatically travel in direction and speed indicated
+ Automatically rotates to point in indicated direction
+ Five kinds of boundary collision
+ """
+
+# TODO: No pasar scene, sino que en el constructor usar self.mScene = CGame().inst().getScreen()
+ def __init__(self, scene):
+ pygame.sprite.Sprite.__init__(self)
+ self.scene = scene
+ self.screen = scene.mScreen
+
+ #create constants
+ self.WRAP = 0
+ self.BOUNCE = 1
+ self.STOP = 2
+ self.HIDE = 3
+ self.CONTINUE = 4
+
+ #create a default text image as a placeholder
+ #This will usually be changed by a setImage call
+ print "Csupersprite"
+ print pygame.font.get_init()
+ self.font = pygame.font.Font("goodfoot.ttf", 30)
+ self.imageMaster = self.font.render(">sprite>", True, (0, 0,0), (0xFF, 0xFF, 0xFF))
+ self.image = self.imageMaster
+ self.rect = self.image.get_rect()
+
+ #create properties
+ #most will be changed through method calls
+ self.x = 200
+ self.y = 200
+ self.dx = 0
+ self.dy = 0
+ self.dir = 0
+ self.rotation = 0
+ self.speed = 0
+ self.maxSpeed = 10
+ self.minSpeed = -3
+ self.boundAction = self.WRAP
+ self.pressed = False
+ self.oldCenter = (100, 100)
+ self.states = {}
+ self.currentState = "default"
+
+ def update(self):
+ self.oldCenter = self.rect.center
+ self.checkEvents()
+ self.__rotate()
+ self.__calcVector()
+ self.__calcPosition()
+ self.checkBounds()
+ self.rect.center = (self.x, self.y)
+
+ def checkEvents(self):
+ """ overwrite this method to add your own event code """
+ pass
+
+ def __rotate(self):
+ """ PRIVATE METHOD
+ change visual orientation based on
+ rotation property.
+ automatically called in update.
+ change rotation property directly or with
+ rotateBy(), setAngle() methods
+ """
+ oldCenter = self.rect.center
+ self.oldCenter = oldCenter
+ self.image = pygame.transform.rotate(self.imageMaster, self.rotation)
+ self.rect = self.image.get_rect()
+ self.rect.center = oldCenter
+
+ def __calcVector(self):
+ """ calculates dx and dy based on speed, dir
+ automatically called in update
+ """
+ theta = self.dir / 180.0 * math.pi
+ self.dx = math.cos(theta) * self.speed
+ self.dy = math.sin(theta) * self.speed
+ self.dy *= -1
+
+ def __calcPosition(self):
+ """ calculates the sprites position adding
+ dx and dy to x and y.
+ automatically called in update
+ """
+ self.x += self.dx
+ self.y += self.dy
+
+ def checkBounds(self):
+ """ checks boundary and acts based on
+ self.BoundAction.
+ WRAP: wrap around screen (default)
+ BOUNCE: bounce off screen
+ STOP: stop at edge of screen
+ HIDE: move off stage and wait
+ CONTINUE: keep going at present course and speed
+
+ automatically called by update
+ """
+
+ scrWidth = self.screen.get_width()
+ scrHeight = self.screen.get_height()
+
+ #create variables to simplify checking
+ offRight = offLeft = offTop = offBottom = offScreen = False
+
+ if self.x > scrWidth:
+ offRight = True
+ if self.x < 0:
+ offLeft = True
+ if self.y > scrHeight:
+ offBottom = True
+ if self.y < 0:
+ offTop = True
+
+ if offRight or offLeft or offTop or offBottom:
+ offScreen = True
+
+ if self.boundAction == self.WRAP:
+ if offRight:
+ self.x = 0
+ if offLeft:
+ self.x = scrWidth
+ if offBottom:
+ self.y = 0
+ if offTop:
+ self.y = scrHeight
+
+ elif self.boundAction == self.BOUNCE:
+ if offLeft or offRight:
+ self.dx *= -1
+ if offTop or offBottom:
+ self.dy *= -1
+
+ self.updateVector()
+ self.rotation = self.dir
+
+ elif self.boundAction == self.STOP:
+ if offScreen:
+ self.speed = 0
+
+ elif self.boundAction == self.HIDE:
+ if offScreen:
+ self.speed = 0
+ self.setPosition((-1000, -1000))
+
+ elif self.boundAction == self.CONTINUE:
+ pass
+
+ else:
+ # assume it's continue - keep going forever
+ pass
+
+ def setSpeed(self, speed):
+ """ immediately sets the objects speed to the
+ given value.
+ """
+ self.speed = speed
+
+ def speedUp(self, amount):
+ """ changes speed by the given amount
+ Use a negative value to slow down
+ """
+ self.speed += amount
+ if self.speed < self.minSpeed:
+ self.speed = self.minSpeed
+ if self.speed > self.maxSpeed:
+ self.speed = self.maxSpeed
+
+ def setAngle(self, dir):
+ """ sets both the direction of motion
+ and visual rotation to the given angle
+ If you want to set one or the other,
+ set them directly. Angle measured in degrees
+ """
+ self.dir = dir
+ self.rotation = dir
+
+ def turnBy (self, amt):
+ """ turn by given number of degrees. Changes
+ both motion and visual rotation. Positive is
+ counter-clockwise, negative is clockwise
+ """
+ self.dir += amt
+ if self.dir > 360:
+ self.dir = amt
+ if self.dir < 0:
+ self.dir = 360 - amt
+ self.rotation = self.dir
+
+ def rotateBy(self, amt):
+ """ change visual orientation by given
+ number of degrees. Does not change direction
+ of travel.
+ """
+ self.rotation += amt
+ if self.rotation > 360:
+ self.rotation = amt
+ if self.rotation < 0:
+ self.rotation = 360 - amt
+
+ def setImage (self, image):
+ """ loads the given file name as the master image
+ default setting should be facing east. Image
+ will be rotated automatically """
+ self.imageMaster = pygame.image.load(image)
+ self.imageMaster = self.imageMaster.convert()
+
+ def setDX(self, dx):
+ """ changes dx value and updates vector """
+ self.dx = dx
+ self.updateVector()
+
+ def addDX(self, amt):
+ """ adds amt to dx, updates vector """
+ self.dx += amt
+ self.updateVector()
+
+ def setDY(self, dy):
+ """ changes dy value and updates vector """
+ self.dy = dy
+ self.updateVector()
+
+ def addDY(self, amt):
+ """ adds amt to dy and updates vector """
+ self.dy += amt
+ self.updateVector()
+
+ def setComponents(self, components):
+ """ expects (dx, dy) for components
+ change speed and angle according to dx, dy values """
+
+ (self.dx, self.dy) = components
+ self.updateVector()
+
+ def setBoundAction (self, action):
+ """ sets action for boundary. Values are
+ self.WRAP (wrap around edge - default)
+ self.BOUNCE (bounce off screen changing direction)
+ self.STOP (stop at edge of screen)
+ self.HIDE (move off-stage and stop)
+ self.CONTINUE (move on forever)
+ Any other value allows the sprite to move on forever
+ """
+ self.boundAction = action
+
+ def setPosition (self, position):
+ """ place the sprite directly at the given position
+ expects an (x, y) tuple
+ """
+ (self.x, self.y) = position
+
+ def moveBy (self, vector):
+ """ move the sprite by the (dx, dy) values in vector
+ automatically calls checkBounds. Doesn't change
+ speed or angle settings.
+ """
+ (dx, dy) = vector
+ self.x += dx
+ self.y += dy
+ self.checkBounds()
+
+ def forward(self, amt):
+ """ move amt pixels in the current direction
+ of travel
+ """
+
+ #calculate dx dy based on current direction
+ radians = self.dir * math.pi / 180
+ dx = amt * math.cos(radians)
+ dy = amt * math.sin(radians) * -1
+
+ self.x += dx
+ self.y += dy
+
+ def addForce(self, amt, angle):
+ """ apply amt of thrust in angle.
+ change speed and dir accordingly
+ add a force straight down to simulate gravity
+ in rotation direction to simulate spacecraft thrust
+ in dir direction to accelerate forward
+ at an angle for retro-rockets, etc.
+ """
+
+ #calculate dx dy based on angle
+ radians = angle * math.pi / 180
+ dx = amt * math.cos(radians)
+ dy = amt * math.sin(radians) * -1
+
+ self.dx += dx
+ self.dy += dy
+ self.updateVector()
+
+ def updateVector(self):
+ #calculate new speed and angle based on dx, dy
+ #call this any time you change dx or dy
+
+ self.speed = math.sqrt((self.dx * self.dx) + (self.dy * self.dy))
+
+ dy = self.dy * -1
+ dx = self.dx
+
+ radians = math.atan2(dy, dx)
+ self.dir = radians / math.pi * 180
+
+ def setSpeedLimits(self, max, min):
+ """ determines maximum and minimum
+ speeds you will allow through
+ speedUp() method. You can still
+ directly set any speed you want
+ with setSpeed() Default values:
+ max: 10
+ min: -3
+ """
+ self.maxSpeed = max
+ self.minSpeed = min
+
+ def dataTrace(self):
+ """ utility method for debugging
+ print major properties
+ extend to add your own properties
+ """
+ print "x: %d, y: %d, speed: %.2f, dir: %.f, dx: %.2f, dy: %.2f" % \
+ (self.x, self.y, self.speed, self.dir, self.dx, self.dy)
+
+ def mouseDown(self):
+ """ boolean function. Returns True if the mouse is
+ clicked over the sprite, False otherwise
+ """
+ self.pressed = False
+ if pygame.mouse.get_pressed() == (1, 0, 0):
+ if self.rect.collidepoint(pygame.mouse.get_pos()):
+ self.pressed = True
+ return self.pressed
+
+ def clicked(self):
+ """ Boolean function. Returns True only if mouse
+ is pressed and released over sprite
+ """
+ released = False
+ if self.pressed:
+ if pygame.mouse.get_pressed() == (0, 0, 0):
+ if self.rect.collidepoint(pygame.mouse.get_pos()):
+ released = True
+ return released
+
+ def collidesWith(self, target):
+ """ boolean function. Returns True if the sprite
+ is currently colliding with the target sprite,
+ False otherwise
+ """
+ collision = False
+ if self.rect.colliderect(target.rect):
+ collision = True
+ return collision
+
+ def collidesGroup(self, target):
+ """ wrapper for pygame.sprite.collideany
+ simplifies checking sprite - group collisions
+ returns result of collision check (sprite from group
+ that was hit or None)
+ """
+ collision = pygame.sprite.spritecollideany(self, target)
+ return collision
+
+ def distanceTo(self, point):
+ """ returns distance to any point in pixels
+ can be used in circular collision detection
+ """
+ (pointx, pointy) = point
+ dx = self.x - pointx
+ dy = self.y - pointy
+
+ dist = math.sqrt((dx * dx) + (dy * dy))
+ return dist
+
+ def dirTo(self, point):
+ """ returns direction (in degrees) to
+ a point """
+
+ (pointx, pointy) = point
+ dx = self.x - pointx
+ dy = self.y - pointy
+ dy *= -1
+
+ radians = math.atan2(dy, dx)
+ dir = radians * 180 / math.pi
+ dir += 180
+ return dir
+
+ def drawTrace(self, color=(0x00, 0x00, 0x00)):
+ """ traces a line between previous position
+ and current position of object
+ """
+ pygame.draw.line(self.scene.background, color, self.oldCenter,
+ self.rect.center, 3)
+ self.screen.blit(self.scene.background, (0, 0))
+
+ def addState(self, stateName, stateImageFile):
+ """ Creates a new sprite state with the associated name
+ and image. Useful to build multi-state sprites.
+ """
+ #load the image
+ tempImage = pygame.image.load(stateImageFile)
+ tempImage.convert()
+ self.states[stateName] = tempImage
+
+ def setState(self, stateName):
+ """ attempts to set the sprite to the indicated state
+ (image)
+ """
+ self.imageMaster = self.states[stateName]
+ self.rect = self.imageMaster.get_rect()
+ self.currentState = stateName
+
+ def getState(self):
+ """ returns the current state name
+ (default if no states have been explicitly set)
+ """
+ return self.currentState