JAVA

버블버블게임 7단계 (물방울의 벽, 천장 감지)

jiyoon12 2025. 5. 8. 17:50
  • 백그라운드버블서비스 설계하기
package bubble.test07;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * BackgroundBubbleService 는 스레드가 계속 돌고 있는 상태이다.
 * BackgroundBubbleService 는 스레드가 너무 많이 발생이 되어서
 * 게임에 많은 영향을 미칠 수 있다. 즉, 너무 느려질 가능성이 많다.
 */
public class BackgroundBubbleService {

    private BufferedImage image;
    private Bubble bubble;

    public BackgroundBubbleService(Bubble bubble) {
        try {
            this.bubble = bubble;
            image = ImageIO.read(new File("img/BackgroundMapService.png"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

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

        Color leftColor = new Color(image.getRGB(bubble.getX() + 10, bubble.getY() + 25));
        // 빨간색 --> R G B (255 0 0) --> 왼쪽 벽 판단 됨
        if (leftColor.getRed() == 255 && leftColor.getBlue() == 0 && leftColor.getGreen() == 0) {
            // 왼쪽 벽에 붙음
            return true;
        }
        return false;
    }

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

        Color rightColor = new Color(image.getRGB(bubble.getX() + 70, bubble.getY() + 25));
        if (rightColor.getRed() == 255 && rightColor.getBlue() == 0 && rightColor.getGreen() == 0) {
            return true;
        }
        return false;
    }

    // 천장 확인
    public boolean topWall(){

        Color topColor = new Color(image.getRGB(bubble.getX() + 35, bubble.getY()));
        if (topColor.getRed() == 255 && topColor.getBlue() == 0 && topColor.getGreen() == 0) {
            return true;
        }
        return false;
    }
}

 

  • 버블 벽, 천장 감지 코드 추가하기
package bubble.test07;

import javax.swing.*;

public class Bubble extends JLabel implements Moveable {

    private int x;
    private int y;

    // 물방울 움직임 상태
    private boolean left;
    private boolean right;
    private boolean up;

    private boolean isLeft; // true, false

    private ImageIcon bubble; // 기본 물방울
    private ImageIcon bomb; // 물방울이 터진 상태

    private Player player;

    private BackgroundBubbleService backgroundBubbleService;

    // 생성자를 통해서 player 객체의 주소값을 주입 받기 -> 생성자 의존 주입
    public Bubble(Player player) {
        this.player = player;
        this.backgroundBubbleService = new BackgroundBubbleService(this);

        initData();
        setInitLayout();
        // 버블은 스레드가 하나면 된다.
        bubbleStartThread();
    }

    private void bubbleStartThread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (player.getPlayerWay() == PlayerWay.LEFT) {
                    left();
                } else {
                    right();
                }
            }
        }).start();
    }

    private void initData() {
        bubble = new ImageIcon("img/bubble.png");
        bomb = new ImageIcon("img/bomb.png");
        left = false;
        right = false;
        up = false;
    }

    private void setInitLayout() {
        x = player.getX();
        y = player.getY();
        setIcon(bubble);
        //setIcon(bomb);
        setSize(50, 50);
        setLocation(x, y);
    }

    // getter
    @Override
    public int getX() {
        return x;
    }

    @Override
    public int getY() {
        return y;
    }

    public boolean isLeft() {
        return left;
    }

    public boolean isRight() {
        return right;
    }

    public boolean isUp() {
        return up;
    }

    public ImageIcon getBubble() {
        return bubble;
    }

    public Player getPlayer() {
        return player;
    }

    // setter
    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setLeft(boolean left) {
        this.left = left;
    }

    public void setRight(boolean right) {
        this.right = right;
    }

    public void setUp(boolean up) {
        this.up = up;
    }

    public void setBubble(ImageIcon bubble) {
        this.bubble = bubble;
    }

    public void setPlayer(Player player) {
        this.player = player;
    }

    @Override
    public void left() {
        left = true;
        for (int i = 0; i < 400; i++) {
            x--;
            setLocation(x, y);
            if (backgroundBubbleService.leftWall() == true) {
                // 왼쪽 벽이다.
                break;
            }
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        up();
    }

    @Override
    public void right() {
        right = true;
        for (int i = 0; i < 400; i++) {
            x++;
            // 좌표 오른쪽으로 1 움직였는데 오른쪽 벽인지 아닌지 매번 확인
            setLocation(x, y);
            if (backgroundBubbleService.rightWall() == true) {
                break;
            }
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        up();
    }

    @Override
    public void up() {
        up = true;
        while (true) {
            y--;
            setLocation(x, y);
            if (backgroundBubbleService.topWall() == true) {
                break;
            }
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        // TODO 추후 수정 예정
        // 3초 뒤에 이미지 변경해 보세요
        try {
            Thread.sleep(3000);
            setIcon(bomb);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        try {
            Thread.sleep(500);
            setIcon(null);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}