4. Main.Java
package project;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Main extends JFrame {
ImageIcon bgImage;
JLabel bgLabel;
Clip clip; //오디오 클립 만들기
public Main() {
setTitle("1 조");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container container = getContentPane();
container.setLayout(null);
/*
* 백그라운드 이미지
*/
bgImage = new ImageIcon("image/main.png");
bgLabel = new JLabel(bgImage);
loadAudio("audio/main.wav"); //loadAudio 함수 호출
clip.start(); //오디오 클립 실행
clip.loop(clip.LOOP_CONTINUOUSLY); //오디오 클립 무한 반복 : 음악이 끝나면
처음부터 다시 반복해줍니다.
5. /*
* 버튼 1 과 게임 1 연결
*/
JButton btn1 = new JButton("폭탄 피하기");
btn1.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
clip.stop();
// if(FlappyBird.flappyBird.clipBackGroundMusic.isActive()==true)
// FlappyBird.flappyBird.clipBackGroundMusic.stop();
Snow.snow = new Snow();
}
});
/*
* 버튼 위치 및 크기 설정
* 버튼 색깔 지정
* 버튼 글자 색깔 지정
*/
btn1.setBounds(203, 620, 131, 87);
btn1.setBackground(Color.RED);
// btn1.setForeground(Color.WHITE);
/*
* 버튼 2 과 게임 2 연결운전
*/
JButton btn2 = new JButton("운전 면허 시험");
btn2.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
clip.stop();
FlappyBird.flappyBird = new FlappyBird();
}
});
/*
* 버튼 위치 및 크기 설정
* 버튼 색깔 지정
* 버튼 글자 색깔 지정
*/
btn2.setBounds(334, 583, 143, 124);
btn2.setBackground(Color.BLUE);
// btn2.setForeground(Color.WHITE);
6. /*
* 버튼 3 과 게임 3 연결
*/
JButton btn3 = new JButton("백수퇴치");
btn3.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
clip.stop();
AdultFilter.adultfilter = new AdultFilter();
}
});
/*
* 버튼 위치 및 크기 설정
* 버튼 색깔 지정
* 버튼 글자 색깔 지정
*/
btn3.setBounds(477, 620, 120, 87);
btn3.setBackground(Color.GREEN);
// btn3.setForeground(Color.WHITE);
/*
* 배경화면
*/
bgLabel.setBounds(0, 0, 790,800);
/*
* 컨테이너에 버튼 붙이기
*/
container.add(btn1);
container.add(btn2);
container.add(btn3);
// container.add(btn4);
container.add(bgLabel);
setSize(780, 800);
setVisible(true);
}
/*
* loadAudio 함수
* 오디오 클립에 오디오 스트림 객체를 AudioInputStream 으로 생성한 후
* 오디오 클립과 오디오 스트림을 clip.open() 으로 연결한다.
* 이 함수를 거친 후 clip 은 오디오 스트림으로부터 오디오 데이터를 받아 재생할 수 있는
상태가 된다.
7. * clip.start(); 메서드를 호출하면 오디오 재생을 시작한다.
*/
private void loadAudio(String pathName) {
try {
clip = AudioSystem.getClip();
File audioFile = new File(pathName);
AudioInputStream audioStream =
AudioSystem.getAudioInputStream(audioFile);
clip.open(audioStream);
}
catch (LineUnavailableException e) { e.printStackTrace(); }
catch (UnsupportedAudioFileException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
}
public staticvoid main(String[] args) {
new Main();
}
}
코드설명
메인 코드에서는 JFrame 을 이용해서 총 3 개의 버튼을 만들었습니다.
각 버튼에는 mouseevent 의 mousepressed 를 넣었으며 mousepressed 가 되면 각 게임의 메인 코드를
실행 시켜줌으로서 각 버튼에 맞는 게임이 실행이 됩니다..
clip 객체를 생성하고 clip 생성에 구한 사운드를 넣고 loadaudio 함수를 이용하여 실행시켰습니다.
8. 산타의 폭탄 피하기
스토리
산타가 어린아이들에게 선물을 주로 가는 도중 폭풍우를 만나 선물을
모두 잃어버리게 되었습니다. 산타가 떨어트린 선물을 모두 수집하는데
도움을 주세요!
게임 방법
1. 산타가 떨어지는 선물을 받으면 점수 1점 추가
2. 하지만 떨어지는 폭탄을 받게된다면 목숨이 하나 줄어요
3. 하늘에서 떨어지는 하트를 먹으면 목숨이 하나 증가(최대 4개)
4. A버튼을 누르면 산타가 왼쪽으로 이동하고 D버튼을 누르면 산타가
오른쪽으로 이동 합니다.
10. import javax.swing.JFrame;
import javax.swing.Timer;
public class Snow implements ActionListener, KeyListener{
public staticSnow snow;
public final int WIDTH=1200, HEIGHT = 800;
public Mypanel panel;
public Rectangle santa;
public ArrayList<Rectangle> snows;
public ArrayList<Rectangle> snows1;
public ArrayList<Rectangle> hearts;
public ArrayList<Rectangle> presents;
public Random rand;
public boolean gameOver=false, started=true;
public int xMotion,score,life=3;
public Clip clip;
public Clip clipBackGroundMusic;
public boolean gameOverSound=false;
public Snow() {
JFrame jframe = new JFrame();
Timer timersnow = new Timer(1000,new ActionListener() { //눈 객체 생성
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
int rainsnow = rand.nextInt(WIDTH-230);
snows.add(new Rectangle(rainsnow+100, 10, 32, 32));
}
});
Timer timersnow1 = new Timer(1000,new ActionListener() { //눈 객체 생성
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
int rainsnow1 = rand.nextInt(WIDTH-230);
11. snows1.add(new Rectangle(rainsnow1+100,-200,32,32));
}
});
Timer timerheart = new Timer(700,new ActionListener() { //눈 객체 생성
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
int rainheart = rand.nextInt(WIDTH-230);
hearts.add(new Rectangle(rainheart+100, 10, 32, 32));
}
});
Timer timerpresent = new Timer(1000,new ActionListener() { //선물 객체 생성
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
int rainpresent = rand.nextInt(WIDTH-230);
presents.add(new Rectangle(rainpresent+100, 0, 32, 32));
}
});
Timer timer2 = new Timer(20, this);
panel = new Mypanel();
rand = new Random();
jframe.add(panel);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
jframe.setSize(WIDTH,HEIGHT);
jframe.setResizable(false); //화면 크기 조절 차단
jframe.addKeyListener(this);
jframe.setTitle("눈 피하기 게임");
santa = new Rectangle(WIDTH /2 , HEIGHT-175, 100, 100);
snows = new ArrayList<Rectangle>();
snows1 = new ArrayList<Rectangle>();
presents = new ArrayList<Rectangle>();
hearts= new ArrayList<Rectangle>();
timersnow.start();
timersnow1.start();
timerpresent.start();
timerheart.start();
18. Mypanel.java
package project;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Mypanel extends JPanel
{
private static final long serialVersionUID = 1L;
protected void paintComponent(Graphics g){ //스윙 컴포넌트가 자신의 모양을 그리는 메서드
super.paintComponent(g);
Snow.snow.repaint(g);
}
}
코드설명
눈,선물,하트를 arrylist[Rectangle]로 선언하고 Class 안에서는 Timer 를 이용해서 일정 시간 동안
어레이리스트 안에다 객체들을 넣어주었습니다. 그리고 이렇게 들어간 객체들은 repaint 함수에서 객체 들이
소환되게 되고 이 객체들은 Jframe 의 y 축으로 떨어져야 합니다 그래서 actionPerformed 에서
snow.y+=speed 를 이용해서 어레이 리스트에 있는 객체들이 y 축으로 떨어지게 됩니다.
XrightMove(),YrightMove() 메서드를 만들었습니다. 이 메서드 안에서는 산타의 속도를 변화시켜주었으며
gameOver 가 되었을 때 이 함수를 불러오면 다시 게임이 시작되게 만들었습니다.
산타와 arraylist 로 구현한 객체들(눈,선물,하트)가 부딪히는 것은 intersects 함수를 이용해서 충돌 판정을
하였고 충돌이 일어날 때 부딪친 객체를 remove 를 이용해서 삭제시켰습니다. 만약 삭제를 하지않으면
충돌이 계속 일어나 목숨이 계속 깎이거나 점수가 계속 상승하였습니다.
백그라운드 사운드는 로드뮤직함수를 이용해서 실행 시키고 중간중간에 나오는 이팩트사운드는 clip 객체의
loadaudio 함수를 이용해서 실행시켰습니다.
19. 산타의 면허 시험
스토리
산타는 아무나 되는 게 아니다! 산타가 되려면 루돌프를 이용하여 하늘
에서 자유자재로 움직이는 시험을 통과해야 한다. 산타를 도와서 운전
면허 시험을 통과해보자
게임 방법
1. space나 마우스 좌클릭을 하면 산타가 위로 간다.
2. 산타가 벽 사이를 통과해야한다.
3. 벽을 안전하게 통과한다면 1점
4. 통과하지 못하거나 벽에 부딪히면 게임 오버
5. 다시 시작 하려면 space를 누르면 된다.
21. import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.Timer;
public class FlappyBird implements ActionListener,MouseListener,KeyListener
{
public staticFlappyBird flappyBird;
public final int WIDTH=1500, HEIGHT=800; //창 크기
public Renderer renderer;
public Rectangle bird; //새 모양
public int ticks, yMotion, score; //?? , y축 속도, 점수
public ArrayList<Rectangle> columns; //장애물 어레이 리스트
public Random rand; //랜덤함수J
public boolean gameOver, started=true; //게임 오버와, 게임 시작
public boolean gameOverSound = false;
Clip clipBackGroundMusic; //배경음악 클립
Clip clip; //효과음 클립
public FlappyBird() {
JFrame jframe = new JFrame();
Timer timer = new Timer(20,this);
renderer = new Renderer();
rand = new Random();
jframe.add(renderer);
jframe.setTitle("Flappy Bird"); //타이틀 제목
// jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.addMouseListener(this); //마우스 리스트
jframe.addKeyListener(this); //키 리스너
jframe.setSize(WIDTH,HEIGHT); //창 화면 크기
jframe.setVisible(true);
jframe.setResizable(false); //화면 창을 늘릴 수 있음
27. // TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
Renderer.java
package project;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Renderer extends JPanel
{
private static final long serialVersionUID = 1L;
protected void paintComponent(Graphics g){ //스윙 컴포넌트가 자신의 모양을 그리는 메서드
super.paintComponent(g);
FlappyBird.flappyBird.repaint(g);
}
}
28. 코드 설명
클레스 안에 선언
1. boolean gameOver,started //게임 오버 게임 시작
2. boolean gameOverSound //게임 사운드
3. Rectangle bird //새 객체
4. ArrayList<Rectangle> columns //장애물
5. Random rand //장애물이 랜덤한 위치에서 생기게하는 랜덤 함수
를 선언해주었습니다.
addColumn 메서드
이 메서드 안에서는 게임 안에 들어갈 벽을 생성해줍니다.
columns.add(new Rectangle(WIDTH + width + columns.size() * 300, HEIGHT -
height, width,height));
columns.add(new Rectangle(WIDTH + width + (columns.size() -1) * 300, 0,
width, HEIGHT -height -space));
어레이리스트로 선언한 columns 안에 게임 위쪽 벽과 아래쪽 벽을 생성해줍니다.
jump()메서드
if(yMotion >0){
yMotion=0;
}
yMotion -= 10;
게임이 over 상태가 아닐 떄 점프 메서드를 실행시키면 yMotion값이 -가 됩니다. 이
yMotion값은 나중에 소개할 actionPerformed에서 사용됩니다.
actionPerforemd(ActionEvent e) 메서드
이 메서드 안에서는 어레이리스로 구현한 columns의 x위치와 santa의 y위치가 변경되고
santa와 columns가 충돌되는 코드가 있습니다.
int speed = 10; //columns의 스피드
for(int i=0; i< columns.size(); i++)
{
Rectangle column = columns.get(i);
column.x -= speed;
}
for을 이용해서 어레이리스트를 전부 호출하고 이 columns의 x위치를 변경 시켜줍니다.
bird.y += yMotion;
앞에서 jump에서 변경된 yMotion 으로 bird(santa)의 y축 위치를 변경 시켜줍니다. 이 jump는
keyLister에서 호출됩니다.
29. column.intersects(bird)
intersects라는 함수를 이용해서 충돌판정을 하였고 충돌을 하면 gameOver=true;가 되면서
게임 오버가 됩니다.
repaint(Graphics g) 메서드
이 메서드에서는 jframe으로 구성된 창을 꾸미는 역할을 합니다.
ImageIcon i3 = new ImageIcon("image/santa2.png");
Image image3 = i3.getImage();
g.drawImage(image3,bird.x,bird.y,bird.x+bird.width,bird.y+bird.height, 120, 20, 10,
95, null);
예를 들어서 이 코드는 i3를 선언하고 i3안에 image디렉토리 안에 있는 santa2.png를
저장합니다 그리고 Image image3로 그 사진을 읽어서 저장하고 g.drawImage을 이용해 이
사진을 적용시킵니다. drawImage에는 총 10개의 메서드가 들어가는데 처음은 image를 불러오고
2,3번쨰는 그래픽에 적용시킬 x,y좌표이고 4,5번쨰는 이 그래픽이 끝나는 지점의 x,y좌표입니다.
그리고 6,7번째는 불러올 이미지의 x,y좌표 시작점이고 8,9번째는 불러올 이미지의 끝나는 점의
x,y좌표입니다.
loadMusic(String pathName) 메서드
이 메서드는 매개변수를 하나 받는데 이 매개변수는 디렉토리 이름을 뜻합니다.
그리고 메서드 안에서는 clipBackGroundMusic.open을 이용해 음악파일을 열어서 실행시킵니다.
keyReleased(KeyEvent arg0) 메서드
keyLister에서 키 버튼을 눌렸다 땠을 때 실행되는 메서드입니다.
이 메서드 안에서는 점프 메서드를 실행시키고 점프 메서드가 실행함과 동시에 loadAudio를
통해서 이팩트사운드를 실행시킵니다.
30. 산타의 백수 퇴치
스토리
산타가 어린이들에게 선물을 나눠주고 있어요. 하지만 어린이들 사이에
선물을 받을 수 없는 어른이 숨어있습니다. 산타를 도와 어린이들 사이
에 숨어있는 어른을 골라냅시다!
게임 방법
1. 어린이와 어른이 한 줄로 줄서있다.
2. 선물을 받을 차례인 사람이 어린이면 왼쪽으로 어른이면 오른쪽으로
보내야 한다,
3. 왼쪽으로 보내는 방법은 키보드 방향키의 <- 오른쪽이면 키보드 방
향키 ->이다.
4. 만약 구별해내지 못한다면 목숨이 감소!(목숨 3개)
5. 목숨이 전부 없어지면 game over!
32. import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.Timer;
public class AdultFilter implements ActionListener ,KeyListener{
public staticAdultFilter adultfilter;
public final int WIDTH=400, HEIGHT=600;
public Kidpanel kidpanel;
public Rectangle kid;
public Rectangle kid1;
public Rectangle adult1;
public Rectangle adult;
public ArrayList<Rectangle> kidadult;
public Random rand;
public boolean gameOver, started=true;
public boolean gameOverSound = false;
public int score,life=3,buttonclick;
public Clip clipBackGroundMusic; //배경음악 클립
public Clip clip; //효과음 클립
public AdultFilter() {
JFrame jframe = new JFrame();
Timer timer = new Timer(20,this);
kidpanel = new Kidpanel();
rand = new Random();
jframe.add(kidpanel);
41. clip = AudioSystem.getClip();
File audioFile = new File(pathName);
AudioInputStream audioStream =
AudioSystem.getAudioInputStream(audioFile);
clip.open(audioStream);
}
catch (LineUnavailableException e) { e.printStackTrace(); }
catch (UnsupportedAudioFileException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
Kidpanel.java
package project;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Kidpanel extends JPanel
{
private static final long serialVersionUID = 1L;
protected void paintComponent(Graphics g){ //스윙 컴포넌트가 자신의 모양을 그리는 메서드
super.paintComponent(g);
AdultFilter.adultfilter.repaint(g);
}
}
코드 설명
public Rectangle kid; //첫 번째 어린이
public Rectangle kid1; //두 번째 어린이
public Rectangle adult1; //첫 번째 어른
public Rectangle adult; //두 번째 어른
public ArrayList<Rectangle> kidadult; //위에서 선언한 것들이 들어갈 어레이 리스트
public boolean gameOver, started=true; //게임 오버와 게임 스타트
public int score,life=3,buttonclick; // 점수, 목숨, 버튼 클릭
42. repaint(Graphics g) 메서드
이 메서드는 게임 내의 그래픽을 꾸며줍니다.
for(int i=kidadult.size()-1; i>=0; i--) {
Rectangle kidadult1 = kidadult.get(i);
if(score<50) {
if(kidadult1 == kid) {
g.drawImage(image1, kid.x, HEIGHT-i*40-230, kid.x+kid.width,
HEIGHT-i*40-230+kid.height, 0, 0, 128, 128, null);
}
if(kidadult1 == adult) {
g.drawImage(image2, adult.x, HEIGHT-i*40-230,
adult.x+adult.width, HEIGHT-i*40-230+adult.height, 0, 0, 128,
128, null);
}
}
}
다른 것들은 전부 위에서 설명했고 다른 점을 설명하겠습니다.
이 코드는 arrylist인 kidadult를 for을 이용해서 전부 불러옵니다. 그리고 이 불러온 값들은
인덱스 번호를 이용헤 y축의 위치를 변화 시켜줍니다. ->> (HEIGHT-i*40) y축
leftmove() 메서드
이 메서드에서는 왼쪽을 클릭했을 시에 실행됩니다.
if(kidadult.get(0)==kid) {
score++;
kidadult.remove(0);
loadAudio("audio/adult_correct.wav");
clip.start();
int random = rand.nextInt(2);
if(random==0) {
kidadult.add(adult);
}else {
kidadult.add(kid);
}
}
만약 어린아이일 때 점수가 1점 증가하고 에러이리스트의 인덱스 0번째에 있는 값을 삭제시켜줍
니다. 그러면 어레이리스트는 내부적으로 한 번 정렬을 하게되고 1번째 인덱스에 있는 값이 0번
째로 떨어집니다. 그리고 랜덤함수를 이용해서 0이 나올 떄는 어레이리스트에 adult객체를 넣어
주고 1이 나오면 어레이리스트에 kid객체를 넣어줍니다.
if(kidadult.get(0)==kid || kidadult.get(0)==kid1) {
score++;
kidadult.remove(0);
loadAudio("audio/adult_correct.wav");
clip.start();
int random = rand.nextInt(4);
if(random==0) {
kidadult.add(adult);
}else if(random==1){
kidadult.add(kid);
}else if(random==2){
kidadult.add(kid1);
}else {
kidadult.add(adult1);
43. }
}
위 코드는 50점 이상일 때 실행되는 코드입니다. 50점 이상일 때는 캐릭터 객체가 2개 들어갔다
면 이 코드는 random함수에 4를 넣어 4가지의 캐릭터 객체가 들어갔다는 점이 다릅니다.(난이도
상승)
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getKeyCode()==KeyEvent.VK_LEFT)
{
leftmove();
buttonclick=0;
}
if(arg0.getKeyCode()==KeyEvent.VK_RIGHT)
{
rightmove();
buttonclick=0;
}
}
이 함수는 버튼을 눌렸다 땠을 때 실행되는 메서드입니다.
왼쪽 버튼을 누르면 leftmove가 실행되고 오른쪽 버튼을 누르면 rightmove가 실행됩니다.
이외에도 많은 코드들이 많은데 중복된 코드들이라 중요한 기능만 설명하였습니다. 감사합니다.
느낀점
코드를 구현하면서 재미있으면서 한편으로는 힘든 작업이었습니다. 기능을 구현하는 것까지는
쉬웠지만 구현을 다하고 나서 오류를 잡아내는 것이 힘들었으며 또 게임에서 디자인적인 측면도
중요하다고 생각해서 디자인을 직접 구현하고 인터넷에서 좋은 디자인을 찾아와 java에 적용시
키는 것이 많이 힘들었습니다. 사진을 찾고 사진에서의 픽셀을 java에서의 픽셀에 알맞게 적용
시키려면 시작하고 끄는 것을 수십번 시도해야 알맞게 들어갈 수 있었습니다.
이번 프로젝트를 하면서 평소 하던 자바 문법과 JFrame, swing 등을 이용해서 게임을 만들어보
니까 뭔가 새롭고 배울 점이 많았습니다!