본문 바로가기

Coding_Study/Java_Code_Memo

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

저는 게임 구상을 페이즈 1,2(Phase1, Phase2)로 나눠서 진행하도록 했습니다.

Phase1 에서는 일반 몹들이 나오고,

그 중 특정 몹(Monster)을 몇 번 이상 잡으면 Phase1이 종료,

보스(Boss)가 나오는 Phase2로 넘어갑니다.

(전과 마찬가지로 Phase는 JPanel로 구분합니다.)

 

전제 : Phase1, Phase2의 공통점으로 주인공 JButton

         주인공은 Phase2에서 재활용 예정이므로 Class로 따로 빼줌

 

오늘 할 일 : 주인공 JButton Class 만들기

                Phase1에 JButton 붙이고 Key Listener로 움직이게 하기

 

*주인공을 찾아보세요 ㅋㅋㅋㅋ

 

 

 

- JButton을 재활용하기 위해 Class따로 빼기

   (메인 JPanel(Play_Phase1)에 붙여도 되지만 한 class가 너무 길어지는 것을 방지하기 위해 ..)

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

package Game1;

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

public class BtnMe extends JButton {
	Play_Phase1 play1;
	
	BtnMe(Play_Phase1 play1){
		this.play1 = play1;
		ImageIcon imageMe = new ImageIcon("주인공.png");
		this.setIcon(imageMe);
		this.setBorderPainted(false);
		this.setFocusPainted(false);
		this.setContentAreaFilled(false);
	}
}

 

 

 

- 플레이를 위한 JPanel에 만들었던 JButton과 Key Listener 붙이기

- (중요) 움직일 JButton이 아니라 버튼이 붙어있는 JPanel에 Key Listener붙여줘야함

- keyPressed : 해당 key(키보드)에 따른 기능을 if문으로 설정해줌

                        총알 쏘는 내용은 아직 만들지 않아서 비워둠

                        총알을 쏠 때 스페이스 연속으로 누를 수 없게 막아두기( + keyReleased)

                        주인공(btnMe)이 일정 범위를 벗어나지 못하게 범위 설정

package Game1;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import miniGame_Main_ChooseGame.Main_StartHere;

public class Play_Phase1 extends JPanel implements KeyListener{
	Main_StartHere main;
	BtnMe btnMe;
	private Image backgroundImage; //배경 이미지
	private int meX = 225, meY =720;
	private boolean isSpacePress;
	
	public Play_Phase1(Main_StartHere main) {
		this.main = main;
		try {//배경 이미지 삽입
			backgroundImage = ImageIO.read(new File("스테이지1.jpg"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		this.setSize(500,800); 
		this.setLayout(null); //자유롭게 움직이기위해 레이아웃을 없앤다.
		this.addKeyListener(this); //btnMe를 키값으로 움직이기 위해
		
		btnMe = new BtnMe(this); //주인공 버튼 class
		btnMe.setBounds(meX,meY, 50,50);
		this.add(btnMe);
		
	}
	
	

	

	@Override
	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;
			}
			
			//총알 발사 내용 넣기
			 
		}
		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); //위치 설정
		
		this.repaint(); //화면 갱신
		this.revalidate();
	}
	
	@Override
	   public void keyReleased(KeyEvent e) {//스페이스 연사를 방지하기 위함
	      isSpacePress=false;
	   }
	
	
	public void keyTyped(KeyEvent e) {} //사용 안 함

	@Override
	protected void paintComponent(Graphics g) {	 //이미지 작업
		super.paintComponent(g);
		g.drawImage(backgroundImage,0,0,500,800,null);			
	}

}

 

 

 

여기까지 만들고 게임을 실행시키면 btnMe가 꿈쩍도 안하는 것을 볼 수 있습니다.

왜냐하면 보통 Key Listener를 JFrame에 사용하는데,

저는 JPanel을 사용했기 때문이고,

JPanel을 사용하는 경우에는 아래 두 가지가 필요하기 때문입니다.

.setFocusable(true);
.requestFocus();

Focus를 JPanel에 끌어와야 Key를 눌렀을 때 JPanel에 적용이 되는 거죠.

그런데 또 문제가 있습니다.

JFrame과 JPanel이 다른 class인데, 과연 이 두개를 어디에 붙여야 할까요?

 

2020/12/11 - [Java_Study/Code_Memo] - JButton으로 슈팅게임 1-2 시작 패널 마무리

 

JButton으로 슈팅게임 1-2 시작 패널 마무리

저는 전체적인 틀이 정해지지 않으면 뭔가 조금 찝찝한 마음이 들어서 팀프로젝트를 하면 어쩔 수 없이 일단 기능을 만들고 이미지를 완성하지만 혼자 할 때는 일 여러번 하지 않게 한 클래스씩

mintpearl-story.tistory.com

저번에 만들어둔 Play Panel 연결 메소드에 넣어주면 됩니다.

public void MainPnl2ToNext(int i) { //메인 패널에서 첫화면/게임화면 이동
		this.remove(main2);
		if (i == 1) { //첫 화면으로
			this.add(firstPage); 
		} else if (i ==2) { //게임 화면으로
			playPhase1 = new Play_Phase1(this);
			this.add(playPhase1); 
			playPhase1.setFocusable(true); //포커스 추가!
			playPhase1.requestFocus();
		}
		this.repaint();
		this.revalidate();
	}

그러면 이제 주인공이 구름을 타고 날아다니는 모습을 볼 수 있습니다 :)