Java/Java.Swing

Swing bubble bubble Game 9 (버블 생성 동작 수정)

H_u 2024. 5. 7. 16:45
728x90
반응형
SMALL

BubbleFrame - 컨텍스트 생성 , Player getter 생성

package bubble.test.ex09;

 

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

 

import javax.swing.ImageIcon;

import javax.swing.JFrame;

import javax.swing.JLabel;

 

public class BubbleFrame extends JFrame {

 

// 컨텍스트를 생성하는 방법 (셀프 참조)

BubbleFrame mContext = this;

 

private JLabel backgroundMap;

// 포함관계 - 콤포지션

private Player player;

 

public BubbleFrame() {

 

initData();

setInitLayout();

addEventListener();

// Player 백그라운드 서비스 시작

new Thread(new BackgroundPlayerService(player)).start();

}

 

 

private void initData() {

// todo 이미지 변경

backgroundMap = new JLabel(new ImageIcon("img/backgroundMap.png"));

// backgroundMap = new JLabel(new ImageIcon("img/test.png"));

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Frame --> root Panel

setContentPane(backgroundMap); // add 처리

setSize(1000, 640);

 

// mContext --> 참조 타입( ) --> 주소값에 크기는 기본 4byte 이다.

player = new Player(mContext);

 

}

 

private void setInitLayout() {

// 좌표 값으로 배치

setLayout(null);

setResizable(false); // 프레임 조절 불가

setLocationRelativeTo(null); // JFrame 여러분 모니터 가운데 자동 배치

setVisible(true);

 

add(player);

}

 

private void addEventListener() {

 

this.addKeyListener(new KeyAdapter() {

 

@Override

public void keyPressed(KeyEvent e) {

System.out.println("key code : " + e.getKeyCode());

 

switch (e.getKeyCode()) {

case KeyEvent.VK_LEFT:

// 왼쪽으로 방향키 누르고 있다면

// key 이벤트가 계속 <- <- <- <- <- <-

// 왼쪽 상태가 아니라면

// 왼쪽 벽에 충돌 한게 아니라면

if (!player.isLeft() && !player.isLeftWallCrash()) {

player.left();

}

break;

case KeyEvent.VK_RIGHT:

if (!player.isRight() && !player.isRightWallCrash()) {

player.right();

}

 

break;

case KeyEvent.VK_UP:

player.up();

break;

case KeyEvent.VK_SPACE:

//add(new Bubble(player));

player.attack();

// 프레임에 컴포넌트를 add 동작은 누구? JFrame --> add() 메서드 이다.

// 버블 실행시에 끊김 현상이 발생하는 이유는 왜 일까??

break;

default:

break;

}

} // end of KeyPressed

 

@Override

public void keyReleased(KeyEvent e) {

switch (e.getKeyCode()) {

case KeyEvent.VK_LEFT:

// 왼쪽으로 가능 상태 멈춤

player.setLeft(false);

break;

case KeyEvent.VK_RIGHT:

// 오른쪽으로 가능 상태 멈춤

player.setRight(false);

break;

default:

break;

}

} // end of KeyReleased

 

});

}

 

// getter

public Player getPlayer() {

return player;

}

 

// 코드 테스트

public static void main(String[] args) {

// main 함수를 가지고 있는 클래스는 하위에 생성된 모든 객체들의

// 주소값을 알고 있다. (중요)

new BubbleFrame();

} // end of main

 

}

 

 

player 생성자 수정 , 멤버 변수 추가

package bubble.test.ex09;

 

import java.awt.Point;

 

import javax.swing.ImageIcon;

import javax.swing.JLabel;

 

public class Player extends JLabel implements Moveable {

 

BubbleFrame mContext;

 

private int x;

private int y;

private ImageIcon playerR, playerL;

 

// 움직임의 상태

private boolean left;

private boolean right;

private boolean up;

private boolean down;

 

// 벽에 충돌한 상태

private boolean leftWallCrash;

private boolean rightWallCrash;

 

// 플레이어 속도 상태

private final int SPEED = 4;

private final int JUMPSPEED = 2;

 

// enum 타입의 활용 <---------- 코드 추가

PlayerWay playerWay;

 

// get,set

public Player(BubbleFrame mContext) {

this.mContext = mContext;

initData();

setInitLayout();

}

 

public int getX() {

return x;

}

 

public void setX(int x) {

this.x = x;

}

 

public int getY() {

return y;

}

 

public void setY(int y) {

this.y = y;

}

 

public ImageIcon getPlayerR() {

return playerR;

}

 

public void setPlayerR(ImageIcon playerR) {

this.playerR = playerR;

}

 

public ImageIcon getPlayerL() {

return playerL;

}

 

public void setPlayerL(ImageIcon playerL) {

this.playerL = playerL;

}

 

public boolean isLeft() {

return left;

}

 

public void setLeft(boolean left) {

this.left = left;

}

 

public boolean isRight() {

return right;

}

 

public void setRight(boolean right) {

this.right = right;

}

 

public boolean isUp() {

return up;

}

 

public void setUp(boolean up) {

this.up = up;

}

 

public boolean isDown() {

return down;

}

 

public void setDown(boolean down) {

this.down = down;

}

 

public boolean isLeftWallCrash() {

return leftWallCrash;

}

 

public void setLeftWallCrash(boolean leftWallCrash) {

this.leftWallCrash = leftWallCrash;

}

 

public boolean isRightWallCrash() {

return rightWallCrash;

}

 

public void setRightWallCrash(boolean rightWallCrash) {

this.rightWallCrash = rightWallCrash;

}

 

public int getSPEED() {

return SPEED;

}

 

public int getJUMPSPEED() {

return JUMPSPEED;

}

 

private void initData() {

playerR = new ImageIcon("img/playerR.png");

playerL = new ImageIcon("img/playerL.png");

 

// 처음 실행 시 초기 값 셋팅

x = 450;

y = 535;

 

// 플레이어가 가만이 멈춤 상태

left = false;

right = false;

up = false;

down = false;

 

leftWallCrash = false;

rightWallCrash = false;

 

playerWay = PlayerWay.RIGHT;

 

}

 

private void setInitLayout() {

setIcon(playerR);

setSize(50, 50);

setLocation(x, y);

}

 

@Override

public void left() {

playerWay = PlayerWay.LEFT;

left = true;

setIcon(playerL);

 

new Thread(new Runnable() {

@Override

public void run() {

while (left) {

x = x - SPEED;

setLocation(x, y);

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();

}

 

@Override

public void right() {

playerWay = PlayerWay.RIGHT;

right = true;

setIcon(playerR);

 

new Thread(new Runnable() {

@Override

public void run() {

while (right) {

x = x + SPEED;

setLocation(x, y);

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();

} // end of right

 

@Override

public void up() {

System.out.println("점프");

up = true;

new Thread(new Runnable() {

@Override

public void run() {

 

for (int i = 0; i < 130 / JUMPSPEED; i++) {

y = y - JUMPSPEED;

setLocation(x, y);

try {

Thread.sleep(5);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

 

// 객체의 상태값을 잘 조절해야 한다.

up = false;

down();

 

}

}).start();

 

}

 

@Override

public void down() {

System.out.println("다운");

down = true;

new Thread(new Runnable() {

@Override

public void run() {

while (down) {

y = y + SPEED;

setLocation(x, y);

try {

Thread.sleep(3);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

down = false;

}

}).start();

}

 

// 플레이어에 공격

public void attack() {

 

// 일 작업자에게 위임 처리

// 람다 표현식 --> 말 그대로 표현식, 타입 추론 가능(자바는)

new Thread(() -> {

// run() 안에 들어오는 식을 작성해 주면 된다.

Bubble bubble = new Bubble(mContext);

// mContext 통해서 (JFrame의 메서드를 호출 할 수 있다)

mContext.add(bubble);

 

if(playerWay == PlayerWay.LEFT) {

// 버블을 왼쪽으로 쏘기

bubble.left();

} else {

// 버들을 오른쪽으로 쏘기

bubble.right();

}

}).start();

}

 

}

 

 

Bubble 코드 수정

package bubble.test.ex09;

 

import javax.swing.ImageIcon;

import javax.swing.JLabel;

 

public class Bubble extends JLabel implements Moveable {

 

private BubbleFrame mContext;

 

// 의존성 컴포지션 관계

private Player player;

private BackgroundBubbleService backgroundBubbleService;

 

 

private int x;

private int y;

 

// 움직임 상태

private boolean left;

private boolean right;

private boolean up;

 

// 적군을 맞춘 상태

private int state; // 0.(기본 물방울), 1.(적을 가둔 상태 물방울)

 

private ImageIcon bubble; // 기본 물방울

private ImageIcon bubbled; // 적을 가둔 물방울

private ImageIcon bomb; // 물방울 팡!

 

// 연관관계, 의존성 컴포지션 관계, 생성자 의존 (DI)

public Bubble(BubbleFrame mContext) {

this.mContext = mContext;

this.player = mContext.getPlayer();

initData();

setInitLayout();

}

 

//get,set

public Player getPlayer() {

return player;

}

 

public void setPlayer(Player player) {

this.player = player;

}

 

public int getX() {

return x;

}

 

public void setX(int x) {

this.x = x;

}

 

public int getY() {

return y;

}

 

public void setY(int y) {

this.y = y;

}

 

public boolean isLeft() {

return left;

}

 

public void setLeft(boolean left) {

this.left = left;

}

 

public boolean isRight() {

return right;

}

 

public void setRight(boolean right) {

this.right = right;

}

 

public boolean isUp() {

return up;

}

 

public void setUp(boolean up) {

this.up = up;

}

 

public int getState() {

return state;

}

 

public void setState(int state) {

this.state = state;

}

 

public ImageIcon getBubble() {

return bubble;

}

 

public void setBubble(ImageIcon bubble) {

this.bubble = bubble;

}

 

public ImageIcon getBubbled() {

return bubbled;

}

 

public void setBubbled(ImageIcon bubbled) {

this.bubbled = bubbled;

}

 

public ImageIcon getBomb() {

return bomb;

}

 

public void setBomb(ImageIcon bomb) {

this.bomb = bomb;

}

 

private void initData() {

 

bubble = new ImageIcon("img/bubble.png");

bubbled = new ImageIcon("img/bubbled.png");

bomb = new ImageIcon("img/bomb.png");

backgroundBubbleService = new BackgroundBubbleService(this);

 

left = false;

right = false;

up = false;

state = 0;

 

}

 

private void setInitLayout() {

 

x = player.getX();

y = player.getY();

 

setIcon(bubble);

setSize(50, 50);

setLocation(x, y);

}

 

 

 

@Override

public void left() {

left = true;

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

x--;

setLocation(x, y);

 

// 만약 왼쪽벽 --> up()

if(backgroundBubbleService.leftWall()) {

break;

}

 

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);

if(backgroundBubbleService.rightWall()) {

break;

}

try {

Thread.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

up();

 

}

 

@Override

public void up() {

up = true;

while(true) {

y--;

setLocation(x, y);

if(backgroundBubbleService.topWall()) {

break;

}

try {

Thread.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

clearBubble();

}

 

// 외부 호출 안될 메서드

private void clearBubble() {

// 3초뒤에 터짐

try {

Thread.sleep(3000);

setIcon(bomb);

// 메모리에서 해제 처리 해야 함

 

 

Thread.sleep(500);

// 컴포넌트 제거 --> 다시 그림을 그리지 않는다

setIcon(null);

// mContext.remove(this);

// mContext.repaint();

// setIcon(null);

// JFrame 안에 remove 메서드가 있다

 

 

} catch (InterruptedException e) {

e.printStackTrace();

}

 

}

 

}

728x90
반응형
SMALL