Click here to Skip to main content
15,891,033 members
Please Sign up or sign in to vote.
1.33/5 (3 votes)
See more:
        Sprite gigel = new Sprite(WindowsFormsApplication2.Properties.Resources.Gigel_img);
        Sprite tree = new Sprite(WindowsFormsApplication2.Properties.Resources.tree_img);

        void Screen_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.E)
            {
                gigel.Atack(tree.life);
                tree.LifeUpdate();
            }
            gigel.Reposition();
            Refresh();
        }

...
inside Sprite class 
        public void Atack(int targetLife)
        {
            targetLife -= damage;
        }



'targetLife' is decrementing conform 'damage'
but is not passing the value OUT to tree.life from "gigel.Atack(tree.life);"
tree.life is not getting the value from process ! Why? Or what i am doing wrong?
Thank you.

What I have tried:

//I hope now is more clear: 

            if (e.KeyCode == Keys.E)
            {
                int num = 20;
                gigel.Atack(num);
                tree.life = num; // num is 20 and not 7

                tree.LifeUpdate();
            }
...
inside Sprite class 
        public void Atack(int targetLife) //targetLife = 20
        {
            targetLife -= damage; // 20-13 targetLife=7
            //from this point (num) must take targetLife value of 7
            //but (num) remains at 20.
        }
Posted
Updated 1-Aug-18 12:30pm
v4
Comments
[no name] 31-Jul-18 21:24pm    
You haven't shown what "LifeUpdate" does.

Also, "gigel" seems to be sucking its own life.
_Q12_ 31-Jul-18 21:39pm    
1- tree.life does not update, so the other classes (LifeUpdate) after are irrelevant.
2- not really... it's a single class called [Sprite] from which I created 2 objects - gigel and tree. The 2 objects have same base class from which they derive. But it seems something is not working right.
Eric Lynch 1-Aug-18 0:18am    
Having some trouble following your question. My guess is that you are asking why tree.life, which is passed as a parameter, is not updated when you call Attack.

If this is the case, it is because the data type int is a value type. This means that when you pass it as a parameter, you pass a copy of the value (unless you specify the ref or out keyword). When you decrement targetlife, you are decrementing a copy. Since you do nothing with that copy, its value is discarded after it passes out of scope.

Assuming "life" is a property of tree, this poses further difficulties. You cannot simply pass properties by reference (with a ref/out keyword).

So, you have a few possible options. Expose a "Damage" property from the Sprite, and then: tree.life -= gigel.Damage.

Or, change the signature of the Attack method: public int Attack(targetlife) { return targetlife - damage; } and then: tree.life = gigel.Attack(tree.life).
_Q12_ 1-Aug-18 12:43pm    
I updated " What I have tried:" section with more clear example of what i have tried other than original post.
Eric Lynch 1-Aug-18 13:15pm    
Read the comment a bit more carefully. This has the exact same problem. When you pass "num" to "Attack", you pass a COPY of the value. This is how value types (e.g. int) work. Then you increment the "targetlife" (which is a copy NOT the original). After this, you return. Since "targetlife" passes out of scope, when you return, it ceases to exist.

I recommended some possible solutions in the earlier comment. You may also want to re-think your object model a bit. There is not enough code for me to be certain, but my intuition tells me the model could be improved to make this less difficult.

For example, if Sprite has both life and damage, you could do the following:

public void Attack(Sprite target)
{
target.life -= damage;
}

gigel.Attack(tree);

To better understand the difference between value types (int, struct, etc.) and reference types (class), you may want to read here:

http://www.albahari.com/valuevsreftypes.aspx

1 solution

So, here is the basic problem: value type versus reference type. For more details, read:

Value vs Reference Types in C#[^]

When you pass a value type (e.g. int) like num or tree.life as a parameter, you are passing a copy of that value. In your method (Attack), you are then decrementing the copy of the value (targetlife), not the original. When you return from the Attack method, that copy (targetlife) passes out of scope and is discarded.

In modern versions of C#, it is possible to pass a value type, by reference, using the ref or out keyword. For details, see the following links:

ref (C# Reference) | Microsoft Docs[^]
out parameter modifier (C# Reference) | Microsoft Docs[^]

However, in your case, there may be additional considerations. While the source code is not shared, I suspect life may be a property. Regrettably, it is not currently possible to pass a property using the ref/out keyword.

So, I would consider slightly re-modeling your Sprite class, which is common to both gigel and tree. In your code, it seems that gigel is attacking tree, so the method signature for Attack should probably more closely resemble this action.

I would suggest you change the method signature of Attack as follows:
public void Attack(Sprite target) =>
  target.life -= damage;
Then, to have a gigel attack a tree, you would do the following:
gigel.Attack(tree);
 
Share this answer
 
Comments
_Q12_ 1-Aug-18 21:21pm    
Awesome answer ! Thank you very much. It solved my problem! I was indeed not even thinking about value/reference types. I did read your recommended tutorial about this subject. From it i get that classes are reference and struct are value type. After that it get into garbage collector and more advanced stuff but the idea i get it. Very interestingly about Dispose() class that i find it almost everywhere in c#; it is the -manual- clean up RAM memory (especially for files) . This information i find it very good also. I must use it more often.
My gigel can happily chop trees now.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900