переменная beign изменена без beign явно приписана - PullRequest
0 голосов
/ 05 апреля 2020

Я не знаю, как описать это странное поведение, с которым я сейчас сталкиваюсь, но дело в том, что

У меня есть класс Player. java, который имеет личную жизнь с плавающей точкой, довольно основы c. у этого числа есть метод установки / получения, и НЕТ другого способа получения / присвоения этой переменной без использования метода получения / установки.

Кроме того, я поместил println в каждый, так что я могу получить обратную связь, когда эта переменная извлекается, и когда присваивается beign, и я получаю ЭТО на моей консоли:

моя консоль

я не думаю, что трассировка стека полезна любым способом, но если вы хотите, я тоже могу вставить код за трассировкой стека

в любом случае, если вы не заметили, есть извлечение жизни = 61, СЛЕДУЮЩЕЕ путем извлечения жизни = 70, без указания авторства WHATSOEVER этой переменной обратно к 70.

также, я не знаю, полезно ли это, но вот код, который печатает «1 поврежденный 0, передавая клиентам - отправлено»:

это возобновляется через: - уменьшает жизнь игрока - если он умер, пометьте как мертвый и сделайте другие мелочи - отправьте событие в Google Analytics - после всего этого, если игра является сервером, транслируйте да событие mage для всех клиентов

    public void takeDamage(float amount, Player owner, boolean showBlood, boolean local){
        if(local && KambojaMain.getInstance().multiplayerConnection && !KambojaMain.getInstance().isServer) return;
        if(imunity <= 0){
            //new Exception().printStackTrace();
            setLife(getLife() - amount * def);

            if(owner != null) {
                owner.score += amount*def;
            }

            if(showBlood)
            state.showBlood(body.getWorldCenter());

            System.out.println(" - DAMAGE DETECTED from " + owner.getId() + " to " + getId() + " with value " + amount + ", it was a local? " + local + ", and show blood is: " + showBlood);
            System.out.println("target life is now at " + getLife());

            hitTimer = 1f;
            if(getLife() <= 0){
                if(!isDead()){
                    deaths++;
                    if(owner != null){
                        owner.kills ++;
                        owner.ghosts.add(new Ghost(getId(), getPosition()));
                        owner.score += 100;
                    }
                    setDead(true);
                    body.getFixtureList().get(0).setSensor(true);
                    getState().showSkull(body.getWorldCenter(), getAngle());


                    String playerType = "controller";
                    if(isKeyboard()) {
                        playerType = "keyboard";
                    }
                    if(this instanceof BetterBot) {
                        playerType = "bot";
                    }

                    HashMap<String, String> customs = new HashMap<String, String>();
                    customs.put("cd1", KambojaMain.getMapName());
                    customs.put("cd3", getWeapon().getClass().getSimpleName());
                    customs.put("cd4", "player_" + playerType);

                    String ow = "Suicide";

                    if(owner != null)
                        ow = owner.getWeapon().getClass().getSimpleName();

                    KambojaMain.event("game", "player_kill",  ow, customs);
                }
            }
            if(gruntTimer < 0){
                if(GameState.SFX)
                grunt[(int)(Math.random()*5)].play();
                gruntTimer = 0.5f;
            }

            if(KambojaMain.getInstance().multiplayerConnection && KambojaMain.getInstance().isServer) {
                KambojaPacket kp = new KambojaPacket(PacketType.PLAYER_DAMAGE);
                PlayerDamage pd = new PlayerDamage();
                pd.damage = amount;
                pd.showBlood = showBlood;
                pd.owner = owner.getId();
                pd.target = getId();
                kp.data = pd;
                System.out.print(pd.owner + " damaged " + pd.target + ", broadcasting to clients - ");
                KambojaMain.getInstance().broadcast(kp, Protocol.TCP);
                System.out.println("Sent");
            }
        }
    }

примечание: я использую многопоточную среду, потому что это многопользовательская игра локальной сети, и эту переменную можно получить в других потоках, отличных от основного потока.

Я искал ключевое слово volatile, классы Atomi c (AtomicFloat не существует, и его реализация с использованием AtomicInt в качестве битовых данных также использовалась), но ничего из этого не могло предотвратить это, и я понятия не имею, что это за поведение и что его вызывает

может кто-нибудь помочь мне? я не знаю, что искать

1 Ответ

0 голосов
/ 05 апреля 2020

Попробуйте сделать ваш метод synchronized (это позволит убедиться, что только один поток может запустить этот метод на экземпляре вашего класса).

public synchronized void takeDamage(.... // same as before

Извлечь это сообщение , у него есть похожий вопрос с дополнительной информацией об атомарном запуске блоков кода.

...