티스토리 뷰

목차


    반응형

     

     

    package site.metacoding.mytest;
    
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    
    /**
     * 
     * @author 정재원
     * 
     *
     */
    
    // main을 가진 클래스는 해당 프로그램의 컨텍스트(문맥)를 다 알고 있다.
    public class BubbleFrame extends JFrame {
    
    	private static final String TAG = "BubbleFrame : ";
    
    	private BubbleFrame context = this;
    
    	private JLabel backgroundMap; // JLabel로 사진 붙이기
    	private Player player;
    
    	public Player getPlayer() {
    		return player;
    	}
    
    	public void setPlayer(Player player) {
    		this.player = player;
    	}
    
    	public BubbleFrame() {
    		initObject();
    		initSetting();
    		initListener();
    		initService();
    
    		setVisible(true); // 내부에 paintComponent() 호출 코드가 있다.
    	}
    
    	// 각종 모든 세팅
    	private void initSetting() {
    		setSize(1000, 640);
    		setLayout(null); // JFrame의 기본 JPanel의 레이아웃을 AbsoulteLayout으로 설정
    		setLocationRelativeTo(null); // JFrame 화면 가운데 배치
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // x버튼 클릭시 JVM 같이 종료
    	}
    
    	// new 하는 곳
    	private void initObject() {
    		backgroundMap = new JLabel(new ImageIcon("image/backgroundMap.png"));
    		setContentPane(backgroundMap); // 백그라운드 화면 설정
    
    		player = new Player(context); // 플레이어 생성
    		add(player); // Frame에 플레이어 붙이기
    	}
    
    	private void initListener() {
    		addKeyListener(new KeyAdapter() {
    
    			@Override
    			public void keyPressed(KeyEvent e) {
    
    				if (e.getKeyCode() == KeyEvent.VK_LEFT) {
    					if (!player.isLeft() && !player.isLeftWallCrash()) {
    						player.left();
    					}
    				} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
    					if (!player.isRight() && !player.isRightWallCrash()) {
    						player.right();
    					}
    				} else if (e.getKeyCode() == KeyEvent.VK_UP) {
    					if (!player.isUp() && !player.isDown()) {
    						player.up();
    					}
    				} else if (e.getKeyCode() == KeyEvent.VK_SPACE) {
    					player.attack();
    				}
    			}
    
    			@Override
    			public void keyReleased(KeyEvent e) {
    				// System.out.println(TAG + "키보드 릴리즈");
    
    				if (e.getKeyCode() == KeyEvent.VK_LEFT) {
    					// isLeft를 false로
    					player.setLeft(false);
    				} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
    					// isRight를 false로
    					player.setRight(false);
    				}
    			}
    
    		});
    	}
    
    	// backgroundMapService 독립적인 스레드
    	private void initService() {
    		new Thread(new BackgroundMapService(player)).start();
    
    	}
    
    	public static void main(String[] args) {
    		new BubbleFrame();
    	}
    
    }
    package site.metacoding.mytest;
    
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    
    /**
     * 
     * @author 정재원 플레이어는 좌우이동이 가능하다. 점프가 가능하다. 방울을 발사한다.
     *
     */
    
    public class Player extends JLabel {
    
    	private static final String TAG = "Player : ";
    
    	private BubbleFrame context;
    
    	private static final int SPEED = 4;
    	private static final int JUMPSPEED = 2;
    
    	// 위치 상태
    	private int x, y;
    	private ImageIcon playerR, playerL;
    
    	// 움직임 상태
    	private boolean isLeft, isRight, isUp, isDown;
    
    	// 충돌 상태
    	private boolean leftWallCrash, rightWallCrash;
    
    	// 방향 상태
    	private int direction; // -1 왼쪽 0 상태x 1 오른쪽
    
    	// X
    	public int getX() {
    		return x;
    	}
    
    	public void setX(int x) {
    		this.x = x;
    	}
    
    	// Y
    	public int getY() {
    		return y;
    	}
    
    	public void setY(int y) {
    		this.y = y;
    	}
    
    	// isLeft
    	public boolean isLeft() {
    		return isLeft;
    	}
    
    	public void setLeft(boolean isLeft) {
    		this.isLeft = isLeft;
    	}
    
    	// isRight
    	public boolean isRight() {
    		return isRight;
    	}
    
    	public void setRight(boolean isRight) {
    		this.isRight = isRight;
    	}
    
    	// isUp
    	public boolean isUp() {
    		return isUp;
    	}
    
    	public void setUp(boolean isUp) {
    		this.isUp = isUp;
    	}
    
    	// isDown
    	public boolean isDown() {
    		return isDown;
    	}
    
    	public void setDown(boolean isDown) {
    		this.isDown = isDown;
    	}
    
    	// leftWallCrash
    	public boolean isLeftWallCrash() {
    		return leftWallCrash;
    	}
    
    	public void setLeftWallCrash(boolean leftWallCrash) {
    		this.leftWallCrash = leftWallCrash;
    	}
    
    	// rightWallCrash
    	public boolean isRightWallCrash() {
    		return rightWallCrash;
    	}
    
    	public void setRightWallCrash(boolean rightWallCrash) {
    		this.rightWallCrash = rightWallCrash;
    	}
    
    	// direction
    	public int getDirection() {
    		return direction;
    	}
    
    	public void setDirection(int direction) {
    		this.direction = direction;
    	}
    
    	// 생성자
    	public Player(BubbleFrame context) {
    		this.context = context;
    
    		initObject();
    		initSetting();
    	}
    
    	private void initSetting() {
    		// 플레이어 좌표 설정
    		x = 90;
    		y = 535;
    
    		// default 사진 설정
    		setIcon(playerR);
    		setSize(50, 50);
    
    		// 플레이어 그림 그리기 paintComponent 호출
    		setLocation(x, y);
    
    		isLeft = false;
    		isRight = false;
    		isUp = false;
    		isDown = false;
    
    		leftWallCrash = false;
    		rightWallCrash = false;
    
    		direction = 1;
    	}
    
    	private void initObject() {
    		playerR = new ImageIcon("image/playerR.png");
    		playerL = new ImageIcon("image/playerL.png");
    	}
    
    	public void left() {
    		System.out.println(TAG + "왼쪽");
    
    		isLeft = true;
    		setRightWallCrash(false);
    		direction = -1;
    		setIcon(playerL);
    
    		new Thread(() -> {
    			while (isLeft) {
    				x = x - SPEED;
    				setLocation(x, y);
    
    				try {
    					Thread.sleep(10);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		}).start();
    	}
    
    	public void right() {
    		System.out.println(TAG + "오른쪽");
    
    		isRight = true;
    		setLeftWallCrash(false);
    		direction = 1;
    		setIcon(playerR);
    
    		new Thread(() -> {
    			while (isRight) {
    				x = x + SPEED;
    				setLocation(x, y);
    
    				try {
    					Thread.sleep(10);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		}).start();
    	}
    
    	public void up() {
    		System.out.println(TAG + "위쪽");
    
    		isUp = true;
    
    		new Thread(() -> {
    			// up
    			for (int i = 0; i < 130 / JUMPSPEED; i++) {
    				y = y - JUMPSPEED;
    				setLocation(x, y);
    
    				try {
    					Thread.sleep(5);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    
    			isUp = false;
    			down();
    
    		}).start();
    	}
    
    	public void down() {
    		System.out.println(TAG + "아래쪽");
    		isDown = true;
    
    		new Thread(() -> {
    			// down
    			while (isDown) {
    				y = y + JUMPSPEED;
    				setLocation(x, y);
    
    				try {
    					Thread.sleep(3);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    
    		}).start();
    	}
    
    	public void attack() {
    		System.out.println(TAG + "공격!");
    		Bubble bubble = new Bubble(context); // JLabel
    		context.add(bubble);
    
    		new Thread(new BackgroundBubbleService(bubble)).start();
    	}
    }
    package site.metacoding.mytest;
    
    import java.awt.Color;
    import java.awt.image.BufferedImage;
    import java.io.File;
    
    import javax.imageio.ImageIO;
    
    // 백그라운드 서비스 (독립적인 스레드로 돌려야 한다)
    public class BackgroundMapService implements Runnable {
    
    	private static final String TAG = "BackgroundMapService : ";
    
    	// 컴포지션
    	private Player player;
    	private BufferedImage image;
    
    	// 컴포지션을 위한 기술 -> 의존성 주입 (생성자를 통해서 주입) = DI (Dependency Injection)
    	public BackgroundMapService(Player player) {
    		this.player = player;
    
    		try {
    			image = ImageIO.read(new File("image/backgroundMapService.png"));
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	@Override
    	public void run() {
    		// 멈추지 않고 while을 돌며 색상 확인
    		while (true) {
    			try {
    				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));
    
    				// System.out.println(TAG + "leftColor : " + leftColor);
    				// System.out.println(TAG + "rightColor : " + rightColor);
    
    				int bottomColor = image.getRGB(player.getX() + 10, player.getY() + 50 + 5) // -1
    						+ image.getRGB(player.getX() + 50 - 10, player.getY() + 50 + 5); // -1
    
    				// System.out.println(TAG + bottomColor);
    
    				if (bottomColor != -2) { // 바닥에 장애물이 있다!
    					// System.out.println(TAG + "바닥에 밟히는게 있네");
    					player.setDown(false); // 그만 떨어져
    				} else { // 바닥이 흰색
    					if (!player.isDown() && !player.isUp()) {
    						// System.out.println(TAG + "바닥에 아무것도 없어!!");
    						player.down();
    					}
    				}
    
    				if (leftColor.getRed() == 255 && leftColor.getGreen() == 0 && leftColor.getBlue() == 0) { // 왼쪽벽이 빨간색이면
    					System.out.println(TAG + "왼쪽 벽에 부딪혔다!");
    					player.setLeftWallCrash(true);
    					player.setLeft(false);
    				} else if (rightColor.getRed() == 255 && rightColor.getGreen() == 0 && rightColor.getBlue() == 0) {
    					System.out.println(TAG + "오른쪽 벽에 부딪혔다!");
    					player.setRightWallCrash(true);
    					player.setRight(false);
    				}
    
    				Thread.sleep(10);
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    }
    package site.metacoding.mytest;
    
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    
    public class Bubble extends JLabel {
    
    	private static final String TAG = "Bubble : ";
    	private static final int BUBBLESPEED = 1;
    
    	private BubbleFrame context;
    	private Player player;
    
    	private int x, y;
    
    	private ImageIcon bubble, bomb;
    
    	private boolean isLeft, isRight, isUp, topWallCrash, leftWallCrash, rightWallCrash;
    
    	// isLeft
    	public boolean isLeft() {
    		return isLeft;
    	}
    
    	public void setLeft(boolean isLeft) {
    		this.isLeft = isLeft;
    	}
    
    	// isRight
    	public boolean isRight() {
    		return isRight;
    	}
    
    	public void setRight(boolean isRight) {
    		this.isRight = isRight;
    	}
    
    	// isUp
    	public boolean isUp() {
    		return isUp;
    	}
    
    	public void setUp(boolean isUp) {
    		this.isUp = isUp;
    	}
    
    	// topWallCrash
    	public boolean isTopWallCrash() {
    		return topWallCrash;
    	}
    
    	public void setTopWallCrash(boolean topWallCrash) {
    		this.topWallCrash = topWallCrash;
    	}
    
    	// leftWallCrash
    	public boolean isLeftWallCrash() {
    		return leftWallCrash;
    	}
    
    	public void setLeftWallCrash(boolean leftWallCrash) {
    		this.leftWallCrash = leftWallCrash;
    	}
    
    	// rightWallCrash
    	public boolean isRightWallCrash() {
    		return rightWallCrash;
    	}
    
    	public void setRightWallCrash(boolean rightWallCrash) {
    		this.rightWallCrash = rightWallCrash;
    	}
    
    	// bubble은 player의 위치에 의존해야한다.
    	// player에만 의존하면 적군을 만들 때 문제가 발생함
    	// 따라서 context에 의존!
    	public Bubble(BubbleFrame context) {
    		this.context = context;
    		this.player = context.getPlayer();
    
    		isLeft = false;
    		isRight = false;
    		isUp = false;
    		topWallCrash = false;
    		leftWallCrash = false;
    		rightWallCrash = false;
    
    		initObject();
    		initSetting();
    
    		// 방향체크
    		if (player.getDirection() == -1) {
    			left();
    		} else if (player.getDirection() == 1) {
    			right();
    		}
    	}
    
    	private void initObject() {
    		bubble = new ImageIcon("image/bubble.png");
    		bomb = new ImageIcon("image/bomb.png");
    	}
    
    	private void initSetting() {
    		x = player.getX();
    		y = player.getY();
    
    		setIcon(bubble);
    		setSize(50, 50);
    		setLocation(x, y);
    	}
    
    	public void left() {
    		isLeft = true;
    
    		new Thread(() -> {
    			try {
    				for (int i = 0; i < 400; i++) {
    					x = x - BUBBLESPEED;
    					setLocation(x, y);
    					Thread.sleep(1);
    
    					if (leftWallCrash == true) {
    						up();
    						break;
    					} else if (i == 399) {
    						up();
    					}
    				}
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}).start();
    
    	}
    
    	public void right() {
    		new Thread(() -> {
    			try {
    				for (int i = 0; i < 400; i++) {
    					x = x + BUBBLESPEED;
    					setLocation(x, y);
    					Thread.sleep(1);
    
    					if (rightWallCrash == true) {
    						up();
    						break;
    					} else if (i == 399) {
    						up();
    					}
    				}
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}).start();
    	}
    
    	public void up() {
    		isUp = true;
    
    		try {
    			while (isUp) {
    				y = y - BUBBLESPEED;
    				setLocation(x, y);
    				Thread.sleep(1);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	public void pop() {
    		// 천장에 붙고 4초뒤에 사진변경, repaint
    		// setTopWallCrash가 트루면
    
    		new Thread(() -> {
    
    			try {
    				Thread.sleep(4000);
    
    				if (topWallCrash == true) {
    					setIcon(bomb);
    					setLocation(x, y);
    
    					Thread.sleep(1000);
    					context.remove(this);
    					context.repaint();
    				}
    
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    
    		}).start();
    
    	}
    }
    package site.metacoding.mytest;
    
    import java.awt.Color;
    import java.awt.image.BufferedImage;
    import java.io.File;
    
    import javax.imageio.ImageIO;
    
    // 백그라운드 서비스 (독립적인 스레드로 돌려야 한다)
    public class BackgroundBubbleService implements Runnable {
    
    	private static final String TAG = "BackgroundBubbleService : ";
    
    	private Bubble bubble;
    	private BufferedImage image;
    
    	public BackgroundBubbleService(Bubble bubble) {
    		this.bubble = bubble;
    
    		try {
    			image = ImageIO.read(new File("image/backgroundMapService.png"));
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	@Override
    	public void run() {
    		// 멈추지 않고 while을 돌며 색상 확인
    		while (true) {
    			try {
    
    				Color leftColor = new Color(image.getRGB(bubble.getX() - 10, bubble.getY() + 25));
    				Color rightColor = new Color(image.getRGB(bubble.getX() + 50 + 10, bubble.getY() + 25));
    
    				int topColor = image.getRGB(bubble.getX() + 25, bubble.getY() - 5);
    
    				// System.out.println(TAG + topColor);
    
    				if (topColor == -65536) { // 버블이 천장에 닿았어!
    					// System.out.println(TAG + "머리 부딪혔어");
    					bubble.setUp(false); // 그만 올라가
    					bubble.setTopWallCrash(true);
    					bubble.pop();
    				}
    
    				if (leftColor.getRed() == 255 && leftColor.getGreen() == 0 && leftColor.getBlue() == 0) { // 왼쪽벽이 빨간색이면
    					// System.out.println(TAG + "왼쪽 벽에 부딪혔다!");
    					bubble.setLeftWallCrash(true);
    					bubble.setLeft(false);
    				} else if (rightColor.getRed() == 255 && rightColor.getGreen() == 0 && rightColor.getBlue() == 0) {
    					// System.out.println(TAG + "오른쪽 벽에 부딪혔다!");
    					bubble.setRightWallCrash(true);
    					bubble.setRight(false);
    				}
    
    				Thread.sleep(10);
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    반응형