如何使变量出血与这两个事件一起工作

时间:2014-08-10 00:33:43

标签: java plugins minecraft bukkit

@EventHandler
public void onEntityDamageByEntityEvent(EntityDamageEvent event)
{

    if(Math.random()<=0.02)
    {
        Entity e = event.getEntity();

        int bleed = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin,      new Runnable()
        {
            public void run()
            {
                //Two percent chance you will bleed

                if(e instanceof Player)
                {
                    Player player = (Player) e;

                    player.damage(1.0D);
                    player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 200, 2));
                    player.sendMessage(ChatColor.RED + "You are bleeding, find a bandage and heal yourself");

                    public void onPlayerEvent(PlayerInteractEvent event) { //ERROR HAPPENS ON THIS LINE ON THE PARENTHESES

                        Player player = event.getPlayer();
                        Action act = event.getAction();

                        if(event.getAction() == act.RIGHT_CLICK_AIR) {
                            if(player.getItemInHand().getType() == Material.PAPER) {
                                plugin.getServer().getScheduler().cancelTask(bleed);
                            }
                        }
                    }
                }
            }
        }, 20, 400);
    }
}

我完全清楚我不允许在方法中使用方法,但我不知道有任何其他方法可以使其工作。

第7行的bleed变量应该与第22行的相同变量相对应

第二个事件应该取消第一个事件。

我得到的错误是:Syntax error on "(" , ; expected

编辑:

@AndrewG所以,我测试了你的代码,它没有正常工作,这是我所拥有的类的全部来源:`

package com.aidan.TeamHeal;


import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;



public class BukkitListener implements Listener  {

Map<UUID, Integer> bleed = new HashMap<UUID, Integer>();

public static Bukkit plugin;

public BukkitListener(Bukkit instance) {
    plugin = instance;
}



@EventHandler
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
    if(Math.random() <1) {
        Entity e = event.getEntity();
//          Entity z = event.getDamager();

        if(e instanceof Player) {
            Player player = (Player) e;

            player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 100, 1));   
        }
    }
}



 @EventHandler
    public void onEntityDamageByEntityEvent(EntityDamageEvent event) {

        if (Math.random() <= 1) {
            final Entity e = event.getEntity();

           int playersBleed = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {

                public void run() {
                    // Two percent chance you will bleed

                    if (e instanceof Player) {
                        Player player = (Player) e;

                        player.damage(1.0D);
                        player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 200, 2));
                        player.sendMessage(ChatColor.RED + "You are bleeding, find a bandage and heal yourself");

                    }
                }
            }, 20, 400);
            bleed.put(e.getUniqueId(), new Integer(playersBleed));
        }
    }

    // Don't forget the @EventHandler annotation here too!
    @EventHandler
    public void onPlayerEvent(PlayerInteractEvent event) {

        Player player = event.getPlayer();
        if (event.getAction() == Action.RIGHT_CLICK_AIR) {
            if (player.getItemInHand().getType() == Material.PAPER) {

                if(bleed.containsKey(player.getUniqueId())) {
                    Integer playersBleed = bleed.get(player.getUniqueId());
                    int playersBleedInt = playersBleed.intValue();
                    plugin.getServer().getScheduler().cancelTask(playersBleedInt);
                    player.sendMessage("YOu have been healed");



                }
            }
        }
    }
}

`

3 个答案:

答案 0 :(得分:1)

这是Bukkit吗?如果您完全清楚方法中没有方法,为什么还有方法?

您的问题是您没有使用方法之外的变量。例如:

public class Bleed extends JavaPlugin {

    // Put the variable here, so it can be accessed by all the methods in the class.

    int bleed = 0; // Declare it here, use it elsewhere. We'll just have 0 as the default value.


    @EventHandler
    public void onEntityDamageByEntityEvent(EntityDamageEvent event) {

        if (Math.random() <= 0.02) {
            Entity e = event.getEntity();

            // Don't declare it again, just assign a value to it.
            bleed = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {

                public void run() {
                    // Two percent chance you will bleed

                    if (e instanceof Player) {
                        Player player = (Player) e;

                        player.damage(1.0D);
                        player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 200, 2));
                        player.sendMessage(ChatColor.RED + "You are bleeding, find a bandage and heal yourself");

                    }
                }
            }, 20, 400);
        }
    }

    // Don't forget the @EventHandler annotation here too!
    @EventHandler
    public void onPlayerEvent(PlayerInteractEvent event) {

        Player player = event.getPlayer();
        Action act = event.getAction();

        if (event.getAction() == act.RIGHT_CLICK_AIR) {
            if (player.getItemInHand().getType() == Material.PAPER) {
                // Assuming that the onEntityDamageByEntityEvent is called before this, bleed will have the value set in that method.
                // Let's make sure that actually happened, and bleed isn't still 0.
                if(bleed != 0) {
                    plugin.getServer().getScheduler().cancelTask(bleed);
                }
            }
        }
    }
}

我所做的更改主要是在类的范围内声明一个出血变量。 (在这里停下来阅读关于Java中变量范围的所有内容,它非常重要。)现在我们有一个两个方法都可以访问的变量,我们采用另一个方法,并将它放在应该的位置。我做的最后一件事就是确保我们只调用cancelTask()如果一个任务实际已被设置(意味着bleed内部有一些东西)使用{{ 1}}陈述。

现在这引入了另一个问题,如果玩家A开始流血,那么玩家B在玩家A停止之前就开始出血了?现在玩家B的任务存储在if中,玩家A已经消失。我们需要的是为每个出血的玩家存储不同的bleed变量。为此,我们可以使用HashMap。改变这个:

bleed

到此:

int bleed = 0;

这会创建一个列表,因此我们可以在Integer对象旁边存储一个玩家的ID(因为我们不能在HashMap中使用原语,我们使用Integer对象)来表示它&#39;流血的任务。

然后,我们改变了这个:

Map<UUID, Integer> bleed = new HashMap<UUID, Integer>();

到此:

bleed = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {

                public void run() {
                    // Two percent chance you will bleed

                    if (e instanceof Player) {
                        Player player = (Player) e;

                        player.damage(1.0D);
                        player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 200, 2));
                        player.sendMessage(ChatColor.RED + "You are bleeding, find a bandage and heal yourself");

                    }
                }
            }, 20, 400);

这样做是从任务中获取int,将其放入新的Integer中,并将其放在玩家的ID旁边。然后我们改变这个:

int playersBleed = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {

                public void run() {
                    // Two percent chance you will bleed

                    if (e instanceof Player) {
                        Player player = (Player) e;

                        player.damage(1.0D);
                        player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 200, 2));
                        player.sendMessage(ChatColor.RED + "You are bleeding, find a bandage and heal yourself");

                    }
                }
            }, 20, 400);
bleed.put(player.getUniqueId(), new Integer(playersBleed));

为:

if(bleed != 0) {
    plugin.getServer().getScheduler().cancelTask(bleed);
}

最后(呵呵),你需要改变这个:

if(bleed.containsKey(player.getUniqueId()) { // If that player is bleeding.
    Integer playersBleed = bleed.get(player.getUniqueId());
    int playersBleedInt = playersBleed.intValue();
    plugin.getServer().getScheduler().cancelTask(playersBleedInt);
}

到此:

Entity e = event.getEntity();

这只允许runnable中的代码获取final Entity e = event.getEntity(); 变量。

这一切都有意义吗?我知道我有点快......我很乐意在评论中再解释一下。 我希望有帮助,随时在评论中提出任何问题。

答案 1 :(得分:0)

你错过了一些花括号引起你的错误。

我基本上只是打开了你的一些方法,这个问题变得很明显。

你还有一个范围问题:

  

&#34;匿名类无法访问其封闭范围内未声明为final或者有效最终的局部变量。&#34; - http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

^你会看到我在buildBleedHandler(final Entity e)中有一个决赛,它允许我的新Runnable访问该实体e。

您还需要使用BukkitRunnable将Runnable设为cancel itself

以下是代码:

public class BukkitListener extends JavaPlugin {
    public static Bukkit plugin;
    private static BukkitScheduler scheduler;
    final Float chanceYouWillBleed = 0.02f;
    final long bleedDelay = 20;
    final long bleedPeriod = 400;

    public BukkitListener(Bukkit instance) {
        plugin = instance;
        scheduler = Bukkit.getServer().getScheduler();
    }

    public static void bleedAction(Player player) {
        player.damage(1.0D);
        player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 200, 2));
        player.sendMessage(ChatColor.RED + "You are bleeding, find a bandage and heal yourself");
    }

    BukkitRunnable buildBleedHandler(final Entity e) {
        return new BukkitRunnable() {
            public void run() {
                if (e instanceof Player) {
                    bleedAction((Player) e);
                }
            }

            @EventHandler
            public void onPlayerEvent(PlayerInteractEvent event) {
                if (event.getAction() == Action.RIGHT_CLICK_AIR &&
                        event.getPlayer().getItemInHand().getType() == Material.PAPER) {
                    cancel();
                }
            }
        };
    }

    @EventHandler
    public void onEntityDamageByEntityEvent(EntityDamageEvent event) {
        if (Math.random() <= chanceYouWillBleed) {
            Entity e = event.getEntity();
            scheduler.scheduleSyncRepeatingTask(this, buildBleedHandler(e), bleedDelay, bleedPeriod);
        }
    }
}

答案 2 :(得分:0)

你把一个方法放在另一个方法里面,在另一个类里面!

onPlayerEvent之后移动onEntityDamageByEntityEvent,并且不要忘记@EventHandler注释。

但首先,学习Java。如果不了解这种编程语言,就不能玩Bukkit。