PenguinGameApp
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class PenguinGameApp extends JFrame {
private static final long serialVersionUID = 1L;
private static final int JFRAME_WIDTH=646;
private static final int JFRAME_HEIGHT=461;
private static final int PENGUIN_SIZE=50;
private Image backImage;
private Image[] penguins;
private int penguinNo;
private int penguinX, penguinY;
private int direction;
private boolean isRun;
private boolean isPenguinAlive;
private static final int STONE_SIZE=30;
private Image stoneImage;
private Set<StoneThread> stoneSet;
public PenguinGameApp(String title) {
super(title);
backImage=new ImageIcon(getClass().getResource("/images/back.jpg")).getImage();
penguins=new Image[3];
for(int i=0;i<penguins.length;i++) {
penguins[i]=new ImageIcon(getClass().getResource("/images/penguin"+(i+1)+".gif")).getImage();
}
stoneImage=new ImageIcon(getClass().getResource("/images/stone.gif")).getImage();
stoneSet=new HashSet<StoneThread>();
init();
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode=e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_LEFT:
direction=1;
break;
case KeyEvent.VK_RIGHT:
direction=2;
break;
case KeyEvent.VK_P:
isRun=!isRun;
if(!isRun) repaint();
break;
case KeyEvent.VK_F5:
if(!isPenguinAlive) init();
break;
}
}
});
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBounds(700, 200, JFRAME_WIDTH, JFRAME_HEIGHT);
setVisible(true);
}
private void init() {
penguinNo=0;
penguinX=JFRAME_WIDTH / 2 - PENGUIN_SIZE / 2;
penguinY=JFRAME_HEIGHT - PENGUIN_SIZE;
direction=0;
isRun=true;
isPenguinAlive=true;
new PenguinAnimationThread().start();
new CreateStoneThread().start();
}
public static void main(String[] args) {
new PenguinGameApp("Penguin Game");
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(backImage, 0, 0, JFRAME_WIDTH, JFRAME_HEIGHT, this);
if(isPenguinAlive) {
g.drawImage(penguins[penguinNo], penguinX, penguinY, PENGUIN_SIZE, PENGUIN_SIZE, this);
if(!isRun) {
g.setFont(new Font("굴림체", Font.BOLD, 50));
g.setColor(Color.RED);
g.drawString("일시 중지", 200, 200);
}
} else {
g.setFont(new Font("굴림체", Font.BOLD, 50));
g.setColor(Color.RED);
g.drawString("GAME OVER", 150, 200);
g.drawString("다시(F5)", 200, 300);
}
synchronized (stoneSet) {
for(StoneThread stone : stoneSet) {
g.drawImage(stoneImage, stone.stoneX, stone.stoneY, STONE_SIZE, STONE_SIZE, this);
}
}
}
public class PenguinAnimationThread extends Thread {
@Override
public void run() {
while(isPenguinAlive) {
if(isRun) {
switch(direction) {
case 1:
penguinX-=5;
if(penguinX <= 0) {
penguinX=0;
}
break;
case 2:
penguinX+=5;
if(penguinX >= JFRAME_WIDTH-PENGUIN_SIZE) {
penguinX=JFRAME_WIDTH-PENGUIN_SIZE;
}
break;
}
penguinNo++;
penguinNo%=3;
repaint();
}
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class StoneThread extends Thread {
private int stoneX, stoneY;
private boolean isStoneAlive;
private int stoneSpeed;
public StoneThread() {
stoneX=new Random().nextInt(JFRAME_WIDTH-STONE_SIZE);
stoneY=0;
isStoneAlive=true;
stoneSpeed=40;
start();
}
@Override
public void run() {
while(isPenguinAlive && isStoneAlive) {
if(isRun) {
stoneY+=5;
if(stoneY >= JFRAME_HEIGHT-STONE_SIZE) {
isStoneAlive=false;
synchronized (stoneSet) {
stoneSet.remove(this);
}
}
if(stoneY+20 >= penguinY) {
if(stoneX+10 >= penguinX && stoneX+10 <= penguinX+PENGUIN_SIZE
&& stoneX+20 >= penguinX && stoneX+20 <= penguinX+PENGUIN_SIZE) {
isPenguinAlive=false;
synchronized (stoneSet) {
stoneSet.clear();
}
repaint();
}
}
}
try {
Thread.sleep(stoneSpeed);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class CreateStoneThread extends Thread {
@Override
public void run() {
while(isPenguinAlive) {
if(isRun) {
synchronized (stoneSet) {
stoneSet.add(new StoneThread());
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}