inblog logo
|
[HootJem] 개발 기록 블로그
    java

    [STS] 버블버블 - 물방울로 공격하기

    HootJem's avatar
    HootJem
    Jan 14, 2025
    [STS] 버블버블 - 물방울로 공격하기
    진행상황
    물방울로 적을 맞추면 물방울 모양이 적이 가둬진 상태로 변경됩니다.
     
    @Override public void attack() { state = 1; setIcon(bubbled); mContext.remove(enemy); //메모리에서 사라진다 mContext.repaint(); }
    코드를 추가하여 물방울이 닿았을 때 적개체가 사라지도록 하였습니다.
     
    left 메서드에 적과 충돌하면 이동을 멈추고 바로 상승하게 하기 위해 break 를 추가하였습니다.
    if((Math.abs(x-enemy.getX()) > 40 && Math.abs(x-enemy.getX())<60) && (Math.abs(y-enemy.getY()) > 0 && Math.abs(y-enemy.getY())<50)) { System.out.println("적군 충돌"); attack(); break; }
    notion image
     
    ❗이때 문제가 발생합니다.
    적 개체는 mContext.remove(enemy); 를 통해 사라졌지만 해당 부분에 물방울이 닿게되면 적이 보이지 않더라도 계속해서 물방울에 적이 가둬집니다.
    이는 remove 된 적 개체가 가비지 컬렉션으로 가게 되는데 이 가비지 컬렉션은 즉시 비워지지 않기 때문에 일어나는 현상입니다.
     
    가비지 컬렉션이 비워질 때 까지 기다릴 수 없기 때문에 Enemy 클래스 자체에 상태값을 줍니다.
    private int state; // 0(살아있다), 1(죽었다)
     
    기본적으로 적 개체는 state = 0 을 갖고, attack 메서드는 enemy.getState() == 0 일 때만 작동하도록 코드를 수정합니다. attack 메서드도 맞추게 되면 enemy 의 상태를 변경하도록 코드를 추가하였습니다.
    @Override public void attack() { state = 1; enemy.setState(1); setIcon(bubbled); mContext.remove(enemy); //메모리에서 사라진다 mContext.repaint(); }
     
    이때 적을 가둔 방울은 플레이어가 직접 터트릴 때 사라져야 합니다. (지금은 up 메서드 자체에서 clearBubble 호출하여 방울이 터지고 있음) up 메서드가 crearBubble 호출할 때 조건을 추가하여 에러를 잡았습니다.
    @Override public void up() { while(true) { y--; setLocation(x, y); if(backGroundBubbleService.topWall()) { break; } try { if(state==0) { // 기본 Thread.sleep(1); }else { // 공격 성공 물방울 Thread.sleep(10); } } catch (InterruptedException e) { e.printStackTrace(); } } if(state == 0) clearBubble(); // 천장에 버블이 도착하고 나서 3초 후에 메모리에서 소멸 }
     
    적을 가둔 방울은 state = 1
    그냥 방울은 state = 0 을 갖습니다.
    이를 프로그램이 알고있기 위해서는 방울을 관리하는 list 가 필요합니다.
     
    Player 클래스에서 물방울이 생성될 때 마다 bubbleList 에 추가되도록 코드를 수정합니다.
    private List<Bubble> bubbleList; private void initObject() { playerR = new ImageIcon("image/playerR.png"); playerL = new ImageIcon("image/playerL.png"); bubbleList = new ArrayList<>(); } @Override public void attack() { new Thread(()->{ Bubble bubble = new Bubble(mContext); mContext.add(bubble); bubbleList.add(bubble); System.out.println("방울 시작"); if(playerDirection == playerDirection.LEFT) { bubble.left(); System.out.println("방울 왼쪽"); }else { bubble.right(); System.out.println("방울 오른쪽"); } System.out.println("방울 종료"); }).start(); }
     
    플레이어 자신이 닿았는지 알아야 하기 때문에 BackGroundPlayerService 도 수정을 합니다.
    // 1. 버블 충돌 체크 for(int i=0; i<bubbleList.size(); i++) { if(bubbleList.get(i).getState()==1) { if((Math.abs(player.getX()-bubbleList.get(i).getX()) < 10) && (Math.abs(player.getY()-bubbleList.get(i).getY()) > 0 && Math.abs(player.getY()-bubbleList.get(i).getY())<50)) { System.out.println("몸통 박치기"); } } }
     
    이렇게 실행한 뒤 방울에 플레이어를 부딪히면 설정했던 몸통 박치기 로그가 나옵니다.
     
    Bubble 클래스에 적이 갇힌 물방울을 제거하는 메서드를 추가합니다.
    public void clearBubbled() { try { up = false; setIcon(bomb); Thread.sleep(1000); mContext.remove(this); mContext.repaint(); } catch (InterruptedException e) { e.printStackTrace(); } }
    백그라운드플레이어서비스를 수정하고 실행해 보면 이렇게 작동합니다.
    for(int i=0; i<bubbleList.size(); i++) { Bubble bubble = bubbleList.get(i); if(bubbleList.get(i).getState()==1) { if((Math.abs(player.getX()-bubble.getX()) < 10) && (Math.abs(player.getY()-bubble.getY()) > 0 && Math.abs(player.getY()-bubble.getY())<50)) { System.out.println("몸통 박치기"); bubble.clearBubbled(); } } }
    notion image
    바닥을 뚫고 아래로 추락하게 됩니다…
    아마 crearBubbled 메서드의 repaint 가 작동되는 동안 바닥을 뚫지 못하게 설정해 놓은 코드가 적용되지 않아 발생하는 문제 같아 보입니다.
     
    따라서 crearBubbled 에 별도의 스레드를 적용시켜 코드를 수정하겠습니다.
    public void clearBubbled() { new Thread(()->{ try { up = false; setIcon(bomb); Thread.sleep(1000); mContext.remove(this); mContext.repaint(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); }
     
    이제 BGM 과 적군이 움직이도록 하는 기능만 하면 끝납니다~ 👍
    notion image
     

    💡
    1. 게임 맵과 캐릭터 추가 https://inblog.ai/hj/sts-버블버블-게임-맵과-캐릭터-추가하기-33126
    1. 캐릭터 이동 https://inblog.ai/hj/sts-버블버블-캐릭터-이동-33127
    1. 스레드 사용하여 이동하기 https://inblog.ai/hj/sts-버블버블-스레드-사용이동-33335
    1. 점프하기 https://inblog.ai/hj/sts-버블버블-점프하기-33388
    1. 충돌 감지 https://inblog.ai/hj/sts-버블버블-충돌감지-33391
    1. 외벽 충돌 시 캐릭터 정지 https://inblog.ai/hj/sts-버블버블-외벽-충돌-시-캐릭터-정지-36946
    1. 캐릭터 업 다운 https://inblog.ai/hj/sts-버블버블-캐릭터-업-다운-38143
    1. 캐릭터 업 다운 시키기 https://inblog.ai/hj/sts-버블버블-캐릭터-업-다운-38143
    1. 물방울 생성하기(기본셋팅) https://inblog.ai/hj/sts-버블버블-물방울-기본-셋팅-38154
    1. 물방울 움직이게 하기 https://inblog.ai/hj/sts-버블버블-물방울-움직이게-하기-38195
    1. 물방울 메모리에서 해제 하고 화면 다시 그리기 https://inblog.ai/hj/sts-버블버블-물방울-완성하기-38589
    1. 리팩토링 하기 https://inblog.ai/hj/sts-버블버블-리팩토링-하기-39820
    1. 적군 만들기 https://inblog.ai/hj/sts-버블버블-적군-만들기-39821
    1. 물방울 공격하기 완료 https://inblog.ai/hj/sts-버블버블-물방울로-공격하기-40303
    1. 적 움직이기 https://inblog.ai/hj/sts-버블버블-적-움직이기-40305
    Share article

    [HootJem] 개발 기록 블로그

    RSS·Powered by Inblog