좋은 사람의 공격은 어떻게 나쁜 사람을 때리는가?


11

내 게임에는 다양한 유형의 좋은 사람과 많은 다른 유형의 나쁜 사람이 있습니다. 그들은 모두 서로 발사체를 발사하지만, 어느 쪽 정렬에 대해서도 우발적 인 부수적 피해는 원하지 않습니다. 따라서 나쁜 녀석은 다른 나쁜 녀석을 때리거나 손상시킬 수 없어야하며 좋은 녀석은 다른 좋은 녀석을 때리거나 손상시킬 수 없어야합니다.

내가 이것을 해결하려고 생각하는 방법은 Unit인스턴스 (이것은 자바 스크립트, btw)가 또는 일 alignment수 있는 속성을 갖도록 만드는 것 입니다. 그리고 충돌이 발생할 경우에만goodbad

class Attack

    boolean didAttackCollideWithTarget(target)
        return attack.source.alignment != target.alignment and collisionDetected(attack.source, target)

이것은 물론 의사 코드입니다.

그러나 Unit클래스에 또 다른 속성을 추가하는 것 외에도이를 디자인하는 훨씬 더 우아한 방법이있을 수 있기 때문에이 질문을하고 있습니다 .


5
필터링은 일반적인 접근 방식입니다. 본질적으로 그것은 당신이 묘사 한 것입니다. 레이어도 있습니다. 나쁜 레이어와 좋은 레이어의 두 레이어. 나쁜 녀석 발사체는 좋은 층으로 발사되고 그 반대도 마찬가지입니다.
MichaelHouse

@ Byte56이 "계층"개념에 대해 자세히 설명해 주시겠습니까? 아니면 적어도 그것에 대해 뭔가를 링크? 전에는 들어 본 적이 없습니다.
Daniel Kaplan

본질적으로 그들은 "세계"가 다릅니다. 레이어의 모든 객체는 서로 상호 작용하지만 다른 레이어와 상호 작용하지는 않습니다. 이것은 필터링과 같은 태그를 사용하거나 각 레이어에 대해 완전히 다른 데이터 세트를 사용하여 수행 할 수 있습니다.
MichaelHouse

3
한마디로, 그것은 그룹화입니다. 좋은 총알을 그룹화하고 나쁜 사람과의 충돌 만 확인하십시오. Flixel은 이와 같은 개념을 가지고 있습니다.
ashes999

3
하나의 nitpicky 디자인 노트 : 당신은 '친절한 사격'샷을 치기를 원 하지만 손상을 입히기를 원합니까, 아니면 아군을 완전히 무시하고 대신 통과하여 적을 때리기 를 원합니까?
Steven Stadnicki

답변:


6

충돌 필터링

많은 계층으로 확장되는보다 강력한 상황은 필터링을 사용하는 것인데, 이는 그룹화와 동일하지 않습니다.

이것은 모든 객체에 2 비트 마스크 를 제공함으로써 가장 잘 작동합니다 .

Category
Mask

아래에 해당하는 경우에만 충돌을 트리거하십시오.

(filterA.maskBits & filterB.categoryBits) != 0 &&
(filterA.categoryBits & filterB.maskBits) != 0;

마스크를 0xFFFF로 기본 설정하는 것이 가장 쉬워 모든 것과 충돌합니다. 그리고 기본 카테고리는 0x0001입니다. 다른 마스크의 범주와 개체가 충돌하면 충돌이 발생합니다.

그것을 생각하는 또 다른 방법은 각 객체가 유형과 충돌 할 수있는 모든 유형의 목록을 가지고 있다는 것입니다. 두 객체가 서로 유형과 충돌 할 때만 충돌이 발생합니다. 마스크 대신 열거 형 목록을 사용하지만 마스크를 10 배 빠른 속도로 동일한 동작을 수행 할 수 있습니다.

설명하는 시나리오

이 상황에서 열거 형을 활용하고 싶습니다.

우리가 있다고 말해

enum Categories {
    GoodGuy =           0x0001,
    BadGuy =            0x0002,
    Bullet =            0x0004,
    GlassWall =         0x0008,
    Lazer =             0x0010,
    All =               0xFFFF
};

좋은 사람이 총알

 Category = Bullet
 Mask = BadGuy | GlassWall

좋은 녀석들

 Category = GoodGuy
 Mask = All

나쁜 녀석들

 Category = BadGuy
 Mask = All

좋은 사람이 총알을 쐈을 때 다른 좋은 사람을 때리는 결과는 다음과 같습니다.

(All & GoodGuy) != 0 && <-- Passes
(GoodGuy & (BadGuy | GlassWall)) != 0; <-- This would fail

그러나 그것은 나쁜 사람을 때릴 것입니다.

(All & BadGuy) != 0 && <- Passes
(BadGuy & (BadGuy | GlassWall)) != 0; <-- Passes

비트 산술의 하위 수준에서 설명하는 대신 개념적으로 설명 하시겠습니까 ?
Daniel Kaplan

@tieTYT 5 분 후에 다시 확인하십시오
ClassicThunder

2

현재 프로젝트 (Java)에서 동일한 문제가 발생했습니다. 몇 번의 시도 후에 네 개의 목록을 만들어 해결합니다. 이 솔루션은 Java 및 2D 게임용으로 작성되었지만 유사한 방식으로 JavaScript에서도 작동해야합니다.

public static main (String [] args)
{
    private List<Bullets> bullets_GoodGuys = new LinkedList <Bullet>(); //List of all bullets fired by good guys
    private List<Bullets> bullets_BadGuys  = new LinkedList <Bullet>(); //List of all bullets fired by bad guys
    private List<Guys> goodGuys  = new LinkedList <Guys>(); //List of all good guys
    private List<Guys> badGuys  = new LinkedList <Guys>();  //List of all good guys

    init();
    ...
    while(game_is_running)
    {
        ... 
        for(int i=0;i>=goodGuys.length;i++)
        {
            for(int j=0;j>=bullets_BadGuys.length;i++)
            {
                if(goodGuys.get(i).getBounding().interacts(bullets_BadGuys.get(i).getBounding()))
                {// If a good guy was hit by a bullet from a bad guy
                    goodGuys.get(i).getDamage();
                    bullets_BadGuys.remove((bullets_BadGuys.get(i));
         }   }   }
       for(...) //same for the bad guys
       {...}
}

의사 코드

class Guys
{
   private float xkoordinate;
   private float ykoordinate;
   private BufferedImage look;
   private Rectangle bounding = new Rectangle(xkoordinate,ykoordinate,look.getWith(),look.getHight())
   ...
}

총알 클래스와 동일한 의사 코드

이것은 최선의 해결책이 아닐 수도 있지만 현재 도움이 될 것입니다. JavaScript로 솔루션을 제공 할 수 없어서 죄송하지만 도와 드릴 수 있기를 바랍니다.

그건 그렇고 내 영어가 최고는 아니지만 내 설명을 따를 수 있기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.