栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java小游戏

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java小游戏

前言

        此小游戏写的比较简易,具有一些小游戏基本功能,后续有可能会对游戏进行优化,如果优化会再更新,本文对于刚接触小游戏的小白来说可能会有所帮助,本人也是小白,有问题敬请指正。另外,因为代码有点长,会有适当的缩减与描述不周的地方,还请见谅。

一:小游戏介绍:

        (一):内容介绍

                这是一个人物闯关游戏,击败小怪与boss即可通关,人物素材是关于龙珠,小怪与boss素材是随便找的。

        (二):功能介绍

                1.人物的功能

                基本的血量蓝量,移动还有

                (1):四种形态:normal、super1、super2、super3

                        normal形态下每秒恢复一点生命和两点法力

                        super1形态下不会恢复生命和法力同时也不会消耗

                        super2形态下每秒消耗一点生命和一点法力

                        super3形态下每秒消耗三点生命和三点法力

                        目前每个形态的攻击力还是一致,后续攻击力改变会再更新

                (2):用拳,腿攻击以及防御

                (3):三个技能:shoot、gpqg、yuanqidan

                2.小怪功能

                        向左攻击

                3.boss功能

                        三个技能:用翅膀攻击、用爪子攻击、发射子弹

二:小游戏代码实现:

创建窗体

首先写游戏要先创建窗体,可以单独写成一个类

import javax.swing.JFrame;
import javax.swing.WindowConstants;
import java.awt.*;

public class StartGame {
	public static void main(String[] args) {
		//创建JFrame类的对象
		JFrame jf=new JFrame();
		//设置游戏标题
		jf.setTitle("World");
		//设置窗体的大小与位置
		//获得屏幕的尺寸
		int width=Toolkit.getDefaultToolkit().getScreenSize().width;
		int height=Toolkit.getDefaultToolkit().getScreenSize().height;
		jf.setBounds((width-780)/2,(height-520)/2,1000,520);//前两个参数是窗体位置(屏幕中间),后两个参数为窗体大小
		//设置窗体不可调节大小
		jf.setResizable(false);
		//关闭窗体结束代码运行
		jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		//游戏界面对象
		GamePanel gp=new GamePanel();
		//添加游戏界面
		jf.add(gp);
		//设置窗体左上角图标
		jf.setIconImage(ImagesArray.img);
		//设置窗体可见(写到最后)
		jf.setVisible(true);
	}
}

封装图片

然后将游戏要用到的图片进行封装,这里我创建了两个类一个是Images类,用来存放单张图片,一个是ImagesArray类,用来存放图片数组

Images类先是用URL获取图片路径,然后再创建ImageIcon对象,因为前面都添加了public static可以直接通过 类名. 的形式进行调用

格式为:

public static URL 路径名 = Images.class.getResource("路径");
public static ImageIcon 图片名=new ImageIcon(路径名);

ImageIcon对象在绘画时用Images.图片名.paintIcon(面板,画笔参数,坐标,坐标);方法绘制

带颜色的为自命名

图片有点多都是重复性内容只是改变了路径与对象名,这里省略一些,因为太长了

import java.net.URL;
import javax.swing.ImageIcon;

public class Images {
    //touxiang
	public static URL touxiang1URL = Images.class.getResource("/images/touxiang/touxiang1.png");
	public static ImageIcon touxiang1Img =new ImageIcon(touxiang1URL);
	public static URL touxiang2URL = Images.class.getResource("/images/touxiang/touxiang2.png");
	public static ImageIcon touxiang2Img =new ImageIcon(touxiang2URL);
	public static URL touxiang3URL = Images.class.getResource("/images/touxiang/touxiang3.png");
	public static ImageIcon touxiang3Img =new ImageIcon(touxiang3URL);
	public static URL touxiang4URL = Images.class.getResource("/images/touxiang/touxiang4.png");
	public static ImageIcon touxiang4Img =new ImageIcon(touxiang4URL);
	public static URL lanlongtouxiangURL = Images.class.getResource("/images/touxiang/lanlongtouxiang.png");
	public static ImageIcon lanlongtouxiangImg =new ImageIcon(lanlongtouxiangURL);
	//background
	
    ...

	//super3
	public static URL s3idleURL = Images.class.getResource("/images/super3/idle.gif");
	public static ImageIcon s3idleImg =new ImageIcon(s3idleURL);
	public static URL s3updownURL = Images.class.getResource("/images/super3/updown.gif");
	public static ImageIcon s3updownImg =new ImageIcon(s3updownURL);
	public static URL s3leftmoveURL = Images.class.getResource("/images/super3/leftmove.gif");
	public static ImageIcon s3leftmoveImg =new ImageIcon(s3leftmoveURL);
	public static URL s3rightmoveURL = Images.class.getResource("/images/super3/rightmove.gif");
	public static ImageIcon s3rightmoveImg =new ImageIcon(s3rightmoveURL);
	public static URL s3guardURL = Images.class.getResource("/images/super3/guard.gif");
	public static ImageIcon s3guardImg =new ImageIcon(s3guardURL);
	public static URL s3hurtURL = Images.class.getResource("/images/super3/hurt.gif");
	public static ImageIcon s3hurtImg =new ImageIcon(s3hurtURL);
	public static URL s3deathURL = Images.class.getResource("/images/super3/death.gif");
	public static ImageIcon s3deathImg =new ImageIcon(s3deathURL);
}

ImagesArray类创建了Image对象,也是直接通过 类名. 的形式进行调用

格式:

public static Image[] 图片数组名 =new Image[图片数量];
    public static int Count变量=0;(用来表示播放到哪张图片)
    static {
        for(int i=0; i
            图片数组名[i] = Toolkit.getDefaultToolkit().getImage("图片路径"+(i+1)+".图片格式");
        }
    }

Image对象在绘画时用g.drawImage(图片数组名[Count变量],坐标,坐标,面板);方法绘制

import java.awt.*;

public class ImagesArray {
	//窗体左上角图片
	public static Image img = Toolkit.getDefaultToolkit().getImage("E:\esclipse\DragonWorldProject\bin\images\background\biao.png");
	//背景图片图集
	public static Image[] backgroundimgs =new Image[2];
	public static int backgroundCount=1;
	static {
		for(int i=0; i<2; i++) {
			backgroundimgs[i] = Toolkit.getDefaultToolkit().getImage("E:\esclipse\DragonWorldProject\bin\images\background\background"+(i+1)+".gif");
		}
	}
	//用拳攻击图集
	
    ...

	//super3OverLoad
	public static Image[] s3olimgs =new Image[3];
	public static int s3olCount=0;
	static {
		for(int i=0; i<3; i++) {
			s3olimgs[i] = Toolkit.getDefaultToolkit().getImage("E:\esclipse\DragonWorldProject\bin\images\super3\overload"+(i+1)+".gif");
		}
	}
}

游戏界面

创建游戏界面类该类要继承JPanel类

先写一个初始化方法(有初始化方法可以用来重新开始游戏),再写一个构造方法里面放键盘、鼠标、事件监听,线程,JPanel类重写画笔方法

初始化方法里面放的是角色、怪物..的初始化信息(根据游戏开始时所要初始化的东西来定)

键盘监听里加的是角色的键盘监听

鼠标监听里是鼠标的移动,与点击监听

事件监听要先声明一个定时器,里面放的是角色的移动,判定内容

paint()方法里是别的类的paintSelf方法和一些其他的要画的东西

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;

public class GamePanel extends JPanel {
    //定义定时器
	Timer timer;
    //初始化方法
	public void init() {
		
	}
    //构造器
	public GamePanel() {
		init();
		//将焦点定位在当前操作的面板上
		this.setFocusable(true);
		
		//鼠标监听
		this.addMouseMotionListener(new MouseMotionListener() {
			@Override
			public void mouseDragged(MouseEvent e) {
				// TODO Auto-generated method stub
			}
			//鼠标移动监听
			@Override
			public void mouseMoved(MouseEvent e) {
				mouseX=e.getX();
				mouseY=e.getY();
			}
		});
		this.addMouseListener(new MouseListener() {
			//鼠标点击监听
			@Override
			public void mouseClicked(MouseEvent e) {
				
			}
			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub
			}
			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
			}
			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub
			}
			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub
			}
		});
		
		//键盘监听
		this.addKeyListener(new KeyAdapter() {
			//按下监听
			@Override
			public void keyPressed(KeyEvent e) {
				super.keyPressed(e);
				
			}
			//松开监听
			public void keyReleased(KeyEvent e) {
				super.keyPressed(e);
				
			}
		});
		
		//事件监听
		timer = new Timer(10,new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
            
            }
        });
		timer.start();
	//paint()方法
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);	
        
    }
}

封面背景

实现封面是要在游戏开始前,因此需要一个变量来控制游戏的不同状态,游戏可能有的状态有:未开始,开始,暂停,胜利,失败,按照需要准备图片,然后用一个int变量来表示这多种状态

----------------------
//写在Gampanel类的成员变量中
//游戏状态
	int gameState=0;
//定义背景初始位置
	int a=0;
-------------------------------------
//写在Gampanel类的paint方法中
//游戏开始封面
		if(gameState==0) {
			Images.fengmianImg.paintIcon(this, g, 0, 0);
			Images.startGameImg.paintIcon(this, g, 390, 350);
		}
		//游戏胜利封面
		if(gameState==2) {
			Images.fengmian1Img.paintIcon(this, g, 0, 0);
			Images.shengliImg.paintIcon(this, g, 330, 350);
		}
		//游戏失败封面
		if(gameState==3) {
			Images.fengmian2Img.paintIcon(this, g, 0, 0);
			Images.shibaiImg.paintIcon(this, g, 380, 350);
		}
		//游戏开始
		if(gameState==1) {
        //画背景
			 g.drawImage(ImagesArray.backgroundimgs[ImagesArray.backgroundCount],a,0,this);
			Images.background3Img.paintIcon(this, g, 372, 0);
			//画人物
			if(character.death==false) {
				character.paintSelf(g);
			}
			if(character.death) {
				Images.deathImg.paintIcon(this, g, character.wkX, character.wkY);
				character.isIdle = false;
				character.up = false;
				character.down = false;
				character.left = false;
				character.right = false;
				character.hit = false;
				character.kick = false;
				character.guard = false;
				character.hurt = false;
				character.shoot = false;
				character.gpqg = false;
				character.yuanqidan = false;
				character.normaloverload = false;
				character.super12overload = false;
				character.super3overload = false;
				gameState=3;
			}
        }

封面中有开始游戏字样,当鼠标移动到这块区域,并点击一下时开始游戏,通过鼠标监听实现

----------------------------
//写在GamePanel类的成员变量
//定义鼠标坐标
	int mouseX;
	int mouseY;
	//定义鼠标是否点击
	boolean isClick;
----------------------------
//鼠标监听
//写在鼠标监听
		this.addMouseMotionListener(new MouseMotionListener() {
			@Override
			public void mouseDragged(MouseEvent e) {
				// TODO Auto-generated method stub
			}
			//鼠标移动监听
			@Override
			public void mouseMoved(MouseEvent e) {
				mouseX=e.getX();
				mouseY=e.getY();
			}
		});
		this.addMouseListener(new MouseListener() {
			//鼠标点击监听
			@Override
			public void mouseClicked(MouseEvent e) {
				if(390<=mouseX && mouseX<=553 && 350 

至此封面添加完成

为了实现背景的每隔一段时间进行切换,需要将背景写在线程中 ,线程放在GamPanel类的构造方法中

//写在GamePanel类中的构造方法里
//背景移动线程
		new Thread() {
			public void run() {
				while(true) {
					repaint();
					a-=4;
					if(a<=-1244) {
						a=0;
					}
					try {
						Thread.sleep(30);
					} catch(InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();

//背景变换线程
		new Thread() {
			public void run() {
				while(true) {
					ImagesArray.backgroundCount++;
					if(ImagesArray.backgroundCount==2) {
						ImagesArray.backgroundCount=0;
					}
					try {
						Thread.sleep(50*1000);
					} catch(InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
		
		

至此背景添加完成

角色类

写出角色的各种信息与构造方法、paint方法

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class Character{
    //定义角色尺寸
	int width = 40;
	int height = 48;
	//定义角色坐标
	int wkX;
	int wkY;
	//定义角色血量
	int hp;
	//定义角色蓝量
	int mp;
	//定义角色状态
	//是否站着
	boolean isIdle;
	//方向
	boolean up;
	boolean down;
	boolean left;
	boolean right;
	//是否用拳攻击
	boolean hit;
	boolean hitcool;
	//是否用腿攻击
	boolean kick;
	boolean kickcool;
	//是否防御
	boolean guard;
	//是否被攻击
	boolean hurt;
	//是否发射气波
	boolean shoot;
	//是否用气功
	boolean gpqg;
	boolean gpqgcool;
	//是否使用元气弹
	boolean yuanqidan;
	//是否死亡
	boolean death;
	//形态
	boolean normal;
	boolean super1;
	boolean super2;
	boolean super3;
	boolean normaloverload;
	boolean super12overload;
	boolean super3overload;
    //无参构造
	public Character() {
		super();
	}
	//全参构造
	public Character(int wkX, int wkY, int hp, int mp, boolean isIdle, boolean up, boolean down, boolean left,
			boolean right, boolean hit, boolean kick, boolean guard, boolean hurt, boolean shoot, boolean gpqg,
			boolean yuanqidan, boolean death) {
		super();
		this.wkX = wkX;
		this.wkY = wkY;
		this.hp = hp;
		this.mp = mp;
		this.isIdle = isIdle;
		this.up = up;
		this.down = down;
		this.left = left;
		this.right = right;
		this.hit = hit;
		this.kick = kick;
		this.guard = guard;
		this.hurt = hurt;
		this.shoot = shoot;
		this.gpqg = gpqg;
		this.yuanqidan = yuanqidan;
		this.death = death;
	}
    
    //画人物
	public void paintSelf(Graphics g) {

    }
}

 画角色头像、血量与蓝条(paintSelf方法里)

//画头像
		if(normal) {
			Images.touxiang1Img.paintIcon(null, g, 0, 0);
		}else if(super1) {
			Images.touxiang2Img.paintIcon(null, g, 0, 0);
		}else if(super2) {
			Images.touxiang3Img.paintIcon(null, g, 0, 0);
		}else if(super3) {
			Images.touxiang4Img.paintIcon(null, g, 0, 0);
		}
		//画血量
		g.setColor(new Color(220,20,60));
		g.fillRect(40,0,300,20);
		if(hp<200) {
			g.setColor(new Color(255,255,255));
			g.fillRect(340-(200-hp)*3/2,0,(200-hp)*3/2,20);
		}
		g.setColor(new Color(0,0,0));
		g.setFont(new Font("Times New Roman",Font.ITALIC,15));
		g.drawString(""+hp+"/200",43,16);
		//画蓝条
		g.setColor(new Color(0,0,255));
		g.fillRect(40,20,200,20);
		if(mp<100) {
			g.setColor(new Color(255,255,255));
			g.fillRect(240-(100-mp)*2,20,(100-mp)*2,20);
		}
		g.setColor(new Color(0,0,0));
		g.setFont(new Font("Times New Roman",Font.ITALIC,15));
		g.drawString(""+mp+"/100",43,36);

角色的形态和移动(用不同坐标的图片来表示移动)

实现人物的移动通过以下步骤实现:

1.Character类中写出移动方法(通过添加键盘监听来控制,摁下移动,松开停止),在Character类中写下键盘监听后添加到GamePanel类中去

//人物移动方法
	//键盘摁下监听
	public void keyPressed(KeyEvent e) {
		int keyCode=e.getKeyCode();
		switch (keyCode) {
			case KeyEvent.VK_W:
				up=true;
				isIdle=false;
				down = false;
				break;
			case KeyEvent.VK_S:
				down=true;
				isIdle=false;
				up = false;
				break;	
			case KeyEvent.VK_A:
				left = true;
				isIdle=false;
				right = false;
				break;
			case KeyEvent.VK_D:
				right = true;
				isIdle=false;
				left = false;
				break;
            case KeyEvent.VK_0:
				normal=true;
				super1=false;
				super2=false;
				super3=false;
				break;
			case KeyEvent.VK_1:
				normaloverload=true;
				Music.baoqi();
				super12overload=false;
				super3overload=false;
				break;
			case KeyEvent.VK_2:
				normaloverload=false;
				super12overload=true;
				Music.baoqi();
				super3overload=false;
				break;
			case KeyEvent.VK_3:
				normaloverload=false;
				super12overload=false;
				super3overload=true;
				Music.baoqi();
				break;
			default :
				break;
		}
	}
	//键盘松开监听
	public void keyReleased(KeyEvent e) {
		int keyCode=e.getKeyCode();
		switch (keyCode) {
			case KeyEvent.VK_W:
				up=false;
				isIdle=true;
				break;
			case KeyEvent.VK_S:
				down=false;
				isIdle=true;
				break;
			case KeyEvent.VK_A:
				left = false;
				isIdle=true;
				break;
			case KeyEvent.VK_D:
				right = false;
				isIdle=true;
				break;
			default :
				break;
		}
	}
//添加到GamePanel类中
        //键盘监听
		this.addKeyListener(new KeyAdapter() {
			//按下监听
			@Override
			public void keyPressed(KeyEvent e) {
				super.keyPressed(e);
				character.keyPressed(e);
			}
			//松开监听
			public void keyReleased(KeyEvent e) {
				super.keyPressed(e);
				character.keyReleased(e);
			}
		});

2. 在Character类的paintSelf方法里按照键盘监听的指令画出人物(避免图片重叠,加入限制条件)这里包括了形态

        if(isIdle) {
			if(normal) {
				Images.idleImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1idleImg.paintIcon(null, g, wkX, wkY);		
			}else if(super2) {
				Images.s2idleImg.paintIcon(null, g, wkX, wkY);	
			}else if(super3) {
				Images.s3idleImg.paintIcon(null, g, wkX, wkY);	
			}
		}
		if(up || down || left || right || hit || kick || guard || hurt || shoot || gpqg || yuanqidan || death) {
			isIdle = false;
		}
		if(guard) {
			isIdle = false;
			up = false;
			down = false;
			left = false;
			right = false;
			hit= false;
			kick = false;
			shoot = false; 
			gpqg = false;
			yuanqidan = false;
			normaloverload = false;
			super12overload = false;
			super3overload = false;
		}
		if(hurt) {
			isIdle = false;
			up = false;
			down = false;
			left = false;
			right = false;
			hit = false;
			kick = false;
			guard = false;
			shoot = false;
			gpqg = false;
			yuanqidan = false;
			normaloverload = false;
			super12overload = false;
			super3overload = false;
		}
		if(shoot) {
			isIdle = false;
			up = false;
			down = false;
			left = false;
			right = false;
			hit = false;
			kick = false;
			guard = false; 
			gpqg = false;
			yuanqidan = false;
			normaloverload = false;
			super12overload = false;
			super3overload = false;
		}
		if(gpqg) {
			isIdle = false;
			up = false;
			down = false;
			left = false;
			right = false;
			hit = false;
			kick = false;
			guard = false;
			shoot = false;
			yuanqidan = false;
			normaloverload = false;
			super12overload = false;
			super3overload = false;
		}
		if(yuanqidan) {
			isIdle = false;
			up = false;
			down = false;
			left = false;
			right = false;
			hit = false;
			kick = false;
			guard = false;
			shoot = false;
			gpqg = false;
			normaloverload = false;
			super12overload = false;
			super3overload = false;
		}
		if(normaloverload) {
			isIdle = false;
			up = false;
			down = false;
			left = false;
			right = false;
			hit = false;
			kick = false;
			guard = false;
			hurt = false;
			shoot = false;
			gpqg = false;
			yuanqidan = false;
			super12overload = false;
			super3overload = false;
		}
		if(super12overload) {
			isIdle = false;
			up = false;
			down = false;
			left = false;
			right = false;
			hit = false;
			kick = false;
			guard = false;
			hurt = false;
			shoot = false;
			gpqg = false;
			yuanqidan = false;
			normaloverload = false;
			super3overload = false;
		}
		if(super3overload) {
			isIdle = false;
			up = false;
			down = false;
			left = false;
			right = false;
			hit = false;
			kick = false;
			guard = false;
			hurt = false;
			shoot = false;
			gpqg = false;
			yuanqidan = false;
			normaloverload = false;
			super12overload = false;
		}
		if(up && down==false && left==false && right==false && hit==false && kick==false) {
			if(normal) {
				Images.updownImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1updownImg.paintIcon(null, g, wkX, wkY);	
			}else if(super2) {
				Images.s2updownImg.paintIcon(null, g, wkX, wkY);		
			}else if(super3) {
				Images.s3updownImg.paintIcon(null, g, wkX, wkY);		
			}
		}
		if(up && right && hit==false && kick==false) {
			if(normal) {
				Images.rightmoveImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1rightmoveImg.paintIcon(null, g, wkX, wkY);
			}else if(super2) {
				Images.s2rightmoveImg.paintIcon(null, g, wkX, wkY);	
			}else if(super3) {
				Images.s3rightmoveImg.paintIcon(null, g, wkX, wkY);	
			}
		}
		if(up && left && hit==false && kick==false) {
			if(normal) {
				Images.leftmoveImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1leftmoveImg.paintIcon(null, g, wkX, wkY);		
			}else if(super2) {
				Images.s2leftmoveImg.paintIcon(null, g, wkX, wkY);	
			}else if(super3) {
				Images.s3leftmoveImg.paintIcon(null, g, wkX, wkY);		
			}
		}
		if(up && right && hit) {
			if(normal) {
				g.drawImage(ImagesArray.hitimgs[ImagesArray.hitCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1hitimgs[ImagesArray.s1hitCount],wkX,wkY,null);		
			}else if(super2) {
				g.drawImage(ImagesArray.s2hitimgs[ImagesArray.s2hitCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3hitimgs[ImagesArray.s3hitCount],wkX,wkY,null);	
			}
		}
		if(up && right && hit) {
			if(normal) {
				g.drawImage(ImagesArray.hitimgs[ImagesArray.hitCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1hitimgs[ImagesArray.s1hitCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2hitimgs[ImagesArray.s2hitCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3hitimgs[ImagesArray.s3hitCount],wkX,wkY,null);	
			}
		}
		if(up && right && kick) {
			if(normal) {
				g.drawImage(ImagesArray.kickimgs[ImagesArray.kickCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1kickimgs[ImagesArray.s1kickCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2kickimgs[ImagesArray.s2kickCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3kickimgs[ImagesArray.s3kickCount],wkX,wkY,null);	
			}
		}
		if(up && right && kick) {
			if(normal) {
				g.drawImage(ImagesArray.kickimgs[ImagesArray.kickCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1kickimgs[ImagesArray.s1kickCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2kickimgs[ImagesArray.s2kickCount],wkX,wkY,null);
			}else if(super3) {
				g.drawImage(ImagesArray.s3kickimgs[ImagesArray.s3kickCount],wkX,wkY,null);	
			}
		}
		if(up && hit) {
			if(normal) {
				g.drawImage(ImagesArray.hitimgs[ImagesArray.hitCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1hitimgs[ImagesArray.s1hitCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2hitimgs[ImagesArray.s2hitCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3hitimgs[ImagesArray.s3hitCount],wkX,wkY,null);	
			}
		}
		if(up && kick) {
			if(normal) {
				g.drawImage(ImagesArray.kickimgs[ImagesArray.kickCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1kickimgs[ImagesArray.s1kickCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2kickimgs[ImagesArray.s2kickCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3kickimgs[ImagesArray.s3kickCount],wkX,wkY,null);	
			}
		}
		if(down && up==false && left==false && right==false && hit==false && kick==false) {
			if(normal) {
				Images.updownImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1updownImg.paintIcon(null, g, wkX, wkY);	
			}else if(super2) {
				Images.s2updownImg.paintIcon(null, g, wkX, wkY);	
			}else if(super3) {
				Images.s3updownImg.paintIcon(null, g, wkX, wkY);	
			}
		}
		if(down && left && hit==false && kick==false) {
			if(normal) {
				Images.leftmoveImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1leftmoveImg.paintIcon(null, g, wkX, wkY);	
			}else if(super2) {
				Images.s2leftmoveImg.paintIcon(null, g, wkX, wkY);	
			}else if(super3) {
				Images.s3leftmoveImg.paintIcon(null, g, wkX, wkY);		
			}
		}
		if(down && right && hit==false && kick==false) {
			if(normal) {
				Images.rightmoveImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1rightmoveImg.paintIcon(null, g, wkX, wkY);	
			}else if(super2) {
				Images.s2rightmoveImg.paintIcon(null, g, wkX, wkY);	
			}else if(super3) {
				Images.s3rightmoveImg.paintIcon(null, g, wkX, wkY);		
			}
		}
		if(down && left && hit) {
			if(normal) {
				g.drawImage(ImagesArray.hitimgs[ImagesArray.hitCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1hitimgs[ImagesArray.s1hitCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2hitimgs[ImagesArray.s2hitCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3hitimgs[ImagesArray.s3hitCount],wkX,wkY,null);		
			}
		}
		if(down && right && hit) {
			if(normal) {
				g.drawImage(ImagesArray.hitimgs[ImagesArray.hitCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1hitimgs[ImagesArray.s1hitCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2hitimgs[ImagesArray.s2hitCount],wkX,wkY,null);
			}else if(super3) {
				g.drawImage(ImagesArray.s3hitimgs[ImagesArray.s3hitCount],wkX,wkY,null);		
			}
		}
		if(down && left && kick) {
			if(normal) {
				g.drawImage(ImagesArray.kickimgs[ImagesArray.kickCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1kickimgs[ImagesArray.s1kickCount],wkX,wkY,null);		
			}else if(super2) {
				g.drawImage(ImagesArray.s2kickimgs[ImagesArray.s2kickCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3kickimgs[ImagesArray.s3kickCount],wkX,wkY,null);		
			}
		}
		if(down && right && kick) {
			if(normal) {
				g.drawImage(ImagesArray.kickimgs[ImagesArray.kickCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1kickimgs[ImagesArray.s1kickCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2kickimgs[ImagesArray.s2kickCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3kickimgs[ImagesArray.s3kickCount],wkX,wkY,null);	
			}
		}
		if(down && hit) {
			if(normal) {
				g.drawImage(ImagesArray.hitimgs[ImagesArray.hitCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1hitimgs[ImagesArray.s1hitCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2hitimgs[ImagesArray.s2hitCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3hitimgs[ImagesArray.s3hitCount],wkX,wkY,null);		
			}
		}
		if(down && kick) {
			if(normal) {
				g.drawImage(ImagesArray.kickimgs[ImagesArray.kickCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1kickimgs[ImagesArray.s1kickCount],wkX,wkY,null);		
			}else if(super2) {
				g.drawImage(ImagesArray.s2kickimgs[ImagesArray.s2kickCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3kickimgs[ImagesArray.s3kickCount],wkX,wkY,null);	
			}
		}
		if(left && up==false && down==false && right==false && hit==false && kick==false) {
			if(normal) {
				Images.leftmoveImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1leftmoveImg.paintIcon(null, g, wkX, wkY);	
			}else if(super2) {
				Images.s2leftmoveImg.paintIcon(null, g, wkX, wkY);	
			}else if(super3) {
				Images.s3leftmoveImg.paintIcon(null, g, wkX, wkY);		
			}
		}
		if(left && hit) {
			if(normal) {
				g.drawImage(ImagesArray.hitimgs[ImagesArray.hitCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1hitimgs[ImagesArray.s1hitCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2hitimgs[ImagesArray.s2hitCount],wkX,wkY,null);
			}else if(super3) {
				g.drawImage(ImagesArray.s3hitimgs[ImagesArray.s3hitCount],wkX,wkY,null);	
			}
		}
		if(left && kick) {
			if(normal) {
				g.drawImage(ImagesArray.kickimgs[ImagesArray.kickCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1kickimgs[ImagesArray.s1kickCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2kickimgs[ImagesArray.s2kickCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3kickimgs[ImagesArray.s3kickCount],wkX,wkY,null);
			}
		}
		if(right && up==false && down==false && left==false && hit==false && kick==false) {
			if(normal) {
				Images.rightmoveImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1rightmoveImg.paintIcon(null, g, wkX, wkY);	
			}else if(super2) {
				Images.s2rightmoveImg.paintIcon(null, g, wkX, wkY);
			}else if(super3) {
				Images.s3rightmoveImg.paintIcon(null, g, wkX, wkY);	
			}
		}
		if(right && hit) {
			if(normal) {
				g.drawImage(ImagesArray.hitimgs[ImagesArray.hitCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1hitimgs[ImagesArray.s1hitCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2hitimgs[ImagesArray.s2hitCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3hitimgs[ImagesArray.s3hitCount],wkX,wkY,null);	
			}
		}
		if(right && kick) {
			if(normal) {
				g.drawImage(ImagesArray.kickimgs[ImagesArray.kickCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1kickimgs[ImagesArray.s1kickCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2kickimgs[ImagesArray.s2kickCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3kickimgs[ImagesArray.s3kickCount],wkX,wkY,null);	
			}
		}
		if(hit && up==false && down ==false && left==false && right==false) {
			if(normal) {
				g.drawImage(ImagesArray.hitimgs[ImagesArray.hitCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1hitimgs[ImagesArray.s1hitCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2hitimgs[ImagesArray.s2hitCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3hitimgs[ImagesArray.s3hitCount],wkX,wkY,null);		
			}
		}
		if(kick && up==false && down ==false && left==false && right==false) {
			if(normal) {
				g.drawImage(ImagesArray.kickimgs[ImagesArray.kickCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1kickimgs[ImagesArray.s1kickCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2kickimgs[ImagesArray.s2kickCount],wkX,wkY,null);
			}else if(super3) {
				g.drawImage(ImagesArray.s3kickimgs[ImagesArray.s3kickCount],wkX,wkY,null);		
			}
		}

3.再将Charact类的paintSelf方法添加到GamPanel类中的paint方法中(此时人物只能画出,并能接收键盘发出的指令但是并不会按照键盘的指令来画图片)

//画人物
			if(character.death==false) {
				character.paintSelf(g);
			}
			if(character.death) {
				Images.deathImg.paintIcon(this, g, character.wkX, character.wkY);
				character.isIdle = false;
				character.up = false;
				character.down = false;
				character.left = false;
				character.right = false;
				character.hit = false;
				character.kick = false;
				character.guard = false;
				character.hurt = false;
				character.shoot = false;
				character.gpqg = false;
				character.yuanqidan = false;
				character.normaloverload = false;
				character.super12overload = false;
				character.super3overload = false;
				gameState=3;
			}

4.再在ganpanel类中的事件监听中添加移动,与范围判定(这时便能根据键盘进行移动)

//角色移动监听
                    if(0<=character.wkX && character.wkX<=950 && character.wkY>=0 && character.wkY<=420) {
					if(character.left) {
						character.wkX-=3;
					}
					if(character.right) {
						character.wkX+=3;
					}
					if(character.up) {
						character.wkY-=3;
					}
					if(character.down) {
						character.wkY+=3;
					}
					repaint();//重绘
				}
				//角色移动边界
				if(character.wkX<=0) {
					character.wkX=0;
				}
				if(character.wkX>=950) {
					character.wkX=950;
				}
				if(character.wkY<=0) {
					character.wkY=0;
				}
				if(character.wkY>=420) {
					character.wkY=420;
				}

至此,角色就实现了上下左右移动,与三种形态

角色的出拳与踢腿,shoot,gpqg,yuanqidan(这些都是一组图片的播放,用线程控制)

步骤:(与移动相似)

1.在Character类中添加攻击方法(依然通过键盘监听,不同的是,这次只是通过摁下监听,不在有松开监听,只有shoot方法依旧有松开监听)

//添加到键盘监听中
            case KeyEvent.VK_J:
				hit=true;
				hitcool=true;
				isIdle = false;
				kick = false;
				break;
			case KeyEvent.VK_K:
				kick = true;
				kickcool = true;
				isIdle = false;
				hit=false;
				break;
			case KeyEvent.VK_V:
				guard = true;
				isIdle = false;
				up = false;
				down = false;
				left = false;
				right = false;
				hit=false;
				kick =false;
				shoot = false; 
				break;
            case KeyEvent.VK_Y:
				shoot = true;
				this.shootBullet();
				isIdle = false;
				up = false;
				down = false;
				left = false;
				right = false;
				hit = false;
				kick = false;
				guard = false; 
				break;
			case KeyEvent.VK_U:
				if(mp>=10) {
					gpqg = true;
					gpqgcool = true;
					Music.startplay();
					isIdle = false;
					up = false;
					down = false;
					left = false;
					right = false;
					hit = false;
					kick = false;
					guard = false; 
					shoot = false;
					break;
				}
			case KeyEvent.VK_I:
				if(mp>=10) {
					yuanqidan = true;
					isIdle = false;
					up = false;
					down = false;
					left = false;
					right = false;
					hit = false;
					kick = false;
					guard = false; 
					shoot = false;
					gpqg = false;
					break;
				}
//松开监听
            case KeyEvent.VK_Y:
				shoot = false;
				isIdle = true;
                break;

2. 添加到Character类中的绘制方法中(伴随了两个简单判定guard、hurt,写在这里下文不在赘述,二者就是简单的判定然后画图,不涉及到用线程播放)

if(guard) {
			if(normal) {
				Images.guardImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1guardImg.paintIcon(null, g, wkX, wkY);		
			}else if(super2) {
				Images.s2guardImg.paintIcon(null, g, wkX, wkY);	
			}else if(super3) {
				Images.s3guardImg.paintIcon(null, g, wkX, wkY);		
			}
		}
		if(hurt) {
			if(normal) {
				Images.hurtImg.paintIcon(null, g, wkX, wkY);
			}else if(super1) {
				Images.s1hurtImg.paintIcon(null, g, wkX, wkY);		
			}else if(super2) {
				Images.s2hurtImg.paintIcon(null, g, wkX, wkY);	
			}else if(super3) {
				Images.s3hurtImg.paintIcon(null, g, wkX, wkY);		
			}
		}
		if(shoot) {
			if(normal) {
				g.drawImage(ImagesArray.shootimgs[ImagesArray.shootCount],wkX,wkY,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1shootimgs[ImagesArray.s1shootCount],wkX,wkY,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2shootimgs[ImagesArray.s2shootCount],wkX,wkY,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3shootimgs[ImagesArray.s3shootCount],wkX,wkY,null);	
			}
		}
		if(gpqg) {
			if(normal) {
				g.drawImage(ImagesArray.gpqgimgs[ImagesArray.gpqgCount],wkX,wkY-10,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1gpqgimgs[ImagesArray.s1gpqgCount],wkX,wkY-10,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2gpqgimgs[ImagesArray.s2gpqgCount],wkX,wkY-10,null);
			}else if(super3) {
				g.drawImage(ImagesArray.s3gpqgimgs[ImagesArray.s3gpqgCount],wkX,wkY-10,null);	
			}
		}
		if(yuanqidan) {
			if(normal) {
				g.drawImage(ImagesArray.yuanqidanimgs[ImagesArray.yuanqidanCount],wkX-21,wkY-69,null);
			}else if(super1) {
				g.drawImage(ImagesArray.s1yuanqidanimgs[ImagesArray.s1yuanqidanCount],wkX-21,wkY-69,null);	
			}else if(super2) {
				g.drawImage(ImagesArray.s2yuanqidanimgs[ImagesArray.s2yuanqidanCount],wkX-21,wkY-69,null);	
			}else if(super3) {
				g.drawImage(ImagesArray.s3yuanqidanimgs[ImagesArray.s3yuanqidanCount],wkX-21,wkY-69,null);	
			}
		}

 至此,角色就实现了三种形态下的攻击,踢腿,shoot,gpqg,元气弹,防御,受伤的动作

小怪类 

先创建怪物类的父类

import java.awt.*;

public abstract class Monster {
	//绘制自身方法
	public abstract void paintSelf(Graphics g);
	//返回自身矩形方法
	public abstract Rectangle getRec();
}

为实现小怪与boss的随机移动创建一个方向的枚举类

public enum Direction {
	RIGHT,LEFT,UP,DOWN
}

创建小怪类,小怪就有随机移动与随机攻击的功能,比较简单,先写出随机移动:

import java.awt.*;
import java.util.Random;

public class XiaoGuai extends Monster{
	//小怪朝一个方向运动的时间
	int moveTime=0;
	//定义小怪尺寸
	int width = 44;
	int height = 45;
	//定义小怪坐标
	int xgX;
	int xgY;
	//定义小怪血量
	int xghp=50;
	//小怪移动速度
	int speed=1;
	//小怪的方向
	private Direction direction =Direction.UP;
	
	//无参构造
	public XiaoGuai() {
		
	}
	//全参构造
	public XiaoGuai(int xgX, int xgY) {
		super();
		this.xgX = xgX;
		this.xgY = xgY;
	}
	
	//小怪移动方向
	public void leftWard() {
		xgX-=speed;
		direction=Direction.LEFT;
	}
	public void rightWard() {
		xgX+=speed;
		direction=Direction.RIGHT;
	}
	public void upWard() {
		xgY-=speed;
		direction=Direction.UP;
	}
	public void downWard() {
		xgY+=speed;
		direction=Direction.DOWN;
	}
	
	//小怪移动
	public void go() {
		//小怪移动边界
		if(xgX<=100) {
			xgX=100;
		}
		if(xgX>=950) {
			xgX=950;
		}
		if(xgY<=0) {
			xgY=0;
		}
		if(xgY>=420) {
			xgY=420;
		}
		if(moveTime>=50) {
			direction=randomDirection();
		    moveTime=0;
		}else{
		    moveTime+=1;
		}
		switch(direction) {
			case UP:
		      upWard();
		      break;
		    case DOWN:
		      downWard();
		      break;
		    case RIGHT:
		      rightWard();
		      break;
		    case LEFT:
		      leftWard();
		      break;
		}
	}
	
	//随机改变方向
	public Direction randomDirection() {
		Random r=new Random();
		int rnum=r.nextInt(4);
		switch(rnum) {
		case 0:
            return Direction.UP;
        case 1:
            return Direction.RIGHT;
        case 2:
            return Direction.LEFT;
        default:
            return Direction.DOWN;
        }
	}
	
	
	//绘制小怪
	@Override
	public void paintSelf(Graphics g) {
		// TODO Auto-generated method stub
		Images.xiaoguaiImg.paintIcon(null, g, xgX, xgY);
		go();
		g.setColor(new Color(220,20,60));
		g.fillRect(xgX,xgY-10,50,10);
		if(xghp<50) {
			g.setColor(new Color(255,255,255));
			g.fillRect(xgX+50-(50-xghp),xgY-10,(50-xghp),10);
		}
		g.setColor(new Color(0,0,0));
		g.setFont(new Font("Times New Roman",Font.ITALIC,10));
		g.drawString(""+xghp+"/50",xgX,xgY);
	}
	
	//获得小怪矩形
	@Override
	public Rectangle getRec() {
		// TODO Auto-generated method stub
		return new Rectangle(xgX, xgY, width, height);
	}
}

要写出小怪的随机攻击,先创建子弹类

import java.awt.*;
import java.util.ArrayList;

public class Bullet{
	//定义子弹尺寸
	int width = 42;
	int height = 15;
	//定义子弹坐标
	int bulletX;
	int bulletY;
	
	//无参构造
	public Bullet() {
		
	}
	//全参构造
	public Bullet(int bulletX, int bulletY) {
		super();
		this.bulletX = bulletX;
		this.bulletY = bulletY;
	}
	
	
	
	//画子弹
	public void paintSelf(Graphics g) {
		
	}
	
	//获得子弹矩形
	public Rectangle getRec() {
		return new Rectangle(bulletX, bulletY, width, height);
	}
}

让小怪的子弹继承子弹类

import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;

public class EnemyBullet extends Bullet{
	//定义敌方子弹的尺寸
	int width = 20;
	int height = 20;
	//定义敌方子弹的坐标
	int eBulletX;
	int eBulletY;
	
	//无参构造
	public EnemyBullet() {
		
	}
	//全参构造
	public EnemyBullet(int eBulletX, int eBulletY) {
		super();
		this.eBulletX = eBulletX;
		this.eBulletY = eBulletY;
	}
	
	//敌方子弹向左发射方法
	public void leftWard() {
		eBulletX-=3;
	}
	
	//子弹越界删除子弹
	public void moveToBoarder() {
		if(eBulletX<=0 || eBulletX>=1000) {
			GamePanel.removeList1.add(this);
		}
	}
	
	//画敌方子弹
	@Override
	public void paintSelf(Graphics g) {
		// TODO Auto-generated method stub
		this.leftWard();
		Images.enemybulletImg.paintIcon(null, g, eBulletX, eBulletY);
		this.moveToBoarder();
	}
	
	//获得敌方子弹矩形
	@Override
	public Rectangle getRec() {
		// TODO Auto-generated method stub
		return new Rectangle(eBulletX, eBulletY, width, height);
	}

 最后实现小怪随机射击的方法

//小怪随机攻击
	public void attack() {
		Point p = getHeadPoint();
		Random random = new Random();
		int rnum = random.nextInt(100);
		enemybullet.eBulletX=p.x;
		enemybullet.eBulletY=p.y;
		if(rnum < 1) {
			GamePanel.ebList.add(new EnemyBullet(p.x,p.y));
		}
	}

将attack方法添加到小怪的移动方法中 

//小怪移动
	public void go() {
		//小怪移动边界
		if(xgX<=100) {
			xgX=100;
		}
		if(xgX>=950) {
			xgX=950;
		}
		if(xgY<=0) {
			xgY=0;
		}
		if(xgY>=420) {
			xgY=420;
		}
		attack();//将attack方法添加到go()方法中
		if(moveTime>=50) {
			direction=randomDirection();
		    moveTime=0;
		}else{
		    moveTime+=1;
		}
		switch(direction) {
			case UP:
		      upWard();
		      break;
		    case DOWN:
		      downWard();
		      break;
		    case RIGHT:
		      rightWard();
		      break;
		    case LEFT:
		      leftWard();
		      break;
		}
	}

至此小怪会随机射击与随机移动 

为实现批量添加小怪,并让小怪能一直发射子弹,需要通过集合实现

在GamePanel类中创建集合并绘制,这里集合的内容一并写出,下文不在赘述

//写在成员变量中
//创建各类集合
	public static ArrayList bulletList =new ArrayList();
	public static ArrayList removeList =new ArrayList();
	public static ArrayList ebList =new ArrayList();
	public static ArrayList removeList1 =new ArrayList();
	public static ArrayList yqdList =new ArrayList();
	public static ArrayList removeList2 =new ArrayList();
	public static ArrayList lanlongbulletList =new ArrayList();
	public static ArrayList  removeList3 = new ArrayList();
	public static ArrayList xgList =new ArrayList();
	public static ArrayList characterList =new ArrayList();
	public static ArrayList lanlongList =new ArrayList();
-----------------------------------------------------------------------------------
写在paint方法中
//画集合内容
			for(Bullet bullet : bulletList) {
				bullet.paintSelf(g);
			}
			bulletList.removeAll(removeList);
			for(EnemyBullet enemybullet : ebList) {
				enemybullet.paintSelf(g);
			}
			ebList.removeAll(removeList1);
			for(LanLongBullet lanlongbullet : lanlongbulletList) {
				lanlongbullet.paintSelf(g);
			}
			lanlongbulletList.removeAll(removeList3);
			for(YuanQiDan yuanQiDan : yqdList) {
				yuanQiDan.paintSelf(g);
			}
			yqdList.removeAll(removeList2);
			for(XiaoGuai xiaoguai : xgList) {
				xiaoguai.paintSelf(g);
			}

因为小怪的批量添加是受时间与数量的限制的,因此,要在GamePanel类中写出一个方法来控制数量,用线程来控制添加的时间间隔

//批量添加敌人数目(成员变量)
	int enemyCount=0;
//批量添加小怪(成员方法)
	public void addXiaoGuai() {
		while(true) {
			if(xgList.size()==0 && enemyCount==5) {
				lanlong.s=true;
				System.out.println(lanlong.s);
				return;
			}
			if(gameState==1) {
				if(enemyCount<5) {
					Random r=new Random();
					int rnum=r.nextInt(800);
					xgList.add(new XiaoGuai(rnum,200));
					enemyCount++;
					try {
						Thread.sleep(2*1000);
					}catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			try {
				repaint();
				Thread.sleep(1*1000);
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
//线程,写在构造方法中
//批量添加小怪线程
		new Thread() {
			public void run() {
				addXiaoGuai();
			}
		}.start();

boss类

关于boss的一切都会在小怪全部消失后才会出现,都用boolean变量s控制

boss类与小怪类同理有随机移动与射击,比起小怪boss多了两个技能攻击,现在boss类中画出,在添加到GamePanel类中

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Random;

public class LanLong extends Monster {
	//蓝龙朝一个方向运动的时间
	int moveTime=0;
	//定义蓝龙尺寸
	int width = 208;
	int height = 236;
	//定义蓝龙坐标
	int lanlongX;
	int lanlongY;
	//定义蓝龙血量
	int lanlonghp=200;
	//蓝龙移动速度
	int speed=1;
	//蓝龙的方向
	private Direction direction =Direction.UP;
	//定义蓝龙是否用翅膀攻击
	boolean windhit;
	//定义蓝龙是否用爪子攻击
	boolean clawhit;
	//定义蓝龙是否发射子弹
	boolean shoot;
	//判断蓝龙是否出现
	boolean s;
	
	//无参构造
	public LanLong() {
		
	}
	//带参构造
	public LanLong(int lanlongX, int lanlongY) {
		super();
		this.lanlongX = lanlongX;
		this.lanlongY = lanlongY;
	}
	
	//蓝龙的移动方向
	public void leftWard() {
		lanlongX-=speed;
		direction=Direction.LEFT;
	}
	public void rightWard() {
		lanlongX+=speed;
		direction=Direction.RIGHT;
	}
	public void upWard() {
		lanlongY-=speed;
		direction=Direction.UP;
	}
	public void downWard() {
		lanlongY+=speed;
		direction=Direction.DOWN;
	}
	//蓝龙的移动
	public void go() {
		//蓝龙移动边界
		if(lanlongX<=500) {
			lanlongX=500;
		}
		if(lanlongX>=762) {
			lanlongX=762;
		}
		if(lanlongY<=0) {
			lanlongY=0;
		}
		if(lanlongY>=244) {
			lanlongY=244;
		}
		attack();
		if(moveTime>=50) {
			direction=randomDirection();
		    moveTime=0;
		}else{
		    moveTime+=1;
		}
		switch(direction) {
			case UP:
		      upWard();
		      break;
		    case DOWN:
		      downWard();
		      break;
		    case RIGHT:
		      rightWard();
		      break;
		    case LEFT:
		      leftWard();
		      break;
		}
	}
	//随机改变方向
	public Direction randomDirection() {
		Random r=new Random();
		int rnum=r.nextInt(4);
		switch(rnum) {
		case 0:
            return Direction.UP;
        case 1:
            return Direction.RIGHT;
        case 2:
            return Direction.LEFT;
        default:
            return Direction.DOWN;
        }
	}
	//获取子弹坐标
	public Point getHeadPoint() {
		return new Point(lanlongX,lanlongY);
	}
	//蓝龙随机攻击
	public void attack() {
		LanLongBullet lanlongbullet = new LanLongBullet();
		Point p = getHeadPoint();
		Random random = new Random();
		int rnum = random.nextInt(100);
		lanlongbullet.lanlongBulletX=p.x;
		lanlongbullet.lanlongBulletY=p.y;
		if(rnum < 1) {
			GamePanel.lanlongbulletList.add(new LanLongBullet(p.x,p.y));
		}
	}
	
	@Override
	public void paintSelf(Graphics g) {
		// TODO Auto-generated method stub
		this.go();
		//画怪物血量
		Images.lanlongtouxiangImg.paintIcon(null, g, 946, 0);
		g.setColor(new Color(220,20,60));
		g.fillRect(746,0,200,20);
		if(lanlonghp<200) {
			g.setColor(new Color(255,255,255));
			g.fillRect(946-(200-lanlonghp),0,(200-lanlonghp),20);
		}
		g.setColor(new Color(0,0,0));
		g.setFont(new Font("Times New Roman",Font.ITALIC,15));
		g.drawString(""+lanlonghp+"/200",800,15);
		//画怪物
		Images.monster1Img.paintIcon(null, g, lanlongX, lanlongY);
		//画龙的攻击
		if(windhit) {
			Images.windhitImg.paintIcon(null, g, lanlongX-100, lanlongY);
		}
		if(clawhit) {
			Images.clawhitImg.paintIcon(null, g, lanlongX-450, lanlongY-50);
		}
	}
	
	@Override
	public Rectangle getRec() {
		// TODO Auto-generated method stub
		return new Rectangle(lanlongX, lanlongY, width, height);
	}
}

将LanLong类的paintSelf方法添加到GamePanel类中

//画蓝龙
			if(lanlong.s) {
				lanlong.paintSelf(g);
			}

在GamePanel类中添加控制蓝龙攻击的线程

//蓝龙用爪子攻击线程
		new Thread() {
			public void run() {
				while(true) {
					lanlong.clawhit=!lanlong.clawhit;
					if(lanlong.clawhit) {
						if(0<(character.wkY-lanlong.lanlongY) && (character.wkY-lanlong.lanlongY)<250 && 0<(lanlong.lanlongX-character.wkX) && (lanlong.lanlongX-character.wkX)<420) {
							if(lanlong.s) {
								character.hurt=true;
								character.hp-=10;
							}
						}
						try {
							Thread.sleep(1*1000);
							character.isIdle=true;
						} catch(InterruptedException e) {
							e.printStackTrace();
						}
					}else if(lanlong.clawhit==false) {
						character.hurt=false;
						try {
							Thread.sleep(5*1000);
						} catch(InterruptedException e) {
								e.printStackTrace();
							}
						}
					}
				
				}
		}.start();
		
		//蓝龙用翅膀攻击线程
		new Thread() {
			public void run() {
				while(true) {
					lanlong.windhit=!lanlong.windhit;
					if(lanlong.windhit) {
						if(lanlong.s) {
							character.hurt=true;
						}
						try {
							Thread.sleep(1*1000);
							if(lanlong.s) {
								character.isIdle=true;
								character.hp-=10;
							}
						} catch(InterruptedException e) {
							e.printStackTrace();
						}
					}else if(lanlong.windhit==false) {
						character.hurt=false;
						try {
							Thread.sleep(10*1000);
						} catch(InterruptedException e) {
								e.printStackTrace();
							}
						}
					}
				}
		}.start();

至此蓝龙的技能攻击添加完成,蓝龙每隔十秒使用一次翅膀攻击,每隔五秒使用一次爪子攻击

同小怪类一样,boss攻击也会向左发射子弹

同理创建蓝龙的子弹类

import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;

public class LanLongBullet extends Bullet{
	//定义蓝龙子弹的尺寸
	int width = 164;
	int height = 124;
	//定义蓝龙子弹的坐标
	int lanlongBulletX;
	int lanlongBulletY;
	
	//无参构造
	public LanLongBullet() {
		
	}
	//全参构造
	public LanLongBullet(int lanlongBulletX, int lanlongBulletY) {
		super();
		this.lanlongBulletX = lanlongBulletX;
		this.lanlongBulletY = lanlongBulletY;
	}
	
	//蓝龙子弹向左发射方法
	public void leftWard() {
		lanlongBulletX-=3;
	}
	
	//蓝龙子弹与人物的碰撞检测
	public void hitCharacter() {
		ArrayList characters = GamePanel.characterList;
		for(Character character: characters) {
			if(this.getRec().intersects(character.getRec())) {
				character.hp-=5;
				GamePanel.removeList3.add(this);
				break;
			}
		}
	}
	
	//子弹越界删除子弹
	public void moveToBoarder() {
		if(lanlongBulletX<=0 || lanlongBulletX>=1000) {
			GamePanel.removeList3.add(this);
		}
	}
	
	@Override
	public void paintSelf(Graphics g) {
		// TODO Auto-generated method stub
		this.leftWard();
		Images.shootImg.paintIcon(null, g, lanlongBulletX-35, lanlongBulletY+17);
		this.moveToBoarder();
		this.hitCharacter();
	}
	
	@Override
	public Rectangle getRec() {
		// TODO Auto-generated method stub
		return new Rectangle(lanlongBulletX, lanlongBulletY, width, height);
	}
	
}

蓝龙子弹也在集合元素内 

角色的攻击与攻击冷却

在子弹类中添加碰撞检测方法

import java.awt.*;
import java.util.ArrayList;

public class Bullet{
	//定义子弹尺寸
	int width = 42;
	int height = 15;
	//定义子弹坐标
	int bulletX;
	int bulletY;
	
	//无参构造
	public Bullet() {
		
	}
	//全参构造
	public Bullet(int bulletX, int bulletY) {
		super();
		this.bulletX = bulletX;
		this.bulletY = bulletY;
	}
	
	//子弹与小怪的碰撞检测
	public void hitXiaoGuai() {
		ArrayList xiaoguais = GamePanel.xgList;
		for(XiaoGuai xg: xiaoguais) {
			if(this.getRec().intersects(xg.getRec())) {
				xg.xghp-=5;
				if(xg.xghp<=0) {
					GamePanel.xgList.remove(xg);
					GamePanel.removeList.add(this);
					break;
				}
				GamePanel.removeList.add(this);
			}
		}
	}
	
	//子弹与蓝龙的碰撞检测
	public void hitLanLong() {
		ArrayList lanlongs = GamePanel.lanlongList;
		for(LanLong lanlong: lanlongs) {
			if(this.getRec().intersects(lanlong.getRec())) {
				if(lanlong.s) {
					lanlong.lanlonghp-=5;
					GamePanel.removeList.add(this);
					break;
				}
			}
		}
	}
	
	//子弹向右发射方法
	public void rightWard() {
		bulletX+=7;
	}
	
	//子弹越界消失
	public void moveToBoarder() {
		if(bulletX<=0 || bulletX>=1000) {
			GamePanel.removeList.add(this);
		}
	}
	
	//画子弹
	public void paintSelf(Graphics g) {
		this.rightWard();
		Images.qibo1Img.paintIcon(null, g, bulletX, bulletY);
		//Images.qibo2Img.paintIcon(null, g, bulletX, bulletY);
		this.hitXiaoGuai();
		this.hitLanLong();
		this.moveToBoarder();
	}
	
	//获得子弹矩形
	public Rectangle getRec() {
		return new Rectangle(bulletX, bulletY, width, height);
	}
}

添加角色的另一个子弹元气弹类

import java.awt.*;
import java.util.ArrayList;

public class YuanQiDan {
	//定义元气弹尺寸
	int width = 67;
	int height = 66;
	//元气弹坐标
	int yqdX;
	int yqdY;
	
	//无参构造
	public YuanQiDan() {
		
	}
	//全参构造
	public YuanQiDan(int yqdX, int yqdY) {
		super();
		this.yqdX = yqdX;
		this.yqdY = yqdY;
	}
	//元气弹与小怪的碰撞检测
		public void hitXiaoGuai() {
			ArrayList xiaoguais = GamePanel.xgList;
			for(XiaoGuai xg: xiaoguais) {
				if(this.getRec().intersects(xg.getRec())) {
					xg.xghp-=10;
					if(xg.xghp<=0) {
						GamePanel.xgList.remove(xg);
						GamePanel.removeList2.add(this);
						break;
					}
					GamePanel.removeList2.add(this);
				}
			}
		}
		//元气弹与蓝龙的碰撞检测
		public void hitLanLong() {
			ArrayList lanlongs = GamePanel.lanlongList;
			for(LanLong lanlong: lanlongs) {
				if(this.getRec().intersects(lanlong.getRec())) {
					if(lanlong.s) {
						lanlong.lanlonghp-=20;
						GamePanel.removeList2.add(this);
						break;
					}
				}
			}
		}
	//元气弹向右发射方法
	public void rightward() {
		yqdX+=7;
	}
	//画元气弹
	public void paintSelf(Graphics g) {
		this.rightward();
		Images.yuanqidanImg.paintIcon(null, g, yqdX, yqdY-10);
		this.hitXiaoGuai();
		this.hitLanLong();
	}
	public Rectangle getRec() {
		return new Rectangle(yqdX, yqdY, width, height);
	}
}

 角色的攻击冷却

//攻击冷却状态
private boolean shootCool = true;
private boolean yuanqidanCool = true;
//攻击冷却时间毫秒间隔
private int shootCoolTime = 200;
private int yuanqidanCoolTime = 1000;

//获得角色坐标
	public Point getHeadPoint() {
		return new Point(wkX,wkY);
	}
	//发射子弹方法
	public void shootBullet() {
		if(shootCool) {
			Point p = getHeadPoint();
			bullet.bulletX=p.x;
			bullet.bulletY=p.y;
			Bullet bullet = new Bullet(p.x+23,p.y+17);
			GamePanel.bulletList.add(bullet);
			//启动攻击冷却线程
			new AttackCD().start();
		}
	}
	//shootCD线程
	class AttackCD extends Thread {
		public void run() {
			//将攻击功能设置为冷却状态
			shootCool = false;
			//休眠
			try {
				Thread.sleep(shootCoolTime);
			}catch(Exception e) {
				e.printStackTrace();
			}
			//将攻击冷却解除
			shootCool = true;
			//线程终止
			this.stop();
		}
	}
	//发射元气弹方法
	public void yqd() {
		if(yuanqidanCool) {
			Point px = getHeadPoint();
			yuan.yqdX=px.x;
			yuan.yqdY=px.y;
			YuanQiDan yuanQiDan =new YuanQiDan(px.x+20,px.y-10);
			GamePanel.yqdList.add(yuanQiDan);
			new YuanQiDanCD().start();
		}
	}
	//元气弹CD线程
	class YuanQiDanCD extends Thread {
		public void run() {
			//将攻击功能设置为冷却状态
			yuanqidanCool = false;
			//休眠
			try {
				Thread.sleep(yuanqidanCoolTime);
			}catch(Exception e) {
				e.printStackTrace();
			}
			//将攻击冷却解除
			yuanqidanCool = true;
			//线程终止
			this.stop();
		}
	}
	//hit、kick攻击小怪
	public void hitXiaoGuai() {
		ArrayList xiaoguais = GamePanel.xgList;
		for(XiaoGuai xg: xiaoguais) {
			if(this.getRec().intersects(xg.getRec())) {
				if((hit && hitcool) || (kick && kickcool)) {
					xg.xghp-=2;
					hitcool=false;
					kickcool=false;
					break;
				}
			}
			if(xg.xghp<=0) {
				GamePanel.xgList.remove(xg);
				break;
			}
		}
	}
	//龟派气功攻击小怪
	public void gpqgXiaoGuai() {
		ArrayList xiaoguais = GamePanel.xgList;
		for(XiaoGuai xg: xiaoguais) {
			if(0 

 至此角色的shoot方法就添加上了子弹,与子弹和小怪,boss的检测,并且攻击是有间隔的

音乐类

最后添加音乐类,三个音乐:背景音乐,gpqg,爆气,分别添加在GamePanel的鼠标监听、Character类的键盘监听中

import java.io.File;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;


public class Music{
	private static Clip clip;
	private static Clip clip1;
	private static Clip clip2;
	static {
        File bgMusicFile = new File("E:\esclipse\DragonWorldProject\bin\music\BGM.wav");
        File gpqgMusicFile = new File("E:\esclipse\DragonWorldProject\bin\music\gpqg.wav");
        File baoqiMusicFile = new File("E:\esclipse\DragonWorldProject\bin\music\baoqi.wav");
        try {
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(bgMusicFile);
            clip = AudioSystem.getClip();
            clip.open(audioInputStream);
            AudioInputStream gpqgInputStream = AudioSystem.getAudioInputStream(gpqgMusicFile);
            clip1 = AudioSystem.getClip();
            clip1.open(gpqgInputStream);
            AudioInputStream baoqiInputStream = AudioSystem.getAudioInputStream(baoqiMusicFile);
            clip2 = AudioSystem.getClip();
            clip2.open(baoqiInputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
	}
	public static void playBackground(){
        //循环播放
        clip.setFramePosition(0);
        clip.loop(Clip.LOOP_CONTINUOUSLY);
        
    }
	public static void startplay(){
		clip1.start();
		clip1.setFramePosition(0);
	}
	public static void baoqi(){
		clip2.start();
		clip2.setFramePosition(0);
	}
}
------------------
//鼠标点击监听
			@Override
			public void mouseClicked(MouseEvent e) {
				if(390<=mouseX && mouseX<=553 && 350=10) {
					gpqg = true;
					gpqgcool = true;
					Music.startplay();//龟派气功
					isIdle = false;
					up = false;
					down = false;
					left = false;
					right = false;
					hit = false;
					kick = false;
					guard = false; 
					shoot = false;
					break;
				}
-----------------
            case KeyEvent.VK_0:
				normal=true;
				super1=false;
				super2=false;
				super3=false;
				break;
			case KeyEvent.VK_1:
				normaloverload=true;
				Music.baoqi();//爆气
				super12overload=false;
				super3overload=false;
				break;
			case KeyEvent.VK_2:
				normaloverload=false;
				super12overload=true;
				Music.baoqi();//爆气
				super3overload=false;
				break;
			case KeyEvent.VK_3:
				normaloverload=false;
				super12overload=false;
				super3overload=true;
				Music.baoqi();//爆气
				break;

最终效果展示:

java小游戏

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/888498.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号