2013-07-16 5 views
0

에 나는 for 루프를 통해 이와 유사한 실행 타일 맵이 있습니다삭제 스프라이트는 파이 게임

def Draw_Level(x, y, column, obsticles, entities, image_cache): 

    #Grass# 
    if column == "G": 
     g = Grass(x, y, image_cache) 
     entities.add(g) 
    #Plain Grass# 
    elif column == "P": 
     p = Plain_Grass(x,y, image_cache) 
     entities.add(p) 
    #Grass with yellow flower# 
    elif column == "F": 
     f = Grass_Flower(x,y, image_cache) 
     entities.add(f) 
    #Grass To Sand (50/50 split block) Direct# 
    elif column == "Y": 
     q = Grass_To_SandD(x,y, image_cache) 
     entities.add(q) 

#Example If a class 
class Grass(Entity): 

    def __init__(self, x, y, image_cache): 
     Entity.__init__(self) 
     self.image = functions.get_image("data/images/Grass.png", image_cache) 
     self.image.convert() 
     self.rect = Rect(x, y, 32, 32) 

는 말, 예를 들어, 내 마우스는이 중 하나는 x에 클릭 한 y는로 결정 하였다 가장 가까운 32 (블록의 폭과 높이). 스프라이트가 클릭 된 것을 어떻게 알 수 있습니까? 예를 들어 잔디 블록이 화면에 그려지는 좌표가있는 "잔디 블록"을 클릭 한 경우 어떻게 제거합니까?

Entites 모든 개체

나는 개체의 목록에서 호출 할 수있는 방법이 있나요

을 들고 목록을 =? 그것은 List를 통해 List를 호출하는 것을 혼란스럽게합니다. 그래서 나는 갇혀 있습니다 : S.

답변

2

당신이하고 싶은 것을 "히트 탐지"또는 "hit-testing"이라고합니다. 코드의 경우 엔티티 목록을 살펴보고 각 마우스가 차지하는 사각형의 범위에 대해 마우스 클릭의 x, y 위치를 확인해야합니다.

각 클래스를 만들면 hit_test(self, x, y) 메서드를 추가하여 각각에 대해 호출 할 수 있습니다. 이 줄의 어떤 것 :

class Grass(Entity): 
    def __init__(self, x, y, image_cache): 
     Entity.__init__(self) 
     self.image = functions.get_image("data/images/Grass.png", image_cache) 
     self.image.convert() 
     self.rect = Rect(x, y, 32, 32) 
    def hit_test(self, x, y): 
     return (self.rect.x <= x < self.rect.x+self.rect.width and 
       self.rect.y <= y < self.rect.y+self.rect.height) 
+0

감사합니다. 나는 그것을 얻을 수 있었다. 또한 적중 테스트에 대한 정보를 제공해 주셔서 감사합니다. – ReallyGoodPie

+1

당신을 진심으로 환영합니다. 이것은 x와 y 경계를 사전 계산하여 Entity에 저장함으로써 가속화 될 수 있음에 유의하십시오. 마찬가지로, 마우스 x, y가 (가상의) 바운딩 박스 (바운딩 박스)의 바깥에있는 경우, 그 중 하나라도 선택하지 않고 함께 쌓인 전체 그룹에 동일한 로직을 적용 할 수 있습니다. 이것은 "사소한 거부"(http://www.expertsmind.com/questions/trivial-rejectioncase-of-cohen-sutherland-line-clipping-30149795.aspx)라고하며 라인 클리핑에 사용됩니다 . – martineau

2

rect.collidepoint을 사용하면 마우스 커서가 rect 안에 있는지 확인할 수 있습니다.

entities_the_mouse_is_over = [entity for entity in entities if entity.rect.collidepoint(mouse_x, mouse_y)] 

이 접근법을 사용하려면 반올림 알고리즘을 다시 고려하십시오. mouse_x 또는 mouse_y 중 하나를 32로 반올림 한 경우에는 작동하지 않습니다. 예를 들어 타일에 (0,0,32,32)의 rect가 있고 사용자가 (20,20)을 클릭한다고 가정합니다. mouse_xmouse_y은 (32,32)로 반올림되며 collidepoint까지는 rect (0,0,32,32) 안에 있지 않습니다.

으로 반올림 한 경우 collidepoint이 작동합니다. 앞의 예에서 (20,20)은 rect (0,0,32,32) 안에있는 (0,0)으로 반올림됩니다.

전혀 반올림하지 않을 수도 있습니다.