Bubble 바닥 층 감지 기능 추가 - 5

목차

    목표

    1. down()을 계속 떨어지도록 변경
    2. 바닥 색 감지 후 떨어지지 않도록 함
    3. 바닥이 없을 때는 계속 떨어져야함

     

    Player 코드

    package bubble.test.ex06;
    
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    
    public class Player extends JLabel implements Moveable {
    
    	private int x;
    	private int y;
    	private ImageIcon playerR, playerL;
    	private Bubble bubble;
    
    	// 움직임의 상태
    	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;
    
    	// get, set
    
    	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 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 boolean isLeft() {
    		return left;
    	}
    	public boolean isRight() {
    		return right;
    	}
    	public int getSPEED() {
    		return SPEED;
    	}
    	public int getJUMPSPEED() {
    		return JUMPSPEED;
    	}
    	public int getP_WIDTH() {
    		return P_WIDTH;
    	}
    	public int getP_HEIGTH() {
    		return P_HEIGTH;
    	}
    
    	public Bubble getBubble() {
    		return bubble;
    	}
    	public void setBubble(Bubble bubble) {
    		this.bubble = bubble;
    	}
    
    	// 플레이어 크기
    	private final int P_WIDTH = 50;
    	private final int P_HEIGTH = 50;
    
    	// setter
    	public void setLeft(boolean left) {
    		this.left = left;
    	}
    	public void setRight(boolean right) {
    		this.right = right;
    	}
    
    	public Player() {
    		initData();
    		setInitLayout();
    	}
    
    	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;
    
    	}
    
    	private void setInitLayout() {
    		setIcon(playerR);
    		setSize(P_WIDTH, P_HEIGTH);
    		setLocation(x, y);
    	}
    
    	@Override
    	public void left() {
    		left = true;
    		setIcon(playerL);
    
    		// 메인 작업자는 계속 키 입력을 받아야함
    		new Thread(new Runnable() {
    
    			@Override
    			public void run() {
    				while (left) {
    					x -= SPEED;
    					setLocation(x, y);
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}).start();
    	}
    
    	@Override
    	public void right() {
    		right = true;
    		setIcon(playerR);
    
    		new Thread(new Runnable() {
    
    			@Override
    			public void run() {
    				while (right) {
    					x += SPEED;
    					setLocation(x, y);
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}).start();
    
    	}
    
    	@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 -= 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 += SPEED;
    					setLocation(x, y);
    					try {
    						Thread.sleep(3);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    				down = false;
    			}
    		}).start();
    	}
    }

     

    감지 코드

    package bubble.test.ex06;
    
    import java.awt.Color;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    
    /**
     * 현재 메인 쓰레드는 너~무 바쁨
     * 백그라운드에서 계속 Player의 움직임을 관찰할 예정
     */
    public class BackgroundPlayerService implements Runnable {
    
    	private BufferedImage image;
    	private Player player;
    	
    	// 생성자 의존 주입 DI
    	public BackgroundPlayerService(Player player) {
    		this.player = player;
    		
    		try {
    			image = ImageIO.read(new File("img/backgroundMapService.png"));
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    	
    	@Override
    	public void run() {
    		while(true) {
    			System.out.println("1111");
    			// 색상 확인 todo (보정값 필요)
    			Color leftColor = new Color(image.getRGB(player.getX() + 10, player.getY() + 25));
    			Color rightColor = new Color(image.getRGB(player.getX() + 50 + 10, player.getY() + 25));
    			// Color bottomColor = new Color(image.getRGB(player.getX(), player.getY()));
    			
    			// 흰색이면  RGB => 255 255 255
    			// 빨간바닥인 경우 --> 255 0 0 
    			// 파란바닥인 경우 --> 0 0 255
    			int bottomColorLeft = image.getRGB(player.getX() + 20, player.getY() + 50 + 5);
    			int bottomColorRight = image.getRGB(player.getX() + 50 + 10, player.getY() + 50 + 5);
    			
    			// 흰색이면 -----> int 값이 - 2
    			if(bottomColorLeft + bottomColorRight != -2) {
    				// 여기는 멈추어야 한다. (빨간 바닥 또는 파란 바닥)
    				player.setDown(false);
    				// 플레이어가 올라가는 상태가 아니고, 내려가는 상태가 아니면 down() 호출
    			} else if (!player.isUp() && !player.isDown()) {
    					player.down();
    			}
    			System.out.println("bottomColor : " + bottomColorLeft);
    			
    			// 왼쪽 벽에 충돌함
    			if (leftColor.getRed() == 255 && leftColor.getGreen() == 0 && leftColor.getBlue() == 0) {
    				System.out.println("왼쪽벽에 충돌함");
    				player.setLeftWallCrash(true);
    				player.setLeft(false);
    			} else if (rightColor.getRed() == 255 && rightColor.getGreen() == 0 && rightColor.getBlue() == 0) {
    				System.out.println("오른쪽벽에 충돌함");
    				player.setRightWallCrash(true);
    				player.setRight(false);
    			} else {
    				player.setLeftWallCrash(false);
    				player.setRightWallCrash(false);
    			}
    			// 위 두 조건이 아니면 player는 마음대로 움직일 수 있다.
    			
    			try {
    				Thread.sleep(10);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    }

    정리

    down()을 계속 떨어지도록 변경

    • 기존의 for문으로 작성된 반복을 while문으로 변경

    바닥 색 감지 후 떨어지지 않도록 함

    • 역으로 흰색을 감지해서 흰색아닐때만 떨어지지 않도록 함

    바닥이 없을 때는 계속 떨어져야함

    • 위의 상황에서는 3층 까지 올라간 다음 바닥이 없는 곳으로 가면 공중에 떠있음
    • 그러면 그냥 항상 떨어지도록 한다음 특정 상황에서만 안떨어지게 하면됨
    • 그 특정 상황은 이미 적용되었던 흰색이 아닐때, 점프하는 중, 이미 떨어지고 있는중일때

    Swing 목차로 돌아가기

    'Java > Swing 프로젝트' 카테고리의 다른 글

    Bubble 버블 벽 감지 - 7  (0) 2024.05.07
    Bubble 버블 동작 처리 - 6  (1) 2024.05.03
    Bubble (물방울 생성) - 4  (0) 2024.05.03
    Bubble (Daemon Thread 활용) - 3  (0) 2024.05.02
    Bubble (Thread 활용) - 2  (0) 2024.05.02