这个很简单的小游戏终于要被我说完了。在上一篇中,已经实现了多条鱼在“海”里自由自在的游玩了,现在,该玩家出手了·,要能控制网的大小,并且,当鼠标点到游动的鱼图片的时候,鱼能“感受”到,这就涉及到事件的监听。关于Java中事件机制的参与者有3中角色:1、event object:事件状态对象,用于listener的相应的方法之中,作为参数,一般存在于listener的方法之中。2、event source:具体的事件源,比如说,你点击一个button,那么button就是even source,要想是button对某些事件进行响应,你就需要注册特定的listener。3、event listener:对每个明确的事件的发生,都相应的定义一个明确的java方法。这些方法都集中定义在时间监听者的接口中,这个接口要继承java.util.EventListener。实现事件监听者接口中一些或全部方法的类就是事件监听者。
在这里,控制鱼的血量Pool的类和渔网的Net类都继承自java.awt.event包,提供处理由 AWT 组件所激发的各类事件的接口和类。
关于Net.java类:
package my.control;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import my.ui.Fish;
public class Net {
BufferedImage netImage;
int net_x;
int net_y;
int width;
int height;
boolean show;
public Net() throws Exception{
File file=new File("images\\net_1.png");
netImage=ImageIO.read(file);
net_x=100;
net_y=100;
width=netImage.getWidth();
height=netImage.getHeight();
show=true;
}
//网跟随鼠标移动
public void moveTo(int x,int y){
this.net_x=x;
this.net_y=y;
}
//渔网捕鱼
public boolean catchThe(Fish fish,int power){
int dx=net_x-fish.fish_x;
int dy=net_y-fish.fish_y;
boolean catchOn=dx>=0 && dy>=0
&& dx<=fish.width && dy<=fish.height;
if(catchOn){
fish.blood -= power;
}
return fish.blood<=0;
}
//
public void change(int power) throws Exception{
//改变渔网尺寸
File file=new File("images\\net_"+power+".png");
netImage=ImageIO.read(file);
//改变渔网的位置坐标
//由于在drawImage渔网的时候,会自动根据鼠标的
// 位置调节图片的位置,所以不需要动态改变图片的坐标
//重置渔网的大小
width=netImage.getWidth();
height=netImage.getHeight();
}
}
关于Pool.java:
package my.control;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import my.ui.Fish;
public class Pool extends JPanel{
BufferedImage background;
//分数
int score=0;
//捕鱼个数
int count=0;
//子弹
int bullet=300;
//子弹能量大小
int power=1;
Fish[] fishes;
Net net;
int width;
int height;
public Pool() throws Exception{
fishes=new Fish[9*2+1+1];//18+2 == 20
// 0 1 2 3 4 5 6 7 8
for(int i=0;i<(fishes.length-2)/2;i++){
fishes[i]=new Fish(i+1);
fishes[i+9]=new Fish(i+1);
}
fishes[18]=new Fish(13);
fishes[19]=new Fish(14);
net=new Net();
initMouseEvent();
File imgFile=new File("images\\bg.jpg");
try {
background=ImageIO.read(imgFile);
width=background.getWidth();
height=background.getHeight();
} catch (IOException e) {
e.printStackTrace();
}
}
//初始化鼠标事件
public void initMouseEvent(){
this.setCursor(new Cursor(Cursor.HAND_CURSOR));
//创建处理鼠标事件的对象
MouseAdapter mouseListener=new MouseAdapter() {
//鼠标移动
public void mouseMoved(MouseEvent e) {
net.moveTo(e.getX(), e.getY());
}
//鼠标进入面板
public void mouseEntered(MouseEvent e) {
net.show=true;
}
//鼠标离开面板
public void mouseExited(MouseEvent e) {
net.show=false;
}
//点击鼠标
public void mousePressed(MouseEvent e) {
int n=e.getModifiers();
if(n==16){
catchTheFish();
}
if(n==4){
changePower();
}
}
};
this.addMouseListener(mouseListener);
this.addMouseMotionListener(mouseListener);
}
//
public void changePower() {
power ++;
if(power==8){
power=1;
}
//power改变时,渔网的图像改变
changeTheNet();
}
//power改变时,渔网的图像改变
public void changeTheNet(){
try {
net.change(power);
} catch (Exception e) {
e.printStackTrace();
}
}
//捕鱼动作
public synchronized void catchTheFish(){
if(bullet<=0){
//游戏结束
return;
}
bullet -= power;
if(bullet<0){
bullet=0;
}
for(int i=0;i<fishes.length;i++){
if(net.catchThe(fishes[i],power)){
if(!fishes[i].catched){
count++;
score += fishes[i].width/10;
bullet += fishes[i].width/10;
fishes[i].catched=true;
}
}
}
}
public void paint(Graphics g) {
//画背景图片
g.drawImage(background, 0, 0, null);
//画当前鱼的图像
for(int i=0;i<fishes.length;i++){
Fish fish=fishes[i];
g.drawImage(fish.animation_current, fish.fish_x, fish.fish_y, null);
}
//画渔网
if(net.show){
int net_x=net.net_x-net.width/2;
int net_y=net.net_y-net.height/2;
g.drawImage(net.netImage, net_x, net_y, null);
}
Font f=new Font("宋体",Font.ITALIC,28);
g.setColor(Color.YELLOW);
g.setFont(f);
g.drawString("个数:"+count, 20, 30);
g.drawString("分数:"+score, 150, 30);
g.drawString("子弹:"+bullet, 280, 30);
g.drawString("power:"+power, 650, 30);
Font f1=new Font("宋体",Font.ITALIC,18);
g.setColor(Color.RED);
g.setFont(f1);
g.drawString("(右键改变power值)", 610, 50);
if(bullet<=0){
Font f2=new Font("宋体",Font.ITALIC,120);
g.setColor(Color.YELLOW);
g.setFont(f2);
g.drawString("Game Over!", 120, 270);
}
}
//开始动画效果
public void action() throws Exception{
for(int i=0;i<fishes.length;i++){
fishes[i].start();
}
while(true){
repaint();
Thread.sleep(1000/24);
}
}
}