|
안녕하세요.
Timer 대신 Thread를 쓰는 방법이 있습니다. Thread는 Timer보다 세심하게 프로그래밍 할 수 있으며,
실행 우선 순위도 지정할 수 있습니다. 따라서 말씀하신 최소 Timer Interval 보다 더 빠른 Tick을
가질 수 있습니다. (Tick이라기 보다 같이 돌아간다는 개념이 맞을 듯 싶군요)
하지만 Timer의 Interval이 1로도 잘 돌아가지 않았던 것이 Thread에서 부드럽게 돌아갈 이유는
없습니다. 그리고 이런 루틴에서는 Timer나 Thread를 사용하시는 것보다, 잘 안되더라도 이벤트를
이용하시는 것이 더욱 좋다고 생각합니다.
또한 CM_MOUSEENTER와 CM_MOUSELEAVE에 모든 이벤트를 의존하는 것은 별로 좋지 않습니다. 빠르게
움직여서 다른 이벤트가 거의 비슷하게 발생되거나 ShowMessage, MessageDlg 같은 우선권을 가진
Modal Dialog가 나타나면, 이 때는 이벤트를 발생하지 않게 됩니다. (당연한 결과겠지만, 예외가
생길 수 있다는 것을 염두해 두고 프로그래밍을 해야한다고 생각합니다)
추천하는 방법으로는 이전에 생각하신 OnMouseMove를 추천해 드립니다. 동적으로 이미지를 생성
하시는 것 같은데, 동적으로 생성하신다 하더라도 생성을 시킨 후, 이벤트를 다시 지정해 주어
똑같은 이벤트를 발생시킨다면 문제가 되지 않을 것 같습니다.
아래 소스는 OnMouseMove에 해당하는 이벤트 입니다. 폼에도 설정하시고, 이미지에도 이 함수로
설정을 해두시면 됩니다. (폼 위에 있는 모든 객체의 이벤트를 아래 함수로 지정해 두시면 됩니다)
간단히 설명하자면, 마우스의 좌표를 읽고 Image1가 마우스를 따라 다니게 해 둔 소스입니다.
GetCursorPos에서 읽혀지는 좌표중에 Y 좌표는 Title Bar가 있을 경우 그 Height까지 계산되어
연산되므로 적당한 수 (약 25정도) 를 빼준 뒤 연산을 해주시는 것이 좋겠습니다.
void __fastcall TForm1::LocateImage(TObject *Sender, TShiftState Shift, int X, int Y)
{
POINT poPosition;
int itX, itY;
if(GetCursorPos(&poPosition)) {
itX = poPosition.x - Form1->Left;
itY = poPosition.y - Form1->Top;
Image1->Left = itX;
Image1->Top = itY;
}
}
김정훈 님이 쓰신 글 :
: MOUSEENTER 메세지와 MOUSELEAVE 메세지를 사용해서 폼안에 들어와있나없나를
: 플래그로 해서 체크해두고 폼안에 들어와있는 상태이면 무조건 실행하고 싶은데요.
: 타이머를 쓰니 윈도우안에서 ONPAINT가 계속 동작해서 그런지 몰라도 마우스를 폼안으로
: 오면 타이머가 작동이 안하는군요. 타이머 말고 그냥 계속 작동하게 할 수 없나요?
:
: 혹시라도 더 좋은 답변을 얻을 수 있을까해서 자세하게 제 상황을 올리겠습니다 ㅠ.ㅠ;
: 일단 전 빌더로 게임 스테이지 에디터를 만드려고 합니다.
: 폼위에는 클라이언트영역크기의 배경그림이 덮혀져 있습니다(Timage)
: 라디오체크메뉴에서 적종류를 선택하면 마우스를 따라서 적그림이 움직이고
: 마우스를 클릭하면 스테이지위에 적(Timage생성)이 찍히는 식입니다.
:
: 처음에는 Form에서의 MouseMove에서 처리하려고 했지요.
: 근데 클라이언트영역전체를 배경그림(Timage)가 덮고 있어서 안되더군요.
: 그래서 배경그림(Timage)에 대한 MouseMove처리를 했지요.
:
: 잘되는듯 싶었으나 문제가 있더군요. 일단 마우스끝점을 적그림(Timage2)의 Top,Left가 되서
: 마우스를 따라다니는데.그래서 마우스가 왼쪽이나 아래로 가면 이번엔 MouseMove가
: Timage2로 넘어가버리는것입니다. 이것만이라면 어떻게 참을 수 있을지 모르겠지만
: 몬스터를 배경에 찍다보면 배경위에 Timage 투성일텐데 이래서야 배경그림에 대한 MouseMove
: 처리는 불가능하다고 생각되더군요.
:
: 그래서 계속 헤메이다가 여길 찾게되어서 FAQ에 CM_MOUSEENTER와 CM_MOUSELEAVE 메세지를
: 받아서 쓰는 법을 알게되었습니다. 그래서 CM_MOUSEENTER일때 처리를 하려고 했더니
: 이게 계속 호출되는게 아니고 마우스가 밖에서 안으로 들어올때만 메세지가 들어오는거 같더군요 ㅠ.ㅠ
:
: 그래서 위에 맨위에 질문한 타이머까지 써보았지만 이건 너무 느린거 같더군요--;
: (인터벌을 1로해도;)
:
: 타이머가 아닌 루프를 쓰고 싶은데 API에선 게임짤때 Idle타임을 이용하는거던가요?
: (초보라 짜놓고도 잘 모르겠음-_-;)
: 어쨋든 어떻게든 루프로 돌렸으면 좋겠는데..아아- 무슨 해결책없을까요?
:
: 결국 이 프로그램이 뭐하는 놈이냐면 마우스로 적 찍으면 적의 좌표와 종류를
: 저장해주고(링크드리스트로 만들예정) 읽어들일수도있고 편집기능인데.
: 이것땜에 몇일 해메고 있어요ㅠ.ㅠ;
: 아마추어게임팀에서 프로그래머가 저뿐인데 팀원들이 재촉하진 않지만
: 저땜에 자꾸 미루어져서 너무 부담스럽네요.
:
: 고수님들 도움을 주세요!ㅠ.ㅠ
:
|