본문 바로가기
Java/자바 Swing

[Java] 71. Swing: 버블버블 게임 만들기(2)

글: Song hyun 2024. 5. 2.
728x90
반응형

[Java] 71. Swing: 버블버블 게임 만들기(2)

이전 글: https://whatsthatsound.tistory.com/132

 

[Java] 70. Swing: 버블버블 게임 만들기(1)

[Java] 70. Swing: 버블버블 게임 만들기(1) 자바의 GUI Swing을 사용해 버블버블 게임을 구현해보자. (1) Moveable 인터페이스 구현하기(2) Player 클래스 및 메서드 구현하기(3) BubbleFrame 내에서 배경 및

whatsthatsound.tistory.com


1. 목차

자바의 GUI Swing을 사용해 이전의 코드를 보완해보자.

 

(1) 플레이어 캐릭터의 좌/우 움직임을 부드럽게 만들기

(2) 방향키에서 손을 떼었을 때, 움직임 멈추게 하기

(3) 부드럽게 점프 시키기(올라갔다가-내려가기)


2. 구현해야 할 동작들

(1) 플레이어 캐릭터의 좌/우 움직임을 부드럽게 만들기

-방향키를 누르고 있는 동안(keyEvent 발생/KeyPressed) 계속 움직이도록(while 반복문) 하기

-해당 동작을 Thread로 구현해보자. 

 

(2) 방향키에서 손을 떼었을 때, 움직임 멈추게 하기

-방향키에서 손을 떼었을 때(keyEvent 발생/KeyReleased) 움직임을 멈추도록 하기

-(1)에서 구현한 while문에 Boolean형 멤버 변수를 선언해 움직임을 제어해보자.

keyReleased 신호를 받았을 때, while문의 실행 조건을 false로 만들면 간단하게 움직임을 제어할 수 있다.


3. 코드 블록

(2) BubbleFrame : 프레임 / 키 이벤트 / 시범 실행

(3) Player : player 객체 및 메서드 생성 (moveable 구현), 움직임 쓰레드 구현(Run-Start)

(4) Moveable : 인터페이스

package BubbleBubble.test.ex02;

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

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class BubbleFrame extends JFrame {
	private JLabel backgroundMap;
	private Player player;

	public BubbleFrame() {
		initData();
		setInitLayout();
		addEventListener();
	}

	private void initData() {
		backgroundMap = new JLabel(new ImageIcon("img/backgroundMap.png"));
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// Frame --> root Panel
		setContentPane(backgroundMap);
		setSize(1000, 640);

		player = new Player();
	}

	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:
					player.left();
					break;
				case KeyEvent.VK_RIGHT:
					player.right();
					break;
				case KeyEvent.VK_UP:
					player.up();
					break;
				}
			} // end of key pressed
			
			@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;
				}
			} // end of keyReleased
			
		}); // end of keyAdapter
	}
	
	// 코드 테스트
	public static void main(String[] args) {
		new BubbleFrame();
	}

}
package BubbleBubble.test.ex02;

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 boolean left;
	private boolean right;
	private boolean up;
	private boolean down;

	// 플레이어 속도 상태
	private final int SPEED = 4;
	private final int JUMPSPEED = 2;
	
	// setter 메서드
	public void setLeft(boolean left) {
		this.left=left;
	}
	public void setRight(boolean right) {
		this.right=right;
	}
	public void setUp(boolean up) {
		this.up=up;
	}

	public Player() {
		initData();
		setInitLayout();

	}

	private void initData() {
		playerR = new ImageIcon("img/playerR.png");
		playerL = new ImageIcon("img/playerL.png");

		// 처음 실행 시 초기 값 셋팅
		x = 55;
		y = 535;
		// 플레이어가 가만히 멈춘 상태
		left=false;
		right=false;
		up=false;
		down=false;
		
		setIcon(playerR);
		this.setSize(50, 50);
		setLocation(x, y);
	}

	private void setInitLayout() {

	}

	@Override
	public void 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) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				} // end of while
			} // end of run
			
		}).start(); // end of Thread
		
	}

	@Override
	public void 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) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				} // end of while
			} // end of run
		}).start(); // end of Rannable

	} // end of right

	@Override
	public void up() {
		System.out.println("점프");
		up=true;
		setIcon(playerR);
		
		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();
					}
				} // end of for
				
				up=false;
				down();
				
				} // end of run
		}).start();
		//객체의 상태값을 잘 조절해야 한다.
	}

	@Override
	public void down() {
		System.out.println("다운");
		down=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(3);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			
		}).start();
		// 상태 처리
		down = false;

	}

}
package BubbleBubble.test.ex02;

public interface Moveable {

	// public abstract 생략 가능
	public abstract void left();

	public abstract void right();

	public abstract void up();

	public abstract void down();

}

 

728x90
반응형