저는 게임 구상을 페이즈 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 시작 패널 마무리
저번에 만들어둔 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();
}
그러면 이제 주인공이 구름을 타고 날아다니는 모습을 볼 수 있습니다 :)
'Coding_Study > Java_Code_Memo' 카테고리의 다른 글
JButton으로 슈팅게임 2-3 몬스터 1 만들기 (0) | 2020.12.11 |
---|---|
JButton으로 슈팅게임 2-2 총알 만들기 (0) | 2020.12.11 |
JButton으로 슈팅게임 1-2 시작 패널 마무리 (0) | 2020.12.11 |
JButton으로 슈팅게임 1-1 시작 패널 (0) | 2020.12.10 |
HashMap(1) (0) | 2020.12.02 |