# # Google.py # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # Copyright # Author: Salvatore S. Gionfriddo # Contributors: Nicholas F. Hoover # Created: 2007.11.18 # Last Modified: 2007.11.18 # import pygame from GameObject import GameObject from Animation import Animation from Hero import Hero from Flame import Flame, Gas class Google(Hero): """ A playable character with hunger, heartburn, and gas stats the allow him to breathe fire and fart noxious gas to destroy his enemies. """ HERO_NAME = 'Google' ######### # STATS # ######### MAX_HUNGER = 100 MIN_HUNGER = 0 START_HUNGER = 40 HUNGER_DAMAGE_PER_TICK = 2 STARVATION_DAMAGE = 4 STARVATION_MIN = 0 STARVATION_MAX = 20 HEARTBURN_MIN = 80 HEARTBURN_END = 70 FLAME_COST = 10 MIN_GAS = 0 MAX_GAS = 100 GAS_COST = 15 ############## # ANIMATIONS # ############## PUNCH = Hero.ATTACK1 KICK = Hero.ATTACK2 FLAME = Hero.SPECIAL1 GAS = Hero.SPECIAL2 ############### # FRAME_TICKS # ############### IDLE_FRAME_TICKS = 4 WALK_FRAME_TICKS = 2 PUNCH_FRAME_TICKS = [1,1,1] #3 updates for 2 kills .75 efficiency KICK_FRAME_TICKS = [1,2,3,2,1] #9 updates for 7 kills .77 efficiency EAT_FRAME_TICKS = [1,1,2,2,2,1] FLAME_FRAME_TICKS = [2,3,2,5] GAS_FRAME_TICKS = 2 PICKUP_FRAME_TICKS = [1,1,2,2,1] USE_FRAME_TICKS = 1 ############## # KEY FRAMES # ############## PUNCH_KEY_FRAME = 1 KICK_KEY_FRAME = 2 EAT_KEY_FRAME = 3 FLAME_KEY_FRAME = 3 GAS_KEY_FRAME = 2 PICKUP_KEY_FRAME = 3 USE_KEY_FRAME = 1 ######################### # ATTACK COLLISION DATA # ######################### PUNCH_RECT = pygame.Rect((10,50),(20,10)) KICK_RECT = pygame.Rect((15,60),(15,20)) EAT_RECT = pygame.Rect((10,80),(12,12)) # PICKUP_RECT = pygame.Rect(EAT_RECT) ################### # ANIMATION TABLE # ################### ANIMATION_TABLE = [ (Hero.IDLE, 'Google_Idle', IDLE_FRAME_TICKS, Animation.NO_KEY_FRAME), (Hero.WALK_UP, 'Google_WalkUp', WALK_FRAME_TICKS, Animation.NO_KEY_FRAME), (Hero.WALK_DOWN, 'Google_WalkDown', WALK_FRAME_TICKS, Animation.NO_KEY_FRAME), (Hero.WALK_SIDE, 'Google_WalkSide', WALK_FRAME_TICKS, Animation.NO_KEY_FRAME), (PUNCH, 'Google_Punch', PUNCH_FRAME_TICKS, PUNCH_KEY_FRAME), (KICK, 'Google_Kick', KICK_FRAME_TICKS, KICK_KEY_FRAME), (FLAME, 'Google_Flame', FLAME_FRAME_TICKS, FLAME_KEY_FRAME), (GAS, 'Google_Gas', GAS_FRAME_TICKS, GAS_KEY_FRAME), (Hero.EAT, 'Google_Eat', EAT_FRAME_TICKS, EAT_KEY_FRAME), (Hero.PICKUP, 'Google_Pickup', PICKUP_FRAME_TICKS,PICKUP_KEY_FRAME), (Hero.USE, 'Google_Use', USE_FRAME_TICKS, USE_KEY_FRAME), ] ############# # MOVEMENTS # ############# MOVEMENTS = [(0,0), #IDLE (0,-12), #WALK_UP (0,12), #WALK_DOWN (12,0), #WALK_SIDE (0,0), #PUNCH (0,0), #KICK (0,0), #EAT (0,0), #FLAME (0,0), #GAS (0,0), #PICKUP (0,0), #USE ] ########### # ATTACKS # ########### PUNCH_DAMAGE = 200 #Kill 2 basic kids KICK_DAMAGE = 700 #Kill 7 basic kids FLAME_DAMAGE = 2000 #Kill 20 basic kids per animation frame GAS_DAMAGE = 1000 ATTACK1_DAMAGE = PUNCH_DAMAGE ATTACK2_DAMAGE = KICK_DAMAGE SPECIAL1_DAMAGE = FLAME_DAMAGE SPECIAL2_DAMAGE = GAS_DAMAGE ######## # MISC # ######## DEFAULT_POSITION = (300,300) RECT_SIZE = (60,100) COLLISION_RECT_SIZE = (0,0) COLLISION_RECT_POSITION = (20,95) ############# # FUNCTIONS # ############# def __init__(self): Hero.__init__(self) self.statusFunctions.append(self.updateHungerStatus) self.reset() def reset(self): Hero.reset(self) self.hunger = Google.START_HUNGER self.heartBurn = False self.gas = Google.MIN_GAS def updateHungerStatus(self): self.decHunger(self.HUNGER_DAMAGE_PER_TICK) if self.isStarving(): self.decHealth(self.STARVATION_DAMAGE) elif self.hunger >= self.HEARTBURN_MIN: self.setHeartBurn(True) elif self.hunger < self.HEARTBURN_END: self.setHeartBurn(False) ######### # STATS # ######### def incHunger(self,amount): self.hunger += amount if self.hunger > self.MAX_HUNGER: self.hunger = self.MAX_HUNGER def decHunger(self,amount): prevHunger = self.hunger self.hunger -= amount if self.hunger < self.MIN_HUNGER: self.hunger = self.MIN_HUNGER if prevHunger > self.HEARTBURN_END and self.hunger < self.HEARTBURN_END: self.playSound('EG_Hungry') elif prevHunger > self.STARVATION_MAX and self.isStarving(): self.playSound('EG_Starving') def incHealth(self, amount): Hero.incHealth(self, amount) def decHealth(self, amount): Hero.decHealth(self,amount) pass def setHeartBurn(self, status): if not self.heartBurn and status: self.playSound('EG_Heartburn') self.heartBurn = status def incGas(self, amount): self.gas += amount if self.gas > self.MAX_GAS: self.gas = self.MAX_GAS def decGas(self, amount): self.gas -= amount if self.gas < self.MIN_GAS: self.gas = self.MIN_GAS def getStats(self): return (self.health, self.hunger, self.heartBurn, self.gas, self.speed_bonus, self.regen_bonus, self.toughness_bonus) def isStarving(self): return self.hunger >= self.STARVATION_MIN and self.hunger <= self.STARVATION_MAX def isSatiated(self): return self.hunger == self.MAX_HUNGER def flame(self): if self.canAct() and self.heartBurn: self.setAnimation(Google.FLAME) self.decHunger(Google.FLAME_COST) self.playSound('EG_Flame') def gasAttack(self): if self.canAct() and self.gas >= Google.GAS_COST: self.setAnimation(Google.GAS) self.decGas(Google.GAS_COST) self.playSound('Flame') def createAttack1Sprite(self): punchSprite = pygame.sprite.Sprite() punchSprite.rect = pygame.Rect(Google.PUNCH_RECT) punchSprite.rect.top += self.rect.top if self.facing == Google.RIGHT: punchSprite.rect.left += self.rect.centerx else: punchSprite.rect.left = self.rect.centerx - Google.PUNCH_RECT.left - Google.PUNCH_RECT.width return punchSprite def createAttack2Sprite(self): kickSprite = pygame.sprite.Sprite() kickSprite.rect = pygame.Rect(Google.KICK_RECT) kickSprite.rect.top += self.rect.top if self.facing == Google.RIGHT: kickSprite.rect.left += self.rect.centerx else: kickSprite.rect.left = self.rect.centerx - Google.KICK_RECT.left - Google.KICK_RECT.width return kickSprite def createFlameSprite(self): flame = Flame() if self.facing == Google.RIGHT: flame.setPosition((self.rect.centerx + 20, self.rect.top + 30)) else: flame.setPosition((self.rect.centerx - flame.rect.width - 20, self.rect.top + 30)) flame.facing = Flame.LEFT flame.setAnimation(Flame.FLAME) return flame def createGasSprite(self): gas = Gas() if self.facing == Google.RIGHT: gas.setPosition((self.rect.left - gas.rect.width, self.rect.top + 60)) else: gas.setPosition((self.rect.right, self.rect.top + 60)) gas.facing = Gas.LEFT gas.setAnimation(Gas.GAS) return gas def createEatSprite(self): eatSprite = pygame.sprite.Sprite() eatSprite.rect = pygame.Rect(Google.EAT_RECT) eatSprite.rect.top += self.rect.top if self.facing == Google.RIGHT: eatSprite.rect.left += self.rect.centerx else: eatSprite.rect.left = self.rect.centerx - Google.EAT_RECT.left - Google.EAT_RECT.width return eatSprite class DeadGoogle(GameObject): NUM_ANIMATIONS = 1 DEAD = 0 LEFT = NUM_ANIMATIONS ################### # ANIMATION TABLE # ################### ANIMATION_TABLE = [ (DEAD, 'EG_Dead', 1, Animation.NO_KEY_FRAME), ] DEFAULT_ANIMATION = DEAD RECT_SIZE = (100, 60)