비행기 겜 완성

개발/코딩 2013. 10. 21. 16:01

package shooting;

public class Program {
 public static void main(String[] args){
  //GameBoard gameBoard=new GameBoard(); 안된다 Frame부터 띄워야한다.
  MainFrame frm=new MainFrame();
  frm.setSize(450,700);
  frm.setVisible(true);
 }
}

==============================================

package shooting;

import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

public class MainFrame extends JFrame {
 private SplashBoard splashBoard;
 private GameBoard gameBoard;
 private JMenuBar mainMenu;
 private JMenu mnFile;   //메뉴바 선택
 private JMenu mnWindow; //메뉴바 선택
 private JMenuItem miFileExit;
 private JMenuItem miWindowSplash;
 private JMenuItem miWindowGame;

 public MainFrame() {

  mainMenu = new JMenuBar();
  mnFile = new JMenu("File");
  miFileExit = new JMenuItem("Exit");//file 메뉴바에 속해있는 메뉴
  mnWindow=new JMenu("Window");
  miWindowSplash = new JMenuItem("Splash"); //Window메뉴바에 속해있는 메뉴
  miWindowSplash.addActionListener(new ActionListener() {
   
   public void actionPerformed(ActionEvent e) { //화면전환
    /*JOptionPane.showMessageDialog
    (MainFrame.this,"스플레시입니다");*/
    gameBoard.pause();
    gameBoard.setVisible(false);
    
    splashBoard.setVisible(true); 
    MainFrame.this.revalidate();
   }
  });
  
  miWindowGame = new JMenuItem("Gmae"); //Window메뉴바에 속해있는 메뉴
  miWindowGame.addActionListener(new ActionListener() {
   
   public void actionPerformed(ActionEvent e) { //화면전환
   /* JOptionPane.showMessageDialog
    (MainFrame.this,"게임입니다");*/
    splashBoard.setVisible(false);
    MainFrame.this.add(gameBoard);
    gameBoard.setVisible(true);
    gameBoard.start();
    MainFrame.this.revalidate(); //사라졌던 잔재가 다시 호출
   }
  });
  splashBoard=new SplashBoard();
  gameBoard=new GameBoard();
  mnFile.add(miFileExit);  //메뉴에 붙여준다
  mnWindow.add(miWindowSplash);
  mnWindow.add(miWindowGame);
  mainMenu.add(mnFile);
  mainMenu.add(mnWindow);
  this.setJMenuBar(mainMenu);
  
 
  gameBoard.setFocusable(true);  //겜 시작하자 마자 움직일 수 있도록.클릭안해도 됨
  this.add(gameBoard); //이걸 해줘야 게임이 뜬다. add는 프레임에 보드 붙여준다.
  this.add(splashBoard);
  
  addWindowListener(new WindowAdapter() { //윈도창에 X표로 닫을 수 있게
  public void windowClosing(WindowEvent e) {
  System.exit(0);    
  }  
  }); 
 }
}

===================================================

package shooting;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Random;

public class GameBoard extends Canvas implements Runnable { // 겜보드가 세가지를 가지고 있다.
 private Fighter fighter; // Canvas는 윈도우가 제공해주는거(도화지 역할)
 private ArrayList enemies;
 private ArrayList userMissiles;
 private StatusBar statusBar; // 정의만 한다
 private Image img; // 함수를 구현할때 필요한 이미지
 // 게임 상태 변수들
 // updateItems를 위한 입력 변수
 private int hKey;
 private int vKey;
 private int timerToEnemyAppear; // 적기 출현 시간
 private int timerToFire; //미사일 발사 카운터
 private int key;
 private int space;
 private Thread thread;

 public GameBoard() {
  hKey = 0;
  vKey = 0;
  timerToEnemyAppear = 0;

  fighter = new Fighter(); // 객체 생성
  statusBar = new StatusBar();

  Toolkit tk = Toolkit.getDefaultToolkit(); // 윈도우 제공
  img = tk.getImage("res/우주.jpg"); // 이미지 불러오는거
  addKeyListener(new KeyAdapter() { // KeyListener와 달리 어탭더 안에 세가지 기능이 있다.
           // public void keyPressed(KeyEvent
           // e)
           // public void keyReleased(KeyEvent
           // e) { }
           // public void keyTyped(KeyEvent e)
           // { }

  public void keyPressed(KeyEvent e) {

   int key = e.getKeyCode();
   switch (key) {
   case KeyEvent.VK_LEFT: // 왼쪽키
   case KeyEvent.VK_RIGHT: // 오른쪽키
   case KeyEvent.VK_DOWN:
   case KeyEvent.VK_UP:
   
    hKey = key;
    vKey = key;
    GameBoard.this.key = key;
    break;
    }
   if (key == KeyEvent.VK_SPACE)   //화살표랑 다르게 써줘야한다
    space = key;
  }

  public void keyReleased(KeyEvent e) {
   hKey=0;
   vKey=0;
   int key = e.getKeyCode();
   super.keyReleased(e);
   switch (key) {
    case KeyEvent.VK_LEFT: // 비행기를 왼쪽으로
     if (GameBoard.this.key == KeyEvent.VK_LEFT)
      GameBoard.this.key = 0;
     break;
    case KeyEvent.VK_RIGHT:
     if (GameBoard.this.key == KeyEvent.VK_RIGHT)
      GameBoard.this.key = 0;
     break;
    case KeyEvent.VK_DOWN:
     if (GameBoard.this.key == KeyEvent.VK_DOWN)
      GameBoard.this.key = 0;
     break;
    case KeyEvent.VK_UP:
     if (GameBoard.this.key == KeyEvent.VK_UP)
      GameBoard.this.key = 0;
     break;
    }
   if (key == KeyEvent.VK_SPACE)
    space = 0;
  }
  });

  enemies = new ArrayList();
  userMissiles = new ArrayList();
 }
 
 public void start(){  //스레드 시작
  if(thread==null){
  thread =new Thread(this);
  thread.start();
  }
  else
   thread.resume();//멈췄던것을 다시
   
 }
 
 public void pause(){
  thread.suspend();
 }
 
 public void stop(){
  thread.stop();
 }

 public void run() {
  while (true) {
   updateItems();
   repaint();
   try {
    Thread.sleep(17);
   } catch (InterruptedException e) {

    e.printStackTrace();
   }
  }
 }

 private void updateItems() {
  Random rand = new Random();
  if (hKey != 0)

   fighter.move(hKey);

  for (int i = 0; i < enemies.size(); i++)
   ((Enemy)enemies.get(i)).move();

  if (timerToEnemyAppear-- == 0) {
   enemies.add(new Enemy(this));
   timerToEnemyAppear = (rand.nextInt(500) + 500) / 17; // 스레드가 17
  } // 스레드 500이면 05초 0.5초~1초 사이에 하나 생성
  
  if(timerToFire>0)
   timerToFire--;
  if (space == KeyEvent.VK_SPACE){   //스페이스라면 발사
   if(timerToFire ==0){    //미사일 발사 카운터
    UserMissile um=fighter.fire();  //미사일
    userMissiles.add(um);
    timerToFire=10;
   }
  }
   for(int i=0;i<userMissiles.size();i++)
    ((UserMissile)userMissiles.get(i)).move();
  
   for(int ei=0;ei<enemies.size();ei++){ //적기에 물어본다 부딪혔냐
   Enemy en=(Enemy)enemies.get(ei);
   
  for(int i=0;i<userMissiles.size();i++){  //미사일이 여러개
  UserMissile um=(UserMissile)userMissiles.get(i);
  
   if(um.hasCrashed(en)){    //부딪혔다면
    en.burst(); //터져! 터져! 터져! 
    userMissiles.remove(um);  //미사일 지움 
   }
   }
 }
   for(int ei=0;ei<enemies.size();ei++){
    Enemy en=(Enemy)enemies.get(ei);
    if(en.hasBurst()) {   //너 터졌니?
   enemies.remove(en); //적기 지우자
    }
   }
 }
 
 public void update(Graphics g) { // 윈도우에서 지원.지웠다 다시 그리는것을 재정의
  // super.update(g); 부모클래래스 호출하면 소용없은게.
  paint(g);
 }

 public void paint(Graphics g) {
  // super.paint(g);
  Image buf = createImage(this.getWidth(), this.getHeight());
  Graphics g1 = buf.getGraphics(); // 비트맵에 그림을 그리고 프레임에 덮어서 깜빡임사라지게

  g1.drawImage(img, 0, 0, this); // 그림을 그려달라 배경
  fighter.paint(g1, this);  // 파이터에 그림을 그려달라(그림 그리는 도구,도화지)
  for (int i = 0; i < enemies.size(); i++)
   ((Enemy)enemies.get(i)).paint(g1);
  
  for(int i=0;i<userMissiles.size();i++)
   ((UserMissile)userMissiles.get(i)).paint(g1);
  
  g.drawImage(buf, 0, 0, this);

 }
}

=================================================

package shooting;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;

public class SplashBoard extends Canvas {  //화면 전환.얘가 제일 먼저뜬다
 private Image img;
 public SplashBoard() {
  Toolkit tk = Toolkit.getDefaultToolkit();
  img = tk.getImage("res/title3.jpg"); // 이미지 불러오는거
  // Toolkit tk=Tookit.getDefaultToolkit().getImage("res/start.png");
 }
 
 public void paint(Graphics g) {
   super.paint(g);
   g.drawImage(img,0, 0, this);
  }
}
====================================================

package shooting;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;

public class Fighter {
// private UserMissile missiles[];
 private Image img;
 private int x,y;  //뱅기 좌표
 private int speed;
 public Fighter() {
  
 // missiles=new UserMissile[100]; //미사일 보유
  x=170;
  y=500;
  speed=5; //스피드 만큼 좌표를 바꾼다
  Toolkit tk=Toolkit.getDefaultToolkit();  //윈도우 제공
  img=tk.getImage("res/fighter.png");  //이미지 불러오는거
 }
 
 public void paint(Graphics g,GameBoard parent) {
  g.drawImage(img,x,y,parent);  //게임 보드에 그림을 그려달라
  }

 public void move(int key) {
 switch(key){
 case KeyEvent.VK_LEFT:
  x -= speed;
  break;
 case KeyEvent.VK_RIGHT:
  x += speed;
  break;
 case KeyEvent.VK_DOWN:
  y += speed;
  break;
 case KeyEvent.VK_UP:
  y -= speed;
  break;
 }
  
 }
 
 public UserMissile fire() {
  UserMissile um=new UserMissile();  //미사일 무한
 
  
  um.setX(this.x+25);  //비행기 중앙 앞에서 나오게 
  um.setY(this.y-40);
  
  return um;
 }
}

=============================================

package shooting;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;

public class UserMissile {
private int x;
private int y;
private static Image img;  //미사일이 여러개
private GameBoard parent;

 public UserMissile() {   //생성자
 this(0,0); 
 }
 
 public UserMissile(int x,int y){  //오버로딩 생성자
  this.x=x;
  this.y=y;
  this.parent=parent;
 }
 
 static{
  Toolkit tk=Toolkit.getDefaultToolkit();  //윈도우 제공
  img=tk.getImage("res/missile.png");  //이미지 불러오는거
 }
 
 
 public void paint(Graphics g) {
  g.drawImage(img,x,y,parent);  //게임 보드에 그림을 그려달라
 }

 public void move() {
  
 y -= 7;  //미사일 속도
 }
 
 public int getX() {
  return x;
 }
 public void setX(int x) {
  this.x = x;
 }
 public int getY() {
  return y;
 }
 public void setY(int y) {
  this.y = y;
 }

 public boolean hasCrashed(Enemy en) { //충돌 알고리즘
  int w=48;
  int h=64;
  if((en.getX()<x && x<en.getX()+w)
    && (en.getY()<y && y<en.getY()+h))
   return true;
  
  return false;
 }
}

======================================

package shooting;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.util.Random;

public class Enemy {
 private static final int LEFT = 1; // static 하나만 선언해서 모든 객체가 공유
 private static final int RIGHT = 2;  //final은 정의를 해야하기때문에 연산자 가능.
 private static Image img;        //static으로 공유를 해야하기때문에 연산자 넣어줌
 private static Image explosion;
 private int x;
 private int y;
 private EnemyMissile[] missiles;
 private int speed;
 private GameBoard parent;
 private int dir; // 적뱅기 움직이는 방향
 private int rightWall;
 private int leftWall;
 private Random rand;
 private boolean isBursting;  //터지고 있다
 private boolean doneBusrt;   //터졌다
 private int delayBurst;
 private int offsetX;
 private int offsetY;

 static{    //스태틱 멤버 초기화, 그림 공통
  Toolkit tk = Toolkit.getDefaultToolkit();
  img = tk.getImage("res/enemy.png"); // 이미지 불러오는거
  explosion=tk.getImage("res/explosion.png");
 }
 
 public int getX() {
  return x;
 }

 public void setX(int x) {
  this.x = x;
 }

 public int getY() {
  return y;
 }

 public void setY(int y) {
  this.y = y;
 }


 public Enemy(GameBoard parent) { // 태어날때부터 이 정보를 갖고 있는다.
  rand = new Random();
  this.parent = parent;
  missiles = new EnemyMissile[100];
  x =rand.nextInt(400) - 100; // 범위를 잡아주는것
  y = -100;
  speed = rand.nextInt(3)+1; // 스피드 만큼 좌표를 바꾼다
  dir=rand.nextInt(2)+1; //LEFT,RIGHT 정해준다 
 
  rightWall=0;
  leftWall=350;
  isBursting=false;
  doneBusrt=true;
  
  offsetX=0;
  offsetY=0;
  delayBurst=2;
 }
 

 public void move() { // 움직일 수 있도록.
  if(dir==LEFT){
   x -= speed;
   y += speed;
   if(x < rightWall){   //창에 부딪히면 다시 오른쪽으로 이동
    dir=RIGHT;
    leftWall=rand.nextInt(350);
   }
  }
  
  else if(dir==RIGHT){
   x += speed;
   y += speed;
   if(x >= leftWall){
    dir=LEFT;
    rightWall=rand.nextInt(350);
   }
  }
 }
 
 public void paint(Graphics g) {
  g.drawImage(img, x, y, parent); // 게임 보드에 그림을 그려달라
  if(isBursting)  //터지는 상황인가
  g.drawImage(explosion,x-110,y-50,x+160,y+120,0+offsetX,0+offsetY,0+160+offsetX,0+120+offsetY,parent);  //비행기 위에 그리는거다
 }
 //explosin x-110,y-50은 뱅기 가운데, x,y는 그림의 크기
 public boolean hasBurst() {
  
  if(isBursting){
   if(--delayBurst>0) //터지는 그림이 빨라서 딜레이줌
    return false;
   delayBurst=2;
   if(offsetX==640-160){  //뭐가 매끄럽지 않아서 -160
    offsetY+=120;
    offsetX=0;
   }
   offsetX+=160;
  }
  if(offsetY==600)
   return true;
  //offsetY=120;
  return false;
 }


 public void burst() { //터지는 그림의 좌표
  isBursting=true; //터지는 중이라면
  
 }

}
============================================

package shooting;

public class EnemyCollection {  //Enemy에 대한 정보
 private int current;
 private int max;
 private Enemy[] enemies;
 
 public EnemyCollection() {
  current=0;
  max=3;
  enemies=new Enemy[max];
 }
 public void add(Enemy enemy){
  if(current >= max){   //공간을 늘려준다
      //1.배열을 temp라는 이름으로 max+10만큼의 배열을 새로 생성
      //2.enemies 공간의 Enemy들을 새로운 temp배열로 이주 시킨다.
   Enemy[] temp = new Enemy[max+10];
   for(int i = 0; i < max ; i++)
   temp[i] = enemies[i];
   enemies=temp;
   max += 10;
  }
  this.enemies[current++]=enemy;
 }
 
 public Enemy get(int idx){
  
  return enemies[idx];
 }
 
 public int size(){ //현재 몇개가 있는가
  return current;
 }
}
========================================

package shooting;

public class EnemyMissile {

}
===================================

package shooting;

public class StatusBar {

}

 

 

'개발 > 코딩' 카테고리의 다른 글

JSP 작동방식  (1) 2013.11.15
JSP특징  (0) 2013.11.15
숫자 맞추기 겜  (0) 2013.10.11
비행기  (0) 2013.10.11
삽입 정렬  (0) 2013.10.11