0

I don't event know how to describe this weird behaviour i'm dealing with right now, but the thing is:

I have a class Player.java that has a private float life, pretty basic. this float has its setter / getter and there is NO other way of retrieving / attributing this variable without using the getter / setter.

also, i have put a println in each, so i can have a feedback of when this variable is being retrieved, and when is beign attributed, and i get THIS on my console:

my console

i don't think the stack trace is usefull in any way, but if you want to, i can paste the code behind the stack trace too

anyway, if you haven't notice, there is a retrieve of life = 61, FOLLOWED by a retriving of life = 70, with NO attribution WHATSOEVER of this variable back to 70.

also, i dont know if this is useful, but here is the code that prints the "1 damaged 0, broadcasting to clients - Sent":

it resume in: - decreases the player life - if it has died, mark as dead and do other little effect things - send event to google analytics - after all that, if the game is a server, broadcast the damage event to all clients

    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");
            }
        }
    }

note: i AM using multi threading environment because this is a lan multiplayer game, and this variable can be retrieved in other threads different from the main thread.

I have searched about the volatile keyword, Atomic classes (AtomicFloat dont exist, and the implementation of it using AtomicInt as a bit data also was used), but none of this could prevent this from happening and i have NO idea of what is this behaviour and what is causing it

can someone please help me? i don't know what to search anymore

1 Answers1

0

Try making your method synchronized (this would make sure only one thread can be running this method, on an instance of your class).

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

Check out this post, it has a similar question with more info about running blocks of code atomically.

emarteca
  • 51
  • 4