def test_collide_mask__opaque(self): # make some fully opaque sprites that will collide with masks. self.s1.image.fill((255,255,255,255)) self.s2.image.fill((255,255,255,255)) self.s3.image.fill((255,255,255,255)) # masks should be autogenerated from image if they don't exist. self.assertEqual ( sprite.spritecollide ( self.s1, self.ag2, dokill = False, collided = sprite.collide_mask ), [self.s2] ) self.s1.mask = pygame.mask.from_surface(self.s1.image) self.s2.mask = pygame.mask.from_surface(self.s2.image) self.s3.mask = pygame.mask.from_surface(self.s3.image) # with set masks. self.assertEqual ( sprite.spritecollide ( self.s1, self.ag2, dokill = False, collided = sprite.collide_mask ), [self.s2] )
def update(self, dt): self.player.update(dt) self.coins.update(dt) # lock player in bounds self.player.rect.clamp_ip(self.bounds) spritecollide(self.player, self.coins, True)
def update(self, dt): self.player.update(dt) self.cookies.update(dt) # lock player in bounds self.player.rect.clamp_ip(self.bounds) # collide player with coins spritecollide(self.player, self.cookies, True)
def update(self, time, player_group, platform_group): if self.KILL: self.explode() hit_players = PS.spritecollide(self, player_group, False) hit_platforms = PS.spritecollide(self, platform_group, False) if hit_players: for this_player in hit_players: self.react(this_player) if hit_platforms: for this_platform in hit_platforms: self.rect.centery = (this_platform.get_top() - self.rect.height/4)
def attack(self, player, playerX, playerY, playerFace, screen, bg): #this bg is enemy block group #collisions with the new weapon rect! score = 0 collision_list = [] if "r" in playerFace: self.rectrl.x = playerX self.rectrl.y = playerY self.rect = self.rectrl elif "l" in playerFace: self.rectrl.x = playerX self.rectrl.y = playerY self.rect = self.rectrl elif "u" in playerFace: self.rectud.x = playerX self.rectud.y = playerY self.rect = self.rectud elif "d" in playerFace: self.rectud.x = playerX self.rectud.y = playerY self.rect = self.rectud collisions = PS.spritecollide(self, bg, False) for collision in collisions: collision_list.append(collision) return collision_list # to be added to Player's score
def update(self, time, scene): self.floatX += self.speedX * time * GRENADE_SPEED self.floatY += self.speedY * time * GRENADE_SPEED self.rect.x = roundToInt(self.floatX) self.rect.y = roundToInt(self.floatY) self.timeToBoom -= time if self.timeToBoom <= 0: scene.bulletGroup.remove(self) scene.bulletGroup.add(Explosion(self.rect.x, self.rect.y)) # Kill people! originalRect = self.rect.copy() self.rect.inflate_ip(80, 80) # 80x80 area damage enemies_hit = sprite.spritecollide(self, scene.enemyGroup, False) for enemy in enemies_hit: # Friendly fire if self.creator.__class__.__name__ == enemy.__class__.__name__: continue enemy.receive_attack(self.atk) if sprite.collide_rect(self, scene.player): scene.player.receive_attack(self.atk) self.rect = originalRect # Restore the real rect self.timeToStop -= time if self.timeToStop <= 0: self.speedX = 0 self.speedY = 0
def detect_collision(self): collisions = spritecollide(self.player, self.obstacle_group, True) for c in collisions: self.collision_strategy_factory.get_strategy(c).on_collision() self.obstacles.remove(c) c.kill()
def update(self): dt = self.clock.tick(FPS) # basic update self.player.update(dt) self.coins.update(dt) # check if the player is on the path onpath = spritecollide(self.player, self.level.path, False) self.player.on_path(onpath) # collide coins for coin in spritecollide(self.player, self.coins, True): self.score += 1 self.cam.update(self.player.rect)
def update(self): BouncySprite.update(self) if sprite.spritecollide(self, self.game.monsters, True): self.kill() self.life -= 1 if self.life <= 0: self.kill()
def kill_people(self, scene): hitted_players = sprite.spritecollide(self, scene.enemyGroup, False) # scene.bulletGroup.remove(self) for player in hitted_players: player.hit_by_bullet(self.atk) # A bullet should not be capable of going through an infinite amount of bodies scene.bulletGroup.remove(self)
def handle_collision(self, bg, m_back=False): if m_back: face_copy = self.face self.face = self.move_face collisions = PS.spritecollide(self, bg, False) if 'r' in self.face: for collision in collisions: if(self.rect.x + self.rect.width) >= collision.rect.left: self.rect.x = collision.rect.left - self.rect.width elif 'l' in self.face: for collision in collisions: if (self.rect.x) <= (collision.rect.left + collision.rect.width): self.rect.x = collision.rect.left + \ collision.rect.width elif 'd' in self.face: for collision in collisions: if(self.rect.y + self.rect.height) >= collision.rect.top: self.rect.y = collision.rect.top - self.rect.height elif 'u' in self.face: for collision in collisions: if (self.rect.y <= (collision.rect.top + collision.rect.height)): self.rect.y = collision.rect.top + \ collision.rect.height if m_back: self.face = face_copy return (collisions is None)
def execute(self): '''Controls the actor movement as a regular object under Newton's laws. Checks collisions with grounds''' actor=self.__parent self.velocity=self.velocity+(actor.steering_acceleration+PS_freefall.GRAVITY)*self.time_step self.position=self.position+self.velocity*self.time_step if self.i==4: for floor in spritecollide(actor, actor.get_level().floors, False): if not actor.crect.colliderect(floor.crect): continue if -16<floor.crect.top-actor.crect.bottom<3 and self.velocity[1]>=0: self.velocity[1]=0 actor.standing_on=floor self.position[1]=floor.crect.top-actor.rect.height/2 self.__parent_PM.set_state(PS_walking) continue elif -16<floor.crect.left-actor.crect.right<3 and self.velocity[0]>0: self.velocity[0]=-self.velocity[0] elif -3<floor.crect.right-actor.crect.left<16 and self.velocity[0]<0: self.velocity[0]=-self.velocity[0] elif -3<floor.crect.bottom-actor.crect.top<16 and self.velocity[1]<0: self.velocity[1]=-self.velocity[1] self.i=0 else: self.i+=1 actor.set_position([self.position[0], self.position[1]])
def handle_player(self, player): player.sprites()[0].set_attacking_rect() collisions = PS.spritecollide(self, player, False) if(len(collisions) == 1 and isinstance(collisions[0], Player)): if(Globals.INVINCIBILITY_COUNT == 0): self.attacked_player = True player.sprites()[0].reset_attacking_rect()
def useportal(self): # check for portals portalbox = spritecollide(self,self.level.portal_list,False) if portalbox != []: return portalbox[0].destination else: return 0
def test_collide_circle__no_radius_set(self): # collide_circle with no radius set. self.assertEqual ( sprite.spritecollide ( self.s1, self.ag2, dokill = False, collided = sprite.collide_circle ), [self.s2] )
def test_spritecollide__collided_defaults_to_collide_rect(self): # collide_rect should behave the same as default. self.assertEqual ( sprite.spritecollide ( self.s1, self.ag2, dokill = False, collided = sprite.collide_rect ), [self.s2] )
def test_spritecollide__works_if_collided_cb_is_None(self): # Test that sprites collide without collided function. self.assertEqual ( sprite.spritecollide ( self.s1, self.ag2, dokill = False, collided = None ), [self.s2] )
def grounded(self): "Check for ground underneath players feet, if not found switch to falling state" tmp = self.player.rect self.player.rect = self.player.rect.move(0, 1) collides = spritecollide(self.player, level.tile_group, False) if not collides: self.fall() self.player.rect = tmp
def test_collide_rect_ratio__ratio_of_one_like_default(self): # collide_rect_ratio should behave the same as default at a 1.0 ratio. self.assertEqual ( sprite.spritecollide ( self.s1, self.ag2, dokill = False, collided = sprite.collide_rect_ratio(1.0) ), [self.s2] )
def detect_collision(self): if self.elements['ship'].sprite: self.ship_collides = spritecollideany(self.elements['ship'].sprite, self.elements['asteroids']) self.ship_catches = spritecollide(self.elements['ship'].sprite, self.elements['power-ups'], True) if groupcollide(self.elements['lasers'], self.elements['asteroids'], True, True): if randint(1, 20) == 1: self.newPU = True self.score_add(50)
def test_collide_circle_ratio__no_radius_and_ratio_of_one(self): # collide_circle_ratio with no radius set, at a 1.0 ratio. self.assertEqual ( sprite.spritecollide ( self.s1, self.ag2, dokill = False, collided = sprite.collide_circle_ratio(1.0) ), [self.s2] )
def jump(self): # call when 'jump' key pressed # first check if player is on a platform. self.rect.y += 2 harvest = spritecollide(self,self.level.platform_list,False) self.rect.y -= 2 # then 'jump' if not airborne if len(harvest) > 0 or self.rect.bottom >= WINH-self.rect.h: # jump self.dy = -10
def update(self, dt): self.player.update(dt) self.coins.update(dt) # lock player in bounds self.player.rect.clamp_ip(self.bounds) # collide player with coins for coin in spritecollide(self.player, self.coins, False): coin.collect(self.player)
def test_collide_circle_ratio__no_radius_and_ratio_of_twenty(self): # collide_circle_ratio with no radius set, at a 20.0 ratio. self.assert_ ( unordered_equality ( sprite.spritecollide ( self.s1, self.ag2, dokill = False, collided = sprite.collide_circle_ratio(20.0) ), [self.s2, self.s3] ) )
def update(self, dt): self.player.update(dt) self.coins.update(dt) # lock player in bounds self.player.rect.clamp_ip(self.bounds) # collide player with coins if spritecollide(self.player, self.coins, True): self.coin_sfx.stop() self.coin_sfx.play()
def test_collide_rect_ratio__collides_all_at_ratio_of_twenty(self): # collide_rect_ratio should collide all at a 20.0 ratio. self.assert_ ( unordered_equality ( sprite.spritecollide ( self.s1, self.ag2, dokill = False, collided = sprite.collide_rect_ratio(20.0) ), [self.s2, self.s3] ) )
def update(self): dt = self.clock.tick(FPS) # basic update self.player.update(dt) self.coins.update(dt) # collide coins for coin in spritecollide(self.player, self.coins, True): self.score += 1 self.cam.update(self.player.rect)
def update(self): self.player.update() self.npcgroup.update() if sprite.spritecollideany(self.player, self.walls): self.player._goback() for npc in sprite.groupcollide(self.npcgroup, self.walls, False, False): npc._goback() npcCollisions = sprite.spritecollide(self.player, self.npcgroup, False) if len(npcCollisions) > 0: self.prepareForBattle() npcCollisions[0].kill() return BattleEvent(self.player, npcCollisions[0]) return None
def player_detection(self, player_group): hit_players = PS.spritecollide(self, player_group, False) if hit_players: for this_player in hit_players: self.vx = ENEMY_VELOCITY #Enemy reactions to player contact can cause bugs self.vx = HIT_VELOCITY if self.get_rit() > this_player.get_rit(): self.moving_right = True else: self.moving_right = False else: self.vx = ENEMY_VELOCITY
def moveup(self, image_counter, walls): wall_list = PS.spritecollide(self, walls, False) if self.direction != 'moveup': # we just changed directions self.movepos = [0.0, 0.0] # remove deceleration self.image_tracker = 0 self.change_direction = True else: self.movepos[1] = -self.speed self.direction = "moveup" self.update_image(self.image_tracker*4+1, self.change_direction) self.moving = True self.action_rect.width = 64 self.action_rect.height = 32 self.action_rect.midbottom = self.rect.midtop
def collides_detect(self, x_vel, y_vel): if spritecollide(self, MOBS, False): self.rect.x += self.return_impulse if self.x_vel < 0 else -self.return_impulse self.x_vel = 0 self.get_damage(10) for p in PLATFORMS: if collide_rect(self, p): if x_vel > 0: self.rect.right = p.rect.left self.x_vel = 0 if x_vel < 0: self.rect.left = p.rect.right self.x_vel = 0 if y_vel > 0: self.rect.bottom = p.rect.top self.on_ground = True self.in_jump = False self.y_vel = 0 if y_vel < 0: self.rect.top = p.rect.bottom self.y_vel = 0
def moveUnit(unit, tryTurns): for dist in range(Ship.VELOCITY, 0, -1): for turn in tryTurns: unit.tryMove(dist, turn) collidePlanet = sp.spritecollideany( unit, planets, sp.collide_circle) if collidePlanet is unit.destPlanet: unit.destPlanet.arrival(self.team) unit.kill() return else: pass # moveUnit(unit, filtertryTurns) # return if (len( sp.spritecollide(unit, ships, False, Ship.collidedShip)) == 1 and not collidePlanet): unit.doMove() return else: unit.unTryMove()
def boosters_manager(self, frame): """Метод - обработчик всех событий с бустерами в т.ч. столкновений""" hits = spritecollide(self.starship, self.boosters, False) for booster in hits: booster_type = booster.type if booster_type in self.boosters_timeouts: self.timed_booster_handler(booster_type) elif booster_type in self.weapons: self.weapons_handler(booster_type) elif booster_type in self.timed_abilities: self.booster_handlers[booster_type]("activate") booster.pickup_sound.play() booster.kill() for booster_type, timeout in self.boosters_timeouts.items(): # Если бустер активен (timeout > 0), но активное время закончилось (time.time() > timeout)... if time.time() > timeout > 0: self.boosters_timeouts[ booster_type] = 0 # задаём время деактивации равным 0 (отключённое состояние) self.booster_handlers[booster_type]( "deactivate" ) # деактивируем бустер (возвращаем исходное поведение) for booster_type, weapon in self.weapons.items(): if weapon.ammo <= 0: self.weapons[booster_type].ammo = 0 self.booster_handlers[booster_type]("deactivate") for booster_type, ability in self.timed_abilities.items(): status = self.timed_abilities[booster_type].active if ability.amount <= 0 and status: self.timed_abilities[booster_type].active = False self.timed_abilities[booster_type].amount = 0 self.timed_abilities[booster_type].sound.stop() elif ability.amount > 0 and status: self.timed_abilities[booster_type].amount -= status if frame % BOOSTER_SPAWN_RATE == 0 and frame != 0: self.boosters.add( Booster()) # ...размещаем новый бустер на игровом поле
def organizar_ordem_de_sprites(self): for item in spritecollide(self.hero.hitbox, EntidadesGroup, False): if item == self.hero: continue if self.hero.rect.bottom <= item.rect.bottom - 4: lista_sprites = EntidadesGroup.sprites() EntidadesGroup.empty() heroi_index = lista_sprites.index(self.hero) lista_sprites.remove(item) lista_sprites.insert(heroi_index + 1, item) EntidadesGroup.add(lista_sprites) break if self.hero.rect.bottom >= item.rect.bottom - 4: lista_sprites = EntidadesGroup.sprites() EntidadesGroup.empty() heroi_index = lista_sprites.index(self.hero) lista_sprites.remove(item) lista_sprites.insert(heroi_index - 1, item) EntidadesGroup.add(lista_sprites)
def update(self, ticks: int): """ Updates game state with timing information provided by PyGame @param ticks: number of milliseconds passed since pygame.init() was called (obtained with pygame.time.get_ticks()) @return: None """ self.bear.update(ticks) self.bear.clamp(self.world.rect) self.camera.move_to(self.bear.position) self.camera.clamp(self.world.rect) collide_list = spritecollide(self.bear, self.berry_group, True) for _ in collide_list: self.score += 1 self.remaining = len(self.berry_group) if self.remaining == 0: self.running = False if self.running: self.timer = ticks self.text.set_text( "Collected: {0}. Remaining: {1}. Elapsed time: {2:.1f} s".format(self.score, self.remaining, self.timer / 1000.0)) else: self.text.set_text( "You collected all berries in {0:.1f} seconds".format(self.timer / 1000.0))
def update(self, shell_list=None): random_move = self.directions[random.randint(0, 7)] if random_move: self._rotate(random_move) self._move() #Keep the AI on the screen if self.rect.left <= 0: self._rotate('right') elif self.rect.right >= 1024: self._rotate('left') if self.rect.top <= 0: self._rotate('left') elif self.rect.bottom >= 768: self._rotate('left') self.turret.update(self.rect.center, self.rotationCounter) if spritecollide(self, shell_list, 'true'): self._die() #Draw AI tank on screen self.screen.blit(self.image, self.rect) self.turret.shells.update()
def colision_check(self): for bloco in spritecollide(self.hitbox, colisionsGroup, False): if self.hitbox.rect.bottom - bloco.rect.top == 2: self.hitbox.rect.bottom = bloco.rect.top self.pos_y = [False, True] self.pos_x = [True, True] if bloco.rect.bottom - self.hitbox.rect.top == 2: self.hitbox.rect.top = bloco.rect.bottom self.pos_y = [True, False] self.pos_x = [True, True] if self.hitbox.rect.right - bloco.rect.left == 2: self.hitbox.rect.right = bloco.rect.left self.pos_x = [False, True] self.pos_y = [True, True] if bloco.rect.right - self.hitbox.rect.left == 2: self.hitbox.rect.left = bloco.rect.right self.pos_x = [True, False] self.pos_y = [True, True] self.rect.x = self.hitbox.rect.x - 8 self.rect.y = self.hitbox.rect.y - 16
def collision_with_hurdle(self): """Returns if Mario has collision with hurdles on map.""" if sprite.spritecollide(self, HURDLES_GROUP, dokill=False): return True return False
def test_spritecollide__works_if_collided_cb_is_None(self): # Test that sprites collide without collided function. self.assertEqual( sprite.spritecollide(self.s1, self.ag2, dokill=False, collided=None), [self.s2], )
def update(self): self.rect.y += self.dy for _ in spritecollide(self, self.borders, False): self.rect.y -= self.dy self.stop()
def is_resolved(self) -> bool: return any( spritecollide(sprite, self._zone_group, False) for sprite in self._entering_group)
def filter_single_collision(self, single): sprite.spritecollide(single, self, True)
def test_spritecollide__works_if_collided_cb_not_passed(self): # Should also work when collided function isn't passed at all. self.assertEqual(sprite.spritecollide(self.s1, self.ag2, dokill=False), [self.s2])
if spritecollideany(player, gp_walls): player.move(1, 0) else: player_mv = True elif evt.key == K_RIGHT: player.move(1, 0) if spritecollideany(player, gp_walls): player.move(-1, 0) else: player_mv = True if player_mv: # le joueur se déplace # We test the collision between the player and an object of # the game board. In the case of a collision, sp contains the # sprite of the object and is removed from the group # gp_items_onboard sp = spritecollide(player, gp_items_onboard, True) if sp: # According to the value of sp, we add the object # recovered by the player in the border if sp[0] == sp_eth: items_collected.set_item(ETHER) elif sp[0] == sp_tub: items_collected.set_item(TUBE) elif sp[0] == sp_syr: items_collected.set_item(SYRINGE) # test of the collision between the player and the guardian if collide_rect(player, guard): game = False pg.font.init() ft = pg.font.Font(pg.font.get_default_font(), 100) if len(items_collected.items_found) == 3:
def run(self): framesSinceLastEnemyShot = 0 lastMove = "right" while not self.done: #Keyboard press and exit events for event in pygame.event.get(): if event.type == QUIT: exit() #Keyboard hold keys = pygame.key.get_pressed() if keys[K_LEFT] or keys[K_a]: if (not self.player.touchingLeftBorder()): self.player.setSpeed((-1, 0)) if keys[K_RIGHT] or keys[K_d]: if (not self.player.touchingRightBorder()): self.player.setSpeed((1, 0)) if keys[K_SPACE]: if (self.player.attempt_shoot(self.CLOCK)): playSoundPlayerShot() self.player.do() #Checking if monsters can be moved canMoveLeft = canMoveRight = True for monster in self.monsters: if (monster.touchingLeftBorder()): lastMove = "left" canMoveLeft = False if (monster.touchingRightBorder()): lastMove = "right" canMoveRight = False if (canMoveRight and lastMove == "left"): monsSpeed = (1, 0) elif (canMoveLeft and lastMove == "right"): monsSpeed = (-1, 0) else: monsSpeed = (0, 0) for monster in self.monsters: monster.setSpeed(monsSpeed) monster.do() #Player-Shot collision with monster collided = groupcollide(self.player.shots, self.monsters, True, False) for key, values in collided.items(): for value in values: value.life -= self.player.damage if value.life <= 0: self.player.score += value.value collision_pos = value.getPosition() self.temp_effects.append( TempEffect("hit_blue", "effects", collision_pos)) #Monsters-Shots collision with player for monster in self.monsters: collided = spritecollide(self.player, monster.shots, True) if (len(collided)): self.player.life -= monster.damage collision_pos = self.player.getPosition() self.temp_effects.append( TempEffect("hit_blue", "effects", collision_pos)) #Select random enemy to shot and control time between shots indexMonShooting = randint(0, len(self.monsters)) if((framesSinceLastEnemyShot > 30 and len(self.monsters) > 4) or \ (framesSinceLastEnemyShot > 60)): for i, monster in enumerate(self.monsters): if (i == indexMonShooting): monster.shoot() framesSinceLastEnemyShot = 0 else: framesSinceLastEnemyShot += 1 if self.player.life <= 0: self.done = True text = "You lost! Score: " + str(self.player.score) self.showText(text) playSoundDeath() elif len(self.monsters) <= 0: self.done = True #Updating and rendering objects self.renderObjects() self.CLOCK.tick(self.FPS) if (len(self.monsters) <= 0): if (self.key < MAX_STAGE): self.done = False self.key += 1 self.start() else: text = "You won! Score: " + str(self.player.score) self.showText(text) pygame.time.delay(2000)
def collide(self, group, doKill=False, collided=None): return sprite.spritecollide(self, group, doKill, collided)
def __dispatch_collisions(self): collision_results = { 'group': {}, 'sprite': {}, 'foreach_sprite': {}, } for (collision, args) in self.__collisions['group'].items(): collision_results['group'][collision] = groupcollide(*args) for (collision, args) in self.__collisions['sprite'].items(): collision_results['sprite'][collision] = spritecollide(*args) for (collision, args) in self.__collisions['foreach_sprite'].items(): arg_list = list(args) sprite_list = arg_list[0] for sprite in sprite_list: arg_list[0] = sprite args = tuple(arg_list) collision_results['foreach_sprite'][sprite] = spritecollide( *args) for bullet in self.__entities.player_bullets: collision_result = spritecollide(bullet, self.__scene_elements.iron_group, bullet.enhanced, None) if collision_result: bullet.kill() for player_tank in self.__entities.player_tanks: for food in self.__entities.foods: collision_result = collide_rect(player_tank, food) if collision_result: self.__dispatch_food_effect(food, player_tank) # --我方子弹撞敌方坦克 for tank in self.__entities.enemy_tanks: if collision_results['foreach_sprite'][tank]: if tank.food: self.__entities.add(tank.food) tank.clear_food() if tank.decrease_level(): self.__play_sound('bang') self.__total_enemy_num -= 1 # --敌方子弹撞我方坦克 for tank in self.__entities.player_tanks: if collision_results['foreach_sprite'][tank]: if tank.protected: self.__play_sound('blast') else: if tank.decrease_level(): self.__play_sound('bang') if tank.health < 0: self.__entities.remove(tank) if collision_results['sprite'][ 'PlayerBulletWithHome'] or collision_results['sprite'][ 'EnemyBulletWithHome']: self.__is_win_flag = False self.__has_next_loop = False self.__play_sound('bang') self.__home.destroyed = True if collision_results['group']['PlayerTankWithTree']: self.__play_sound('hit')
def move(self, keys): self.acc_x = 0 if self.rectangle.bottom + self.velocity_Y < SCREEN_HEIGHT: self.acc_y = GRAVITY else: self.velocity_Y = 0 self.acc_y = 0 self.rectangle.bottom = SCREEN_HEIGHT if keys[pygame.K_d]: self.acc_x = 1.5 self.directionX = DIRECTION_RIGHT elif keys[pygame.K_a]: self.acc_x = -1.5 self.directionX = DIRECTION_LEFT if keys[pygame.K_w]: self.playerSprite.rect.y += 1 hits = self.playerSprite.rect.midbottom[1] > SCREEN_HEIGHT self.playerSprite.rect.y -= 1 if hits or self.platformCollision: self.velocity_Y = -30 self.velocity_X += self.acc_x self.velocity_Y += self.acc_y if abs(self.velocity_X) > 0.5: if self.velocity_X > 0: self.velocity_X -= self.velocity_X * FRICTION elif self.velocity_X < 0: self.velocity_X += abs(self.velocity_X) * FRICTION if self.velocity_X > 0 or ( self.velocity_X < 0 and self.rectangle.left + self.velocity_X > 0): self.rectangle.x += self.velocity_X platformXCollide = spritecollide(self.playerSprite, self.platformSpriteGroup, False) if platformXCollide and self.velocity_X > 0: # Ruch w prawo self.velocity_X = 0 self.playerSprite.rect.right = platformXCollide[ 0].rect.left - 1 elif platformXCollide and self.velocity_X < 0: #Ruch w lewo self.velocity_X = 0 self.playerSprite.rect.left = platformXCollide[ 0].rect.right + 1 if self.velocity_X > 0 and self.rectangle.left > SCREEN_WIDTH: self.rectangle.right = 0 if abs(self.velocity_Y) > 0.5: if self.velocity_Y > 0: self.velocity_Y -= self.velocity_Y * FRICTION elif self.velocity_Y < 0: self.velocity_Y += abs(self.velocity_Y) * FRICTION self.rectangle.y += self.velocity_Y collidePlatformY = spritecollide(self.playerSprite, self.platformSpriteGroup, False) if collidePlatformY and self.velocity_Y < 0: self.velocity_Y = 0 self.playerSprite.rect.top = collidePlatformY[0].rect.bottom + 1 for bullet in self.bulletSpriteGroup: bullet.updateBullet()
def _compute_reward(self): """compute the reward for moving on the map """ # logg = getMyLogger(f"c.{__class__.__name__}._compute_reward") # logg.debug(f"Start _compute_reward") # compute collision car/road # start = timer() hits = spritecollide(self.racer_car, self.racer_map, dokill=False) # end = timer() # logg.debug(f"Time for sprite collisions {end-start:.6f} s") # logg.debug(f"hitting {hits}") hit_directions = [] hit_sid = [] for segment in hits: # logg.debug(f"hit segment with id {segment.s_id}") hit_directions.append(self.racer_map.seg_info[segment.s_id][0]) hit_sid.append(segment.s_id) # out of the map if len(hit_directions) == 0: return 0, True # if it is in the map, check that is moving if self.racer_car.speed < 0.0001: return -1, False # too many hits, your road is weird, cap them at 2 segments elif len(hit_directions) > 2: # logg.warn(f"Too many segments hit") hit_directions = hit_directions[:2] hit_sid = hit_sid[:2] # now hit_directions is either 1 or 2 elements long if len(hit_directions) == 1: mean_direction = hit_directions[0] else: # 135 90 45 140 95 50 130 85 40 # 180 0 185 5 175 -5 # 225 270 315 230 275 320 220 265 310 # 270, 0 have mean 315 = (270+0+360)/2 # 270, 180 have mean 225 = (270+180)/2 # 0, 90 have mean 45 = (0+90)/2 if abs(hit_directions[0] - hit_directions[1]) > 180: mean_direction = (sum(hit_directions) + 360) / 2 if mean_direction >= 360: mean_direction -= 360 else: mean_direction = sum(hit_directions) / 2 error = self.racer_car.direction - mean_direction if error < 0: error += 360 if error > 180: error = 360 - error # logg.debug(f"direction {self.racer_car.direction} has error of {error:.4f}") # error goes from 0 (good) to 180 (bad) reward = 90 - error # MAYBE a sigmoid-like shape # scale it from -1 to 1 reward /= 90 # make it proportional to speed squared reward *= self.racer_car.speed * self.racer_car.speed return reward, False
def update(self): if not self.start_tick is None: currentTime = get_ticks() if self.hp > 0: if (currentTime - self.start_tick) / 1000 > 1: self.unhurtful = False # Revert back self._updateSprite() else: if (currentTime - self.start_tick) / 1000 > 5: self.dead = False initialLocations = [(968, 300), (968, 400), (280, 400), (968, 250), (280, 250)] self.image = load(os.getcwd() + '/img/sprite-' + self.spriteName + '/' + self.spriteName + '-r1.png') initialLocation = initialLocations[randint(0, 4)] self.rect.x, self.rect.y = initialLocation self.weapon.rect.x, self.weapon.rect.y = self.rect.x, self.rect.y self.hp = 100 else: self.image = load(os.getcwd() + '/img/sprite-' + self.spriteName + '/d.png') self.weapon.rect.right = self.rect.left self.dead = True return self._updateSprite() self.calc_grav() if self.rect.right > 1440: self.rect.right = 1440 if self.rect.left < 0: self.rect.left = 0 move = self._sliding() if move > 4: move = 4 elif move < -4: move = -4 self.rect.x += move self.weapon.update() self.weapon.rect.y = self.rect.y + 50 if self.direction == 1: self.weapon.rect.x = self.rect.x + 20 elif self.direction == -1: self.weapon.rect.x = self.rect.x - 30 self.weapon.rect.x += move self.weapon.update() weakLayer_list = spritecollide(self, self.weakLayer, False) for each in weakLayer_list: if self.ySpeed > 0: self.rect.bottom = each.rect.top elif self.ySpeed < 0: self.rect.top = each.rect.bottom self.ySpeed = 0 block_hit_list = spritecollide(self, self.platforms, False) self._preventMoving(block_hit_list) self.rect.y += self.ySpeed block_hit_list = spritecollide(self, self.platforms, False) for block in block_hit_list: if self.ySpeed > 0: self.rect.bottom = block.rect.top elif self.ySpeed < 0: self.rect.top = block.rect.bottom self.ySpeed = 0 sticks_hit_list = spritecollide(self, self.sticks, False) if len(sticks_hit_list) > 0: if self.unhurtful == False: self.start_tick = get_ticks() self._updateSprite() self.hp -= 10 self.hit_sound.play() if self.hp <= 0: #death self.death_sound.play() else: self.unhurtful = True bullet_hit_list = spritecollide(self, self.bulletList, False) for each in bullet_hit_list: if self.unhurtful == False: self.start_tick = get_ticks() self._updateSprite() if isinstance(each, shotgunShell): self.hp -= 40 else: self.hp -= 20 self.hit_sound.play() if self.hp <= 0: #death self.death_sound.play() else: self.unhurtful = True elevator_hit_list = spritecollide(self, self.elevator, False) for each in elevator_hit_list: if self.rect.bottom > each.rect.top: self.ySpeed = each.speed giantSpike_hit_list = spritecollide(self, self.giantSpike, False) for each in giantSpike_hit_list: if each.rect.bottom >= self.rect.top and self.unhurtful == False: self.start_tick = get_ticks() self._updateSprite() self.hp -= 90 self.hit_sound.play() if self.hp <= 0: #Dead self.death_sound.play() else: self.unhurtful = True
def collide_detect(self): if spritecollide(self, BULLETS, True): self.hp -= BULLET_DAMAGE
def collision_with_gap(self): """Returns if Mario has collision with gaps on map.""" if sprite.spritecollide(self, GAP_GROUP, dokill=False): return True return False
def collision_with_object(self): """Returns if Mario has collision with objects on map.""" if sprite.spritecollide(self, OBJECT_GROUP, dokill=False): return True return False
def run_racer_main(args): """mainloop of the game adapted from https://www.pygame.org/docs/tut/chimp.py.html and https://www.pygame.org/docs/tut/ChimpLineByLine.html """ logg = logging.getLogger(f"c.{__name__}.run_racer_main") template_images = args.template_images fps = args.fps pygame.init() # size is (int, int) tuple field_size = (900, 900) # unpack the field size for clarity field_wid, field_hei = field_size sidebar_size = (300, field_hei) sidebar_wid, sidebar_hei = sidebar_size total_size = (field_wid + sidebar_wid, field_hei) screen = pygame.display.set_mode(total_size) pygame.display.set_caption("Racer") # Create The playing field field = pygame.Surface(field_size) # convert() changes the pixel format # https://www.pygame.org/docs/ref/surface.html#pygame.Surface.convert field = field.convert() # field.fill((250, 250, 250)) field.fill((0, 0, 0)) # Put Text On The field, Centered if not pygame.font: logg.error("You need fonts to put text on the screen") # create a new Font object (from a file if you want) font = pygame.font.Font(None, 36) # draw the field on the screen screen.blit(field, (0, 0)) # create the sidebar sidebar = pygame.Surface(sidebar_size) sidebar = sidebar.convert() sidebar.fill((80, 80, 80)) # render() draws the text on a Surface text_title = font.render("Drive safely", 1, (255, 255, 255)) # somewhere here there is a nice drawing of rect pos # https://dr0id.bitbucket.io/legacy/pygame_tutorial01.html # the pos is relative to the surface you blit to textpos_title = text_title.get_rect(centerx=sidebar_wid / 2) # draw the text on the sidebar sidebar.blit(text_title, textpos_title) val_delta = 50 speed_text_hei = 200 text_speed = font.render("Speed:", 1, (255, 255, 255)) textpos_speed = text_speed.get_rect(center=(sidebar_wid / 2, speed_text_hei)) sidebar.blit(text_speed, textpos_speed) speed_val_hei = speed_text_hei + val_delta direction_text_hei = 300 text_direction = font.render("Direction:", 1, (255, 255, 255)) textpos_direction = text_direction.get_rect(center=(sidebar_wid / 2, direction_text_hei)) sidebar.blit(text_direction, textpos_direction) direction_val_hei = direction_text_hei + val_delta # draw the sidebar on the screen screen.blit(sidebar, (field_wid, 0)) # update the display (linked with screen) pygame.display.flip() # Prepare Game Objects clock = pygame.time.Clock() # racer = RacerCar(template_images, field_wid // 2, field_hei // 2) racer = RacerCar(template_images, 100, 100) rmap = RacerMap(field_wid, field_hei) # draw map on the field, it is static, so there is no need to redraw it every time rmap.draw(field) # draw the map first, the car on top # allsprites = pygame.sprite.RenderPlain((rmap, racer)) allsprites = pygame.sprite.RenderPlain((racer)) # Main Loop going = True while going: clock.tick(fps) logg.debug(f" New frame") # Handle Input Events # https://stackoverflow.com/a/22099654 for event in pygame.event.get(): logg.debug(f"Handling event {event}") if event.type == pygame.QUIT: going = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: going = False logg.debug(f"Done handling") keys = pygame.key.get_pressed() if keys[pygame.K_d]: racer.step("right") elif keys[pygame.K_a]: racer.step("left") elif keys[pygame.K_w]: racer.step("up") elif keys[pygame.K_x]: racer.step("down") elif keys[pygame.K_q]: racer.step("upleft") elif keys[pygame.K_e]: racer.step("upright") elif keys[pygame.K_z]: racer.step("downleft") elif keys[pygame.K_c]: racer.step("downright") else: racer.step("nop") # manually update the racer, pass the action in step # allsprites.update() hits = spritecollide(racer, rmap, dokill=False) logg.debug(f"hitting {hits}") hit_directions = [] hit_sid = [] for segment in hits: logg.debug(f"hit segment with id {segment.sid}") hit_directions.append(rmap.seg_info[segment.sid][0]) hit_sid.append(segment.sid) racer._compute_reward(hit_directions, hit_sid) # Draw Everything again, every frame # the field already has the road drawn screen.blit(field, (0, 0)) # draw all moving sprites (the car) on the screen allsprites.draw(screen) # if you draw on the field you can easily leave a track # allsprites.draw(field) # draw the sidebar template screen.blit(sidebar, (field_wid, 0)) # draw the updated numbers pygame.display.flip() pygame.quit()
def handle_collisions(self, group): return PS.spritecollide(self, group, False)
def handle_enemies(self): collisions = PS.spritecollide(self, self.enemy_list, False) if len(collisions) > 0: self.projectile_attack_enemy = True for collision in collisions: self.enemies_attacked.append(collision)
def game_over(self): if spritecollide(self.player, self.zombies, False) and self.updated: self.game.game_over = True
def handle_player(self, player): collisions = PS.spritecollide(self, player, False) if (len(collisions) == 1 and collisions[0].enemy_ID == -1): if (Globals.INVINCIBILITY_COUNT == 0): self.attacked_player = True
def handle_collision(self, bg): collisions = PS.spritecollide(self, bg, False) #if collide, disappear if (pass_through == 0): if (len(collisions) > 0): self.kill()
def handle_collisions(self, tilemap, entities=None, **kwargs): if tilemap: collisions = [] for x in tilemap: if x.collides: collisions += spritecollide(self, x, False) self.blocked_top = False self.blocked_bottom = False self.blocked_right = False self.blocked_left = False newrect = self.rect.move(self.x_velocity, self.y_velocity) if collisions: for tile in collisions: self.on_tile_collide(tile, entities, **kwargs) if collision.top( newrect, tile.rect ): # Moving down; Hit the top side of the wall self.y_velocity = 0 self.y_acceleration = 0 self.rect.bottom = tile.rect.top self.blocked_bottom = True # For gravity if collision.top(self.rect.move(0, 5), tile.rect): self.jumping = False self.falling = False self.blocked_bottom = True else: self.falling = True if collision.bottom( newrect, tile.rect ): # Moving up; Hit the bottom side of the wall self.y_velocity = 0 self.y_acceleration = 0 self.jumping = False if self.rect.top < tile.rect.bottom: self.rect.top = tile.rect.bottom self.blocked_top = True if collision.left( newrect, tile.rect ): # Moving right; Hit the left side of the wall self.x_velocity = 0 self.x_acceleration = 0 if self.rect.right > tile.rect.left: self.rect.right = tile.rect.left self.blocked_right = True if collision.right( newrect, tile.rect ): # Moving left; Hit the right side of the wall self.x_velocity = 0 self.x_acceleration = 0 if self.rect.left < tile.rect.right: self.rect.left = tile.rect.right self.blocked_left = True