본문 바로가기

Coding_Study/Java_Code_Memo

JButton으로 슈팅게임 2-2 총알 만들기

2020/12/11 - [Java_Study/Code_Memo] - JButton으로 슈팅게임 2-1 주인공 만들기

 

JButton으로 슈팅게임 2-1 주인공 만들기

저는 게임 구상을 페이즈 1,2(Phase1, Phase2)로 나눠서 진행하도록 했습니다. Phase1 에서는 일반 몹들이 나오고, 그 중 특정 몹(Monster)을 몇 번 이상 잡으면 Phase1이 종료, 보스(Boss)가 나오는 Phase2로 넘

mintpearl-story.tistory.com

 

주인공(btnMe)를 붙이는데도 시행착오를 많이 겪었습니다.

키 리스너를 붙이느라 씨름을 했었죠.

산 너머 산이라고, 사실 지금부터 시작입니다.

 

저는 국비지원 학원을 다니고 있고,

스레드를 배운 뒤 사용해보기 위한 팀 프로젝트를 진행했었습니다.

비전공자라 수업시간에 한 것만으로는 부족함을 느꼈고,

그래서 혼자 만들어보면서 기록을 남기는 중입니다.

결론은 지금부터 스레드와의 싸움을 시작해야 한다는 것입니다.

 

지난번에 방향키를 설정했다면 이번에는 Space Bar를 누를 때 총알이 나가는 작업을 해보겠습니다.

 

전제 : Space bar를 누르면 총알 Jbutton을 새로 생성

 

오늘 할 일 : 총알 JButton class를 만들고 Runnable을 이용하여 총알 직전 설정

                  플레이 패널(Play_Phase1) keyPressed에 해당 기능 삽입

 

 

 

 

 

- 총알 JButton class에 Runnable로 Thread 구현

- 플레이 화면(Play_Phase1)에 있는 메소드로 위치(Point) 보내주기

- 만약 움직이지 않고 총부터 쏜다면 Point 값이 null이 되기 때문에 if문으로 초기 위치 설정

- run() 안에 while()을 사용해 총알이 반대편 끝에 닿으면 끝나게 설정

- while문을 빠져나오면, 총알 JButton 스스로를 지우고 화면 갱신

- (중요) 단순히 버튼을 지우면 패널에 버튼은 사라지는데 위치는 계속해서 남아있어서 저어기 우주 끝까지 날아가는 것을 확인할 수 있음

            처음에는 현재와 같이 코드를 구상했으나 스레드를 여러 개 돌리면 컴퓨터가 힘들지 않을까 뇌피셜로 노선을 바꿈

            사실 스레드를 증오한 나머지 한 스레드에 여러개의 객체를 돌려보려고 했으나

            객체를 지울 때 스레드를 멈춰주지 않으면 안 된다는 것을 알고 각각의 스레드로 노선을 다시 바꿈

            결론 : 스레드와 친해질 시간

            + 혹시 더 나은 방법이 있다면 조언 부탁드립니다.

            + 테스트 코드를 통해 총알의 위치가 어디서 멈추는지 확인 완료

package Game1;

import javax.swing.ImageIcon;
import javax.swing.JButton;

public class BtnBullet extends JButton implements Runnable{
	Play_Phase1 play1;
	private int bulletX, bulletY;
	
	
	BtnBullet(Play_Phase1 play1){
		this.play1 = play1;
		
		//btnMe의 위치에 따라 총알의 초기값을 조정해주기
		if(play1.poMe != null) {//btnMe의 중간에서 총알이 나가게 함 
			bulletX = play1.poMe.x+15;
			bulletY = play1.poMe.y;
		} else{ //만약 움직이지 않으면 Point 메소드에 값이 전달되지 않아 null이 됨
			bulletX = 240;
			bulletY = 720;
		}
		
		ImageIcon icon = new ImageIcon("총알.png"); //이미지 처리
		this.setIcon(icon);
		this.setBorderPainted(false);
		this.setFocusPainted(false);
		this.setContentAreaFilled(false);
		this.setBounds(bulletX, bulletY, 20,20);
		
		/**add Bullet*/
		play1.add(this);
	}
	
	
	
	
	@Override
	public void run() {
		while(bulletY > 30) { //끝에 닿을 때 까지 움직이기
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			/**run Bullet*/
			this.setLocation(bulletX, bulletY-= 30);
			//System.out.println(this.getLocation());//테스트 코드
		}
		play1.remove(this);
		play1.repaint();
		play1.revalidate();
	}

}

 

 

 

 

- 플레이 Panel (Play_Phase1)에 keyPressed 내용 갱신

- 스페이스를 누를 때 총알 class 초기와 후 스레드를 생성

bullet = new BtnBullet(this);
Thread t = new Thread(bullet);
t.start();

//한 줄이라도 줄여보고자 수정
bullet = new BtnBullet(this);
(new Thread(bullet)).start();

- 아래 위치 설정하는 부분에 총알 위치 설정 메소드로 위치를 같이 보내기

public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()==KeyEvent.VK_RIGHT) {
			meX += 20;
		} else if(e.getKeyCode()==KeyEvent.VK_LEFT) {
			meX -= 20;
		} else if(e.getKeyCode()==KeyEvent.VK_UP) {
			meY -= 20;
		} else if(e.getKeyCode()==KeyEvent.VK_DOWN) {
			meY += 20;
		} else if(e.getKeyCode()==KeyEvent.VK_SPACE) {
			 if(!isSpacePress){ //스페이스 연사를 방지하기 위함
				isSpacePress=true;
			}
			 bullet = new BtnBullet(this);
			(new Thread(bullet)).start();
			 
		}
		if(meX < 10) {  //일정 범위 이상 못 나가도록
			meX = 10;
		} else if(meX > 450) {
			meX = 440;
		} else if(meY < 300) {
			meY = 300;
		} else if(meY > 700) {
			meY = 700;
		}
		
		btnMe.setLocation(meX, meY); //위치 설정
		setMePosition(meX, meY); //총알을 위한 위치 설정 메소드
		
		this.repaint(); //화면 갱신
		this.revalidate();
	}

- 주인공(btnMe)의 위치로 총알의 초기 위치를 설정하기 위한 메소드 추가

/**Me Location*/
	void setMePosition(int meX, int meY) {
		poMe = new Point(meX, meY);
	}

 

 

아마 다음번에는 기존 코드 대 공사를 들어가야 할 수도 있겠네요 ...

몬스터들을 추가........ㅠㅠ