[Java] 원의 좌표 범위

델버·2022년 5월 19일
0

Java

목록 보기
3/8

Java swing에서 목표물이 생기면 클릭하여 죽이는 게임을 만든다고 하자. 클릭하여 죽는 기능을 만들 때, 네모네모하게 생긴 목표물이면 JButton으로 ActionListener를 연결하여 만들 수 있다. 혹은 JPanel이면 좌표값을 쉽게 구해 사용자 클릭값과 Panel의 좌표값을 비교하면 된다.
그런데 목표물이 동글동글하면? 그때 좌표값을 어떻게 구하는가와 사용자가 누른 좌표값을 원의 중심과 어떻게 비교하는가이다.



// 원 좌표 범위 포함
if (Math.pow(R, 2) > (Math.pow(X - TX, 2) + Math.pow(Y - TY, 2))) { 포함 = true; }
// 원 경계까지 포함
if (Math.pow(R, 2) >= (Math.pow(X - TX, 2) + Math.pow(Y - TY, 2))) { 포함 = true; }

기본적인 좌표와 좌표의 거리를 구하는 공식을 알아야 풀 수 있다. 사용자가 클릭한 값이 B(3,3)라고하고 (A여도 상관없다), 원의 중심이 A(1,1)라고 하자. 위 공식으로 풀면 AB 거리 값이 루트 8가 나온다.
그리고 원의 반지름이 2(루트 4)라고 하면, AB 거리값 > 원의 반지름이 된다. 만약 사용자가 원의 범위 안에 클릭 했을 경우 원의 반지름이 원의 중심으로부터 사용자가 클릭한 좌표값보다 클 것이다.

그 원리를 이용해 만든 조건문이 바로 위에 두 줄이다.

  • Math.pow()는 거듭 제곱(exponentiation)이다.

ActionListener를 만든다고 하면

사용자의 클릭 좌표값과 원의 중심 좌표값을 비교해 원 안에 포함되었는지 물어, 포함되면 "포함!"이 출력되는 문구를 만들 수 있다.

int userClick_X ;
int userClick_Y ;
int circle_X ;
int circle_Y ;
int circle_radius ;
new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				if (Math.pow(circle_radius, 2) >= (Math.pow(circle_X- userClick_X, 2) + 
						Math.pow(circle_Y - userClick_Y, 2))) 
						{ 
							System.out.println("포함!"); 
						}
			}				
}
  • 하지만 이 모든 과정을 하기 전에 고려해야 될 게 있다.
    첫 번째, 과연 사용자의 클릭 좌표값을 어떻게 구할 것인가?
    Panel을 누르게 되면 아마 사용자의 좌표값이 Panel 안의 좌표값으로 나올 것이다.
    방법은 두 가지다. 하나는 배열에 목표물의 중심값을 넣어놓고, 화면에 MouseListener를 연결한 투명 Panel을 덧붙인다. 사용자는 클릭할 때 Panel의 좌표값, 즉 전체 화면의 좌표값을 얻고 원의 중심값이 담긴 배열과 하나씩 비교하면된다.
    다른 하나는 애초에 목표물을 원으로 만들지 않는 것이 좋다...

  • 또한 더 큰 문제는 Panel 자체를 원으로 만들면 간단히 해결이 되지만 그러기 힘들다는 것이다(Button도 마찬가지). Button같은 경우, 원으로 만들 수 있으면 앞 공식 없이 그냥 ActionListener를 넣어주면 된다. 하지만 원 자체를 만들기 힘드니 수학 공식으로 푸는 수밖에 없다. Panel을 사각형으로 놔두고 이미지를 원으로 만들어도 테두리는 남아있어, 만약 목표물과 목표물이 겹치게 되어 테두리를 클릭했을 경우 뒤에 목표물이 아닌 앞 목표물의 테두리로 인식하게 된다. 그러면 정확한 클릭을 했어도 버그가 나는 상황이 나온다.


이 고민들은 게임 프로젝트하면서 겪은 시행착오였다. 결국 우리 팀이 택한 방법은 목표물을 사각형으로 만드는 것이었다...하지만 이것으로 너무 많은 걸 배웠고 공부했다. 어떤 기능을 만들 때 여러 가능성을 생각하는 것, 사용자가 테두리를 연타하는 상황을 미리 아는 것.


참고

https://blog.naver.com/PostView.nhn?blogId=dnflrkwhr888&logNo=221003832228&parentCategoryNo=&categoryNo=66&viewDate=&isShowPopularPosts=true&from=search

https://dundung.tistory.com/152

0개의 댓글