E001 // 이벤트 대기중
E002 // → 키 입력
E003 // 1초마다 타이머 활성화
E004 // → 키 해제
// 파일명 : ./Chapter14/TopViewGameMain.java
import javax.swing.*;
import move.TopViewObject;
import move.ViewPanel;
public class TopViewGameMain
{
1 public static void main( String[] args )
{
final String imagePath = "C:\\Users\\user\\Downloads\\JAVA-main\\src\\move\\image\\";
// 미로 맵을 2차원 배열로 초기화
int[][] map = { { 1,1,1,1,1,1,1 },
{ 1,0,0,1,0,0,1 },
{ 1,1,0,1,0,1,1 },
{ 1,0,0,1,0,0,1 },
{ 1,0,1,1,1,0,1 },
{ 1,0,0,0,0,0,1 },
{ 1,1,1,1,1,1,1 }
};
// 판을 틀에 끼우고 실행 준비 완료
2 ViewPanel panel =
3 new ViewPanel(
4 new TopViewObject( map, 1, 1, imagePath ) );
JFrame frame = new JFrame( "탑 뷰 맵" );
frame.getContentPane().add( panel );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
5 }
}
// 파일명 : ./src/move/ViewPanel.java
package move;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// 뷰 패널
public class ViewPanel extends JPanel
{
protected ObjectByKey character;
protected Timer timer;
V1b public ViewPanel( ObjectByKey character ){
// 키리스너에 방향키로 이동하는 캐릭터를 등록
this.character = character;
addKeyListener( character );
setFocusable( true );
requestFocus();
setPreferredSize( new Dimension( character.backgroundWidth(), character.backgroundHeight() ) );
// 주기적으로 활성화되는 타이머 등록
timer = new Timer( 100, new ActionListener() {
@Override
V2b public void actionPerformed( ActionEvent event ) {
V21 update();
V22 repaint();
V2e }
});
timer.start();
V1e }
// 최신 정보 업데이트
V3b protected void update() {
V31 character.move();
V3e }
// 화면 출력
@Override
V4b public void paint( Graphics g ){
super.paint( g );
V41 character.paint( g );
V4e }
}
// 파일명 : ./src/move/TopViewObject.java
package move;
import java.awt.*;
import javax.swing.*;
// 탑 뷰 캐릭터
public class TopViewObject extends ObjectByKey
{
protected int[][] map;
protected Image[] image;
protected final int PATH = 0, WALL = 1, CHARACTER = 2;
T1b public TopViewObject( int[][] map, int x, int y, final String imagePath ) {
T11 super( imagePath+"character.png", x, y, 0, 0, map[0].length-1, map.length-1 );
this.map = map;
this.image = new Image[3];
this.image[PATH ] = new ImageIcon( imagePath + "path.png" ).getImage();
this.image[WALL ] = new ImageIcon( imagePath + "wall.png" ).getImage();
this.image[CHARACTER] = new ImageIcon( imagePath + "character.png" ).getImage();
T1e }
// 벽이 아니면 캐릭터 이동
@Override
T2b public void move( int directionX, int directionY ) {
if( map[y+directionY][x+directionX] != WALL )
T21 super.move( directionX, directionY );
T2e }
// 캐릭터와 전체 맵을 출력
@Override
T3b public void paint( Graphics g ){
for( int y = 0; y <= map.length; y++ ){
for( int x = 0; x <= map[0].length; x++ ){
int index = WALL;
if ( ( this.x == x ) && ( this.y == y ) )
index = CHARACTER;
else if ( ( minX <= x ) && ( x <= maxX ) && ( minY <= y ) && ( y <= maxY ) )
index = map[y][x];
g.drawImage( image[index], x*IMGSIZE, y*IMGSIZE, IMGSIZE, IMGSIZE, null );
}
}
T3e }
@Override
public int backgroundWidth(){
return IMGSIZE * ( map[0].length );
}
@Override
public int backgroundHeight(){
return IMGSIZE * ( map.length );
}
}
// 파일명 : ./src/move/ObjectByKey.java
package move;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// 방향키로 이동하는 객체
public class ObjectByKey extends KeyAdapter
{
private Image image;
protected int x, y, directionX, directionY;
protected int minX, minY, maxX, maxY;
public static final int LEFT = -1, RIGHT = 1, UP = -1, DOWN = 1, STOP = 0, IMGSIZE = 40;
// 초기화: 이미지, 현재 위치, 이동 허용 범위, 이동 방향을 설정
K1b public ObjectByKey( String image, int x, int y, int minX, int minY, int maxX, int maxY ) {
this.image = new ImageIcon( image ).getImage();
this.x = x;
this.y = y;
this.minX = minX;
this.minY = minY;
this.maxX = maxX;
this.maxY = maxY;
this.directionX = STOP;
this.directionY = STOP;
K1e }
// 키를 누르면 상하좌우 이동방향 설정
@Override
K2b public void keyPressed( KeyEvent event ) {
switch( event.getKeyCode() ) {
case KeyEvent.VK_ESCAPE:
System.exit(0);
break;
case KeyEvent.VK_LEFT: case 'A': case 'a':
directionX = LEFT;
break;
case KeyEvent.VK_RIGHT: case 'D': case 'd':
K21 directionX = RIGHT;
break;
case KeyEvent.VK_UP: case 'W': case 'w':
directionY = UP;
break;
case KeyEvent.VK_DOWN: case 'S': case 's':
K22 directionY = DOWN;
break;
}
K2e }
// 키를 해제하면 이동방향 해제
@Override
K3b public void keyReleased( KeyEvent event ) {
switch( event.getKeyCode() ) {
case KeyEvent.VK_LEFT: case 'A': case 'a':
case KeyEvent.VK_RIGHT: case 'D': case 'd':
K31 directionX = STOP;
break;
case KeyEvent.VK_UP: case 'W': case 'w':
case KeyEvent.VK_DOWN: case 'S': case 's':
directionY = STOP;
break;
}
K3e }
// 이동 허용 범위내에서만 객체 이동
K4b public void move() {
K41 move( directionX, directionY );
K4e }
K5b public void move( int directionX, int directionY ) {
this.x += directionX;
this.y += directionY;
this.x = ( this.x <= minX ) ? minX : this.x;
this.y = ( this.y <= minY ) ? minY : this.y;
this.x = ( this.x >= maxX ) ? maxX : this.x;
this.y = ( this.y >= maxY ) ? maxY : this.y;
K5e }
// 현재 위치에 객체를 출력
K6b public void paint( Graphics g ) {
g.drawImage( image, x, y, IMGSIZE, IMGSIZE, null );
K6e }
public int directionX() {
return directionX;
}
public int directionY() {
return directionY;
}
public int backgroundWidth(){
return maxX;
}
public int backgroundHeight(){
return maxY;
}
}