<s> import pygame <EOL> from pygame . locals import * <EOL> import copy <EOL> import time <EOL> import anim <EOL> Kleft = K_LEFT <EOL> Kright = K_RIGHT <EOL> Kjump = K_SPACE <EOL> Kcrouch = K_DOWN <EOL> NORTH = '<STR_LIT>' <EOL> SOUTH = '<STR_LIT>' <EOL> EAST = '<STR_LIT>' <EOL> WEST = '<STR_LIT>' <EOL> AXISX = '<STR_LIT:x>' <EOL> AXISY = '<STR_LIT:y>' <EOL> class Entity ( object ) : <EOL> color = ( <NUM_LIT:255> , <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> maxSpeed = <NUM_LIT:12> <EOL> accel_amt = <NUM_LIT> <EOL> airaccel_amt = <NUM_LIT:1> <EOL> deaccel_amt = <NUM_LIT:5> <EOL> fallAccel = <NUM_LIT> <EOL> jumpMod = <NUM_LIT> <EOL> jumpAccel = <NUM_LIT> <EOL> maxFallSpeed = <NUM_LIT:30> <EOL> def __init__ ( self , level , rectTuple , image = None ) : <EOL> self . rect = pygame . Rect ( ( rectTuple [ <NUM_LIT:0> ] * level . blockWidth ) , <EOL> ( rectTuple [ <NUM_LIT:1> ] * level . blockHeight ) , <EOL> rectTuple [ <NUM_LIT:2> ] , rectTuple [ <NUM_LIT:3> ] ) <EOL> self . normalHeight = self . rect . height <EOL> self . cameraRect = copy . copy ( self . rect ) <EOL> self . animation_speed = <NUM_LIT> <EOL> if type ( image ) is pygame . Surface : <EOL> self . image = image <EOL> elif type ( image ) is str : <EOL> try : <EOL> spritesheet = pygame . image . load ( image ) <EOL> except pygame . error : <EOL> self . image = pygame . Surface ( ( self . rect . width , self . rect . height ) ) <EOL> self . image . fill ( self . color ) <EOL> elif image == None : <EOL> self . image = pygame . Surface ( ( self . rect . width , self . rect . height ) ) <EOL> self . image . fill ( self . color ) <EOL> self . accelX = <NUM_LIT:0> <EOL> self . speedX = <NUM_LIT:0> <EOL> self . speedY = <NUM_LIT:0> <EOL> self . jumping = False <EOL> self . onBlock = False <EOL> def update ( self ) : <EOL> pass <EOL> def load_frames ( self , filename ) : <EOL> spritesheet = pygame . image . load ( filename ) <EOL> spritesheetWidth , spritesheetHeight = spritesheet . get_size ( ) <EOL> frames = [ ] <EOL> for frame in range ( spritesheetWidth / self . rect . width ) : <EOL> newFrameRect = pygame . Rect ( frame * self . rect . width , <EOL> <NUM_LIT:0> , <EOL> self . rect . width , <EOL> spritesheetHeight ) <EOL> frames . append ( spritesheet . subsurface ( newFrameRect ) ) <EOL> return frames <EOL> def updateAnim ( self ) : <EOL> if time . time ( ) - self . lastFrame >= <NUM_LIT> : <EOL> self . lastFrame = time . time ( ) <EOL> self . currentFrame += <NUM_LIT:1> <EOL> if self . currentFrame > len ( self . frames ) - <NUM_LIT:1> : <EOL> self . currentFrame = <NUM_LIT:0> <EOL> self . image = self . frames [ self . currentFrame ] <EOL> def get_accel ( self , keys , jumping ) : <EOL> if not jumping : <EOL> return ( keys [ Kright ] - keys [ Kleft ] ) * self . accel_amt <EOL> elif jumping : <EOL> return ( keys [ Kright ] - keys [ Kleft ] ) * self . airaccel_amt <EOL> def accelerate ( self , accel , speed ) : <EOL> if accel != <NUM_LIT:0> : <EOL> if ( ( speed < <NUM_LIT:0> ) and ( accel > <NUM_LIT:0> ) ) or ( ( speed > <NUM_LIT:0> ) and ( accel < <NUM_LIT:0> ) ) : <EOL> speed = accel <EOL> else : <EOL> speed += accel <EOL> if speed > self . maxSpeed : <EOL> speed = self . maxSpeed <EOL> if speed < - self . maxSpeed : <EOL> speed = - self . maxSpeed <EOL> if accel == <NUM_LIT:0> : <EOL> if speed > <NUM_LIT:0> : <EOL> speed -= self . deaccel_amt <EOL> if speed < <NUM_LIT:0> : <EOL> speed = <NUM_LIT:0> <EOL> if speed < <NUM_LIT:0> : <EOL> speed += self . deaccel_amt <EOL> if speed > <NUM_LIT:0> : <EOL> speed = <NUM_LIT:0> <EOL> return speed <EOL> def jump ( self , speed , onBlock ) : <EOL> if onBlock : <EOL> speed -= self . jumpAccel <EOL> speed += self . fallAccel - self . jumpMod <EOL> if speed > self . maxFallSpeed : <EOL> speed = self . maxFallSpeed <EOL> return speed <EOL> def fall ( self , speed ) : <EOL> speed += self . fallAccel <EOL> if speed > self . maxFallSpeed : <EOL> speed = self . maxFallSpeed <EOL> return speed <EOL> def get_shortest_distance ( self , rect , speed , axis , level ) : <EOL> dir = self . check_dir ( speed , axis ) <EOL> if dir == WEST : <EOL> front = rect . left <EOL> elif dir == EAST : <EOL> front = rect . right <EOL> elif dir == NORTH : <EOL> front = rect . top <EOL> elif dir == SOUTH : <EOL> front = rect . bottom <EOL> linesToCheck = self . check_lines ( rect , axis , level ) <EOL> if dir : <EOL> minDistance = self . calculate_distance ( front , linesToCheck , dir , level ) <EOL> else : <EOL> minDistance = <NUM_LIT:0> <EOL> if self . check_collision ( speed , minDistance ) : <EOL> return minDistance <EOL> else : <EOL> return speed <EOL> def check_dir ( self , speed , axis ) : <EOL> if axis == AXISX : <EOL> if speed < <NUM_LIT:0> : <EOL> return WEST <EOL> elif speed > <NUM_LIT:0> : <EOL> return EAST <EOL> elif axis == AXISY : <EOL> if speed < <NUM_LIT:0> : <EOL> return NORTH <EOL> elif speed > <NUM_LIT:0> : <EOL> return SOUTH <EOL> def check_lines ( self , rect , axis , level ) : <EOL> linesToCheck = [ ] <EOL> if axis == AXISX : <EOL> for y in range ( level . levelHeight ) : <EOL> if rect . colliderect ( ( <NUM_LIT:0> , <EOL> y * level . blockHeight , <EOL> level . rightEdge , <EOL> level . blockHeight ) ) : <EOL> linesToCheck . append ( y ) <EOL> elif axis == AXISY : <EOL> for x in range ( level . levelWidth ) : <EOL> if rect . colliderect ( ( x * level . blockWidth , <EOL> <NUM_LIT:0> , <EOL> level . blockWidth , <EOL> level . bottomEdge ) ) : <EOL> linesToCheck . append ( x ) <EOL> return linesToCheck <EOL> def calculate_distance ( self , coord , lines , dir , level ) : <EOL> distances = [ ] <EOL> if dir == WEST or dir == EAST : <EOL> playerTile = self . convert_pixel_to_level ( coord , <NUM_LIT:0> , level ) [ <NUM_LIT:0> ] <EOL> elif dir == NORTH or dir == SOUTH : <EOL> playerTile = self . convert_pixel_to_level ( <NUM_LIT:0> , coord , level ) [ <NUM_LIT:1> ] <EOL> if dir == WEST : <EOL> for line in lines : <EOL> nearestBlock = self . scan_line ( line , playerTile , - <NUM_LIT:1> , - <NUM_LIT:1> , AXISX , level ) <EOL> distances . append ( abs ( nearestBlock * level . blockWidth + level . blockWidth - coord ) ) <EOL> elif dir == EAST : <EOL> for line in lines : <EOL> nearestBlock = self . scan_line ( line , playerTile , level . levelWidth , <NUM_LIT:1> , AXISX , level ) <EOL> distances . append ( abs ( nearestBlock * level . blockWidth - coord ) ) <EOL> elif dir == NORTH : <EOL> for line in lines : <EOL> nearestBlock = self . scan_line ( line , playerTile , - <NUM_LIT:1> , - <NUM_LIT:1> , AXISY , level ) <EOL> distances . append ( abs ( nearestBlock * level . blockHeight + level . blockHeight - coord ) ) <EOL> elif dir == SOUTH : <EOL> for line in lines : <EOL> nearestBlock = self . scan_line ( line , playerTile , level . levelHeight , <NUM_LIT:1> , AXISY , level ) <EOL> distances . append ( abs ( nearestBlock * level . blockHeight - coord ) ) <EOL> desiredValue = min ( distances ) <EOL> if dir == WEST or dir == NORTH : <EOL> return - desiredValue <EOL> elif dir == EAST or dir == SOUTH : <EOL> return desiredValue <EOL> def convert_pixel_to_level ( self , x , y , level ) : <EOL> for levelX in range ( level . levelWidth ) : <EOL> for levelY in range ( level . levelHeight ) : <EOL> tempRect = pygame . Rect ( levelX * level . blockWidth , <EOL> levelY * level . blockHeight , <EOL> level . blockWidth , level . blockHeight ) <EOL> if tempRect . collidepoint ( x , y ) : <EOL> return ( levelX , levelY ) <EOL> def scan_line ( self , line , start , end , dir , axis , level ) : <EOL> if axis == AXISX : <EOL> for tile in range ( start , end , dir ) : <EOL> if level . collisionLayer [ line ] [ tile ] == level . block : <EOL> return tile <EOL> elif axis == AXISY : <EOL> for tile in range ( start , end , dir ) : <EOL> if level . collisionLayer [ tile ] [ line ] == level . block : <EOL> return tile <EOL> return start <EOL> def check_collision ( self , speed , minDistance ) : <EOL> if ( speed < <NUM_LIT:0> and minDistance > speed ) or ( speed > <NUM_LIT:0> and minDistance < speed ) : <EOL> return True <EOL> return False <EOL> def check_on_block ( self , rect , level ) : <EOL> for x in range ( level . levelWidth ) : <EOL> for y in range ( level . levelHeight ) : <EOL> if level . collisionLayer [ y ] [ x ] == level . blank : <EOL> continue <EOL> elif level . collisionLayer [ y ] [ x ] == level . block : <EOL> tempCheckRect = copy . copy ( rect ) <EOL> tempLevelRect = pygame . Rect ( x * level . blockWidth , <EOL> y * level . blockHeight , <EOL> level . blockWidth , level . blockHeight ) <EOL> tempCheckRect . bottom += <NUM_LIT:1> <EOL> if tempLevelRect . colliderect ( tempCheckRect ) : <EOL> return True <EOL> return False <EOL> def check_head_collision ( self , level ) : <EOL> '''<STR_LIT>''' <EOL> if not self . crouching : <EOL> return False <EOL> x , y = self . get_coords ( level ) <EOL> levelBlocks = ( level . collisionLayer [ y - <NUM_LIT:1> ] [ x - <NUM_LIT:1> ] , <EOL> level . collisionLayer [ y - <NUM_LIT:1> ] [ x ] , <EOL> level . collisionLayer [ y - <NUM_LIT:1> ] [ x + <NUM_LIT:1> ] , ) <EOL> if all ( block == level . blank for block in levelBlocks ) : <EOL> return False <EOL> else : <EOL> standingRect = copy . deepcopy ( self . rect ) <EOL> standingRect . top += ( self . normalHeight - self . crouchHeight ) <EOL> levelRects = [ pygame . Rect ( i * level . blockWidth , <EOL> y * level . blockHeight , <EOL> level . blockWidth , <EOL> level . blockHeight , ) <EOL> for i in range ( x - <NUM_LIT:1> , x + <NUM_LIT:2> ) ] <EOL> return any ( levelBlocks [ a ] == level . block and <EOL> levelRects [ a ] . colliderect ( standingRect ) <EOL> for a in range ( len ( levelBlocks ) ) ) <EOL> def get_coords ( self , level ) : <EOL> return self . convert_pixel_to_level ( self . rect . centerx , self . rect . centery , level ) <EOL> class Player ( Entity ) : <EOL> crouching = False <EOL> crouchHeight = <NUM_LIT> <EOL> crouchMaxSpeed = <NUM_LIT:6> <EOL> def __init__ ( self , level , rectTuple , image = None ) : <EOL> super ( Player , self ) . __init__ ( level , rectTuple , image ) <EOL> try : <EOL> self . runAnim = anim . Animation ( "<STR_LIT>" , self . rect . width , self . animation_speed ) <EOL> self . crouchAnim = anim . Animation ( "<STR_LIT>" , self . rect . width , <NUM_LIT> ) <EOL> self . idle = anim . Animation ( "<STR_LIT>" , self . rect . width , <NUM_LIT:0> ) <EOL> self . idleCrouching = anim . Animation ( "<STR_LIT>" , self . rect . width , <NUM_LIT:0> ) <EOL> self . hasAnim = True <EOL> except pygame . error : <EOL> self . hasAnim = False <EOL> self . defMaxSpeed = self . maxSpeed <EOL> def update ( self , keys , level ) : <EOL> self . onBlock = self . check_on_block ( self . rect , level ) <EOL> if keys [ Kcrouch ] and not self . crouching and self . onBlock : <EOL> self . crouching = True <EOL> self . maxSpeed = self . crouchMaxSpeed <EOL> self . rect . height = self . crouchHeight <EOL> self . rect . bottom += self . normalHeight - self . crouchHeight <EOL> elif not keys [ Kcrouch ] and self . crouching and self . onBlock : <EOL> if not self . check_head_collision ( level ) : <EOL> self . crouching = False <EOL> self . maxSpeed = self . defMaxSpeed <EOL> self . rect . height = self . normalHeight <EOL> self . rect . bottom -= self . normalHeight - self . crouchHeight <EOL> self . image = pygame . Surface ( ( self . rect . width , self . rect . height ) ) <EOL> self . image . fill ( self . color ) <EOL> self . accelX = self . get_accel ( keys , self . jumping ) <EOL> self . speedX = self . accelerate ( self . accelX , self . speedX ) <EOL> self . jumping = keys [ Kjump ] <EOL> if self . jumping : <EOL> self . speedY = self . jump ( self . speedY , self . onBlock ) <EOL> if self . onBlock : <EOL> self . onBlock == True <EOL> else : <EOL> self . speedY = self . fall ( self . speedY ) <EOL> try : <EOL> self . minXDistance = self . get_shortest_distance ( self . rect , self . speedX , AXISX , level ) <EOL> except ( TypeError , IndexError , ValueError ) : <EOL> self . minXDistance = self . speedX <EOL> if abs ( self . minXDistance ) < abs ( self . speedX ) : <EOL> self . speedX = <NUM_LIT:0> <EOL> self . rect . left += self . minXDistance <EOL> try : <EOL> self . minYDistance = self . get_shortest_distance ( self . rect , self . speedY , AXISY , level ) <EOL> except ( TypeError , IndexError , ValueError ) : <EOL> self . minYDistance = self . speedY <EOL> if abs ( self . minYDistance ) < abs ( self . speedY ) : <EOL> self . speedY = <NUM_LIT:0> <EOL> self . rect . top += self . minYDistance <EOL> self . cameraRect . bottom = self . rect . bottom <EOL> self . cameraRect . left = self . rect . left <EOL> if self . hasAnim : <EOL> if self . speedX > <NUM_LIT:0> : <EOL> if self . runAnim . reversed or self . crouchAnim . reversed : <EOL> self . runAnim . reverse ( ) <EOL> self . crouchAnim . reverse ( ) <EOL> self . idle . reverse ( ) <EOL> self . idleCrouching . reverse ( ) <EOL> self . runAnim . update ( ) <EOL> self . image = self . runAnim . image <EOL> elif self . speedX < <NUM_LIT:0> : <EOL> if not self . runAnim . reversed or not self . crouchAnim . reversed : <EOL> self . runAnim . reverse ( ) <EOL> self . crouchAnim . reverse ( ) <EOL> self . idle . reverse ( ) <EOL> self . idleCrouching . reverse ( ) <EOL> if not self . crouching : <EOL> self . runAnim . update ( ) <EOL> self . image = self . runAnim . image <EOL> elif self . crouching : <EOL> self . crouchAnim . update ( ) <EOL> self . image = self . crouchAnim . image <EOL> if self . speedY != <NUM_LIT:0> or self . jumping : <EOL> self . image = self . runAnim . frames [ <NUM_LIT:4> ] <EOL> elif self . speedX == <NUM_LIT:0> and self . speedY == <NUM_LIT:0> : <EOL> if not self . crouching : <EOL> self . image = self . idle . frames [ <NUM_LIT:0> ] <EOL> elif self . crouching : <EOL> self . image = self . idleCrouching . frames [ <NUM_LIT:0> ] <EOL> self . runAnim . reset ( ) <EOL> self . crouchAnim . reset ( ) </s>
