기사 출처: 컴퓨터 매니아 저자: Zhang Jian
<마지막 날>에서 엘프처럼 헐리우드의 교통 체증을 헤쳐나갔던 미니쿠퍼를 아직도 기억하시나요? 마크 월버그(Mark Wahlberg)와 샐리 테론(Sally Theron)은 이를 이용해 수천만 가치의 금을 적의 코앞으로 운반했습니다. 하지만, 지금 빠르게 달리지 못하는 미니쿠퍼 차체가 당신 앞에 놓여 있다면 어떻게 생각하시겠습니까? 아직도 방황하는 엘프인가요? 오늘은 이 미니쿠퍼의 부품을 하나씩 조립해서 작동시켜 보겠습니다.
머리말
이번 호부터 전체 게임 소스 코드를 제공합니다(다운로드하려면 클릭하세요). Java Cafe는 모든 사람이 이론과 실습에 동등한 관심을 기울일 것을 주장합니다. 시리즈에서 핵심 기술과 구현 아이디어를 소개합니다. 마치 신문을 읽으면서 커피를 마시는 것처럼 친구들이 기사와 함께 소스 코드를 읽을 수 있습니다. 디디의 향기가 고갈되지 않는 곳이다.
게임 레이아웃
"Lianliankan"은 2차원 체스 게임입니다. 체스 게임을 디자인하려면 GridLayout이 최선의 선택입니다. 이제 GridLayout의 생성자를 살펴보겠습니다.
・GridLayout(): 기본적으로 레이아웃 영역은 1*1 크기로 분할됩니다.
・GridLayout(int 행, int cols): 레이아웃 영역의 가로 및 세로 그리드 수를 지정합니다.
・GridLayout(int 행, int cols, int hgap, int vgap): 위와 동일하며 각 그리드 사이의 가로 간격 hgap 및 세로 간격 vgap도 지정합니다.
사실 이 세 가지 생성자를 겁내지 마세요. 실수로 "잘못된" 생성자를 사용하더라도 나중에 조정할 수 있는 방법이 있습니다. 주목해야 할 유일한 점은 GridLayout에 컨트롤을 추가할 때 기본 순서는 왼쪽 위에서 오른쪽 아래로라는 것입니다.
이제 게임의 그리드 수를 결정해 보겠습니다. 몇 개의 그리드가 적합합니까? 너무 적으면 게임이 덜 어려워지고, 너무 많으면 시각적 영향이 커집니다. 따라서 나중에 수정하고 싶어도 한 쌍의 상수를 통해 표현해야 합니다.
Java에서는 상수 정의를 public final static 형식으로 작성해야 합니다. 게임 보드에 가로 8개 그리드, 세로 8개 그리드가 있다고 규정하면 다음과 같이 정의해야 합니다.
공개 최종 정적 int ROW = 8;
공개 최종 정적 int COLUMN = 8;
그런 다음 GridLayout의 두 번째 생성자를 사용하여 레이아웃을 만듭니다.
GridLayout GridLayout = new GridLayout(ROW, COLUMN);
마지막으로 게임 영역(contentPanel)의 레이아웃도 위 레이아웃으로 변경해야 합니다.
contentPanel.setLayout(gridLayout);
이때 프로그램을 컴파일하고 실행해 보면 '왜 인터페이스에 변화가 없는 걸까?'라는 의문이 들 수도 있다. 레이아웃을 지정했지만 컨트롤이 추가되지 않았으므로 당연히 변경 사항도 볼 수 없습니다. 이제 레이아웃에 버튼을 추가해 보겠습니다.
for (int i = 0; i < ROW * COLUMN; i++) {
JButton 버튼 = new JButton("쿄다이");
contentPanel.add(버튼);
}
프로그램을 다시 실행해 보세요. 내 것과 같은가요(그림 1 참조)?
소란을 피우기 위해 JButton을 영리하게 사용
JButton은 Swing에서 매우 일반적인 컨트롤이기도 합니다. 그러나 JButton을 능숙하게 사용할 수 있게 되면 다른 Swing 컨트롤을 찾을 수 있기 때문에 이를 이해하고 사용하려면 약간의 노력이 필요합니다. 또 너무 비슷해요.
방금 작성한 프로그램을 실행해 보면 게임 영역의 버튼이 항상 꽉 차 있는 것을 발견하게 되는데, 이는 실제 게임 운영에 매우 불편하므로 일부 그리드를 비울 수 있는 방법을 찾아야 합니다. GridLayout 레이아웃은 모두 좋지만 컨트롤을 추가할 때 특정 그리드를 건너뛸 수 없습니다. 이제 어떻게 해야 합니까?
사실 이것은 어렵지 않습니다.GridLayout은 건너뛰기를 허용하지 않기 때문에 특정 그리드에 추가된 컨트롤을 GridLayout 레이아웃의 배경과 통합하면 일관된 시각적 효과를 얻을 수 있습니다. 또한 다른 사람이 실수로 이 그리드를 클릭하면 버튼이 계속 노출됩니다. 버튼이 클릭되지 않도록 하는 방법을 찾아야 하며 이를 위해서는 JButton의 setEnabled() 메서드를 사용해야 합니다. 마지막으로, 클릭 가능한 버튼의 경우 클릭할 때 어떤 버튼이 클릭되었는지 구별해야 합니다.
지난번에 "About" 함수를 구현했을 때 e.getSource() 메서드를 사용하여 마우스 클릭 이벤트의 소스를 확인했지만 이는 명명된 컨트롤에만 효과적이었습니다. 여기서는 배열을 사용하여 버튼을 나타내는 것이 의심할 여지 없이 가장 좋은 방법입니다. 먼저 위의 코드를 수정해 보겠습니다.
JButton[] dots = new JButton[ROW * COLUMN];
for (int i = 0; i < ROW * COLUMN; i++) {
dots[i] = new JButton("쿄다이");
dots[i].setActionCommand("" + i);
contentPanel.add(dots[i]);
dots[i].addActionListener(this);
}
루프 본문에 dots[i] = new JButton("Kyodai")을 작성하는 것을 잊지 마십시오. 도트 그룹 번호가 이전에 정의되고 사용되었지만 이는 일부 JButton을 사용해야 한다는 것을 프로그램에 알려줄 뿐입니다. JButton이 아직 초기화되지 않았습니다. 동시에 setActionCommand()를 사용하여 버튼의 이벤트 이름을 지정할 뿐만 아니라 addActionListener() 메서드를 사용하여 각 버튼에 이벤트 응답 처리를 추가합니다.
이벤트 응답 코드와 관련하여 원래 actionPerformed() 이벤트 코드 뒤에 추가할 수 있습니다.
if (e.getSource() JButton 인스턴스) {
JButton 버튼 = (JButton) e.getSource();
int offset = Integer.parseInt(button.getActionCommand());
int 행, 열;
행 = Math.round(offset / COLUMN);
col = 오프셋 - 행 * COLUMN;
JOptionPane.showMessageDialog(this, "ROW="+row+", COL="
+ 열, "버튼", JOptionPane.INFORMATION_MESSAGE);
}
위 코드에서는 JButton의 e.getSource() 인스턴스를 사용하여 생성된 이벤트가 JButton 유형 컨트롤에 의해 생성되었는지 확인한 후 이벤트 소스를 생성하는 컨트롤에 대해 강제 클래스 변환을 수행한 후 Integer.parseInt( 버튼 .getActionCommand()) 메서드는 획득한 이벤트 이름을 정수로 변환하고, 다음 코드는 이 정수를 행 및 열 정보로 복원합니다.
자, 이제 프로그램을 실행하고 각 버튼을 클릭하여 오른쪽과 같은 대화 상자가 나타나는지 확인해 보세요.
아래 첨자는 0부터 시작한다는 점에 유의하세요. 이번 호의 프로그램 소스 코드(다운로드하려면 클릭)
Swing에서 이미지 사용
현재 우리는 사용자 조작 문제를 해결했습니다. 인터페이스를 아름답게 만들기 위해서는 텍스트 대신 그림을 사용해야 합니다. 시간과 인내심이 있는 친구들은 스스로 개인화한 사진을 만들 수 있지만 각 사진의 크기를 일정하게 유지하도록 주의하세요. 그렇지 않으면 너무 보기 흉해집니다. 번거로움을 덜고 싶다면 다운로드 패키지에 제공되는 이미지를 직접 사용할 수도 있습니다.
Swing에서는 setIcon(Image image) 메소드를 사용하여 JButton에 대한 이미지를 설정할 수 있습니다. 매개변수 image는 우리가 설정하려는 이미지 객체입니다.
・Toolkit 클래스를 사용하여 다음을 얻습니다.
이미지 = Toolkit.getDefaultToolkit().getImage(url);
・ImageIcon 클래스의 getImage() 메소드를 사용하여 다음을 얻습니다.
image = new ImageIcon(getClass().getResource(filename)).getImage();
여기서는 첫 번째 방법을 선택합니다. 나중에 Image 객체를 다시 쉽게 얻을 수 있도록 다음과 같은 함수를 작성할 수 있습니다.
이미지 getImage(문자열 파일명){
URLClassLoader urlLoader = (URLClassLoader) this.getClass().getClassLoader();
URL url = null;
이미지 이미지 = null;
url = urlLoader.findResource(파일명);
이미지 = Toolkit.getDefaultToolkit().getImage(url);
이미지 반환;
}
이 기능을 이용하면 앞으로 이미지 활용이 훨씬 더 편리해지지 않을까요?
이제 사진을 사용할 수 있으므로 소스코드 패키지의 Map.Java에 있는 지도 정보를 사진 형태로 표현할 수 있습니다. 이 코드는 게임의 알고리즘 코드에 관한 것이므로 여기서는 코드를 간단히 설명하지 않겠습니다. Map.Java에서는 2차원 배열 map[][]을 사용하여 이미지 정보를 저장하는 동시에 1차원 배열 Images[]를 사용하여 지도의 각 요소를 저장합니다. 이 값은 게임 인터페이스의 버튼에 해당하는 값을 나타낼 뿐만 아니라 이 버튼이 사용하는 이미지[] 배열의 이미지 수를 나타내는 것이기도 합니다.
요약
오늘 우리는 Swing의 JButton 컨트롤을 소개했습니다. 대부분의 Swing 컨트롤의 경우 JButton 사용법을 복사할 수 있습니다. 이 JButton을 과소평가하지 마세요. 잘 익히면 스윙 실력이 한 단계 더 향상됩니다. 또한 Java에서 이미지 파일을 로드하는 두 가지 방법도 배웠습니다. 마지막으로 우리는 위의 두 부분을 결합하여 아름다운 게임 인터페이스를 만들었습니다. 여기에서 완전한 코드를 작성하지는 않았지만, 누구나 제 소스 프로그램을 참고하고 각자의 노력을 통해 목표를 달성할 수 있을 것이라고 믿습니다. 해결할 수 없는 문제가 발생하면 [email protected]으로 연락해 주세요.
오늘 내용에 만족하셨는지 모르겠네요? 아직 설렘이 남아있지 않습니다. 모두가 계속 저희 카페를 애용해 주시기 바랍니다!