NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • NGM 6
  • 매뉴얼

    NGM 6

    본 사이트의 컨텐츠는 저작권법의 보호를 받으므로 무단 복사, 게재, 배포 등을 금합니다.

    커스텀 캐릭터와 몬스터 거리 계산해서 공격 또는 스킬 사용하는 커스텀 액션 만들기.

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 오늘은 커스텀 모듈을 이용해서 캐릭터와 몬스터간의 거리를 알아내는 방법을 알아보도록 하겠습니다. 커스텀 모듈이 아니더라도 캐릭터와 몬스터의 거리를 계산해서 어떤 동작을 수행하는 방법은 쉽게 만들 수 있습니다. 엔지엠 매크로 순정 액션으로 만드는 방법은 아래 글을 참고 해보세요.

    미니맵에서 내 케릭터와 목표 지점 거리를 계산해서 이동시키는 방법 ]

     

    자~ 이제 커스텀 모듈을 만들어볼까요? 커스텀 모듈 개발 환경은 갖춰져 있겠죠? 아직 개발 환경이 없다면 아래 글들을 참고하세요^^

    커스텀 모듈 개발 환경 만들기 ]

    1부 - 커스텀 모듈로 이미지 서치 액션 만들기 ]

    2부 - 커스텀 모듈로 이미지 서치 액션 만들기 ]

    3부 - 커스텀 모듈로 이미지 서치 액션 만들기 ]

     

    Visual Studio Community를 실행하고, 아래와 같이 조건을 상속 받으세요. 캐릭터와 몬스터의 거리를 계산해서 공격이나 스킬을 쓸 수 있는 위치라면 액션을 이동해서 키보드나 마우스 클릭을 해야 합니다. 그래서, 조건 액션으로 만드는게 좋을거 같네요. 카테고리명은 "조건"이고, 액션명은 "거리 체크"입니다.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CustomImageSearch
    {
        [Serializable]
        public class CustomDistanceCalculationModel : NGM.Models.Interface.BaseCustomConditionToolModel
        {
            public override string DisplayCategory => "조건";
    
            public override string DisplayName => "거리 체크";

     

    실제로 캐릭터와 몬스터의 거리를 계산한 결과 값을 표시해주는 속성(Property)입니다.

            [Category("Data")]
            [DisplayName("떨어진 거리")]
            [Description("캐릭터와 몬스터의 거리 결과 값입니다.")]
            [Browsable(true)]
            [DefaultValue(0)]
            public int Result { get; set; }

     

    캐릭터와 몬스터 이미지를 선택하기 위한 속성인데요. 여기에는 처음보는 속성이 추가되어 있습니다. NGM.Models.TypeConverter.ImageConverter 특성입니다. 이 특성은 자동으로 엔지엠 매크로의 이미지 폴더에서 ngi 이미지들을 목록화해서 사용자에게 표시 해줍니다.

            [Category("Action")]
            [DisplayName("캐릭터")]
            [Description("캐릭터 이미지를 선택하세요.")]
            [Browsable(true)]
            [DefaultValue(null)]
            [TypeConverter(typeof(NGM.Models.TypeConverter.ImageConverter))]
            public string Character { get; set; }
    
            [Category("Action")]
            [DisplayName("몬스터")]
            [Description("몬스터 이미지를 선택하세요.")]
            [Browsable(true)]
            [DefaultValue(null)]
            [TypeConverter(typeof(NGM.Models.TypeConverter.ImageConverter))]
            public string Monster { get; set; }

     

    캐릭터와 몬스터의 거리가 얼마나 떨어지면 같음(True)로 처리할지 조건 값을 입력 받는 속성을 하나 추가하세요. 생각 같아서는 X와 Y 그리고, XY를 모두 체크할 수 있도록 만들면 좋겠다는 생각을 해봅니다. 화면에서 거리가 가깝다는 것은 가로, 세로가 다를 수 있으니까요.

            [Category("Action")]
            [DisplayName("체크 거리")]
            [Description("캐릭터와 몬스터의 거리를 체크할 값을 입력하세요. 이 값보다 떨어진 거리가 작으면 같음(True)으로 처리됩니다.")]
            [Browsable(true)]
            [DefaultValue(0)]
            public int DistanceValue { get; set; }

     

    마지막으로 로직을 만들어 볼께요. 내용이 좀 복잡해 보일수도 있는데요. 이미 학습했던 내용들에서 몇가지만 추가한거예요.

            public override bool? Execute()
            {
                Bitmap target = null;
                Image characterImage = null;
                Image monsterImage = null;
    
                try
                {
                    target = new Bitmap(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height);
    
                    using (Graphics graphics = Graphics.FromImage(target))
                        graphics.CopyFromScreen(0, 0, 0, 0, target.Size);
    
                    characterImage = NGM.Models.Common.Reflection.GetNgmImage(MainView.CurrentScriptView.Player, $"{Character}.ngi");
                    monsterImage = NGM.Models.Common.Reflection.GetNgmImage(MainView.CurrentScriptView.Player, $"{Monster}.ngi");
                    var character = NGM.Utility.ImageManager.ImageCondition.IsFind(characterImage, target);
                    var monster = NGM.Utility.ImageManager.ImageCondition.IsFind(monsterImage, target);
    
                    Result = Math.Abs(character.X - monster.X);
                    return DistanceValue > Result;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    return null;
                }
                finally
                {
                    target?.Dispose();
                    characterImage?.Dispose();
                    monsterImage?.Dispose();
                }
            }

     

    위 코드의 비즈니스 로직은 간단합니다. 첫번째 이미지와 두번째 이미지를 가져와서 윈도우 화면 이미지(target)에서 어디 위치에 있는지를 먼저 알아냅니다. 그리고, 캐릭터와 몬스터 이미지 위치를 X축으로 거리를 계산합니다. 이 때 기준이 되는 위치에서 몬스터가 상하좌우에 위치할 수 있기 때문에 마이너스 값이 나올수도 있습니다. 그래서, 절대값으로 변환한 후 결과를 저장하도록 했습니다.

     

    커스텀 모듈을 빌드한 후 배포하세요. 그리고, 테스트용 그림을 하나 만들었습니다. 드래곤 몬스터성기사 캐릭터입니다.

    CTA1gjJ.jpg

     

     

    이 둘의 위치를 확인하기 위해 각각 이미지를 캡쳐해서 저장했습니다.

    v8vgG5S.jpg

     

     

    엔지엠 매크로 에디터에서 새로운 스크립트를 만들고, 아래와 같이 액션들을 구성 했습니다. 커스텀 액션인 거리 체크는 캐릭터 속성과 몬스터 속성에 각각 이미지를 선택 해줘야 합니다. 그리고, 거리 계산에 사용될 값으로 체크 거리에 100을 입력 했습니다.

    lw2PHL1.jpg

     

     

    메세지 박스 a와 메세지 박스 b는 거리가 가까우면 공격 또는 스킬을 사용한다는 걸 시각화 하기 위해 추가한 개념적인 액션입니다. 거리가 멀면 몬스터쪽으로 이동해야 하기 때문에 메세지 박스 b는 이동으로 되어 있습니다. 그리고, 무한 반복하도록 로직을 구성했습니다.

    QRQ3w3b.jpg

     

     

    완성된 매크로를 실행 해볼까요? 아래와 동영상과 같이 캐릭터가 이동할 때마다 거리가 가까워져서 몬스터를 공격하거나 스킬을 사용합니다. 거리가 멀면 또다시 이동합니다.

     

     

    간단하게 몬스터와 캐릭터의 거리를 어떻게 처리해야 하는지 알아봤습니다. 여기에서 추가적으로 Y 좌표도 계산해서 위 아래로 줄을 타고 이동하거나 사다리를 이용하면 효과적일겁니다. 이외에도 대각선을 판단하기 위해 XY를 같이 계산할수도 있습니다. 게임이나 업무에 따라서 로직은 수정해서 사용하면 됩니다. 커스텀 모듈을 이용하면 정말 많은 것들을 쉽고 빠르게 처리할 수 있습니다. 다만, 러닝커브가 크다보니 쉽게 접근할 수 있는 기술은 아닙니다. 시간+노력으로 좋은 결과물을 만들어 낼 수 있으면 좋겠네요^^

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.