今天完成了飞机小游戏。代码结构如下:
其中GameObject类为目标根类,代码为:
public class GameObject {
Image img;
double x,y;
int speed,width,height;
public GameObject(Image img, double x, double y, int speed) {
this.img = img;
this.x = x;
this.y = y;
this.speed = speed;
this.width = img.getWidth(null);
this.height = img.getHeight(null);
}
public GameObject() {}
public void drawMyself(Graphics g) {
g.drawImage(img,(int)x,(int)y,width,height,null);
}
public Rectangle getRectangle() {
return new Rectangle((int)x,(int)y,width,height);
}
}
飞机类Plane为:
public class Plane extends GameObject {
boolean left,right,up,down;
boolean live = true;
public Plane(Image img, double x, double y, int speed) {
super(img, x, y, speed);
}
@Override
public void drawMyself(Graphics g) {
if (live) {
super.drawMyself(g);
if (left) {
this.x -= this.speed;
}
if (right) {
this.x += this.speed;
}
if (up) {
this.y -= this.speed;
}
if (down) {
this.y += this.speed;
}
}
}
public void addDirection(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
left = true;
break;
case KeyEvent.VK_RIGHT :
right = true;
break;
case KeyEvent.VK_UP:
up = true;
break;
case KeyEvent.VK_DOWN:
down = true;
break;
}
}
public void minisDirection(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
left = false;
break;
case KeyEvent.VK_RIGHT :
right = false;
break;
case KeyEvent.VK_UP:
up = false;
break;
case KeyEvent.VK_DOWN:
down = false;
break;
}
}
}
子弹类Shell为:
public class Shell extends GameObject {
double degree;
public Shell() {
this.x = 200;
this.y = 200;
this.degree = Math.random() * 2 * Math.PI;
this.width = 5;
this.height = 5;
this.speed = 3;
}
@Override
public void drawMyself(Graphics g) {
Color c = g.getColor();
g.setColor(Color.yellow);
g.fillOval((int) x, (int) y, width, height);
//炮弹沿着任意角度飞行
x += speed * Math.cos(degree);
y += speed * Math.sin(degree);
//如下代码,用来实现碰到边界,炮弹反弹回来(原理和打台球游戏一样)
if (y > 500 - height || y < 30) {
degree = -degree;
}
if (x < 0 || x > 500 - width) {
degree = Math.PI - degree;
}
//返回给外部,变回以前的颜色
g.setColor(c);
}
}
爆炸类Explode为:
public class Explode extends GameObject {
double x,y;
int count;
static Image[] imgs = new Image[16];
static {
for (int i = 0;i < 16;i++) {
imgs[i] = GameUtil.getImage("Image/explode/e" + (i + 1) + ".gif");
}
}
@Override
public void drawMyself(Graphics g) {
if (count < 16) {
g.drawImage(imgs[count++],(int)x,(int)y,null);
}
}
public Explode(double x,double y){
this.x = x;
this.y = y;
}
}
工具类GameUtil为:
public class GameUtil {
//构造器私有
private GameUtil() {}
public static Image getImage(String path) {
BufferedImage img = null;
URL u = GameUtil.class.getClassLoader().getResource(path);
try {
img = ImageIO.read(u);
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
主类MyGameFrame为:
public class MyGameFrame extends Frame {
Image planeImage = GameUtil.getImage("Image/plane.png");
Image bg = GameUtil.getImage("Image/bg.jpg");
Plane plane = new Plane(planeImage,100,100,7);
Shell[] shells = new Shell[50];
Explode explode;
Date start = new Date();
Date end;
long period = 0;
@Override
public void paint(Graphics g) { //g当作一支笔
g.drawImage(bg,0,0,500,500,null);
plane.drawMyself(g);
for (int i = 0;i < 50;++i) {
shells[i].drawMyself(g);
boolean peng = shells[i].getRectangle().intersects(plane.getRectangle());
if(peng) {
plane.live = false;
if (explode == null) {
explode = new Explode(plane.x,plane.y);
}
explode.drawMyself(g);
}
}
drawTime(g);
}
public void drawTime(Graphics g) {
Color c = g.getColor();
Font f = g.getFont();
g.setColor(Color.green);
if (plane.live) {
period = (System.currentTimeMillis() - start.getTime()) / 1000;
g.drawString("坚持了:" + period + "秒",50,50);
} else {
if (end == null) {
end = new Date();
period = (end.getTime() - start.getTime()) / 1000;
}
g.setColor(Color.red);
g.setFont(new Font("微软雅黑",Font.BOLD,30));
g.drawString("最终坚持了:" + period + "秒",200,200);
}
g.setFont(f);
g.setColor(c);
}
//初始化窗口
public void launchFrame() {
this.setTitle("飞机大战");
setVisible(true); //窗口是否可见
setSize(500, 500); //窗口大小
setLocation(400, 100); //窗口打开位置
for (int i = 0;i < 50;++i) {
shells[i] = new Shell();
}
// 增加关闭窗口的动作
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0); //正常退出程序
}
});
new MyPaint().start();
this.addKeyListener(new KeyMoniter());
}
class MyPaint extends Thread {
@Override
public void run() {
while(true) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class KeyMoniter extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
plane.addDirection(e);
}
@Override
public void keyReleased(KeyEvent e) {
plane.minisDirection(e);
}
}
private Image offScreenImage = null;
public void update(Graphics g) {
if(offScreenImage == null)
offScreenImage = this.createImage(500,500);//这是游戏窗口的宽度和高度
Graphics gOff = offScreenImage.getGraphics();
paint(gOff);
g.drawImage(offScreenImage, 0, 0, null);
}
public static void main(String[] args) {
MyGameFrame myGameFrame = new MyGameFrame();
myGameFrame.launchFrame();
}
}
2个飞机&背景素材链接:提取码:k44l
16个爆炸图片素材链接:提取码:9zkk