Swing动画之子弹

一、游戏效果图: 飞机发射的子弹

二、实现原理:重写paintComponet方法,按照一定的时间间隔,让子弹的坐标一直向Y轴递减,这样这实现了子弹的运动效果,子弹重画的开始位置就是飞机的坐标。
三、代码:在前两次的基础,把代码进行一些简单优化,如下:
package com.jack;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageObserver;

import javax.swing.JPanel;

import com.jack.imp.IProcess;

/**
 * 游戏背景
 * 
 * @author laughing
 * @date 2014年11月20日 下午8:12:25
 */
public class BackGround implements IProcess {
	private static final Image[]	BG_IMAGES	= ImageManager.getInstance()
																.getImagesByType("background");
	private static final int		SPEED		= 20;
	private int						topX		= 0;
	private int						topY		= -480;
	private int						belowX		= 0;
	private int						belowY		= 0;

	@Override
	public void drawMyself(Graphics g, JPanel p) {
		g.drawImage(BG_IMAGES[1], topX, topY, (ImageObserver) p);
		g.drawImage(BG_IMAGES[0], belowX, belowY, (ImageObserver) p);
	}

	@Override
	public void move() {
		if (topY >= 0) {
			topY = -480;
		} else {
			topY += SPEED;
		}

		if (belowY >= 480) {
			belowY = 0;
		} else {
			belowY += SPEED;
		}
	}

	@Override
	public boolean collison() {
		// TODO Auto-generated method stub
		return false;
	}

}

package com.jack;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageObserver;

import javax.swing.JPanel;

import com.jack.imp.IProcess;

/**
 * 游戏子弹
 * 
 * @author laughing
 * @date 2014年11月20日 上午10:27:12
 */
public class Bullet implements IProcess {
	public static final Image[]	BULLET_IMAGES	= ImageManager.getInstance()
																.getImagesByType("bullet");
	public static final int		FLY_SPEED		= 20;
	private boolean				dead			= false;
	public int					x;
	public int					y;

	public Bullet(int x, int y) {
		this.x = x - 50;
		this.y = y;
	}

	public boolean outOfBounds() {
		if (this.y == 0) {
			this.dead = true;
			return false;
		}
		return true;
	}

	/**
	 * @return the y
	 */
	public int getY() {
		return y;
	}

	/**
	 * @return the x
	 */
	public int getX() {
		return x;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jack.imp.IProcess#drawMyself(java.awt.Graphics,
	 * javax.swing.JPanel)
	 */
	@Override
	public void drawMyself(Graphics g, JPanel p) {
		// TODO Auto-generated method stub
		g.drawImage(BULLET_IMAGES[0],
					x,
					y - BULLET_IMAGES[0].getHeight(null),
					(ImageObserver) p);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jack.imp.IProcess#move()
	 */
	@Override
	public void move() {
		if (outOfBounds())
			this.y -= FLY_SPEED;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jack.imp.IProcess#collison()
	 */
	@Override
	public boolean collison() {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Bullet [dead=" + dead + ", x=" + x + ", y=" + y + "]";
	}

	/**
	 * @return the dead
	 */
	public boolean isDead() {
		return dead;
	}

}

package com.jack;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.ImageObserver;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JPanel;

import com.jack.imp.IProcess;

/**
 * 战斗机
 * 
 * @author laughing
 * @date 2014年11月20日 下午2:16:21
 */
public class Plan implements IProcess, KeyListener {
	private static final Image[]		PLAN_IMAGES		= ImageManager.getInstance()
																		.getImagesByType("plan");
	public static Map<Integer, Bullet>	bulletMap		= new HashMap<Integer, Bullet>();
	private static final int			PLAN_MOVE_SPEED	= 10;
	private static int					bulletID		= 0;
	public static int					imageIndex		= 0;
	private int							x;
	private int							y;

	public Plan(int x, int y) {
		this.x = x;
		this.y = y;

	}

	public void shut() {
		Bullet b = new Bullet(x, y);
		bulletMap.put(++bulletID, b);
		System.out.println("crate " + bulletMap);
	}

	@Override
	public void drawMyself(Graphics g, JPanel p) {
		g.drawImage(PLAN_IMAGES[imageIndex], x, y, (ImageObserver) p);
	}

	public void updatePlan() {

		if (imageIndex == 5)
			imageIndex = 0;
		imageIndex++;
	}

	@Override
	public void move() {

	}

	@Override
	public boolean collison() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();
		if (key == KeyEvent.VK_UP) {
			if (y - PLAN_MOVE_SPEED >= 0) {
				y -= PLAN_MOVE_SPEED;
			}
		}
		if (key == KeyEvent.VK_DOWN) {

			if (y + PLAN_MOVE_SPEED <= GamePanel.HEIGHT - PLAN_IMAGES[0].getHeight(null) * 2) {
				y += PLAN_MOVE_SPEED;
			}
		}
		if (key == KeyEvent.VK_LEFT) {
			if (x - PLAN_MOVE_SPEED >= 0)
				x -= PLAN_MOVE_SPEED;
		}
		if (key == KeyEvent.VK_RIGHT) {

			if (x + PLAN_MOVE_SPEED < GamePanel.WEIGHT - PLAN_IMAGES[0].getWidth(null))
				x += PLAN_MOVE_SPEED;
		}
		if (key == KeyEvent.VK_SPACE) {
			shut();
		}

	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}

}

package com.jack;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;
import javax.swing.border.SoftBevelBorder;

/**
 * 游戏容器
 * 
 * @author laughing
 * @date 2014年11月16日 下午7:58:11
 */
public class GamePanel extends JPanel implements Runnable {
	public static final int		HEIGHT	= 480;
	public static final int		WEIGHT	= 320;
	public static Plan			plan	= new Plan(160, 400);
	public static BackGround	ground	= new BackGround();

	public GamePanel() {
		setSize(WEIGHT, HEIGHT);
		setBorder(new SoftBevelBorder(1, Color.white, Color.white));
		// Sets the focusable state of this Component to the specified value.
		// This value overrides the Component's default focusability.
		setFocusable(true);
		// 监听事件
		addKeyListener(plan);
		new Thread(this).start();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
	 */
	@Override
	protected void paintComponent(Graphics g) {
		// TODO Auto-generated method stub
		super.paintComponent(g);
		ground.drawMyself(g, this);
		plan.drawMyself(g, this);
		for (int key : plan.bulletMap.keySet()) {
			Bullet b = plan.bulletMap.get(key);
			if (!b.isDead()) {

				b.drawMyself(g, this);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			plan.updatePlan();
			ground.move();
			for (int key : plan.bulletMap.keySet()) {
				Bullet b = plan.bulletMap.get(key);
				if (!b.isDead()) {
					b.move();
				}
			}
			repaint();
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

package com.jack;

import javax.swing.JFrame;

/**
 *
 * @author laughing
 * @date 2014年11月16日 下午8:11:39
 */
public class Main extends JFrame {
	GamePanel	panel	= new GamePanel();

	public Main() {
		setSize(panel.getWidth(), panel.getHeight());
		getContentPane().add(panel);
		setVisible(true);
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
	}

	public static void main(String args[]) {
		new Main();
	}

}
四、源码: 点击打开链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值