쿠키런 프로젝트 시리즈
1.준비
https://ondolroom.tistory.com/297
2.전역공간
https://ondolroom.tistory.com/298
3.JPanel생성자
https://ondolroom.tistory.com/299
4.mapMove메서드
https://ondolroom.tistory.com/300
5.hit메서드
https://ondolroom.tistory.com/301
6.fall메서드
https://ondolroom.tistory.com/302
7.jump메서드
https://ondolroom.tistory.com/303
8.paintComponent 및 결과
https://ondolroom.tistory.com/304
https://ondolroom.tistory.com/298
더보기를 눌러 전체코드확인
package Test4;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicTreeUI.TreeCancelEditingAction;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
public class CookieRun2 {
private JFrame frame;
private JPanel panel; // 패널
private Button escButton; // esc 버튼 (테스트 중)
// 배경 이미지
private ImageIcon backIc = new ImageIcon("testimg/backTest.png"); // 제일 뒷 배경
private ImageIcon secondBackIc = new ImageIcon("배경이미지2"); // 2번째 배경
// 쿠키 이미지 아이콘들
private ImageIcon cookieIc = new ImageIcon("testimg/cookieTest.png"); // 기본모션
private ImageIcon jumpIc = new ImageIcon("testimg/jumpTest.png"); // 점프모션
private ImageIcon doubleJumpIc = new ImageIcon("testimg/doubleJumpTest.png"); // 더블점프모션
private ImageIcon fallIc = new ImageIcon("testimg/fallTest.png"); // 낙하모션(더블 점프 후)
private ImageIcon slideIc = new ImageIcon("testimg/slideTest.png"); // 슬라이드 모션
private ImageIcon hitIc = new ImageIcon("testimg/hitTest.png"); // 부딛히는 모션
// 젤리 이미지 아이콘들
private ImageIcon jelly1Ic = new ImageIcon("testimg/jelly1Test.png");
private ImageIcon jelly2Ic = new ImageIcon("testimg/jelly2Test.png");
private ImageIcon jelly3Ic = new ImageIcon("testimg/jelly3Test.png");
private ImageIcon jellyHPIc = new ImageIcon("testimg/jellyHPTest.png");
private ImageIcon jellyEffectIc = new ImageIcon("testimg/effectTest.png");
// 발판 이미지 아이콘들
private ImageIcon field1Ic = new ImageIcon("testimg/footTest.png"); // 발판
private ImageIcon field2Ic = new ImageIcon("testimg/footTest2.png"); // 공중발판
// 장애물 이미지 아이콘들
private ImageIcon tacle10Ic = new ImageIcon("testimg/tacleTest10.png"); // 1칸 장애물
private ImageIcon tacle20Ic = new ImageIcon("testimg/tacleTest20.png"); // 2칸 장애물
private ImageIcon tacle30Ic = new ImageIcon("testimg/tacleTest30.png"); // 3칸 장애물
private ImageIcon tacle40Ic = new ImageIcon("testimg/tacleTest40.png"); // 3칸 장애물
// 리스트 생성
private List<Jelly> jellyList = new ArrayList<>(); // 젤리 리스트
private List<Field> fieldList = new ArrayList<>(); // 발판 리스트
private List<Tacle> tacleList = new ArrayList<>(); // 장애물 리스트
private int runPage = 0; // 한 화면 이동할때마다 체력을 깎기 위한 변수
private int runStage = 1; // 스테이지를 확인하는 변수이다. (미구현)
private int resultScore = 0; // 결과점수를 수집하는 변수
private int gameSpeed = 3; // 게임 속도
private int nowField = 2000; // 발판의 높이를 저장.
private boolean escKeyOn = false; // 일시정지를 위한 esc키 확인
private boolean downKeyOn = false; // 다운키 눌렀는지 여부
int face; // 쿠키의 정면
int foot; // 쿠키의 발
// 이미지 파일로 된 맵을 가져온다.
private int[] sizeArr; // 이미지의 넓이와 높이를 가져오는 1차원 배열
private int[][] colorArr; // 이미지의 x y 좌표의 픽셀 색값을 저장하는 2차원배열
private Image buffImage; // 더블버퍼 이미지
private Graphics buffg; // 더블버퍼 g
private AlphaComposite alphaComposite; // 투명도 관련 오브젝트
Cookie c1; // 쿠키 오브젝트
Back b11; // 배경1-1 오브젝트
Back b12; // 배경1-2 오브젝트
class MyPanel extends JPanel {
public MyPanel() {
setFocusable(true);
// 쿠키 인스턴스 생성 / 기본 자료는 클래스안에 내장 되어 있기 때문에 이미지만 넣었다.
c1 = new Cookie(cookieIc.getImage());
// 쿠키의 정면 위치 / 쿠키의 x값과 높이를 더한 값
face = c1.getX() + c1.getWidth();
// 쿠키의 발밑 위치 / 쿠키의 y값과 높이를 더한 값
foot = c1.getY() + c1.getHeight();
// 배경1-1 인스턴스 생성
b11 = new Back(backIc.getImage(), 0, 0, // y 값 (조정 필요)
backIc.getImage().getWidth(null), backIc.getImage().getHeight(null));
// 배경1-2 인스턴스 생성
b12 = new Back(backIc.getImage(), backIc.getImage().getWidth(null), 0, // y 값 (조정 필요)
backIc.getImage().getWidth(null), backIc.getImage().getHeight(null));
// 맵 정보 불러오기
try {
sizeArr = Util.getSize("testimg/firstMap1.png"); // 맵 사이즈를 배열에 저장
colorArr = Util.getPic("testimg/firstMap1.png"); // 맵 픽셀값을 배열에 저장
} catch (Exception e1) {
e1.printStackTrace();
}
int maxX = sizeArr[0]; // 맵의 넓이
int maxY = sizeArr[1]; // 맵의 높이
for (int i = 0; i < maxX; i += 1) { // 젤리는 1칸을 차지하기 때문에 1,1사이즈로 반복문을 돌린다.
for (int j = 0; j < maxY; j += 1) {
if (colorArr[i][j] == 16776960) { // 색값이 16776960일 경우 기본젤리 생성
// 좌표에 40을 곱하고, 넓이와 높이는 30으로 한다.
jellyList.add(new Jelly(jelly1Ic.getImage(), i * 40, j * 40, 30, 30, 1234));
} else if (colorArr[i][j] == 13158400) { // 색값이 13158400일 경우 노란젤리 생성
// 좌표에 40을 곱하고, 넓이와 높이는 30으로 한다.
jellyList.add(new Jelly(jelly2Ic.getImage(), i * 40, j * 40, 30, 30, 2345));
} else if (colorArr[i][j] == 9868800) { // 색값이 9868800일 경우 노란젤리 생성
// 좌표에 40을 곱하고, 넓이와 높이는 30으로 한다.
jellyList.add(new Jelly(jelly3Ic.getImage(), i * 40, j * 40, 30, 30, 3456));
} else if (colorArr[i][j] == 16737280) { // 색값이 16737280일 경우 피 물약 생성
// 좌표에 40을 곱하고, 넓이와 높이는 30으로 한다.
jellyList.add(new Jelly(jellyHPIc.getImage(), i * 40, j * 40, 30, 30, 4567));
}
}
}
for (int i = 0; i < maxX; i += 2) { // 발판은 4칸을 차지하는 공간이기 때문에 2,2사이즈로 반복문을 돌린다.
for (int j = 0; j < maxY; j += 2) {
if (colorArr[i][j] == 0) { // 색값이 0 일경우 (검은색)
// 좌표에 40을 곱하고, 넓이와 높이는 80으로 한다.
fieldList.add(new Field(field1Ic.getImage(), i * 40, j * 40, 80, 80));
} else if (colorArr[i][j] == 6579300) { // 색값이 6579300 일경우 (회색)
// 좌표에 40을 곱하고, 넓이는 80으로 높이는 40 한다.
fieldList.add(new Field(field1Ic.getImage(), i * 40, j * 40, 80, 40));
}
}
}
for (int i = 0; i < maxX; i += 2) { // 장애물은 4칸 이상을 차지한다. 추후 수정
for (int j = 0; j < maxY; j += 2) {
if (colorArr[i][j] == 16711680) { // 색값이 16711680일 경우 (빨간색) 1칸
// 좌표에 40을 곱하고, 넓이와 높이는 80으로 한다.
tacleList.add(new Tacle(tacle10Ic.getImage(), i * 40, j * 40, 80, 80, 0));
} else if (colorArr[i][j] == 16711830) { // 색값이 16711830일 경우 (분홍) 2칸
// 좌표에 40을 곱하고, 넓이와 높이는 160으로 한다.
tacleList.add(new Tacle(tacle20Ic.getImage(), i * 40, j * 40, 80, 160, 0));
} else if (colorArr[i][j] == 16711935) { // 색값이 16711830일 경우 (핫핑크) 3칸
// 좌표에 40을 곱하고, 넓이와 높이는 240으로 한다.
tacleList.add(new Tacle(tacle30Ic.getImage(), i * 40, j * 40, 80, 240, 0));
}
}
}
// 리페인트 전용 쓰레드
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
repaint();
if (escKeyOn) { // esc 키를 누를경우 리페인트를 멈춘다
while (escKeyOn) {
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
mapMove(); // 배경 발판 장애물 작동 메서드
fall(); // 낙하 스레드 발동 메서드
addKeyListener(new KeyAdapter() { // 키 리스너 추가
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { // esc키를 눌렀을 때
if (!escKeyOn) {
escKeyOn = true;
add(escButton);
repaint(); // 화면을 어둡게 하기위한 리페인트
} else {
remove(escButton);
escKeyOn = false;
}
}
if (!escKeyOn) {
if (e.getKeyCode() == KeyEvent.VK_SPACE && c1.getCountJump() < 2) { // 스페이스 키를 누르고 더블점프가 2가 아닐때
jump(); // 점프 메서드 가동
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) { // 다운키를 눌렀을 때
downKeyOn = true; // downKeyOn 변수를 true로
if (c1.getImage() != slideIc.getImage() // 쿠키이미지가 슬라이드 이미지가 아니고
&& !c1.isJump() // 점프 중이 아니며
&& !c1.isFall()) { // 낙하 중도 아닐 때
c1.setImage(slideIc.getImage()); // 이미지를 슬라이드이미지로 변경
}
}
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN) { // 다운키를 뗐을 때
downKeyOn = false; // downKeyOn 변수를 false로
if (c1.getImage() != cookieIc.getImage() // 쿠키이미지가 기본이미지가 아니고
&& !c1.isJump() // 점프 중이 아니며
&& !c1.isFall()) { // 낙하 중도 아닐 때
c1.setImage(cookieIc.getImage()); // 이미지를 기본이미지로 변경
}
}
}
});
}
@Override
protected void paintComponent(Graphics g) {
}
}
void mapMove() {
}
void hit() {
}
void fall() {
}
void jump() {
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CookieRun2 window = new CookieRun2();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public CookieRun2() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 800, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new MyPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(null);
escButton = new Button("재시작");
escButton.setBounds(350, 240, 50, 30);
escButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
panel.remove(escButton);
escKeyOn = false;
}
});
}
}
설명
setFocusable 키입력 우선권획득
내가 만든 패널에 키보드나 마우스 리스너의 우선권을 준다.
인스턴스 생성
쿠키와 배경 인스턴스를 생성하자
맵정보 로딩
게임을 플레이할 맵 정보를 로딩한다.
Util클래스 안의 getSize와 getPic메서드를 이용하여 사이즈와 색값을 가져온다.
아래는 맵 예시이다.
색값을 이용하여 맵을 불러오자.
젤리 객체 생성
저장한 픽셀 정보를 이용하여 색값별로 젤리 객체 생성하여를 jellyList에 저장한다.
발판 객체 생성
발판은 바닥에 있는 발판과 공중에 있는 발판 2가지이다.
색깔로 구분하여 로딩한다.
장애물 객체 생성
장애물 객체를 생성한다.
장애물은 1칸 2칸 3칸 (4단도 있으나 미구현)이 있으니 각각 색값을 달리하여 리스트에 추가한다.
리페인트 전용 쓰레드
리페인트만 전담하는 쓰레드이다.
추가 사항으로 esc를 누르면 해제될 때까지 그림을 그리지 않도록 하였다.
맵이동, 낙하 쓰레드를 실행하는 메서드 (추후 제작)
원래는 맵이동과 낙하 쓰레드를 직접 적었으나 메서드로 따로 분리하였다.
추후 블로깅에서 알아보도록 하자.
키리스너 추가
키리스너를 추가한다.
내용은 아래와 같다.
키를 눌렀을 때
키를 눌렀을 경우,
esc키를 누르면 escKeyOn 변수가 true가 되고 버튼을 화면에 보이게한다.
스페이스 와 다운키 등은 esc메뉴가 없을 때에만 작동하도록 하였고,
스페이스 키를 누르면 점프 메서드가 작동,
다운키를 누르면 슬라이드 이미지로 변경 되도록 하였다.
키를 뗐을 때
키 릴리즈 메서드이다.
다운키를 떼었을 때 슬라이드 이미지를 달리는 이미지로 다시 바꿀 것이다.
다음편에 계속
'Programming Language > Java' 카테고리의 다른 글
자바 스윙 쿠키런 만들기 hit() 메서드 (프로젝트 진행) (0) | 2020.05.06 |
---|---|
자바 스윙 쿠키런 만들기 mapMove() 메서드 (프로젝트 진행) (0) | 2020.05.06 |
자바 스윙 쿠키런 만들기 전역 변수 선언하기 (프로젝트 진행) (2) | 2020.05.05 |
자바 스윙 쿠키런 제작 준비 (프로젝트 진행) (2) | 2020.05.05 |
자바 스윙 이미지로 발판 및 젤리 구현하기 (프로젝트 대비) (0) | 2020.05.03 |