Loading...

JAVA / / 2022. 2. 9. 12:34

자바 53강. 버블게임 만들기(4) : 점프

반응형

점프 구현

package site.metacoding.bubble.test;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 * 
 * @author Administrator 목적 : 점프
 *
 */

public class BubbleFrame extends JFrame {

	private JLabel backgroundMap; // 배경 이미지
	private Player player; // JLabel

	public BubbleFrame() {

		initSetting(); // 각종 모든 세팅
		initObject(); // new 하는 곳
		initListener(); // 리스너

		setVisible(true); // 내부에 paintComponent() 호출 코드가 있음
	}

	// 각종 모든 세팅
	private void initSetting() {
		setSize(1000, 640); // Frame Size
		getContentPane().setLayout(null); // null을 줘야 absoulute 레이아웃으로 변경됨
		setLocationRelativeTo(null); // Frame을 화면 중앙에 배치
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // x버튼 클릭시 JVM 같이 종료하기
	}

	private void initObject() {
		backgroundMap = new JLabel(new ImageIcon("image/backgroundMap.png"));
		setContentPane(backgroundMap); // 백그라운드 이미지 설정

		player = new Player(); // 플레이어 추가
		add(player); // Frame에 추가
	}

	// 리스너
	private void initListener() {
		// 키보드 리스너
		addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {

			}

			@Override
			public void keyReleased(KeyEvent e) { // 누른걸 떼면
				System.out.println("키보드 릴리즈");

				// 키보드를 놓으면 상태를 변경해 주어야 함
				if (e.getKeyCode() == KeyEvent.VK_RIGHT) { // VK_RIGHT = 39
					// isRight를 false로
					player.setRight(false);
				} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
					// isLeft를 false로
					player.setLeft(false);
				}
			}

			// 조이스틱
			@Override
			public void keyPressed(KeyEvent e) { // 키보드를 누르면
				// 왼쪽 37, 위쪽 38, 오른쪽 39, 아래쪽 40
				System.out.println("키보드 프레스 : " + e.getKeyCode());

				// 키보드를 누르고있는지 아닌지 확인하는 상태 변수
				if (e.getKeyCode() == KeyEvent.VK_RIGHT) {

					// 키보드를 누르고 있는 동안 right() 메서드는 한번만 실행하고 싶다.
					if (player.isRight() == false) {
						player.right(); // 오른쪽으로 가고있지 않을때 오른쪽 키를 누르면 right() 메서드 실행
					}
				} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {

					if (player.isLeft() == false) {
						player.left(); // 왼쪽으로 가고있지 않을때 왼쪽 키를 누르면 left() 메서드 실행
					}
				} else if (e.getKeyCode() == KeyEvent.VK_UP) {

					if (player.isJump() == false) {
						player.jump(); // 위쪽으로 가고있지 않을때 위쪽 키를 누르면 jump() 메서드 실행
					}
				}
			}
		});
	}

	public static void main(String[] args) {
		new BubbleFrame();
	}

}

 

package site.metacoding.bubble.test;

import javax.swing.ImageIcon;
import javax.swing.JLabel;

/**
 * 
 * @author Administrator 플레이어는 좌우이동, 점프가 가능하다. 방울을 발사하며 공격을 한다.(나중에) 플레이어의 위치는
 *         x, y좌표로 지정해준다. x좌표로 좌우이동, y좌표로 점프 실행
 *
 */

public class Player extends JLabel {
	private int x; // 플레이어의 x좌표
	private int y; // 플레이어의 y좌표

	private ImageIcon playerR; // 오른쪽을 보고있는 플레이어 Image
	private ImageIcon playerL; // 왼쪽을 보고있는 플레이어 Image

	private boolean isRight; // 보통 boolean타입 변수 이름에는 is가 붙음
	private boolean isLeft;
	private boolean isJump;

	private static final int JUMPSPEED = 2; // 점프 속도
	private static final int SPEED = 4; // 이동 속도

	// 자바 특징 : is가 붙은 boolean 변수의 getter는 getIsRight가 아닌 isRight라고 이름이 붙음
	public boolean isRight() {
		return isRight;
	}

	// 자바 특징 : is가 붙은 boolean 변수의 setter는 setIsRight가 아닌 setRight라고 이름이 붙음
	public void setRight(boolean isRight) {
		this.isRight = isRight;
	}

	public boolean isLeft() {
		return isLeft;
	}

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

	public boolean isJump() {
		return isJump;
	}

	public void setJump(boolean isJump) {
		this.isJump = isJump;
	}

	public Player() {
		initObject();
		initSetting();
	}

	private void initObject() {
		playerR = new ImageIcon("image/playerR.png");
		playerL = new ImageIcon("image/playerL.png");
	}

	// 생성자에서 초기화
	// 생성자에 호출되어있는 메서드니까 얘도 생성자 취급!
	private void initSetting() {
		x = 70;
		y = 535;
		setIcon(playerR);
		setSize(50, 50);
		setLocation(x, y); // paintComponent 호출, 부분 새로고침

		// 처음 시작엔 가만히 있는 상태
		isRight = false;
		isLeft = false;
		isJump = false;

	}

	// 하나의 단일 책임을 가진 메서드, 메서드 모듈
	// 외부에서 호출 가능하게 public
	public void right() {
		isRight = true;

		System.out.println("오른쪽 이동");

		setIcon(playerR);

		// 새로운 스레드 생성
		new Thread(() -> {
			// isRight가 true일때만 이동
			while (isRight) {
				x = x + SPEED;
				setLocation(x, y); // 그림 다시 그리기
				try {
					Thread.sleep(10);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

	public void left() {
		isLeft = true;

		System.out.println("왼쪽 이동");

		setIcon(playerL);

		// 새로운 스레드 생성
		new Thread(() -> {
			// isLeft가 true일때만 이동
			while (isLeft) {
				x = x - SPEED;
				setLocation(x, y); // 그림 다시 그리기
				try {
					Thread.sleep(10);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

	public void jump() {
		isJump = true;

		System.out.println("위로 점프");
		// 점프는 for문을 돌려야함
		// up : sleep(5), down : sleep(3)

		// 새로운 스레드 생성
		new Thread(() -> {
			// up
			for (int i = 0; i < 130 / JUMPSPEED; i++) { // JUMPSPEED에 따라 높이가 달라지면 안됨!
				y = y - JUMPSPEED;
				setLocation(x, y); // 그림 다시 그리기

				try {
					Thread.sleep(5);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			// down
			// 바닥에 떨어지는 건 while로 수정!
			for (int i = 0; i < 130 / JUMPSPEED; i++) {
				y = y + JUMPSPEED;
				setLocation(x, y); // 그림 다시 그리기
				try {
					Thread.sleep(3);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			isJump = false;

		}).start();
	}
}
반응형