def handleDoubleModeCollision(self): '''双人模式碰撞''' for _, rackRect in self.racketSurfaces: left = rackRect[0] top = rackRect[1] width = rackRect[2] height = rackRect[3] # 中间的x centerX = left + width / 2 # 判断左右位置 if centerX < WINDOW_WIDTH / 2: # print('左侧--------------------------------------------------------------------','left',left,' right',right) # 左侧 # 右侧矩形 rightRect = Rect(left + width - 1, top, 1, height * 2 // 3) # 小球从右侧过来 是否和右侧碰撞 if rightRect.colliderect(self.ballRect) and self.vel_x < 0: self.vel_x = abs(self.vel_x) return else: # print('右侧--------------------------------------------------------------------') # 右侧 # 左侧矩形 leftRect = Rect(left, top, 1, height * 2 // 3) # 从左侧过来 是否和左侧碰撞 if leftRect.colliderect(self.ballRect) and self.vel_x > 0: self.vel_x = -abs(self.vel_x) return
def handle_bullets(red_bullets: list, yellow_bullets: list, red: pygame.Rect, yellow: pygame.Rect): """Handles bullets by moving them across the screen in right or left direction for respective spaceships. If a bullet is hit, a custom hit event is posted in pygame.event queue. Args: red_bullets (list): Red bullets list that contains bullet rectangle objects. yellow_bullets (list): Yellow bullets list that contains bullet rectangle objects. red (pygame.Rect): Red spaceship rectangle object. yellow (pygame.Rect): Yellow spaceship rectangle object. """ for bullet in red_bullets: bullet.x += BULLET_VELOCITY if yellow.colliderect(bullet): pygame.event.post( pygame.event.Event(YELLOW_HIT)) # posts custom hit event red_bullets.remove(bullet) elif bullet.x >= WIDTH: # bullet goes out of screen red_bullets.remove(bullet) for bullet in yellow_bullets: bullet.x -= BULLET_VELOCITY if red.colliderect(bullet): pygame.event.post(pygame.event.Event(RED_HIT)) yellow_bullets.remove(bullet) elif bullet.x <= 0: yellow_bullets.remove(bullet)
class Ball: def __init__(self, center, screenDims): self.rect = Rect((0, 0), (20, 20)) self.rect.center = center self.screenRect = Rect((0, 0), screenDims) self.dx = rand(4, 10) self.dy = rand(4, 10) if rand(0, 1): self.dx = -self.dx if rand(0, 1): self.dy = -self.dy def draw(self, screen): pygame.draw.circle(screen, (255, 255, 255), self.rect.center, self.rect.width) def update(self, lefty, righty): if self.rect.colliderect(lefty.rect): self.dx = abs(self.dx) if self.rect.colliderect(righty.rect): self.dx = -abs(self.dx) if self.rect.top <= 0: self.dy = abs(self.dy) if self.rect.bottom >= self.screenRect.bottom: self.dy = -abs(self.dy) self.rect.centerx += self.dx self.rect.centery += self.dy return not self.rect.colliderect(self.screenRect)
def test_colliderect(self): r1 = Rect(1, 2, 3, 4) self.assertTrue( r1.colliderect(Rect(0, 0, 2, 3)), "r1 does not collide with Rect(0, 0, 2, 3)", ) self.assertFalse(r1.colliderect(Rect(0, 0, 1, 2)), "r1 collides with Rect(0, 0, 1, 2)") self.assertFalse( r1.colliderect(Rect(r1.right, r1.bottom, 2, 2)), "r1 collides with Rect(r1.right, r1.bottom, 2, 2)", ) self.assertTrue( r1.colliderect( Rect(r1.left + 1, r1.top + 1, r1.width - 2, r1.height - 2)), "r1 does not collide with Rect(r1.left + 1, r1.top + 1, " + "r1.width - 2, r1.height - 2)", ) self.assertTrue( r1.colliderect( Rect(r1.left - 1, r1.top - 1, r1.width + 2, r1.height + 2)), "r1 does not collide with Rect(r1.left - 1, r1.top - 1, " + "r1.width + 2, r1.height + 2)", ) self.assertTrue(r1.colliderect(Rect(r1)), "r1 does not collide with an identical rect") self.assertFalse( r1.colliderect(Rect(r1.right, r1.bottom, 0, 0)), "r1 collides with Rect(r1.right, r1.bottom, 0, 0)", ) self.assertFalse( r1.colliderect(Rect(r1.right, r1.bottom, 1, 1)), "r1 collides with Rect(r1.right, r1.bottom, 1, 1)", )
def check_paddle_collision(self, paddle: pygame.Rect): if paddle.colliderect(self.rect): distance = self.rect.centerx - paddle.centerx angle_ratio = distance / (paddle.w / 2) new_angle = (angle_ratio * constants.MAX_PADDLE_BOUNCE_ANGLE) self.movement.rotate_ip( self.movement.angle_to(pygame.Vector2(0, -1)) + new_angle)
def rectTest(player_rect,tiles,testVertRect): #side,displacement; divide it by the side and add it by the displacement """ parameters: rect, list, bool gives a list of rects colliding with the player returns list of rects that collided witht the user rect """ col_List = [] if testVertRect == False: for tile in tiles: if player_rect.colliderect(tile): col_List.append(tile) else: preciseRect = Rect(player_rect.x,player_rect.y + 2 ,42,player_rect.height) for tile in tiles: if preciseRect.colliderect(tile): col_List.append(tile) #second tile would be the time it has been stepped on, and to include Rect collision #if player_rect.y < tile.y - 66: #player_rect.bottom = tile.top return col_List
def check_collide(self, other): rect1 = Rect(self.position.x, self.position.y, self.width, self.height) rect2 = Rect(other.position.x, other.position.y, other.width, other.height) return rect1.colliderect(rect2)
def create_rooms(): Rooms = [] for i in range(NUMBER_OF_ROOMS): intersect = True while intersect: intersect = False rm = generate_room() for other in Rooms: room = other[0] padded_pos_x = rm.pos_x - 1 padded_pos_y = rm.pos_y - 1 padded_width = rm.width + 3 padded_height = rm.height + 3 rm_1 = Rect((room.pos_x * 32, room.pos_y * 32), (room.width * 32, room.height * 32)) rm_2 = Rect((padded_pos_x * 32, padded_pos_y * 32), (padded_width * 32, padded_height * 32)) if rm_1.colliderect(rm_2): intersect = True Rooms.append( [rm, { "NORTH": None, "SOUTH": None, "EAST": None, "WEST": None }]) return Rooms
class Ball(BeBarBallSprite): def __init__(self, screen, position=None): # 继承__init__ BeBarBallSprite.__init__(self, screen) # 属性 self.screen = screen self.init_speed = BALL_INIT_SPEED # 最大ball速度 self.max_speed = BALL_MAX_SPEED # ball每次x速度增长 self.speed_increase = BALL_INCREASE_SPEED self.init_position = BALL_INIT_POSITION self.rad = BALL_RAD # 当前方向 self.direction = [random.choice((-1, 1)), random.choice((-1, 1))] # 当前速度 self.speed = [self.init_speed[0], random.randrange(0, self.init_speed[1])] # 自身矩形 self.rect = Rect(0, 0, self.rad, self.rad) if position is not None: self.rect.center = position self.init_position = position else: self.rect.center = self.init_position # 更新函数,每次主循环中更新 def update(self): # 检测与上下边界碰撞,碰撞则y速度取反 if self.rect.top < 0 and self.direction[1] < 0: self.direction[1] = -self.direction[1] elif self.rect.bottom > self.screen.get_height() and self.direction[1] > 0: self.direction[1] = -self.direction[1] # 保持移动 self.rect.move_ip((self.speed[0] * self.direction[0], self.speed[1] * self.direction[1])) if self.speed[1] > self.max_speed[1]: self.speed[1] = self.max_speed[1] if self.speed[1] < 0: self.speed[1] = - self.speed[1] self.direction[1] = - self.direction[1] # 碰撞检测函数 def hit(self, target): # 取自身的矩形大小 return self.rect.colliderect(target.rect) # 重置速度与位置 def reset(self): # 回到初始位置与速度 self.speed = [self.init_speed[0], random.randrange(0, self.init_speed[1])] self.direction = [random.choice((-1, 1)), random.choice((-1, 1))] self.rect.center = self.init_position def blit(self): circle(self.screen, COLOR_BALL, self.rect.center, self.rad, 0)
def collision_cookie(self, verx, very): width = 30 height = 30 newx = self.dx + verx newrectx = Rect(newx, self.dy, width, height) newy = self.dy + very newrecty = Rect(self.dx, newy, width, height) # ブロックとの衝突判定 for cookie in self.cookies: collide_x = newrectx.colliderect(cookie.rect) collide_y = newrecty.colliderect(cookie.rect) if collide_x: # 衝突するブロックあり self.score_board.add_score(100) elif collide_y: # 衝突するブロックあり self.score_board.add_score(100)
def collision_powercookie(self, verx, very): width = 30 height = 30 newx = self.dx + verx newrectx = Rect(newx, self.dy, width, height) newy = self.dy + very newrecty = Rect(self.dx, newy, width, height) # ブロックとの衝突判定 for cookie in self.powercookies: collide_x = newrectx.colliderect(cookie.rect) collide_y = newrecty.colliderect(cookie.rect) if collide_x: # 衝突するブロックあり self.immune_state = True elif collide_y: # 衝突するブロックあり self.immune_state = True
def block_overlaps(block1, block2) -> bool: ''' Assumes two block objects and returns True if they overlap and False otherwise ''' rect1 = Rect(block1.x, block1.y, block1.w, block1.h) rect2 = Rect(block2.x, block2.y, block2.w, block2.h) return rect1.colliderect(rect2)
def collision(self, p_x, p_y): width = 30 height = 30 player_rect = Rect(p_x, p_y, width, height) collide = player_rect.colliderect(self.rect) if collide: # 衝突するプレイヤーあり self.kill()
def collision(self, verx, very): width = 30 height = 30 newx = self.dx + verx newrectx = Rect(newx, self.dy, width, height) newy = self.dy + very newrecty = Rect(self.dx, newy, width, height) # ブロックとの衝突判定 for block in self.blocks: collide_x = newrectx.colliderect(block.rect) collide_y = newrecty.colliderect(block.rect) if collide_x: # 衝突するブロックあり return False elif collide_y: # 衝突するブロックあり return False return True
def is_onscreen(self): """test is screen.colliderect(actor) true?""" x, y = self.loc w, h = get_screen_size() screen = Rect(0, 0, w, h) actor = Rect(x, y, self.width, self.height) if screen.colliderect(actor): return True else: return False
class Player: # create player and initialize char vars def __init__(self, sprite): # starting coords self.rect = Rect(96, 352, 32, 32) self.sprite = sprite self.ms = 4 self.health = 100 self.spec = "Warden" self.skills = [Skill("Boulder Toss", warden_skill_icons[0], 0)] # if player has no health, change sprite and ms def check_dead(self): print self.health if self.health <= 0: self.sprite = dead_player self.ms = 0 # update x and y of player based on input def pos_update(self, x_off, y_off, walls, hazards, powerup): self.rect.x += x_off self.rect.y += y_off if self.rect.colliderect(powerup.rect): self.health += powerup.p_give_buff() powerup.status = 2 for wall in walls: if (self.rect.colliderect(wall)): if x_off > 0: # moving right, hit left side of a wall self.rect.right = wall.left if x_off < 0: # moving left, hit right side of a wall self.rect.left = wall.right if y_off > 0: # moving down, hit top side of a wall self.rect.bottom = wall.top if y_off < 0: # moving up, hit bottom side of a wall self.rect.top = wall.bottom for hazard in hazards: if (self.rect.colliderect(hazard)): if self.health > 0: self.health -= 0.5
class Lifeform(Object): obj_type = 'npc' max_vel = Vec2d(10, 10) friction = 0.9 def __init__(self, left, top): super(Lifeform, self).__init__() self.rect = Rect( (left, top), (60, 50)) self.vel = Vec2d(0, 0) def update(self, walls): self.update_friction() self.update_pos(walls) def update_pos_axis(self, dx, dy, walls): # Move the rect self.rect.x += dx self.rect.y += dy # If you collide with a wall, move out based on velocity for wall in walls: if self.rect.colliderect(wall.rect): if dx > 0: # Moving right; Hit the left side of the wall self.rect.right = wall.rect.left if dx < 0: # Moving left; Hit the right side of the wall self.rect.left = wall.rect.right if dy > 0: # Moving down; Hit the top side of the wall self.rect.bottom = wall.rect.top if dy < 0: # Moving up; Hit the bottom side of the wall self.rect.top = wall.rect.bottom def update_pos(self, walls): if self.vel.x != 0: self.update_pos_axis(self.vel.x, 0, walls) if self.vel.y != 0: self.update_pos_axis(0, self.vel.y, walls) def update_vel(self, other_vector=None): if other_vector: self.vel += other_vector self.vel.restrain(self.max_vel) else: self.vel = Vec2d(0, 0) def update_friction(self): self.vel *= self.friction if abs(self.vel.x) < 0.5: self.vel.x = 0 if abs(self.vel.y) < 0.5: self.vel.y = 0
def is_collided(self): man_bbox = Rect(self.man_x, self.man_y, self.man_width, self.man_height) collided_floor = {'x': 0,'y':0} is_collided = False for floor in self.floors: floor_box = Rect(floor["x"], floor["y"], self.floor_width, self.floor_height) if Rect.colliderect(man_bbox, floor_box): collided_floor['x'] = floor['x'] collided_floor['y'] = floor['y'] is_collided = True return is_collided, collided_floor
def iterSegmentsVisibleFromCam(self, cam): #FIXME ptr = self.trackStart #should actually use cam pos as ref while ptr: if ptr.prev: segRect = Rect(ptr.prev.left[0]+cam.anchorPt.x, ptr.prev.left[1]+cam.anchorPt.y, ptr.prev.right[0]-ptr.prev.left[0], ptr.right[1]-ptr.prev.left[1]) if segRect.colliderect((0,0,cam.displayRect.width, cam.displayRect.height)): yield segRect ptr = ptr.next
class Camera(object): def __init__(self, target, bounds, size): self.bounds = bounds self.rect = Rect((0,0), size) def update(self, target): self.rect.center = target.center self.rect.clamp_ip(self.bounds) def draw_background(self, surf, bg): surf.blit(bg, (-self.rect.x, -self.rect.y)) def draw_background_alpha(self, surf, bg, alpha): new_bg = bg.copy() new_bg.set_alpha(alpha) surf.blit(new_bg, (-self.rect.x, -self.rect.y)) def draw_sprite(self, surf, sprite): if self.rect.colliderect(sprite.rect): surf.blit(sprite.image, rel_rect(sprite.rect, self.rect)) def draw_sprite_group(self, surf, group): for sprite in group: if self.rect.colliderect(sprite.rect): surf.blit(sprite.image, rel_rect(sprite.rect, self.rect)) def draw_sprite_group_alpha(self, surf, group, alpha): for sprite in group: if self.rect.colliderect(sprite.rect): new_sprite = sprite.image.copy() new_sprite.set_alpha(alpha) surf.blit(new_sprite, rel_rect(sprite.rect, self.rect)) def draw_sprite_alpha(self, surf, sprite, alpha): if self.rect.colliderect(sprite.rect): new_sprite = sprite.image.copy() new_sprite.set_alpha(alpha) surf.blit(new_sprite, rel_rect(sprite.rect, self.rect))
def check_player_collision(self, player_tank_logic): for x in self.bullets: if x.damage_group == player_tank_logic.tank.damage_group: continue bullet_rect = Rect(x.pos_x, x.pos_y, x.size, x.size) tank_rect = Rect(player_tank_logic.tank.pos_x, player_tank_logic.tank.pos_y, player_tank_logic.tank.size_x, player_tank_logic.tank.size_y) if tank_rect.colliderect(bullet_rect): player_tank_logic.tank.health -= x.damage_value pass
class BoxCollider(Behaviour): def __init__(self): super().__init__() self.name = "BoxCollider" self.is_trigger = False self.center = Vector2(0, 0) self.offset = Vector2(0, 0) self.extent = Vector2(0, 0) self.box = Rect(0, 0, 0, 0) self.is_debug = False def update(self): super().update() t = self.game_object.get_behaviour("Transform") self.center = Vector2(t.position) self.center.x += self.offset.x self.center.y += self.offset.y self.box.center = self.center self.box.width = int(self.extent.x) self.box.height = int(self.extent.y) def render(self): super().render() if self.is_debug: surf = pygame.display.get_surface() pygame.draw.rect(surf, (0, 255, 0), self.box, 1) #collider-specific methods #overlaps() is designed for AABB only def overlaps(self, other): if isinstance(other, BoxCollider): return self.box.colliderect(other.box) #WIP #prevent_overlap forces the current box away from the other def prevent_overlap(self, other): if (isintance(other, BoxCollider) and self.box.colliderect(other.box)): r = self.box.clip(other.box) t = self.game_object.get_behaviour("Transform")
def isCollision(object1, object2): ''' Check for collision (Positional overlap) between two objects :param object1: Any object with spacial data that corresponds to x,y,w,h :param object2: Any object with spacial data that corresponds to x,y,w,h :return: Boolean if collision ''' rect1 = Rect(object1.x, object1.y, object1.width, object1.height) rect2 = Rect(object2.x, object2.y, object2.width, object2.height) collision = rect1.colliderect(rect2) return collision
def handleSingleModeCollision(self): '''单人模式碰撞''' for _, rackRect in self.racketSurfaces: left = rackRect[0] top = rackRect[1] width = rackRect[2] height = rackRect[3] # 右侧矩形 rightRect = Rect(left + width - 1, top, 1, height * 2 // 3) # 小球从右侧过来 是否和右侧碰撞 if rightRect.colliderect(self.ballRect) and self.vel_x < 0: self.vel_x = abs(self.vel_x) self.rightScore += 1 return # 左侧矩形 leftRect = Rect(left, top, 1, height * 2 // 3) # 从左侧过来 是否和左侧碰撞 if leftRect.colliderect(self.ballRect) and self.vel_x > 0: self.vel_x = -abs(self.vel_x) self.leftScore += 1 return
class Particle(GameObject): ''' Tiny bits and pieces used for graphical effects. Meant for things like explosions, sparkles, impacts, etc. Not meant to be instantiated alone; should only be held by ParticleEmitters. Particles should have some randomization, particularly in initial direction. ''' START_POS = (-100.0, -100.0) STATES = config.Enum(*PARTICLE_STATES) def __init__(self, image, move_func=_p_move, appear_func=_p_appear): ''' @ivar move_func: The function that defines motion; called each update() Takes one parameter ''' super().__init__() self.appear_func = partial(appear_func, self) self.image = image self.move_func = partial(move_func, self) self.position = list(Particle.START_POS) self.rect = Rect(self.position, self.image.get_size()) self.state = Particle.STATES.IDLE def appear(self): self.appear_func() self.change_state(Particle.STATES.ACTIVE) def move(self): self.move_func() if not self.rect.colliderect(config.SCREEN_RECT): #If we're no longer on-screen... self.change_state(Particle.STATES.LEAVING) def leave(self): self.kill() self.acceleration = [0.0, 0.0] self.velocity = [0.0, 0.0] self.position = list(Particle.START_POS) self.rect.topleft = self.position self.change_state(Particle.STATES.IDLE) actions = { STATES.IDLE : None , STATES.APPEARING: 'appear', STATES.ACTIVE : 'move' , STATES.LEAVING : 'leave' , }
class Particle(GameObject): ''' Tiny bits and pieces used for graphical effects. Meant for things like explosions, sparkles, impacts, etc. Not meant to be instantiated alone; should only be held by ParticleEmitters. Particles should have some randomization, particularly in initial direction. ''' START_POS = (-100.0, -100.0) STATES = config.Enum(*PARTICLE_STATES) def __init__(self, image, move_func=_p_move, appear_func=_p_appear): ''' @ivar move_func: The function that defines motion; called each update() Takes one parameter ''' super().__init__() self.appear_func = partial(appear_func, self) self.image = image self.move_func = partial(move_func, self) self.position = list(Particle.START_POS) self.rect = Rect(self.position, self.image.get_size()) self.state = Particle.STATES.IDLE def appear(self): self.appear_func() self.change_state(Particle.STATES.ACTIVE) def move(self): self.move_func() if not self.rect.colliderect(config.SCREEN_RECT): #If we're no longer on-screen... self.change_state(Particle.STATES.LEAVING) def leave(self): self.kill() self.acceleration = [0.0, 0.0] self.velocity = [0.0, 0.0] self.position = list(Particle.START_POS) self.rect.topleft = self.position self.change_state(Particle.STATES.IDLE) actions = { STATES.IDLE: None, STATES.APPEARING: 'appear', STATES.ACTIVE: 'move', STATES.LEAVING: 'leave', }
def has_intersection(self, neigh1, neigh2): rect1 = Rect( neigh1.rect.x - 72, neigh1.rect.y - 43, neigh1.rect.width + 72, neigh1.rect.height + 43, ) rect2 = Rect( neigh2.rect.x - 72, neigh2.rect.y - 43, neigh2.rect.width + 72, neigh2.rect.height + 43, ) return rect1.colliderect(rect2)
class Obstacle(object): def __init__(self, rects=None): self.width = randint(int(WIDTH * 0.01), int(WIDTH * 0.2)) self.height = randint(int(HEIGHT * 0.01), int(HEIGHT * 0.2)) # self.width = int(HEIGHT*0.1) # self.height = self.width self.color = WHITE self.tests = 0 if not rects: self.rect = Rect(WIDTH / 2 - self.width / 2, HEIGHT / 2 - self.height / 2, self.width, self.height) if rects: self.rect = Rect( (randint(int(WIDTH * 0.1), int(WIDTH * 0.8)), randint(int(HEIGHT * 0.3), int(HEIGHT * 0.6)), self.width, self.height)) self.checkAgain = True while self.checkAgain: self.checkCollide(rects) self.tests += 1 def newCenter(self): if self.tests < OBSTACLETESTLIMIT: self.rect.center = (randint(int(WIDTH * 0.1), int(WIDTH * 0.8)), randint(int(HEIGHT * 0.3), int(HEIGHT * 0.6))) print('new pos'), else: self.width = randint(int(WIDTH * 0.01), int(WIDTH * 0.2)) self.height = randint(int(HEIGHT * 0.01), int(HEIGHT * 0.2)) self.rect = Rect( randint(int(WIDTH * 0.1), int(WIDTH * 0.8)) + self.width / 2, randint(int(HEIGHT * 0.3), int(HEIGHT * 0.6)) + self.height / 2, self.width, self.height) print('new rect') self.tests = 0 def checkCollide(self, rects): self.checkAgain = False for i in rects: if self.rect.colliderect(i): self.newCenter() self.checkAgain = True break def draw(self, disp): disp.fill(self.color, self.rect)
class Bullet(object): def __init__(self, params): self.position = Vector2() self.velocity = Vector2() self.radius = params["radius"] self.attack_power = params["attack_power"] self.ttl = params["ttl"] self.initial_speed = params["initial_speed"] self.fire_rate = params["fire_rate"] self.bb = Rect(0, 0, 2*self.radius, 2*self.radius) self.bb.center = self.position self.color = params["color"] self.fire_sound = params["fire_sound"] self.hit_sound = params["hit_sound"] self.sound_player = params["sound_player"] def set_position(self, position): self.position = position self.bb.center = self.position def set_direction(self, direction): self.velocity = self.initial_speed*direction def collides(self, entity): return hasattr(entity, "bb") and self.bb.colliderect(entity.bb) def collided(self, entity): if not isinstance(entity, Bullet): self.sound_player.play(self.hit_sound, self.position) self.die = True def update(self, dt, entities): self.position += dt*self.velocity self.bb = Rect(0, 0, 2*self.radius, 2*self.radius) self.bb.center = self.position self.ttl -= dt if self.ttl < 0: self.die = True def render(self, surface, viewport): pos = viewport.world2screen_coordinates(self.position) px = int(pos.x) py = int(pos.y) pygame.draw.circle(surface, self.color, (px, py), self.radius) if RENDER_BB: bb = viewport.world2screen_rect(self.bb) pygame.draw.rect(surface, (255, 255, 255), bb, 1)
class Camera(object): def __init__(self, target, bounds, size): self.bounds = bounds self.rect = Rect((0, 0), size) def update(self, target): self.rect.center = target.center self.rect.clamp_ip(self.bounds) def draw_background(self, surf, bg): surf.blit(bg, (-self.rect.x, -self.rect.y)) def draw_sprite(self, surf, sprite): if self.rect.colliderect(sprite.rect): surf.blit(sprite.image, rel_rect(sprite.rect, self.rect))
class Camera(object): def __init__(self, target, bounds, size): self.bounds = bounds self.rect = Rect((0,0), size) def update(self, target): self.rect.center = target.center self.rect.clamp_ip(self.bounds) def draw_background(self, surf, bg): surf.blit(bg, (-self.rect.x, -self.rect.y)) def draw_sprite(self, surf, sprite): if self.rect.colliderect(sprite.rect): surf.blit(sprite.image, rel_rect(sprite.rect, self.rect))
def collisioncheck(self, xpos, ypos, current_map): cmask = getmask(self.right_animation.pics[1], self.collidesection) #checks if the player collides with a rock def rockcollisioncheck(arock, x, y): rockmask = arock.get_mask() if (rockmask.overlap( cmask, [int(x - arock.x), int(y - arock.y)]) == None): return False else: return True iscollision = False playermaskrect = cmask.get_bounding_rects()[0] m = current_map t = m.terrain colliderects = m.colliderects numofrocks = len(t) #first check for edges of map, this is the left if xpos < 0 and m.leftbound: iscollision = True elif xpos + self.normal_width > m.map_width() and m.rightbound: iscollision = True elif ypos < 0 and m.topbound: iscollision = True elif ypos + self.normal_height > m.map_height() and m.bottombound: iscollision = True else: #make playerR only the feet playerR = Rect(xpos + playermaskrect.x, ypos + playermaskrect.y, playermaskrect.w, playermaskrect.h) #collision detection for the moved x pos with the unmoved y pos for x in range(0, len(colliderects)): if (playerR.colliderect(colliderects[x]) == 1): iscollision = True break if not iscollision: for x in range(0, numofrocks): r = t[x] if rockcollisioncheck(r, xpos, ypos): iscollision = True break return iscollision
def test_colliderect(self): r1 = Rect(1, 2, 3, 4) self.failUnless(r1.colliderect(Rect(0, 0, 2, 3)), "r1 does not collide with Rect(0,0,2,3)") self.failIf(r1.colliderect(Rect(0, 0, 1, 2)), "r1 collides with Rect(0,0,1,2)") self.failIf(r1.colliderect(Rect(r1.right, r1.bottom, 2, 2)), "r1 collides with Rect(r1.right,r1.bottom,2,2)") self.failUnless( r1.colliderect(Rect(r1.left + 1, r1.top + 1, r1.width - 2, r1.height - 2)), "r1 does not collide with Rect(r1.left+1,r1.top+1," + "r1.width-2,r1.height-2)", ) self.failUnless( r1.colliderect(Rect(r1.left - 1, r1.top - 1, r1.width + 2, r1.height + 2)), "r1 does not collide with Rect(r1.left-1,r1.top-1," + "r1.width+2,r1.height+2)", ) self.failUnless(r1.colliderect(Rect(r1)), "r1 does not collide with an identical rect") self.failIf(r1.colliderect(Rect(r1.right, r1.bottom, 0, 0)), "r1 collides with Rect(r1.right,r1.bottom,0,0)") self.failIf(r1.colliderect(Rect(r1.right, r1.bottom, 1, 1)), "r1 collides with Rect(r1.right,r1.bottom,1,1)")
def rectangleGenerator(height, width, num, invalid=[-100, -100, 1, 1]): #print "rectangleGenerator" #qprint invalid l = [] i = 0 targetRect = Rect(invalid[0], invalid[1], invalid[2], invalid[3]) while i < num: x1, y1 = random.uniform(0, height), random.uniform(0, width) h, w = invalid[2] + random.uniform( -30, 30), invalid[3] + random.uniform(-30, 30) #print h, w if h > 5 and w > 5 and h < height and w < width: rectangle = np.array([x1, y1, h, w]) test = Rect(x1, y1, h, w) if not targetRect.colliderect(test): l.append(rectangle) i += 1 return l
def checkCollision(self, entityList): doCollide = False entityIndex = 0 for index, entity in enumerate(entityList): entityIndex = index #Create Rect of self selfRect = Rect((self.pos[0], self.pos[1]), (self.size[0], self.size[1])) #Create Rect of other entity otherEntityRect = Rect((entity.pos[0], entity.pos[1]), (entity.size[0], entity.size[1])) if(selfRect.colliderect(otherEntityRect)): doCollide = True break return (doCollide, (entityIndex))
def CheckCollisions(self): Player = Rect(self.x, self.y, 32, 32) for Tile in Map : TileRect = Rect(Tile.x, Tile.y, 32, 32) HasCollided = Player.colliderect(TileRect) if HasCollided: if( Tile.PowerUp is not Globals.PowerupType.PW_NONE) : self.CollectPowerUp(Tile) return False if self.Dir == self.Direction.DIR_LEFT: self.x = TileRect.right if self.Dir == self.Direction.DIR_RIGHT: self.x = TileRect.left - Player.width if self.Dir == self.Direction.DIR_FRONT: self.y = TileRect.top - Player.height if self.Dir == self.Direction.DIR_BACK: self.y = TileRect.bottom return True return False
def check_tanks_collision(self, bullet_to_check): bullet_rect = Rect(bullet_to_check.pos_x, bullet_to_check.pos_y, bullet_to_check.size, bullet_to_check.size) for tank_group in self.tanks_groups: if bullet_to_check.damage_group == tank_group.damage_group: continue for tank_logic_to_check in tank_group.tanks_logic: tank_rect = Rect(tank_logic_to_check.tank.pos_x, tank_logic_to_check.tank.pos_y, tank_logic_to_check.tank.size_x, tank_logic_to_check.tank.size_y) if tank_rect.colliderect(bullet_rect): tank_group.do_damage(tank_logic_to_check, bullet_to_check) self.bullets.remove(bullet_to_check) return True return False
def rectangleGenerator(height, width, num, invalid=[-100, -100, 1, 1]): #print "rectangleGenerator" #qprint invalid l = [] i = 0 targetRect = Rect(invalid[0], invalid[1], invalid[2], invalid[3]) while i < num: x1, y1 = random.uniform(0, height), random.uniform(0, width) h, w = invalid[2] + random.uniform(-30, 30), invalid[3] + random.uniform(-30, 30) #print h, w if h > 5 and w > 5 and h < height and w < width: rectangle = np.array([x1, y1, h, w]) test = Rect(x1, y1, h, w) if not targetRect.colliderect(test): l.append(rectangle) i += 1 return l
def paint(self, hierarchy: Graph, shapes: List[Shape], viewing_window: Rect, action_dict): """ Paints an image based on a relationship graph provided :param action_dict: dict of kind -> texture function each texture function gets (hierarchy, shapes and shape) :param hierarchy: interpreted shape hierarchy :param shapes: list of shapes read by the Loader :param viewing_window: viewing window of the hierarchy shapes :return: png """ img = np.zeros( (int(viewing_window.width), int(viewing_window.height), 3)) # Fun mode # img = np.empty((viewing_window.height, viewing_window.width, 3)) drawn_shapes = [ shape for shape in shapes if viewing_window.contains(shape.shape) or viewing_window.colliderect(shape.shape) ] hs = list(zip(hierarchy.nodes, drawn_shapes)) for i in range(len(hs)): node = hs[i][0] shape = hs[i][1] logging.info( f"Generating texture for shape {shape.id} with kind {shape.kind}" ) texture = action_dict[shape.kind].paint(hierarchy, shapes, shape) # Get indices logging.info( f"Getting indices for shape {shape} and viewing window {viewing_window}" ) x1, x2, y1, y2 = get_splices(viewing_window, shape.shape) # Reshape the texture to fit (hopefully) logging.info(f"Indices are {x1}, {x2}, {y1}, {y2}") resize = np.resize(texture, (x2 - x1, y2 - y1, 3)) img[x1:x2, y1:y2] = resize # for i in range(len(hs)): # shape = hs[i][1] # node = hs[i][0] # anchor = camera.world_to_cam([shape.left, shape.up]) # draw.text((anchor[0], anchor[1]), f"{hash(shape)}", fill=(255, 255, 255)) return cv2.flip(cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE), 1)
class Bullet(Sprite): width = 5 height = 5 def __init__(self, x, y, vy, color, bounds, bad=True): Sprite.__init__(self) self.x = x self.y = y self.vy = vy self.color = color self.bounds = bounds self.bad = bad self.rect = Rect(x, y, self.width, self.height) self.image = Surface(self.rect.size) self.draw_image() def draw_image(self): self.image.fill(self.color) def update(self, dt): dt /= 1000.0 dy = int(self.vy * dt) self.rect.y += dy # We don't want to keep track of them once they're off the screen, so get rid of them if self.rect.bottom > self.bounds.bottom or self.rect.top < self.bounds.top: self.kill() # only used for player bullets (separate class?), checks to see if it hit any enemies, if it did kill the enemy and return a point for the player def kill_things(self, ships, player): kills = 0 for ship in ships: if self.rect.colliderect(ship.rect) and not self.bad: ship.die() kills += 1 return kills
class BallOfLight(GameObject): STATES = config.Enum(*BALL_STATES) BLOCK_GROUP = None block_mod = None ENEMY_GROUP = None def __init__(self, startpos=(-300.0, -300.0), newcolor=choice(color.LIST)): GameObject.__init__(self) self._anim = 0 self.color = newcolor self.current_frame_list = _ball_frames_color_blind if settings.SETTINGS['color_blind'] else _ball_frames self.image = self.current_frame_list[id(newcolor)][0] size = self.image.get_size() self.rect = Rect(startpos, size) self.position = list(self.rect.topleft) self.progress = 0 self._target = [None, 0] self.startpos = startpos self.state = BallOfLight.STATES.IDLE del self.acceleration, self.velocity def appear(self): self.image = self.current_frame_list[id(self.color)][0] self.position = list(self.startpos) self.progress = -1 self.rect.topleft = (self.startpos[0] + .5, self.startpos[1] + .5) self.change_state(BallOfLight.STATES.MOVING) assert config.SCREEN_RECT.collidepoint(self._target), \ "BallOfLight's target should be on-screen, but it's %s" % self._target def move(self): position = self.position startpos = self.startpos target = self._target self.progress += 1 percent = self.progress / TIME_TO_MOVE if self._anim < len(FRAMES) - 1: #If we haven't finished animating... self._anim += 1 self.image = self.current_frame_list[id(self.color)][self._anim] if percent >= 1: #If we've reached our target location... self.change_state(BallOfLight.STATES.DYING) else: dx = (percent * percent) * (3 - 2 * percent) dp = 1 - dx position[0] = (startpos[0] * dx) + (target[0] * self.image.get_width() * dp) position[1] = (startpos[1] * dp) + (target[1] * dx) self.rect.topleft = (position[0] + .5, position[1] + .5) assert self.rect.colliderect(config.SCREEN_RECT), \ "A BallOfLight at %s is trying to move off-screen!" % position def vanish(self): _balls.add(self) BallOfLight.BLOCK_GROUP.add(BallOfLight.block_mod.get_block([self._target[0] * 32, 8.0], self.color)) self.kill() self._anim = 0 self.position = [-300.0, -300.0] self.rect.topleft = (self.position[0] + .5, self.position[1] + .5) self.change_state(BallOfLight.STATES.IDLE) actions = { STATES.IDLE : None , STATES.APPEARING: 'appear', STATES.MOVING : 'move' , STATES.DYING : 'vanish', }
center = self.center if not center: center = self.parent.dot.rect.center return center def calculate_deltas(self): ang, distance = self.angle, self.speed return sin(ang) * distance, cos(ang) * distance def collide(self): angle = self.angle x, y = self.center radius = self.get_radius() rect = Rect(x - radius, y - radius, radius * 2, radius * 2) bandit = self.parent.bandit.rect if rect.colliderect(bandit): if bandit.left - rect.right > rect.top - bandit.bottom: angle = -angle rect.right = bandit.left else: angle = pi - angle rect.top = bandit.bottom field = self.parent.rect if rect.right > field.w or rect.left < 0: angle = -angle if rect.right > field.w: rect.right = field.w else: rect.left = 0 if rect.top < 0 or rect.bottom > field.h: angle = pi - angle
class managed_client(object): mask = ( #X.KeyReleaseMask | X.ButtonReleaseMask | X.EnterWindowMask | X.FocusChangeMask | X.PropertyChangeMask ) def __init__(self, hub, dpy, win): self.hub = hub self.dpy = dpy self.win = win self.hub.emit("client_init_before", client=self) self.win.change_attributes(event_mask=self.mask) getgeom = self.win.get_geometry() self.geom = Rect(getgeom.x, getgeom.y, getgeom.width, getgeom.height) self.props = {} #self.grab_all() self.update_prop('WM_PROTOCOLS') self.hub.emit("client_init_after", client=self) def update_prop(self, propname): # some properties are specified to only change at certain times (such # as when the window is mapped), so we keep a property cache for them self.props[propname] = self.fetch_prop(propname) self.hub.emit('client_property_updated', propname=propname, client=self, win=self.win) def fetch_prop(self, propname): return props.get_prop(self.dpy, self.win, propname) #def grab_all(self): # self.win.grab_button(X.AnyButton, X.AnyModifier, 1, # X.NoEventMask, X.GrabModeSync, X.GrabModeSync, X.NONE, X.NONE) # self.win.grab_key(X.AnyKey, X.AnyModifier, 1, X.GrabModeSync, # X.GrabModeSync) def map_normal(self): self.win.map() self.win.set_wm_state(state=Xutil.NormalState, icon=X.NONE) def iconify(self): self.win.unmap() self.win.set_wm_state(state=Xutil.IconicState, icon=X.NONE) def moveresize(self, **kw): for k, v in kw.items(): setattr(self.geom, k, v) self.hub.emit('before_moveresize_client', client=self) self.win.configure( x=self.geom[0], y=self.geom[1], width=self.geom[2], height=self.geom[3], ) def out_of_viewport(self, wm): return not self.geom.colliderect(wm.root_geometry) def configure(self, **changes): self.win.configure(**changes) for k in "x", "y", "width", "height": if k in changes: setattr(self.geom, k, changes[k]) def focus(self): self.dpy.set_input_focus(self.win, X.RevertToPointerRoot, X.CurrentTime) self.hub.emit('after_focus_window', client=self, win=self.win) def stack_top(self): self.win.configure(stack_mode=X.Above) self.hub.emit('after_raise_window', client=self, win=self.win) def stack_bottom(self): self.win.configure(stack_mode=X.Below) self.hub.emit('after_lower_window', client=self, win=self.win) def delete(self): wm_del = self.dpy.get_atom('WM_DELETE_WINDOW') catch = Xerror.CatchError(Xerror.BadWindow, Xerror.BadValue) if wm_del in self.props['WM_PROTOCOLS']: props.send_window_message(self.dpy, self.win, 'WM_PROTOCOLS', [wm_del], self.win, event_mask=0) else: self.win.kill_client() self.dpy.sync()
def rect_collide(rect1,rect2): r1 = Rect(rect1) r2 = Rect(rect2) if r1.colliderect(r2): return True return False
class Camera: def __init__(self, screen, screensize, playerpos, tileImage, tileSize, currentWeapon): self.screen = screen self.screensize = screensize self.playerx,self.playery = playerpos self.halfscreenx,self.halfscreeny = screensize self.halfscreenx /= 2 self.halfscreeny /= 2 self.rect = Rect(self.playerx-self.halfscreenx, self.playery-self.halfscreeny, self.halfscreenx * 2, self.halfscreeny * 2) self.tiledImage = tileImage self.tileSize = tileSize self.dpx = 0 self.dpy = 0 self.currentWeapon = currentWeapon self.goreObjects = [] def setCurrentWeapon(self, cw): self.currentWeapon = cw def registerGore(self, go): self.goreObjects.append(go) def update(self, playerx, playery, dt): self.dpx += self.playerx - playerx self.dpy += self.playery - playery self.playerx = playerx self.playery = playery self.rect.top = playery - self.halfscreeny self.rect.left = playerx - self.halfscreenx if self.tiledImage != None: r = self.screen.get_rect() rect = Rect(r.top - 2 * self.tileSize, r.left - 2 * self.tileSize, r.width + 2 * self.tileSize, r.height + 2 * self.tileSize) rect.centerx += self.dpx rect.centery += self.dpy self.tiledImage.draw(self.screen, rect) toRemove = [] for i,gore in enumerate(self.goreObjects): x = gore.getX() - self.rect.left y = gore.getY() - self.rect.top self.screen.blit(gore.getScreen(), (x,y)) if gore.update(dt): toRemove.append(i) for i in toRemove: del self.goreObjects[i] self.screen.blit(self.currentWeapon, (15,15)) def drawList(self, objList, img1, img2): toRemove = [] for i in range(len(objList)): if not self.rect.colliderect(objList[i].getRect()): toRemove.append(i) continue relposx = objList[i].getX() - self.rect.left relposy = objList[i].getY() - self.rect.top timer = objList[i].getInviTimer() if (timer>150): if math.sqrt(math.pow((int(relposx)-self.halfscreenx),2) + math.pow((int(relposy)-self.halfscreeny),2))>100: self.screen.blit(img1, (int(relposx),int(relposy))) else: self.screen.blit(img2, (int(relposx),int(relposy))) for i in reversed(toRemove): objList.pop(i) def drawPlayer(self, playerimage, Score): self.screen.blit(playerimage, (self.halfscreenx,self.halfscreeny)) font = pygame.font.Font(None, 30) self.screen.blit(font.render(str(Score), 1, (0,0,0)), (25,25)) def drawObj(self, obj, img): if not self.rect.colliderect(obj.getRect()): return relposx = obj.getX() relposy = obj.getY() self.screen.blit(img, (relposx,relposy)) def drawBulletList(self, objList): toRemove = [] for i in range(len(objList)): if not self.rect.collidepoint(objList[i].getX(), objList[i].getY()): toRemove.append(i) continue relposx = objList[i].getX() - self.rect.left relposy = objList[i].getY() - self.rect.top self.screen.blit(objList[i].getImage(), (int(relposx), int(relposy))) #pygame.draw.circle(self.screen, (0,0,0), (int(relposx), int(relposy)), 5) for i in reversed(toRemove): del objList[i]
class BaseAnimation: """ Base class for animations, this should perhaps be changed to use sprites in the future (if one decides to go with a RenderGroup model) @cvar background: Surface Background (screen) @cvar surface : The Surface obj. to work with @cvar active : Should it be updated in the poll @cvar delete : Delete from list on next poll @cvar updates : list of updates from screen @cvar next_updat: timestamp for next update """ background = None # Surface Background (screen) surface = None # The Surface obj. to work with active = False # Should it be updated in the poll delete = False # Delete from list on next poll updates = [] # list of updates from screen next_update = 0 # timestamp for next update def __init__(self, rectstyle, fps=20, bg_update=True, bg_wait=False, bg_redraw=False): """ Initialise an instance of BaseAnimation @ivar rectstyle : the rectangle defining the position on the screen (pygame) @ivar fps : Desired fps @ivar bg_update : update the animation with background from screen @ivar bg_wait : initially wait for updated background before activating @ivar bg_redraw : set background to original screen bg when finished """ logger.log( 9, '__init__(rectstyle=%r, fps=%r, bg_update=%r, bg_wait=%r, bg_redraw=%r)', rectstyle, fps, bg_update, bg_wait, bg_redraw) self.rect = Rect(rectstyle) self.bg_update = bg_update self.bg_wait = bg_wait self.bg_redraw = bg_redraw self.surface = Surface((self.rect.width, self.rect.height)).convert() self.set_fps(fps) def get_surface(self, width, height): """ Helper for creating surfaces """ logger.log( 9, 'get_surface(width=%r, height=%r)', width, height) return Surface( (width, height), 0, 32) def get_osd(self): """ Helper for getting osd singleton """ logger.log( 9, 'get_osd()') return osd.get_singleton() def set_fps(self, fps): """ Sets the desired fps """ logger.log( 9, 'set_fps(fps=%r)', fps) self.interval = int(1000.0/float(fps)) def set_screen_background(self): """ Update the background """ logger.log( 9, 'set_screen_background()') if not self.background: self.background = osd.get_singleton().getsurface(rect=self.rect) self.updates = [] elif len(self.updates) > 0: # find the topleft corner x = self.rect.right y = self.rect.bottom for i in self.updates: x = min(x, i.left) y = min(y, i.top) # find the total rect of the collisions upd = Rect(x, y, 0, 0) upd.unionall_ip(self.updates) self.updates = [] x = upd[0] - self.rect.left y = upd[1] - self.rect.top bg_tmp = osd.get_singleton().getsurface(rect=upd) self.background.blit(bg_tmp, (x, y)) self.surface.blit(self.background, (0,0)) def get_rect(self): """ Get the rectangle of the current object @returns: the rectangle tuple """ logger.log( 9, 'get_rect()') return self.rect def start(self): """ Starts the animation """ logger.log( 9, 'start()') render.get_singleton().add_animation(self) if not self.bg_wait: self.active = True def stop(self): """ Stops the animation from being polled """ logger.log( 9, 'stop()') self.active = False def remove(self): """ Flags the animation to be removed from the animation list """ logger.log( 9, 'remove()') self.active = False # set the org. bg if we use this if self.bg_update: osd.get_singleton().putsurface(self.background, self.rect.left, self.rect.top) osd.get_singleton().update([self.rect]) self.delete = True def damage(self, rectstyles=[]): """ Checks if the screen background has been damaged @note: If the rect passed damages our rect, but no actual blit is done on osd.screen, we'll end up with a copy of our animation in our bg. This is BAD. """ logger.log( 9, 'damage(rectstyles=%r)', rectstyles) if not (self.bg_redraw or self.bg_update) or rectstyles == None: return for rect in rectstyles: if rect == None: continue if self.rect.colliderect(rect): if self.bg_wait: self.active = True self.updates.append(self.rect.clip(rect)) logger.debug('Damaged, updating background') def poll(self, current_time): """ Poll the animations """ logger.log( 9, 'poll(current_time=%r)', current_time) if self.next_update < current_time: self.next_update = current_time + self.interval if self.bg_update: self.set_screen_background() self.draw() return self.rect, self.surface def draw(self): """ Overload to do stuff with the surface """ logger.log( 9, 'draw()') pass
class Platform(object): """ The platform class. An instance of this class represents a platform of a level. Attributes: _pos: The position of the platform. _size: The size of the platform. _surface: The visual representation of the platform. _rect: The rectangle for collision detection. """ def __init__(self, pos=(0, 0), size=(10, 10), picture=None): """ Generates a new instance of this class. Generates a new instance of this class and sets the field information. Args: pos: The position of the platform. size: The size of the platform. picture: The picture for drawing the platform. """ self._pos = pos self._size = size self._surface = Surface(size) self._rect = Rect(pos, size) if picture is None: picture = PictureManager.MANAGER.get_picture("platform.png") x = 0 y = 0 pic_w = picture.get_width() pic_h = picture.get_height() while x < size[0]: while y < size[1]: self._surface.blit(picture, (x, y)) y += pic_h y = 0 x += pic_w def draw(self, surface, tick, camera, size): """ Draws the platform. This method draws the platform on the give surface if it is in the horizontal range to be visible. Args: surface: The surface to draw on. tick: The current tick of the game. This argument is not used at the moment. camera: The position of the camera. size: The size of the window. """ if self._pos[0] + self._size[0] > camera[0] or self._pos[0] < camera[0] + size[0]: surface.blit(self._surface, (self._pos[0] - camera[0], self._pos[1] - camera[1])) def collides(self, rect): """ Checks for collision. This method checks if the platform collides with the given rectangle. Args: rect: The rectangle to check with. Returns: True if the platform collides with the given rectangle. False otherwise. """ return self._rect.colliderect(rect)
class Player: def __init__(self,image_set,sound_set): self.rect = Rect(20,50,10,15) self.sound_set = sound_set self.image_set = image_set self.left = False self.walking = False self.running = False self.jumping = False self.in_air = False self.cheering = False self.done = False self.alive = True self.velocity = [0,0] self.jump_height = 0 self.frame = 0 self.frame_timer = 0 self.sound_set['Start'].play() def move(self,solids): self.rect.left += self.velocity[0] if self.alive: for solid_object in solids: if self.rect.colliderect(solid_object.rect): if self.velocity[0] < 0: if self.rect.left < solid_object.rect.right: self.rect.left = solid_object.rect.right self.velocity[0] = 0 elif self.velocity[0] > 0: if self.rect.right > solid_object.rect.left: self.rect.right = solid_object.rect.left self.velocity[0] = 0 self.rect.top += self.velocity[1] was_in_air = self.in_air self.in_air = True if self.alive: for solid_object in solids: if self.rect.colliderect(solid_object.rect): if self.velocity[1] < 0: if self.rect.top < solid_object.rect.bottom: self.rect.top = solid_object.rect.bottom self.velocity[1] = 0 if self.jumping: self.jumping = False elif self.velocity[1] > 0: if self.rect.bottom > solid_object.rect.top: self.rect.bottom = solid_object.rect.top self.in_air = False self.velocity[1] = 0 if not self.cheering: if was_in_air and not self.in_air: self.sound_set['Land'].play() if self.rect.top > 260 and self.alive: self.sound_set['Die'].play() self.alive = False self.velocity[1] = -15 self.velocity[0] = randint(-7,7) def check_spikes(self,spikes): if self.alive: for spike_set in spikes: if self.rect.colliderect(spike_set.rect): self.sound_set['Die'].play() self.alive = False self.velocity[1] = -15 self.velocity[0] = randint(-7,7) def check_goal(self,goal): if self.alive: if not self.cheering: if self.rect.colliderect(goal.rect): self.sound_set['Win'].play() self.walking = False self.running = False self.cheering = True def walk(self): self.walking = True self.running = False def run(self): self.walking = False self.running = True def jump(self): if not self.in_air and not self.jumping: if not self.cheering: self.sound_set['Jump'].play() self.jump_height = 0 self.jumping = True def update_velocity(self): if self.alive: if not self.jumping and not self.in_air: self.velocity[1] = 1 if self.walking: if self.left: if self.velocity[0] > -4: self.velocity[0] -= 2 elif not self.left and self.velocity[0] < 4: self.velocity[0] += 2 elif abs(self.velocity[0]) > 4 and not self.in_air: if self.velocity[0] < 0: self.velocity[0] += 1 else: self.velocity[0] -= 1 elif self.running: if self.left and self.velocity[0] > -8: self.velocity[0] -= 2 elif not self.left and self.velocity[0] < 8: self.velocity[0] += 2 elif abs(self.velocity[0]) > 8 and not self.in_air: if self.velocity[0] < 0: self.velocity[0] += 1 else: self.velocity[0] -= 1 elif not self.in_air: if self.velocity[0] > 3: self.velocity[0] -= 3 elif self.velocity[0] < -3: self.velocity[0] += 3 else: self.velocity[0] = 0 if self.in_air: if self.jumping and self.jump_height < 40: if self.jump_height > 30: self.velocity[1] = -4 self.jump_height += 4 elif self.jump_height > 20: self.velocity[1] = -8 self.jump_height += 8 else: self.velocity[1] = -10 self.jump_height += 10 else: if self.velocity[1] < 0: self.velocity[1] = 0 elif self.velocity[1] < 8: self.velocity[1] += 1 self.jumping = False else: if self.velocity[1] < 10: self.velocity[1] += 1 def update(self,left,walk,run,jump,solids,spikes,goal): if self.alive: if self.cheering: if not self.in_air: self.jump() self.frame += 1 if self.frame >= 75: self.done = True else: self.frame_timer += 1 if self.frame_timer >= 2: self.frame_timer = 0 self.frame += 1 if self.frame > 3: self.frame = 0 if walk: self.left = left if run: self.run() else: self.walk() else: self.walking = False self.running = False if jump: self.jump() elif self.jumping: self.jumping = False if not walk and not run: self.running = False self.walking = False self.move(solids) self.check_spikes(spikes) self.check_goal(goal) self.update_velocity() def get_frame(self): if self.frame == 2: return 2 elif self.frame in [1,3]: return 1 else: return 0 def get_image(self): if not self.alive: return self.image_set['Dead'][self.left] elif self.jumping: return self.image_set['Jump'][self.left] elif self.in_air: return self.image_set['Fall'][self.left] elif self.walking: return self.image_set['Walk'][self.get_frame()][self.left] elif self.running: return self.image_set['Run'][self.get_frame()][self.left] else: return self.image_set['Idle'][self.left] def get_blit_info(self): image = self.get_image() blit_rect = image.get_rect() blit_rect.centerx = self.rect.centerx blit_rect.bottom = self.rect.bottom return image,blit_rect
class Object(object): def __init__(self, **kwargs): x, y, w, h = None, None, None, None if kwargs.get("rect", None): x, y, w, h = kwargs.pop("rect", None) elif kwargs.get("pos") or kwargs.get("size"): x, y = kwargs.pop("pos", (0, 0)) w, h = kwargs.pop("size", (0, 0)) else: x, y = kwargs.pop("x", 0), kwargs.pop("y", 0) w, h = kwargs.pop("w", 0), kwargs.pop("h", 0) super().__init__(**kwargs) assert None not in [x, y, w, h] self._rect = Rect(x, y, w, h) def asRect(self): return Rect(self.x, self.y, self.w, self.h) def copy(self): return self._rect.copy() def colliderect(self, collide): return self._rect.colliderect(collide.asRect()) @property def top(self): return self._rect.top @top.setter def top(self, value): self._rect.top = value @property def bottom(self): return self._rect.bottom @bottom.setter def bottom(self, value): self._rect.bottom = value @property def left(self): return self._rect.left @left.setter def left(self, value): self._rect.left = value @property def right(self): return self._rect.right @right.setter def right(self, value): self._rect.right = value @property def x(self): return self._rect.x @x.setter def x(self, value): self._rect.x = value @property def y(self): return self._rect.y @y.setter def y(self, value): self._rect.y = value @property def w(self): return self._rect.w @w.setter def w(self, value): self._rect.w = value @property def h(self): return self._rect.h @h.setter def h(self, value): self._rect.h = value def __repr__(self): return repr(self._rect)
class Ship(object): def __init__(self, params, entities_to_add): self.position = params["position"] self.direction = params["direction"] self.team = params["team"] self.thrust = params["thrust"] self.max_speed = params["max_speed"] self.turn_speed = params["turn_speed"] self.shield = params["shield"] self.sensor_range = params["sensor_range"] self.forcefield_radius = params["forcefield_radius"] self.forcefield_strength = params["forcefield_strength"] self.graphic = params["graphic"] self.graphic_direction = params["graphic_direction"] self.graphic_scale = params["graphic_scale"] self.weapon = params["weapon"] self.bb = Rect(0,0,0,0) self.last_fired = 0 self.entities_to_add = entities_to_add self.velocity = Vector2() self.last_detected = None self.resource_cost = params["resource_cost"] self.name = params["name"] self.destroyed_sound = params["destroyed_sound"] self.sound_player = params["sound_player"] if self.team == "blue": self.color = Vector3(0, 0, 255) elif self.team == "red": self.color = Vector3(255, 0, 0) def accelerate(self, dt, magnitude=1): self.velocity += dt*self.thrust*self.direction*magnitude def decelerate(self, dt, magnitude=1): self.velocity -= dt*self.thrust*self.direction*magnitude def turn_left(self, dt, magnitude=1): self.direction = util.rotate_v(self.direction, -dt*self.turn_speed*magnitude) def turn_right(self, dt, magnitude=1): self.direction = util.rotate_v(self.direction, dt*self.turn_speed*magnitude) def fire(self): if self.last_fired > self.weapon.fire_rate: shot = copy.copy(self.weapon) shot.set_direction(self.direction) radius = max([self.graphic.get_width(), self.graphic.get_height()])*self.graphic_scale shot.set_position(self.position + self.direction*(radius+10)) self.entities_to_add.append(shot) self.last_fired = 0 shot.sound_player.play(shot.fire_sound, self.position) def collides(self, entity): return hasattr(entity, "bb") and self.bb.colliderect(entity.bb) def collided(self, entity): if type(entity) is Bullet: self.shield -= entity.attack_power def at_relative_position(self, entity, dt): if isinstance(entity, Ship): v = entity.position - self.position if v.get_magnitude() < self.forcefield_radius: entity.velocity += v*dt*self.forcefield_strength def detect_enemies(self, entities): self.last_detected = None min_dist = 99999 for entity in entities: if entity != self and isinstance(entity, Ship) and entity.team != self.team: dist = (entity.position - self.position).get_magnitude() if dist < self.sensor_range and dist < min_dist: self.last_detected = entity min_dist = dist def update(self, dt, entities): self.position += dt*self.velocity self.update_bb() self.detect_enemies(entities) if self.shield < 0: self.sound_player.play(self.destroyed_sound, self.position) self.die = True if self.last_fired < 9999999: self.last_fired += dt def update_bb(self): a = util.angle_between_v(self.direction, self.graphic_direction) img = pygame.transform.rotozoom(self.graphic, a, self.graphic_scale) self.bb = img.get_rect() self.bb.x = self.position.x - img.get_width()/2 self.bb.y = self.position.y - img.get_height()/2 def render(self, surface, viewport): a = util.angle_between_v(self.direction, self.graphic_direction) img = pygame.transform.rotozoom(self.graphic, a, self.graphic_scale) pos = viewport.world2screen_coordinates(self.position) px = pos.x - img.get_width()/2 py = pos.y - img.get_height()/2 surface.blit(img, (px, py)) if RENDER_BB: bb = viewport.world2screen_rect(self.bb) pygame.draw.rect(surface, (255, 255, 255), bb, 1) if RENDER_FORCEFIELD: px = int(self.position.x) py = int(self.position.y) pygame.draw.circle(surface, (0, 0, 255), (px, py), self.forcefield_radius, 1)
def fancify(): if request.method == 'POST': print request.data cur_request = json.loads(request.data) else: #cur_request = """{"url": "", "debug":true}""" #cur_request = """{"url": "", "debug":true}""" #cur_request = """{"url": "", "debug":true}""" cur_request = """{"url": "http://localhost/images/scrubs.jpg", "debug":true}""" #cur_request = """{"url": "http://www.newrichstrategies.com/wp-content/uploads/2012/03/How-to-Find-Good-People-in-Your-Life.jpg", "debug":false}""" #cur_request = """{"url": "http://greenobles.com/data_images/frank-lampard/frank-lampard-02.jpg", "debug":true}""" #cur_request = """{"url": "http://www.billslater.com/barack__obama.jpg"}""" #cur_request = """{"url": "http://celebrityroast.com/wp-content/uploads/2011/01/arnold-schwarzenegger-body-building.jpg", "debug":false}""" #cur_request = """{"url": "http://face2face.si.edu/.a/6a00e550199efb8833010536a5483e970c-800wi", "debug":true}""" #cur_request = """{"url": "http://collider.com/uploads/imageGallery/Scrubs/scrubs_cast_image__medium_.jpg", "debug":false}""" #cur_request = """{"url": "http://localhost/images/Kevin_Bacon_at_the_2010_SAG_Awards.jpg", "debug":false}""" #cur_request = """{"url": "http://cdn02.cdn.justjared.com/wp-content/uploads/headlines/2012/02/anna-faris-oscars-red-carpet-2012.jpg", "debug":true}""" #cur_request = """{"url": "http://www.viewzone.com/attractive.female.jpg", "debug":true}""" cur_request = json.loads(cur_request) print cur_request["url"] img = Image(str(cur_request["url"])) img = img.scale(2.0) debug = True #if "debug" in cur_request: # debug = cur_request["debug"] chosen_faces = [] faces = img.findHaarFeatures(face_cascade) if faces is not None: for face in faces: face_features = [] invalid_face = False face_rect = Rect(face.x - (face.width() / 2), face.y - (face.height() / 2), face.width(), face.height()) for chosen_face in chosen_faces: if face_rect.colliderect(chosen_face): invalid_face = True break if invalid_face: break nose = None mouth = None left_eye = None right_eye = None cur_face = img.crop(face.x, face.y, face.width(), face.height(), centered=True) #cur_face = face.crop() noses = cur_face.findHaarFeatures(nose_cascade) mouths = cur_face.findHaarFeatures(mouth_cascade) eyes = cur_face.findHaarFeatures(eye_cascade) face_left_edge = face.x - (face.width() / 2) face_top_edge = face.y - (face.height() / 2) if noses is not None: nose = noses[0] nose_dist = (abs(nose.x - (face.width() / 2)) + abs(nose.y - (face.height() * 5 / 9)) + abs(nose.width() - (face.width() / 4))) for cur_nose in noses: cur_dist = (abs(cur_nose.x - (face.width() / 2)) + abs(cur_nose.y - (face.height() * 5 / 9)) + abs(cur_nose.width() - (face.width() / 4))) if cur_dist < nose_dist: nose = cur_nose nost_dist = cur_dist if nose and (nose.y < (face.height() / 3)): nose = None if nose and mouths is not None: mouth = mouths[0] mouth_dist = abs(mouth.x - nose.x) + (abs(mouth.y - (face.height() * 4 / 5)) * 2) for cur_mouth in mouths: cur_dist = abs(cur_mouth.x - nose.x) + (abs(cur_mouth.y - (face.height() * 4/ 5)) * 2) if (cur_dist < mouth_dist) and (cur_mouth.y > nose.y): mouth = cur_mouth mouth_dist = cur_dist if nose and eyes: right_eye = eyes[0] right_eye_dist = (abs(right_eye.x - (3 * face.width() / 4)) * 2 + abs(right_eye.y - (nose.y - (nose.height() / 2)) / 2) + abs(right_eye.width() - (face.width() / 3))) for cur_eye in eyes: cur_right_dist = (abs(cur_eye.x - (3 * face.width() / 4)) + abs(cur_eye.y - (nose.y - (nose.height() / 2)) / 2) + abs(cur_eye.width() - (face.width() / 3))) if (cur_right_dist <= right_eye_dist): # and (cur_eye.y < nose.y): right_eye = cur_eye right_eye_dist = cur_right_dist if nose and right_eye and (((right_eye.y - (right_eye.height() / 2)) > nose.y) or (right_eye.x < nose.x)): print "Culling right_eye" right_eye = None if nose and mouth: chosen_faces.append(face_rect) x_face = face.x - (face.width() / 2) y_face = face.y - (face.height() / 2) x_nose = nose.x - (nose.width() / 2) y_nose = nose.y - (nose.height() / 2) # Setup TopHat Image scale_factor = face.width() / 175.0 cur_hat = hat.copy() cur_hat = cur_hat.scale(scale_factor) cur_hat_mask = hat_mask.copy() cur_hat_mask = cur_hat_mask.scale(scale_factor) cur_hat_mask = cur_hat_mask.createAlphaMask(hue_lb=0, hue_ub=100) # Calculate the hat position if (face.y - face.height() / 2) > cur_hat.height: x_hat = face.x - (cur_hat.width / 2) y_hat = face.y - (face.height() * 7 / 10) - (cur_hat.height / 2) img = img.blit(cur_hat, pos=(x_hat, y_hat), alphaMask=cur_hat_mask) if mouth: x_mouth = mouth.x - (mouth.width() / 2) y_mouth = mouth.y - (mouth.height() / 2) # Setup Mustache Image cur_stache = stache.copy() scale_factor = ((nose.width() / 300.0) + (face.width() / 600.0)) / 2.0 cur_stache = cur_stache.scale(scale_factor) stache_mask = cur_stache.createAlphaMask(hue_lb=0, hue_ub=10).invert() # Calculate the mustache position bottom_of_nose = y_nose + (nose.height() * 4 / 5) top_of_mouth = y_mouth # if top_of_mouth > bottom_of_nose: # top_of_mouth = bottom_of_nose y_must = y_face + ((bottom_of_nose + top_of_mouth) / 2) - (cur_stache.height / 2) middle_of_nose = nose.x middle_of_mouth = mouth.x x_must = x_face + ((middle_of_nose + middle_of_mouth) / 2) - (cur_stache.width / 2) if right_eye: x_right_eye = right_eye.x - (right_eye.width() / 2) y_right_eye = right_eye.y - (right_eye.height() / 2) # Setup Monocle Image cur_mono = monocle.copy() scale_factor = ((right_eye.width() / 65.0) + (face.width() / 200.0)) / 2.0 cur_mono = cur_mono.scale(scale_factor) mono_mask = cur_mono.createAlphaMask(hue_lb=0, hue_ub=100).invert() # Calculate Monocle Position x_mono = x_face + x_right_eye y_mono = y_face + y_right_eye img = img.blit(cur_mono, pos=(x_mono, y_mono), alphaMask=mono_mask) img = img.blit(cur_stache, pos=(x_must, y_must), alphaMask=stache_mask) if debug: noselayer = DrawingLayer((img.width, img.height)) nosebox_dimensions = (nose.width(), nose.height()) center_point = (face.x - (face.width() / 2) + nose.x, face.y - (face.height() / 2) + nose.y) nosebox = noselayer.centeredRectangle(center_point, nosebox_dimensions, width=3) img.addDrawingLayer(noselayer) img = img.applyLayers() else: print "Face culled:" if not nose: print " No Nose" if not mouth: print " No mouth" if not right_eye: print " No right eye" print if debug: face_left_edge = face.x - (face.width() / 2) face_top_edge = face.y - (face.height() / 2) facelayer = DrawingLayer((img.width, img.height)) facebox_dimensions = (face.width(), face.height()) center_point = (face.x, face.y) facebox = facelayer.centeredRectangle(center_point, facebox_dimensions, Color.BLUE) img.addDrawingLayer(facelayer) if noses: for nose in noses: noselayer = DrawingLayer((img.width, img.height)) nosebox_dimensions = (nose.width(), nose.height()) center_point = (face.x - (face.width() / 2) + nose.x, face.y - (face.height() / 2) + nose.y) nosebox = noselayer.centeredRectangle(center_point, nosebox_dimensions) img.addDrawingLayer(noselayer) if mouths: for mouth in mouths: mouthlayer = DrawingLayer((img.width, img.height)) mouthbox_dimensions = (mouth.width(), mouth.height()) center_point = (face.x - (face.width() / 2) + mouth.x, face.y - (face.height() / 2) + mouth.y) mouthbox = mouthlayer.centeredRectangle(center_point, mouthbox_dimensions, Color.GREEN) img.addDrawingLayer(mouthlayer) if eyes: for right_eye in eyes: right_eyelayer = DrawingLayer((img.width, img.height)) right_eyebox_dimensions = (right_eye.width(), right_eye.height()) right_eye_center_point = (face_left_edge + right_eye.x, face_top_edge + right_eye.y) right_eyebox = right_eyelayer.centeredRectangle(right_eye_center_point, right_eyebox_dimensions) img.addDrawingLayer(right_eyelayer) img = img.applyLayers() img = img.scale(0.5) w_ratio = img.width / 800.0 h_ratio = img.height / 600.0 if h_ratio > 1.0 or w_ratio > 1.0: if h_ratio > w_ratio: img = img.resize(h=600) else: img = img.resize(w=800) output = StringIO.StringIO() img.getPIL().save(output, format="JPEG") #, quality=85, optimize=True) img_contents = output.getvalue() mimetype = "image/jpeg" return app.response_class(img_contents, mimetype=mimetype, direct_passthrough=False)
class Person: SIZE_FACTOR = .07 def __init__(self, screen, images, sounds, otherPeopleGroup, widthToHeight, moveSpeedFactor): self.sizeScaleFactor = screen.get_width() self.screenSize = (screen.get_width(), screen.get_height()) width = self.sizeScaleFactor * Person.SIZE_FACTOR self.boundRect = Rect(0,0, width, width * widthToHeight) self.boundRect.center = self.wantedPos = [random.randint(0, self.screenSize[0]), random.randint(0, self.screenSize[1])] self.growFactor = 1.1 self.allImages = PeopleImages(images) self.set_size([self.boundRect.width, self.boundRect.height]) #The probability that the person will change direction or stop when they move self.changeDirectionProb = .03 self.stopProb = .5 self.screen = screen self.sounds = sounds self.speedFactor = moveSpeedFactor self.moveSpeed = self.speedFactor * self.sizeScaleFactor * 1.5 #health self.fullHealth = 1.0 self.health = self.fullHealth self.healthDecreaceAmount = self.speedFactor * 1.5 self.isAlive = True self.timeToDigest = 0.0 self.set_rand_dir() self.moveAmount = list(polar_to_cart((self.moveDistance, self.moveAngle))) self.isHungry = True self.fullfillment = 0 self.otherPeople = otherPeopleGroup self.donationWait = 1.0 self.lastDonationTime = self.donationWait def move(self): if(random.random() < self.changeDirectionProb): #change direction if(random.random() < self.stopProb): #stop self.moveDistance = 0.0 else: #move somewhere self.set_rand_dir() self.moveAmount = list(polar_to_cart((self.moveDistance, self.moveAngle))) #Turn back at the edges of the screen for dimNum in range(2): if ((self.wantedPos[dimNum] < 0 and self.moveAmount[dimNum] < 0) or (self.wantedPos[dimNum] > self.screenSize[dimNum] and self.moveAmount[dimNum] > 0)): self.moveAmount[dimNum] *= -1.0 if self.timeToDigest > 0: self.timeToDigest -= self.speedFactor self.wantedPos[0] += self.moveAmount[0] self.wantedPos[1] += self.moveAmount[1] self.boundRect.center = self.wantedPos #returns the location of the donation if it's made def donate(self, numPowerUps): if not self.isHungry: if self.lastDonationTime >= self.donationWait: self.lastDonationTime = 0.0 donationType = random.randint(0, numPowerUps - 1) return self.boundRect.center, donationType else: self.lastDonationTime += self.speedFactor return None, None #returns true if dead def decrease_health(self): if self.isHungry: self.health -= self.healthDecreaceAmount if self.health > 0: return False else: self.isAlive = False return True else: return False def set_size(self, size): for index in range(2): size[index] = int(size[index]+.5) self.boundRect.width = size[0] self.boundRect.height = size[1] #self.allImages.dead = pygame.transform.scale(self.allImages.dead, size) self.allImages.eating = pygame.transform.scale(self.allImages.eating, size) self.allImages.normal = pygame.transform.scale(self.allImages.normal, size) for imageNum in range(len(self.allImages.images)): self.allImages.images[imageNum] = pygame.transform.scale(self.allImages.images[imageNum], size) #eat any food that is touching, return true if the food was eaten #also sets the person to normal if they ate enough def try_eat_food(self, food): if self.isHungry and self.timeToDigest <= 0: if self.boundRect.colliderect(food.boundRect): self.health += food.healthGain self.fullfillment += food.fullfill self.timeToDigest = food.timeToDigest self.sounds.eatingSound.play() self.set_size([self.boundRect.width * self.growFactor, self.boundRect.height * self.growFactor]) if self.fullfillment >= 1: #person is normal now self.isHungry = False #check to make sure the person didn't die if self in self.otherPeople.allPeople: self.otherPeople.set_normal(self) return True return False def set_rand_dir(self): self.moveAngle = random.random() * 2* math.pi self.moveDistance = self.moveSpeed def draw(self): if self.isHungry: if self.timeToDigest <= 0: #Gets the appropriate image bassed on the person's health. if self.health >= 1: imageNum = len(self.allImages.images) - 1 else: imageNum = int(math.floor(self.health * len(self.allImages.images))) image = self.allImages.images[imageNum] else: image = self.allImages.eating else: image = self.allImages.normal self.screen.blit(image, self.boundRect)
class Controller(): def __init__(self, canvas, parent): self.canvas = canvas self.parent = parent self.objects = OrderedDict() self.objects["LOW"] = Low(self) self.objects["HIGH"] = High(self) self.selected = [] self.select = False self.select_start = False self.select_rect = Rect(0, 0, 0, 0) self.possible_move = False self.pan = False self.pan_x = 0 self.pan_y = 0 self.pan_offset_x = 0 self.pan_offset_y = 0 self.new_node = False self.new_node_direction = NODE_DIR_NA self.zoom = 1.0 self.zoom_step = 0.1 self.obj_id = 0 self.net_id = 0 self.highlight_mode = LIGHT_NONE self.highlight_pos = False self.add_index = 0 self.add_list = ["label", "and", "or", "nand", "nor", "xor", "not", "diode", "led", "hex", "tgl", "push", "clk", "input", "output", "memory"] self.font = pygame.font.Font(pygame.font.get_default_font(), int(self.canvas.style["d_font"] * self.zoom)) self.label_font = pygame.font.Font(pygame.font.get_default_font(), int(self.canvas.style["d_label_font"] * self.zoom)) self.need_solve_drawable = True self.drawable = [] self.read_only = True def highlight(self, mode, pos = False): self.highlight_mode = mode self.highlight_pos = pos self.canvas.request_io_redraw() def get_obj_id(self): self.obj_id += 1 return self.obj_id def get_net_id(self): self.net_id += 1 return self.net_id def normalize_positons(self): big_rect = False for k in self.objects: o = self.objects[k] if not isinstance(o, Invisible): if big_rect: big_rect = big_rect.union(o.rect) else: big_rect = o.rect offset_x = big_rect[0] offset_y = big_rect[1] for k in self.objects: o = self.objects[k] pos_x = o.rect[0] - offset_x pos_y = o.rect[1] - offset_y o.set_pos(pos_x, pos_y) def write_file(self, filename): if self.read_only: return lines = "" self.normalize_positons() # print "Writing file", filename line_n = 0 for k in self.objects: if k in ["HIGH", "LOW"]: continue o = self.objects[k] name = o.name fcs = o.fcs p = o.get_params() if p == False: continue params = " ".join(p) line = "\t".join([name, fcs, params]) lines += "%s\n" % line # print " %5d: %s" % (line_n, line) line_n += 1 f = open(filename, "w") f.write(lines) f.close() # print "done", filename def read_file(self, filename): print "Reading file", filename try: f = open(filename, "r") data = f.readlines() f.close() self.create_objects(data) print "done", filename return True except IOError as e: print "not found", e return False def create_objects(self, data): params = OrderedDict() line_n = 0 for line in data: line_n += 1 arr = line.split() print " %5d: %s" % (line_n, " ".join(arr)) if (len(arr) < 2): continue name = arr[0] fcs = arr[1] #calc obj id s = name.split("_") if len(s) == 4 and s[0] == "" and s[1] == "": try: obj_id = int(s[3]) self.obj_id = max(obj_id + 1, self.obj_id) except ValueError: pass #calc net id if fcs == "node": s = arr[3].split("_") if len(s) == 4 and s[0] == "" and s[1] == "": try: net_id = int(s[3]) self.net_id = max(net_id + 1, self.net_id) except ValueError: pass o = False if fcs in self.canvas.cells: o = self.canvas.cells[fcs](self) if (o is not False): params[name] = arr self.objects[name] = o #let object to parse parameters for name in params: arr = params[name] o = self.objects[name] o.parse(arr) def find_cell(self, name): if name in self.objects: return self.objects[name] else: return False def find_cell_pin(self, name): arr = name.split(".") if (len(arr) == 1): o_name = arr[0] o_pin = False else: o_name, o_pin = arr o = self.find_cell(o_name) if o == False: print name, "not found!" return False if o_pin == False: if len(o.outputs) > 0: o_pin = o.outputs[0] else: o_pin = False return o, o_pin def find_output(self, obj, pin): for k in self.objects: o = self.objects[k] for p in o.inputs: pair = o.inputs[p] if pair == False: continue if pair[0] == obj and pair[1] == pin: return o, p return False def blit(self, surface, rect): rect = Rect(rect) rect.x += self.pan_offset_x rect.y += self.pan_offset_y rect.x *= self.zoom rect.y *= self.zoom self.canvas.screen.blit(surface, rect) def draw_circle(self, pos, state): pos = list(pos) pos[0] += self.pan_offset_x pos[1] += self.pan_offset_y pos = [int(x * self.zoom) for x in pos] if (state): color = self.canvas.style["c_high"] else: color = self.canvas.style["c_low"] self.canvas.draw_circle(color, pos, self.zoom) def draw_line(self, start, end, state): #copy the data start = list(start) end = list(end) start[0] += self.pan_offset_x start[1] += self.pan_offset_y end[0] += self.pan_offset_x end[1] += self.pan_offset_y start = [int(x * self.zoom) for x in start] end = [int(x * self.zoom) for x in end] if state: color = self.canvas.style["c_high"] else: color = self.canvas.style["c_low"] self.canvas.draw_line(start, end, color, self.zoom) def draw_rect(self, surface, color, rect, width = 0): rect = Rect(rect) w = int(width * self.zoom) rect = Rect([int(x * self.zoom) for x in rect]) if width > 0 and w == 0: w = 1 pygame.draw.rect(surface, color, rect, w) def draw_text(self, surface, text, rect): tmp = self.font.render(text, True, self.canvas.style["c_text"]) rect2 = tmp.get_rect() rect = Rect([int(x * self.zoom) for x in rect]) rect = [rect.x + rect.w / 2 - rect2.w / 2, rect.y + rect.h / 2 - rect2.h / 2] surface.blit(tmp, rect) def draw_label(self, text, rect): tmp = self.label_font.render(text, True, self.canvas.style["c_label"]) rect2 = tmp.get_rect() rect = Rect([int(x * self.zoom) for x in rect]) rect = [rect.x + rect.w / 2 - rect2.w / 2, rect.y + rect.h / 2 - rect2.h / 2] return tmp def label_font_size(self, text): label_font = pygame.font.Font(pygame.font.get_default_font(), self.canvas.style["d_label_font"]) tmp = label_font.render(text, True, self.canvas.style["c_text"]) rect2 = tmp.get_rect() return rect2 def draw_highlight(self): if self.highlight_mode == LIGHT_LINE: start = list(self.highlight_pos[0]) end = list(self.highlight_pos[1]) width = self.canvas.style["d_line_height"] w = int(width * self.zoom) start[0] += self.pan_offset_x start[1] += self.pan_offset_y start = [int(x * self.zoom) for x in start] end[0] += self.pan_offset_x end[1] += self.pan_offset_y end = [int(x * self.zoom) for x in end] if width > 0 and w == 0: w = 1 pygame.draw.line(self.canvas.screen, self.canvas.style["c_highlight"], start, end, w) if self.highlight_mode == LIGHT_POINT: width = self.canvas.style["d_point"] w = int(width * self.zoom) point = list(self.highlight_pos) point[0] += int(self.pan_offset_x) point[1] += int(self.pan_offset_y) point = [int(x * self.zoom) for x in point] if width > 0 and w == 0: w = 1 pygame.draw.circle(self.canvas.screen, self.canvas.style["c_highlight"], point, w) def draw_highlight_box(self, rect): rect = Rect(rect) width = self.canvas.style["d_line_height"] w = int(width * self.zoom) rect.x += self.pan_offset_x rect.y += self.pan_offset_y rect = Rect([int(x * self.zoom) for x in rect]) if width > 0 and w == 0: w = 1 pygame.draw.rect(self.canvas.screen, self.canvas.style["c_highlight"], rect, w) def mk_surface(self, rect): size = [int(rect.w * self.zoom), int(rect.h * self.zoom)] return pygame.Surface(size, self.canvas.surface_flags) def update_zoom(self): self.font = pygame.font.Font(pygame.font.get_default_font(), int(self.canvas.style["d_font"] * self.zoom)) self.label_font = pygame.font.Font(pygame.font.get_default_font(), int(self.canvas.style["d_label_font"] * self.zoom)) self.solve_drawable() for k in self.objects: self.objects[k].request_update_body() if self.canvas.mode == MODE_ADD: self.new_node.request_update_body() self.canvas.request_redraw() def request_redraw(self): for o in self.drawable: o.request_redraw() def solve_drawable(self): self.need_solve_drawable = True def draw(self, mode): if self.need_solve_drawable: self.need_solve_drawable = False window = Rect(-self.pan_offset_x, -self.pan_offset_y, self.canvas.size[0] / self.zoom, self.canvas.size[1] / self.zoom) self.drawable = [] for k in self.objects: self.objects[k].solve_drawable(window, self.drawable) if mode == MODE_SELECT: self.canvas.request_redraw() self.canvas.request_io_redraw() for o in self.drawable: o.draw() o.draw_io() if mode == MODE_SELECT: self.select_rect.normalize() self.draw_highlight_box(self.select_rect) for o in self.selected: self.draw_highlight_box(o.rect) if mode == MODE_WIRE: self.draw_highlight() if mode in [MODE_ADD, MODE_ADD_MODULE]: if self.new_node is not False: self.new_node.draw() self.new_node.draw_io() def tick(self): for k in self.objects: self.objects[k].tick() def reset(self): for k in self.objects: self.objects[k].reset() def request_update(self): pass def clear_io_cache(self): for o in self.drawable: o.clear_io_cache() def get_object_pos(self, pos, exclude = []): pos = list(pos) object_list = list(self.drawable) object_list.reverse() for o in object_list: if o in exclude: continue if (o.rect.collidepoint(pos)): return o return False #wire form input / output def get_line_pos(self, pos, exclude = []): pos = list(pos) for o in self.drawable: if o in exclude: continue data = o.check_input_line_collision(pos) if (data): if data[2] in exclude: continue return data return False #wire form net def get_net_line_pos(self, pos, exclude=[]): pos = list(pos) for o in self.drawable: if isinstance(o, wire.Node): if o in exclude: continue data = o.check_net_line_collision(pos) if (data): if data[1] in exclude: continue return data return False def get_output_pos(self, pos, exclude=[]): pos = list(pos) for o in self.drawable: if o in exclude: continue pin = o.check_output_collision(pos) if (pin): return o, pin return False def get_input_pos(self, pos, exclude=[]): pos = list(pos) for o in self.drawable: if o in exclude: continue pin = o.check_input_collision(pos) if (pin): return o, pin return False def add_object(self, fcs, pos, params = []): o = self.canvas.cells[fcs](self) name = "__%s_%d" % (fcs, self.get_obj_id()) self.objects[name] = o o.update() o.middle_offset() pos = "%dx%d" % (pos[0], pos[1]) o.parse([name, fcs, pos] + params) self.request_redraw() self.solve_drawable() return o def add_node(self, pos, net = False): o = self.canvas.cells["node"](self) name = "__node_%d" % (self.get_obj_id()) self.objects[name] = o o.update() o.middle_offset() pos = "%dx%d" % (pos[0], pos[1]) if net is False: net = self.add_net() o.parse([name, "node", pos, net.name]) self.request_redraw() self.solve_drawable() return o def add_net(self, net_name = False): if net_name is False: net_name = "__net_%d" % (self.get_net_id()) o = self.canvas.cells["net"](self) self.objects[net_name] = o o.parse([net_name, "net"]) return o def apply_grid(self, obj): g_hor = self.canvas.style["g_hor"] g_ver = self.canvas.style["g_ver"] obj.rect.x = int(round(obj.rect.x / float(g_hor)) * g_hor) obj.rect.y = int(round(obj.rect.y / float(g_ver)) * g_ver) obj.clear_offset() obj.update_io_xy() def delete(self, name): if name in self.objects: self.objects[name].disconnect() del self.objects[name] self.canvas.request_redraw() self.solve_drawable() def select_obj(self, objs): for o in objs: if o not in self.selected and not isinstance(o, Invisible): self.selected.append(o) #self.canvas.request_io_redraw() def deselect_obj(self, objs): for o in objs: if o in self.selected: self.selected.remove(o) self.canvas.request_redraw() def tglselect_obj(self, obj): if obj in self.selected: self.deselect_obj([obj]) else: self.select_obj([obj]) def clear_selection(self): self.selected = [] #self.canvas.request_io_redraw() def rename_obj(self, obj, new_name): if new_name in self.objects: return False del self.objects[obj.name] obj.name = new_name self.objects[new_name] = obj obj.update() return True def event(self, event, mode): #GET event info hover_object = False keys = pygame.key.get_pressed() if hasattr(event, "pos"): mouse_x = (event.pos[0] / self.zoom) - self.pan_offset_x mouse_y = (event.pos[1] / self.zoom) - self.pan_offset_y hover_object = self.get_object_pos([mouse_x, mouse_y]) if keys[pygame.K_LCTRL]: g_hor = self.canvas.style["g_hor"] g_ver = self.canvas.style["g_ver"] mouse_x = int(round(mouse_x / float(g_hor)) * g_hor) mouse_y = int(round(mouse_y / float(g_ver)) * g_ver) if event.type == pygame.KEYDOWN: if event.key == ord('a') and self.canvas.mode == MODE_EDIT: fcs = self.add_list[self.add_index] pos = "%dx%d" % (0, 0) name = "_%s_" % fcs self.new_node = self.canvas.cells[fcs](self) self.new_node.update() self.new_node.middle_offset() self.new_node.parse([name, fcs, pos]) self.canvas.set_mode(MODE_ADD) if event.key == ord('m') and self.canvas.mode == MODE_EDIT: self.canvas.set_mode(MODE_ADD_MODULE) if event.key == ord('e') and self.canvas.mode in [MODE_IDLE, MODE_WIRE, MODE_RENAME]: self.highlight(LIGHT_NONE) self.canvas.set_mode(MODE_EDIT) if event.key == ord('d') and self.canvas.mode == MODE_IDLE: self.canvas.set_mode(MODE_STEP) if event.key == ord('w') and self.canvas.mode == MODE_EDIT: self.canvas.set_mode(MODE_WIRE) if event.key == ord('r') and self.canvas.mode == MODE_EDIT: self.canvas.set_mode(MODE_RENAME) if event.key == ord('s'): self.read_only = not self.read_only self.canvas.request_redraw() if event.key == pygame.K_SPACE and self.canvas.mode == MODE_STEP: self.tick() if event.key == pygame.K_ESCAPE: self.canvas.request_io_redraw() if self.canvas.mode == MODE_STEP: self.canvas.set_mode(MODE_IDLE) if self.canvas.mode == MODE_EDIT: self.clear_selection() self.canvas.set_mode(MODE_IDLE) if self.canvas.mode == MODE_WIRE: self.canvas.set_mode(MODE_EDIT) self.highlight(LIGHT_NONE) if self.canvas.mode == MODE_ADD: self.canvas.set_mode(MODE_EDIT) self.new_node = False if self.canvas.mode == MODE_ADD_MODULE: self.canvas.set_mode(MODE_EDIT) self.new_node = False if self.canvas.mode == MODE_RENAME: self.canvas.set_mode(MODE_EDIT) #PAN is woring allways #RIGHT DOWN => START PAN if event.type == pygame.MOUSEBUTTONDOWN and event.button == MID: self.pan_x = event.pos[0] / self.zoom self.pan_y = event.pos[1] / self.zoom self.pan = True self.mode_before = mode self.canvas.set_mode(MODE_PAN) if self.pan: #RIGHT UP => STOP PAN if event.type == pygame.MOUSEBUTTONUP and event.button == MID: self.pan_offset_x += event.pos[0] / self.zoom - self.pan_x self.pan_offset_y += event.pos[1] / self.zoom - self.pan_y self.solve_drawable() self.canvas.request_redraw() self.pan = False self.canvas.set_mode(self.mode_before) if event.type == pygame.MOUSEMOTION: self.pan_offset_x += event.pos[0] / self.zoom - self.pan_x self.pan_offset_y += event.pos[1] / self.zoom - self.pan_y self.pan_x = event.pos[0] / self.zoom self.pan_y = event.pos[1] / self.zoom self.solve_drawable() self.canvas.request_redraw() #ZOOM is working allways if event.type == pygame.MOUSEBUTTONDOWN and event.button == WHEEL_UP: if self.zoom < 1.5: self.pan_offset_x -= mouse_x + self.pan_offset_x - event.pos[0] / self.zoom self.pan_offset_y -= mouse_y + self.pan_offset_y - event.pos[1] / self.zoom pan_x = event.pos[0] / self.zoom pan_y = event.pos[1] / self.zoom self.zoom += self.zoom_step self.pan_offset_x += event.pos[0] / self.zoom - pan_x self.pan_offset_y += event.pos[1] / self.zoom - pan_y self.update_zoom() if event.type == pygame.MOUSEBUTTONDOWN and event.button == WHEEL_DOWN: if self.zoom > 0.2: pan_x = event.pos[0] / self.zoom pan_y = event.pos[1] / self.zoom self.zoom -= self.zoom_step self.pan_offset_x += event.pos[0] / self.zoom - pan_x self.pan_offset_y += event.pos[1] / self.zoom - pan_y self.update_zoom() if mode == MODE_IDLE or mode == MODE_STEP: if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT: if hover_object is not False: hover_object.click() if mode == MODE_RENAME: #LEFT DOWN => RENAME if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT: if hover_object is not False: if isinstance(hover_object, cell.Label): label = utils.gui_textedit("Change the label", hover_object.label) if len(label) == 0: utils.gui_alert("Error", "Labels can't be empty") else: hover_object.label = label hover_object.update() self.canvas.set_mode(MODE_EDIT) else: if isinstance(hover_object, wire.Node): obj = hover_object.net else: obj = hover_object old_name = obj.name name = utils.gui_textedit("Rename the object", obj.name) if old_name == name: return if len(name) == 0: utils.gui_alert("Error", "Name can't be empty") return if not self.rename_obj(obj, name): utils.gui_alert("Error", "Unable to rename object") else: self.canvas.set_mode(MODE_EDIT) if mode == MODE_EDIT: #LEFT DOWN => START SELECT if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT: if hover_object is False: #SHIFT prevent clear selection if not keys[pygame.K_LSHIFT]: self.clear_selection() self.canvas.set_mode(MODE_SELECT) self.select_start = [mouse_x, mouse_y] self.select_rect = pygame.Rect(mouse_x, mouse_y, 0, 0) else: if keys[pygame.K_LSHIFT]: self.tglselect_obj(hover_object) else: if hover_object not in self.selected: self.clear_selection() self.select_obj([hover_object]) if hover_object in self.selected: self.possible_move = True if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT: if self.possible_move is True: self.possible_move = False if event.type == pygame.MOUSEMOTION: if self.possible_move is True: self.possible_move = False for o in self.selected: o.set_offset(mouse_x - o.rect[0], mouse_y - o.rect[1]) self.canvas.set_mode(MODE_MOVE) if event.type == pygame.KEYDOWN and event.key == pygame.K_DELETE: for o in self.selected: self.delete(o.name) self.clear_selection() if mode == MODE_SELECT: if event.type == pygame.MOUSEMOTION: w = mouse_x - self.select_start[0] h = mouse_y - self.select_start[1] self.select_rect = pygame.Rect(self.select_start[0], self.select_start[1], w, h) if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT: self.canvas.request_io_redraw() for k in self.objects: o = self.objects[k] if (self.select_rect.colliderect(o.rect)): self.select_obj([o]) self.canvas.set_mode(MODE_EDIT); if mode == MODE_MOVE: if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT: self.canvas.request_redraw() for o in self.selected: o.set_pos(mouse_x, mouse_y) self.apply_grid(o) if (len(self.selected) == 1): self.clear_selection() self.canvas.set_mode(MODE_EDIT); if event.type == pygame.MOUSEMOTION: self.canvas.request_redraw() for o in self.selected: o.set_pos(mouse_x, mouse_y) if mode == MODE_WIRE: if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT: print print "<<" print "get_object_pos", hover_object if isinstance(hover_object, wire.Node): self.new_node = self.add_node([mouse_x, mouse_y], hover_object.net) self.new_node.add_sibling(hover_object) self.new_node_direction = NODE_DIR_FROM_NODE self.solve_drawable() return target = self.get_input_pos([mouse_x, mouse_y]) print "get_input_pos", target if target is not False: obj, pin = target self.new_node = self.add_node([mouse_x, mouse_y]) obj.assign_input(pin, self.new_node, "Y") self.new_node_direction = NODE_DIR_FROM_INPUT self.solve_drawable() return target = self.get_output_pos([mouse_x, mouse_y]) print "get_output_pos", target if target is not False: obj, pin = target self.new_node = self.add_node([mouse_x, mouse_y]) self.new_node.assign_free_input(obj, pin) self.new_node_direction = NODE_DIR_FROM_OUTPUT self.solve_drawable() return target = self.get_line_pos([mouse_x, mouse_y]) print "get_line_pos", target if target is not False: obj, obj_pin, inp, inp_pin = target start_node = self.add_node([mouse_x, mouse_y]) self.apply_grid(start_node) if isinstance(inp, wire.Node): inp.add_sibling(start_node) start_node.net.remove_node(self.new_node) self.delete(start_node.net.name) inp.net.add_node(start_node) obj.assign_input(obj_pin, start_node, "Y") if isinstance(obj, wire.Node): obj.add_sibling(start_node) start_node.net.remove_node(start_node) self.delete(start_node.net.name) obj.net.add_node(start_node) start_node.assign_free_input(inp, inp_pin) self.new_node = self.add_node([mouse_x, mouse_y], start_node.net) self.new_node.add_sibling(start_node) self.new_node_direction = NODE_DIR_FROM_NODE self.solve_drawable() return target = self.get_net_line_pos([mouse_x, mouse_y]) print "get_net_line_pos", target if target is not False: node1, node2, net = target start_node = self.add_node([mouse_x, mouse_y], net) self.apply_grid(start_node) node1.remove_sibling(node2) node1.add_sibling(start_node) node2.remove_sibling(node1) node2.add_sibling(start_node) self.new_node = self.add_node([mouse_x, mouse_y], start_node.net) self.new_node.add_sibling(start_node) self.new_node_direction = NODE_DIR_FROM_NODE self.solve_drawable() return else: if hover_object is False: start_node = self.add_node([mouse_x, mouse_y]) self.apply_grid(start_node) self.new_node = self.add_node([mouse_x, mouse_y], start_node.net) self.new_node.add_sibling(start_node) self.new_node_direction = NODE_DIR_FROM_NODE self.solve_drawable() if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT: if self.new_node is not False: self.new_node.set_pos(mouse_x, mouse_y) self.apply_grid(self.new_node) print print ">>" target = self.get_object_pos([mouse_x, mouse_y], [self.new_node]) print "get_object_pos", target if target is not False: if isinstance(target, wire.Node): #FROM_INPUT / FROM_OUTPUT will be handeled lower if self.new_node_direction == NODE_DIR_FROM_NODE: prev = self.new_node.siblings[0] target.add_sibling(prev) prev.net.asimilate(target.net) self.delete(self.new_node.name) self.new_node = False self.solve_drawable() return target = self.get_input_pos([mouse_x, mouse_y], [self.new_node]) print "get_input_pos", target if target is not False and self.new_node_direction is not NODE_DIR_FROM_INPUT: obj, pin = target if self.new_node_direction == NODE_DIR_FROM_NODE: obj.assign_input(pin, self.new_node.siblings[0], "Y") if self.new_node_direction == NODE_DIR_FROM_OUTPUT: key = self.new_node.inputs.keys()[0] inp, inp_pin = self.new_node.inputs[key] obj.assign_input(pin, inp, inp_pin) self.delete(self.new_node.name) self.new_node = False self.solve_drawable() return target = self.get_output_pos([mouse_x, mouse_y], [self.new_node]) print "get_output_pos", target if target is not False and self.new_node_direction is not NODE_DIR_FROM_OUTPUT: obj, pin = target if self.new_node_direction == NODE_DIR_FROM_NODE: self.new_node.siblings[0].assign_free_input(obj , pin) if self.new_node_direction == NODE_DIR_FROM_INPUT: orig_obj, orig_pin = self.find_output(self.new_node, "Y") orig_obj.assign_input(orig_pin, obj, pin) self.delete(self.new_node.name) self.new_node = False self.solve_drawable() return target = self.get_line_pos([mouse_x, mouse_y], [self.new_node]) print "get_line_pos", target if target is not False: obj, obj_pin, inp, inp_pin = target if isinstance(inp, wire.Node): inp.add_sibling(self.new_node) self.new_node.net.asimilate(inp.net) else: self.new_node.assign_free_input(inp , inp_pin) if isinstance(obj, wire.Node): obj.add_sibling(self.new_node) obj.clear_input(obj_pin) self.new_node.net.asimilate(obj.net) else: obj.assign_input(obj_pin, self.new_node, "Y") self.new_node = False self.solve_drawable() return target = self.get_net_line_pos([mouse_x, mouse_y], [self.new_node]) print "get_net_line_pos", target if target is not False: node1, node2, net = target node1.remove_sibling(node2) node1.add_sibling(self.new_node) node2.remove_sibling(node1) node2.add_sibling(self.new_node) self.new_node.net.asimilate(net) self.new_node = False self.solve_drawable() return self.new_node = False self.canvas.request_redraw() if event.type == pygame.MOUSEBUTTONDOWN and event.button == RIGHT: if self.new_node is not False: self.delete(self.new_node.name) self.new_node = False else: #delete node or split siblings or net if isinstance(hover_object, wire.Node): siblings = hover_object.net.list_node_sibling(hover_object) if len(siblings) > 0: successor = siblings[0] for node in siblings: successor.add_sibling(node) for k in hover_object.inputs: print "hover_object.input", k, hover_object, hover_object.inputs obj, pin = hover_object.inputs[k] successor.assign_free_input(obj, pin) target = self.find_output(hover_object, "Y") while target is not False: obj, pin = target obj.assign_input(pin, successor, "Y") target = self.find_output(hover_object, "Y") self.delete(hover_object.name) self.highlight(LIGHT_NONE) self.solve_drawable() return target = self.get_line_pos([mouse_x, mouse_y]) print "get_line_pos", target if target is not False: obj, obj_pin, inp, inp_pin = target obj.clear_input(obj_pin) self.highlight(LIGHT_NONE) self.solve_drawable() self.canvas.request_redraw() return target = self.get_net_line_pos([mouse_x, mouse_y], [self.new_node]) print "get_net_line_pos", target if target is not False: node1, node2, net = target node1.remove_sibling(node2) node2.remove_sibling(node1) net.rebuild() self.canvas.request_redraw() self.highlight(LIGHT_NONE) self.solve_drawable() return if event.type == pygame.MOUSEMOTION: if self.new_node is not False: self.new_node.set_pos(mouse_x, mouse_y) self.canvas.request_redraw() target = self.get_object_pos([mouse_x, mouse_y], [self.new_node]) # print "get_object_pos", target if target is not False: if isinstance(target, wire.Node): self.highlight(LIGHT_POINT, target.output_xy["Y"]); return target = self.get_input_pos([mouse_x, mouse_y], [self.new_node]) # print "get_input_pos", target if target is not False: obj, pin = target pos = obj.input_xy[pin] self.highlight(LIGHT_POINT, pos); return target = self.get_output_pos([mouse_x, mouse_y], [self.new_node]) # print "get_output_pos", target if target is not False: obj, pin = target pos = obj.output_xy[pin] self.highlight(LIGHT_POINT, pos); return target = self.get_line_pos([mouse_x, mouse_y], [self.new_node]) # print "get_line_pos", target if target is not False: obj, obj_pin, inp, inp_pin = target if isinstance(obj, wire.Node): start = obj.output_xy["Y"] else: start = obj.input_xy[obj_pin] if isinstance(inp, wire.Node): end = inp.output_xy["Y"] else: end = inp.output_xy[inp_pin] self.highlight(LIGHT_LINE, [start, end]) return target = self.get_net_line_pos([mouse_x, mouse_y], [self.new_node]) # print "get_net_line_pos", target if target is not False: node1, node2, net = target start = node1.output_xy["Y"] end = node2.output_xy["Y"] self.highlight(LIGHT_LINE, [start, end]) return self.highlight(LIGHT_NONE) if mode == MODE_ADD: if event.type == pygame.MOUSEBUTTONDOWN and event.button == RIGHT: self.add_index = (self.add_index + 1) % len(self.add_list) fcs = self.add_list[self.add_index] pos = "%dx%d" % (mouse_x, mouse_y) name = "_%s_" % fcs self.new_node = self.canvas.cells[fcs](self) self.new_node.update() self.new_node.middle_offset() self.new_node.parse([name, fcs, pos]) self.new_node.drawable = True self.canvas.request_redraw() if event.type == pygame.MOUSEMOTION: if self.new_node is not False: self.new_node.set_pos(mouse_x, mouse_y) self.new_node.clear_io_cache() self.canvas.request_redraw() if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT: o = self.add_object(self.add_list[self.add_index], [mouse_x, mouse_y]) self.apply_grid(o) if mode == MODE_ADD_MODULE: if event.type == pygame.MOUSEBUTTONDOWN and event.button == RIGHT: fcs = "module" pos = "%dx%d" % (mouse_x, mouse_y) name = "_%s_" % fcs self.new_node = self.canvas.cells[fcs](self) self.new_node.update() self.new_node.middle_offset() self.new_node.parse([name, fcs, pos]) self.new_node_filename = self.new_node.filename self.new_node.drawable = True self.canvas.request_redraw() if event.type == pygame.MOUSEMOTION: if self.new_node is not False: self.new_node.set_pos(mouse_x, mouse_y) self.new_node.clear_io_cache() self.canvas.request_redraw() if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFT: o = self.add_object("module", [mouse_x, mouse_y], [self.new_node_filename]) self.apply_grid(o)
class PopupEnemy(BaseEnemy): """ sprname = sprite key name in game.images array numFrames = number of sprite keys. the key is built like this: sprname + "_x" rotation = angle in degrees this sprite is rotated on each time before drawing flips = tuple of booleans indication whether or not the image/moving direction should be flipped/reversed area = the area in tiles around pos which triggers attack. like: (x_offset, y_offset, width, height) speed = defines attack speed and pulling back speed which is 1/4 of it """ def __init__(self, g, sprname,numFrames,animInterval, pos, rotation, flips, area, trouble, speed = POPUP_SPEED): def onCollision(g, s, a): self.hitDave = 1 if g.daveInTrouble(self.trouble): print "Ouch!" #todo, sound BaseEnemy.__init__(self,g, g.images[sprname + "_1"], pos) self.sprname = sprname self.animInterval = animInterval self.maxFrames = numFrames self.rotation, self.flips = rotation, flips self.orgRect = copy.copy(self.rect) self.area = Rect(self.orgRect.x + area[0] * TILE_SIZE, self.orgRect.y + area[1] * TILE_SIZE, area[2] * TILE_SIZE, area[3] * TILE_SIZE) self.hit = onCollision self.trouble = trouble self.popupSpeed = speed * difficultyMulStep(0.2) self.backupSpeed = self.popupSpeed / 4 self.posPercent = 1.0 #1.0 * random.random() self.moveDir = 0 #1 self.hitDave = 0 self.cdbgmsg = "" def dbgMsg(self,msg): if msg != self.cdbgmsg: print msg self.cdbgmsg = msg def loop(self, game, sprite): self.__move(game) self.__animate(game) def __animate(self, game): if ((game.frame % self.animInterval) == 0): self.anim_frame += 1 if (self.anim_frame > self.maxFrames): self.anim_frame = 1 if (self.anim_frame <= 0): self.anim_frame = self.maxFrames imageString = self.sprname + "_" + str(self.anim_frame) # if we flip the y then we must move adjust the rect.x if self.flips[1]: self.rect.x = self.orgRect.x + self.posPercent * self.orgRect.height - self.orgRect.height + TILE_SIZE else: self.rect.x = self.orgRect.x # clip part of the image img = transform.chop(game.images[imageString][0], Rect(0,0,0,self.posPercent * self.orgRect.height)) # apply flipping and rotation if required if self.flips[0] or self.flips[1]: img = transform.flip(img, self.flips[0], self.flips[1]) if self.rotation != 0: img = transform.rotate(img, self.rotation) self.setimage(img) def __move(self, game): if game.player == None: return if (self.moveDir == 0 or (self.moveDir == -1 and self.hitDave == 0)) and self.area.colliderect(game.player.rect): self.moveDir = 1 if self.moveDir == 1: self.posPercent -= self.popupSpeed if self.posPercent <= 0.0: self.posPercent = 0.0 self.moveDir = -1 elif self.moveDir == -1: self.posPercent += self.backupSpeed if self.posPercent >= 1.0: self.posPercent = 1.0 self.moveDir = 0 self.hitDave = 0
def is_onscreen(self): """test is screen.colliderect(actor) true?""" x,y = self.loc w,h = get_screen_size() screen = Rect(0, 0, w, h) actor = Rect(x, y, self.width, self.height) if screen.colliderect(actor): return True else: return False