Java swing+Thread 打飞机小游戏

简单分析:

1.需要界面 由SWing提供,加载   飞机的图片,子弹图片,敌机图片,

2. 敌机随机下落 、子弹的绘画(线程控制)  主机的控制(implements MouseMotionListener,MouseListener)

3.分析需求:

1.背景 --静态

2.敌机 --随机往下落   主机 --鼠标拖动

3.子弹 --发射向上

4.operation(方向)  上 --》  子弹--

                  下 --》  敌机++

5.type                        1敌机   0子弹

6.速度                         1慢       0快

7.判断敌机和子弹接触(看成两圆接触 R)

   敌机、子弹-->>定义x y 轴坐标   --》 x+R

           敌机、子弹 接触及消失  无接触  敌机则下落最大高度()自动消失  子弹的上升最高点(0)自动消失


4.创建三个类 

JPanel_game.class,

Choose.class

Games_start.class,

如下:

JPanel_game.class

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JPanel;



public class JPanel_game extends JPanel implements MouseMotionListener,MouseListener{
	int x,y;  //主机的坐标
	int xx[]; int yy[];//背景星星数组
	Font[] fonts;
	
	List<Choose> downs; //下落
	List<Choose> fires; //上升的子弹
	
	int fires_speed = 20; //运动的速度(数值越大  速度越慢)
	int downs_speed = 60;
	
	//飞机数量
	int sum = 0;
	
	Boolean isFires=false;
	
	public JPanel_game() {
		// TODO Auto-generated constructor stub
		this.addMouseMotionListener(this);
		this.addMouseListener(this);
		x=150; y=600;  //设置主机坐标
		xx = new int[50];yy = new int[50];
		for(int i = 0 ; i<50;i++){
			xx[i]=(int)(Math.random()*400);
			yy[i]=(int)(Math.random()*700);
		}
		fonts = new Font[4]; //设置字体 四个参数
		fonts[0] = new Font("微软雅黑", Font.BOLD, 18);
		fonts[1] = new Font("微软雅黑", Font.BOLD, 24);
		fonts[2] = new Font("微软雅黑", Font.BOLD, 14);
		fonts[3] = new Font("微软雅黑", Font.BOLD, 32);
	
		downs = new ArrayList<Choose>();   
		fires = new ArrayList<Choose>();
	}

	@Override
	public void paint(Graphics g) {
		// TODO Auto-generated method stub
		super.paint(g);
		
		//调用Choose
		Choose choose = new Choose();
		
		
		//背景图片 import java.net.URL;
		URL B_img = getClass().getResource("back.jpg"); 
		ImageIcon B_icon = new ImageIcon(B_img);
		g.drawImage(B_icon.getImage(), 0, 0, 400, 700,null);
		
		//显示飞机数量
		g.setColor(Color.white);
		g.drawString("干掉飞机:"+sum+"架", 10, 20);
		
		//画星星
		//g.setColor(Color.white);
		g.setColor(new Color((int)(Math.random()*0xffffff))); //随机颜色
		for(int i=0; i<xx.length;i++){
		g.setFont(fonts[(int)(Math.random()*4)]); //改变字体大小
		g.drawString("★", xx[i], yy[i]);
		}
		
		//显示主机
		URL My_img = getClass().getResource("el_0.gif");
		ImageIcon My_icon = new ImageIcon(My_img);
		g.drawImage(My_icon.getImage(), x, y, 60, 60,null);
		
		//显示敌机
		for(int i=0;i<downs.size();i++){
			choose = downs.get(i);
			choose.draw(g);
		}
		//显示子弹
		for(int i=0;i<fires.size();i++){
			choose = fires.get(i);
			choose.draw(g);
		}
		
	}
	
	//创建线程
	public void st() {
		// TODO Auto-generated method stub
		Thread th = new Thread(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				super.run();
				int count = 0; //设定速度初始值
				while (true) {
					count++;
					
					if(count%downs_speed==0){
						//当count 自增到60的时候,敌机开始往下落
						Choose ch = new Choose();
						int tem_x = (int) (Math.random()*400);		//敌机的x轴坐标
						int tem_y = -40;												             						//y轴坐标
						ch.setX(tem_x);																		//将数据放进X
						ch.setY(tem_y);
						ch.setR(20);
						ch.setType(1);
						ch.setOperation(1);
						//将信息加入 downs集合
						downs.add(ch);
					}
					for(int i=0;i<downs.size();i++){
						Choose c = downs.get(i);
						c.move();
						if(c.getY()>=JPanel_game.this.getHeight()){
							downs.remove(i);
						}
					}
					//子弹往上升的动作
					if(isFires&&count%fires_speed==0){
						//isFires满足ture
						//count%fires_speed==0
						Choose ch = new Choose();
						ch.setR(10);
						ch.setX(x+20);
						ch.setY(y);
						ch.setType(0);
						ch.setOperation(0);
						fires.add(ch);
					}
					for(int i=0;i<fires.size();i++){
						Choose c = fires.get(i);
						c.move();
						if(c.getY()<0){
							fires.remove(i);
						}
					}
					//判断飞机子弹是否接触
					//敌r+飞r <=2R  则消除
					for(int i=0;i<fires.size();i++){
						for(int j=0;j<downs.size();j++){
						  									if(i<fires.size()&&j<downs.size()&&fires.get(i).isTouch(downs.get(j))){
		 &&fires.get(i).isTouch(downs.get(j))  对半径判断的引用
							fires.remove(i);
							downs.remove(j);
							sum++;
						  		}
							}
					 	}
					try {
						//休眠时间
						Thread.sleep(5); 
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					repaint();
				}
			}
		};
		th.start();
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		isFires = true;
	}
	//按下
	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		isFires = false;
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	//按下移动
	@Override
	public void mouseDragged(MouseEvent e) {
		// TODO Auto-generated method stub
		x=e.getX()-20;
		y=e.getY()-20;
		repaint();
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub
		x=e.getX()-20;
		y=e.getY()-20;
		repaint();
	}
}


Choose.java:

/**
 * 
 * 
 * operation(方向)  上 --》  子弹--
 * 			                  下 --》  敌机++
 * type    1敌机   0子弹
 * 
 * 速度                1慢       0快
 * 
 * 
 * */
public class Choose {
		int x,y;        //坐标
		int r;		//半径
		int type;	// type    1敌机   0子弹
		int operation;	
		
	public	Choose(){  }
	//画飞机或子弹
	public void draw(Graphics g) {
		// TODO Auto-generated method stub

		//获取图片路径  java.net.URL;
		
		//敌机
		URL herott = getClass().getResource("herot.gif");
		ImageIcon h_icon = new ImageIcon(herott);
		
		//子弹
		URL fire = getClass().getResource("fire.gif");
		ImageIcon f_icon = new ImageIcon(fire);
		
		//switch(){}  选择画 敌机or 子弹
		switch(type){
			case 0: //子弹
				g.drawImage(f_icon.getImage(), x, y, 2*r, 2*r, null);
				break;
			case 1: //敌机
				g.drawImage(h_icon.getImage(), x, y, 2*r, 2*r, null);
				break;
			default:
				break;
		}
		
	}
	//判断方向  operation
	public void move() {
		switch (operation) {
		case 0:
			y--;     //子弹   y--向上
			break;
		case 1:
			y++;     //敌机   y++向下
			break;  
				

		default:
			break;
		}
	}
	//敌机和子弹接触
	public boolean isTouch(Choose ch) {
		//圆心距 =  = (x2-x1)*(x2-x1) +( y2-y1 )*(y2-y1)
		int x1=x+r;
		int y1=y+r;
		int x2=ch.getX()+ch.getR();
		int y2=ch.getY()+ch.getR();
		//计算公式
		double s = Math.sqrt((x2-x1)*(x2-x1) +( y2-y1 )*(y2-y1));
		if(s<=ch.getR()+this.getR()){   //相切 or 相交
			return true;
		}else{
			return false;
		}
	
	}
	
	public Choose(int x,int y,int r,int type,int operation){
		this.x = x;
		this.y = y;
		this.r = r;
		this.type = type;
		this.operation = operation;
	}
	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 getR() {
		return r;
	}

	public void setR(int r) {
		this.r = r;
	}

	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}

	public int getOperation() {
		return operation;
	}

	public void setOperation(int operation) {
		this.operation = operation;
	}
	
	
	
	
}
Games_start.java

import javax.swing.JFrame;
import Fly.Game.JPanel_game;

public class Games_start {
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JFrame jf = new JFrame();
		jf.setSize(400,700);
		jf.setTitle("Fly Game");
		jf.setVisible(true);
		
		//调用 JPanel_game
		JPanel_game game = new JPanel_game();
		jf.add(game);
		game.st();
	}

}


源代码已打包,csdn可下载


以上都是自己在学Java时的笔记

发个博客 纪念点滴

如有雷同,不如加个联系呗



  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值