[STS] 버블버블 - 물방울 움직이게 하기

Moveable 인터페이스로 인한 강제 구현과 Java 의 다중상속을 해결하는 방법을 알아보다. 그리고 스레드 생성으로 인한 성능 저하를 마주하게 되다.
HootJem's avatar
Dec 19, 2024
[STS] 버블버블 - 물방울 움직이게 하기
플레이어가 보는 방향에서 물방울이 나와야 한다. 지금은 플레이어의 방향을 알 수 있는 것은 initSetting
this.setIcon(playerR); 뿐이다.
notion image
 
따라서 PlayerDirection 클래스를 생성한다.
public enum PlayerDirection { LEFT, RIGHT; }
enum 클래스는 제한된 값 중 하나를 선택해야 하는 상황에서 유용하게 사용할 수 있다.
이후 Player 클래스에서 플레이어 방향 설정을 관리한다.
//플레이어 방향 private PlayerDirection playerDirection; private void initSetting() { x = 80; y = 535; left = false; right = false; up = false; down = false; leftWallCrash = false; rightWallCrash = false; playerDirection = playerDirection.RIGHT; this.setIcon(playerR); setSize(50, 50); setLocation(x, y); }
left, right 메서드에 위치 정보를 추가해 준다.
 
현재 움직임을 정의하는 인터페이스는 Moveable 이다.
코드는 이러한데, Bubble 클래스는 down 메서드를 구현하지 않아도 된다.
public interface Moveable { public abstract void left(); public abstract void right(); public abstract void up(); public abstract void down(); }
 
이때, 어댑터 패턴을 활용하여 필요없는 메서드는 선택적으로 구현할 수 있도록 할 수 있다. MoveAdapter 추상 클래스를 만들어 Moveable 인터페이스의 기본 구현을 제공하도록 한다.
public abstract class MoveAdapter implements Moveable{ @Override public void down() {} }
 
이제 Bubble 클래스가 MoveAdapter 을 상속받으면 down 메서드를 강제로 구현하지 않아도 된다.
public class Bubble extends MoveAdapter{ @Override public void left() {} @Override public void right() {} @Override public void up() {} }
 
그러나 기본적으로 Java 는 다중 상속을 지원하지 않는다. Bubble 은 이미 JLabel 을 상속하고 있기 때문에
public class Bubble extends JLabel extends MoveAdapter
이런 식으로 다중 상속을 할 수는 없다.
따라서 인터페이스 자체에서 down 을 기본 구현 해야된다.
public interface Moveable { public abstract void left(); public abstract void right(); public abstract void up(); default public void down() {}; }
default 를 사용하여 기본 구현을 해 주면, down 메서드를 재정의 하지 않아도 된다.
public class Bubble extends JLabel implements Moveable{
 

 

물방울 움직임 구현하기

플레이어는 up 과 좌우 움직임 구현을 위해 두개의 스레드를 사용하고 있다.
물방울은 좌/우 로 이동된 뒤 상승 하기 때문에 한개의 스레드만 사용하여 구현할 것이다.
private void initThread() { new Thread(()-> { System.out.println("스레드 실행 시작"); if(player.getPlayerDirection()==PlayerDirection.LEFT) { left(); }else { right(); } System.out.println("스레드 실행 완료"); }) .start(); } @Override public void left() { left = true; for(int i=0; i<400; i++) { x--; setLocation(x, y); try { Thread.sleep(1); // 물방울 속도 조절을 위해 추가함 } catch (InterruptedException e) { e.printStackTrace(); } } up(); } @Override public void right() { right = true; for(int i=0; i<400; i++) { x++; setLocation(x, y); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } up(); } @Override public void up() { while(true) { y--; setLocation(x, y); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }
 
이렇게 보고 있는 방향으로 물방울이 나오는 모습을 확인할 수 있다.
매번 물방울이 생성될 때 마다 하나의 스레드가 생성 되는데
스레드 실행 완료 라는 로그가 출력되도록 설정했음에도 불구하고
콘솔에서는 실행 시작 로그만 무수히 찍혀 나오게 된다.
이는 물방울이 생성될 수록 많은 스레드로 인해 성능 저하가 발생하는 문제가 생긴다는 의미이다.
따라서 적절한 스레드 관리가 필요하게 된다.
notion image
notion image
 
 
Share article

[HootJem] 개발 기록 블로그