[题目描叙]
多线程程序设计:炮打飞机
实验目的:学会使用多线程进行并发程序设计
实验内容:编写一个应用程序模拟大炮打飞机。在GUI界面上,飞机水平飞行,用界面上的按钮控制大炮的运行方向(如向左,向右,向上,向下)。当炮弹碰着飞机后,爆炸。
[程序代码]
MyGame.java
/*
* 项目名称:炮打飞机
* 版本:1.0
* 作者:张俊强
* 时间:2016/5/17
* */
package drawPanel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
public class MyGame extends JFrame{
int killNum=0;
private MyPanel mp=null;
public static void main(String[] args) {
// TODO Auto-generated method stub
MyGame game=new MyGame();
}
public MyGame(){
mp=new MyPanel();
//启动画板线程
Thread t=new Thread(mp);
t.start();
this.add(mp);
this.addKeyListener(mp);
this.addWindowListener(mp);
this.setSize(600,450);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public int getKillNum() {
return killNum;
}
public void setKillNum(int killNum) {
this.killNum = killNum;
}
}
/*
* 窗口监听
* */
/*
* 画出面板
* */
class MyPanel extends JPanel implements KeyListener,Runnable,WindowListener{
/*
*画出一个大炮
*/
private Canon canon=null;
/*
* 画一些飞机
* */
private Vector plane=new Vector();
//定义炸弹向量
private Vector bomb=new Vector();
private int planeNum=5;
//定义三张图片,三张图片才能组成一颗炸弹
Image image1=null;
Image image2=null;
Image image3=null;
//击杀数
private int killNum=0;
public MyPanel(){
JOptionPane.showMessageDialog(this,"上下左右( w,s,a,d ),开火( j )", "提示",JOptionPane.PLAIN_MESSAGE);
canon=new Canon(150,150);
//初始化plane
for(int i=0;i6)
{
g.drawImage(image1, b.getX(), b.getY(), 55, 55, this);
}else if(b.getLife()>3)
{
g.drawImage(image2, b.getX(), b.getY(), 55, 55, this);
}else{
g.drawImage(image3, b.getX(), b.getY(), 55, 55, this);
}
//让b的生命值减小
b.lifeDown();
//如果炸弹生命值为0,就把该炸弹重bombs向量去掉
if(b.getLife()==0)
{
bomb.remove(b);
}
}
//画出子弹
for(int i=0;i=p.getX()&&s.x<=p.getX()+55)&&(s.y>=p.getY()&&s.y<=p.getY()+55)){
bomb.add(new Bomb(p.getX(),p.getY()));
killNum++;
s.isAlive=false;
return true;
}
return false;
}
public void drawCanon(int x,int y,Graphics g,int direct){
g.setColor(Color.cyan);
g.fill3DRect(x, y, 40, 40,false);
g.drawOval(x, y, 40, 40);
switch (direct){
case 0://上
g.drawLine(x+20, y-15, x+20, y+20);
break;
case 1://右
g.drawLine(x+55, y+20, x+20, y+20);
break;
case 2://下
g.drawLine(x+20, y+55, x+20, y+20);
break;
case 3://左
g.drawLine(x-15, y+20, x+20, y+20);
break;
default:break;
}
}
public void drawPlane(int x,int y,Graphics g,int direct){
switch (direct){
case 0:
g.setColor(Color.red);
g.fillOval(x-6, y+13, 55, 20);
g.setColor(Color.yellow);
g.fillOval(x+10, y, 20, 55);
break;
}
}
@Override
public void keyPressed(KeyEvent e) {//键按压
if(e.getKeyChar()=='w'){
canon.moveUp();
canon.setDirect(0);
}
else if(e.getKeyChar()=='s'){
canon.moveDown();
canon.setDirect(2);
}
else if(e.getKeyChar()=='a'){
canon.moveLeft();
canon.setDirect(3);
}
else if(e.getKeyChar()=='d'){
canon.moveRight();
canon.setDirect(1);
}
if(e.getKeyChar()=='j'){
if(this.canon.ss.size()<10){
this.canon.shotPlane();
}
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {//键释放
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {//具体值的显示
// TODO Auto-generated method stub
}
//画板线程
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i
MyGameMember.java
package drawPanel;
import java.util.Vector;
/*
* 实体类,由此派生出大炮以及飞机
* */
class BaseClass{
//对象的坐标x,y
int x=0;
int y=0;
//定义方向
int direct=0;
//定义速度
int speed=3;
public BaseClass(int x,int y){
this.x=x;
this.y=y;
}
/*
* get 和set方法
* */
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 int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
}
/*
* 大炮类
* */
class Canon extends BaseClass{
public Vector ss=new Vector();
public Shot s=null;
public Canon(int x, int y) {
super(x, y);
// TODO Auto-generated constructor stub
}
public void shotPlane(){
switch(this.direct){
case 0:
s=new Shot(x+20,y-15,0);
ss.add(s);
break;
case 1:
s=new Shot(x+55, y+20,1);
ss.add(s);
break;
case 2:
s=new Shot(x+20, y+55,2);
ss.add(s);
break;
case 3:
s=new Shot(x-15, y+20,3);
ss.add(s);
break;
default:break;
}
//启动子弹线程
Thread t=new Thread(s);
t.start();
}
void moveUp(){
if(y-speed>=15)
y-=speed;
}
void moveRight(){
if(x<=525)
x=x+speed;
}
void moveDown(){
if(y<=350)
y=y+speed;
}
void moveLeft(){
if(x-speed>=15)
x-=speed;
}
}
/*
* 飞机类
* */
class Plane extends BaseClass implements Runnable{
boolean isAlive=true;
int times=0;
public Plane(int x, int y) {
super(x, y);
// TODO Auto-generated constructor stub
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
for(int i=0;i<30;i++){
if(x<600){
x+=speed;
}
else{
this.isAlive=false;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
/*
* 发射子弹
* */
class Shot implements Runnable{
int x;
int y;
int direct;
int speed=5;
boolean isAlive=true;
Shot(int x,int y,int direct){
this.x=x;
this.y=y;
this.direct=direct;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
switch(this.direct){
case 0:
y-=speed;
break;
case 1:
x+=speed;
break;
case 2:
y+=speed;
break;
case 3:
x-=speed;
break;
default:break;
}
if(x<0||x>600||y<0||y>600){
this.isAlive=false;
break;
}
}
}
}
class Bomb{
private int x,y;
private int life=9;
private boolean isLive=true;
public Bomb(int x,int y){
this.x=x;
this.y=y;
}
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 void lifeDown()
{
if(life>0)
{
life--;
}else{
this.isLive=false;
}
}
public int getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
}
[说明]