def collides(hcol,hrow,C,r,v=Vec(0,0),detail=COLLIDE_BBOX,debug=False): """ Collision test: hcol,hrow : hexagon grid coordinates C : circle centre r : circle radius v : circle velocity vector detail: level of collision detail required (see module doc) """ H = h_centre(hcol,hrow) v = Vec(v) C0 = Vec(C) - H C1 = C0 + v left,right = C1.x - r, C1.x + r top,bot = C1.y + r, C1.y - r bbtest = left < 1 and right > -1 and bot < 1 and top > -1 if not bbtest: return False if detail == COLLIDE_BBOX: return True circletest = C1.length() < (1 + r) if not circletest: return False if detail == COLLIDE_CIRCLE: return True # Push the circle away past the edge of the bounding # circle of the hexagon n = C1.normalise() C2 = n * (1+r) if detail == COLLIDE_POSITION: return C2 + H # Find hexagon normal nearest to the direction of the circle nx,ny,_ = n dots = sorted((v.dot(n),i) for (i,v) in enumerate(H_NORMAL)) _,i = dots[-1] # Real normal at hexagon side... n = H_NORMAL[i] # Calculate bounce vector... # Portion of intended distance still to travel speed = v.length() v1 = C2 - C0 remainder = max(0.01,speed - v1.length()) # Midpoint M is above the collision point M = C2 - v1.proj(n) # C3 is opposite C0 through the midpoint M C3 = C0 + (M - C0)*2 # Direction v2 = (C3 - C2).normalise() C2 += v2 * remainder return C2 + H, v2 * speed
def on_collision(self,what,where,direction): if isinstance(what,graphics.Ball): self.harm_type = "provoked the" sounds.play("rumble") self.hunt(what,where,0.9) elif isinstance(what,graphics.Player): self.eat(what,direction) sounds.play("bellow") else: r = self.velocity.length() to_player = Vec(self.player.pos) - self.pos if to_player.dot(direction) > 0: # facing towards player... direction = to_player.normalise() * r if random.random < 0.2: sounds.play("rumble") self.pos = where self.turn_to(direction)