버전3. https://notion6780.tistory.com/62

버전5. https://notion6780.tistory.com/63

버전6. https://notion6780.tistory.com/65

 

 

버전7에서는..

 

🙏 거품이 벽과 천장에 닿으면 멈추는 기능

🙏 멈춘 뒤 일정 시간 뒤에 사라지는 기능 추가

 

이를 위해..

 

⭐ BackgroundBubbleService

천장 감지기능 개발

⭐  Bubble

천장 감지시 정지기능 개발

 

..등의 작업을 수행해야 한다.

 

1. BackgroundBubbleService

 

우리는 과거 BackgroundPlayerService 클래스에서

Player 캐릭터의 움직임을 감지하는 쓰레드를 생성한 적이 있다.

 

💀하지만 현재 BPS 쓰레드는 너무 바쁜 상황이기에 새로운 감시자를 추가해야 한다.

또 버블마다 새로운 쓰레드를 박으면 자원소모가 너무 많아진다.

시스템이 느려질 가능성이 있다는 말이다.


😎BackgroundBubbleService의 기능은 메서드로 구현해본다.

 

변수는

BufferedImage 이미지 수정

Bubble 버블 객체 호출

 

생성자는

좌표 계산을 위한 버블 객체

벽 인식용 배경을 불러온다.

좌표값이 빨간색, 파란색, 흰색이냐로 요소들의 상태를 판단한다.

public class BackgroundBubbleService {

    //member
    private BufferedImage image;
    private Bubble bubble;

    //constructor
    public BackgroundBubbleService(Bubble bubble) {
        this.bubble = bubble;

        try {
            image = ImageIO.read(new File("img/backgroundMapService.png"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

 

벽 확인 메서드

거품의 왼쪽 좌표에 해당하는 색이 빨간색(255,0,0)이면 벽에 닿은 것이다.

// 왼쪽 벽 확인
public boolean leftWall() {

    Color leftcolor = new Color(image.getRGB(bubble.getX() + 10, bubble.getY()+25));
    //빨간색 RGB 255,0,0 => 왼쪽 벽
    if (leftcolor.getRed() == 255 && leftcolor.getGreen() == 0 && leftcolor.getBlue() == 0) {
        return true;
    }
    return false;
}//leftWall

// 오른쪽 벽 확인
public boolean rightWall() {

    Color rightcolor = new Color(image.getRGB(bubble.getX() + 60, bubble.getY()+25));
    //빨간색 RGB 255,0,0 => 오른쪽 벽
    if (rightcolor.getRed() == 255 && rightcolor.getGreen() == 0 && rightcolor.getBlue() == 0) {
        return true;
    }
    return false;
}//rightWall

 

천장 확인 메서드

//파란천장
public boolean ceilingBlue() {

    Color ceilBColor = new Color(image.getRGB(bubble.getX()+35, bubble.getY()));
    //파란색 RGB 0,0,255 => 파란천장
    if (ceilBColor.getRed() == 0 && ceilBColor.getGreen() == 0 && ceilBColor.getBlue() == 255) {
        return true;
    }
    return false;
}//ceilingBlue

//빨간천장
public boolean ceilingRed() {

    Color ceilRColor = new Color(image.getRGB(bubble.getX()+35, bubble.getY()));
    //빨간천장
    if (ceilRColor.getRed() == 255 && ceilRColor.getGreen() == 0 && ceilRColor.getBlue() == 0) {
        return true;
    }
    return false;
}//ceilingRed

 

 

2. Bubble

 

벽과 천장을 인식했다면

다음은 상화작용을 구현할 때다.

 

(수정전)

지난 버전6에서는 버블이 player 캐릭터에서 발사된 뒤 400 길이를 직선이동하고 위로 올라가는 구문을 만들어뒀다. 

@Override
public void left() {

    left = true;

    for (int i = 0; i < 400; i++) {

        x--;
        setLocation(x, y);

        try {
            Thread.sleep(1); //메인쓰레드가 수행
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }//for

    up(); //수평이동을 마친 뒤 위로 올라간다

}//left

@Override
public void right() {

    right = true;

    for (int i = 0; i < 400; i++) {

        x++;
        setLocation(x, y);

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }//for

    up(); //수평이동을 마친 뒤 위로 올라간다

}//right

@Override
public void up() {

    up = true;

    while (true) {

        y--;
        setLocation(x, y);

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }//while

}//up

 

 

2-1. Bubble 클래스에서 변수와 생성자 수정

 

변수

터지는 애니메이션 구현을 위해 ImageIcon bomb 변수를 선언해준다.

BackgroundBubbleService 기능을 불러오기 위해 클래스 변수도 선언해준다.

 

생성자

BackgroundBubbleService 를 호출한다.

public class Bubble extends JLabel implements Movable {

    //물방울의 좌표 변수
    private int x;
    private int y;

    //물방울 이미지 변수
    private ImageIcon bubble;
    private ImageIcon bomb; // 터졌을때

    //물방울 움직임 상태를 나타내는 제어변수
    private boolean left;
    private boolean right;
    private boolean up;

    //
    private boolean isLeft;
    private boolean isRight;

    //Player 클래스 변수
    private Player player;
    private BackgroundBubbleService backgroundBubbleService;

    //생성자
    public Bubble(Player player) {
        //Player 객체의 주소값을 주입받는다 = 생성자 의존 주입
        this.player = player;
        this.backgroundBubbleService = new BackgroundBubbleService(this);

        initData();
        setInitLayout();
        bubbleStartThread();

    }//constructor

 

 

2-2. left() 메서드 수정

다음과 같은 기능을 하는 조건문을 각 동작메서드에 넣어준다.

오른쪽은 반대로 넣으면 된다.

if (backgroundBubbleService.leftWall()) {
    //왼쪽벽일때
    break;
}
@Override
    public void left() {

//        new Thread().start(); 여기서는 쓰레드를 활용하지 않는다

        left = true;

        for (int i = 0; i < 400; i++) {

            x--;
            setLocation(x, y);

            if (backgroundBubbleService.leftWall()) {
                //왼쪽벽일때
                break;
            }

            try {
                Thread.sleep(1); //메인쓰레드가 수행
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }//for

        up(); //수평이동을 마친 뒤 위로 올라간다

    }//left

 

2-3. up 메서드 수정

if (backgroundBubbleService.ceilingBlue()) {
    //파란천장일때
    break;
}
if (backgroundBubbleService.ceilingRed()) {
    //빨간천장일때
    break;
}

 

빨강, 혹은 파랑 천장에 도달해 while문이 break 됐다면

3초 뒤에 bubble 아이콘을 터지는 그림으로 바꿔준다.

bubble.png
bomb.png

터진 뒤 0.5초 뒤에는 bubble 아이콘을 제거한다.

    }//while

    //3초 뒤에 이미지를 변경한다.
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    this.setIcon(bomb);

    //0.5초 뒤에 이미지를 없앤다.
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    this.setIcon(null);

}//up

 

2-4) 수정완료된 코드

@Override
public void up() {

    up = true;

    while (true) {

        y--;
        setLocation(x, y);

        if (backgroundBubbleService.ceilingBlue()) {
            //파란천장일때
            break;
        }
        if (backgroundBubbleService.ceilingRed()) {
            //빨간천장일때
            break;
        }

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }//while

    //3초 뒤에 이미지를 변경한다.
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    this.setIcon(bomb);

    //0.5초 뒤에 이미지를 없앤다.
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    this.setIcon(null);

}//up

버블이 정상적으로 벽과 천장에 막히고 멈춘뒤 3초가 지나면 터졌다가 없어지고 있다.

 

+ Recent posts