Sign in to follow this  
metorsummoner7

C# and Three Class files

Recommended Posts

I'm currently working on a Zelda clone in C#. I'm currently stuck, I want the background tiles to scroll when the player reaches the end of the screen. However, when I pass my variables across the Class files, the background doesn't change and neither do the values of the variables I passed.

Share this post


Link to post
Share on other sites
[quote name='Nypyren' timestamp='1307755454' post='4821937']
Can you post some code? There are a bunch of different things that might be causing it. The one I suspect off the top of my head is 'passing by value'.
[/quote]


Here's the code from the Background Class file:
[code]

// OverworldX and OverworldY
// are supposed to pass the data from m_nOverworldX and m_nOverworldY
// in the main class file
public void Update(GameTime gameTime, int OverworldX, int OverworldY)
{

// m_nX and m_nY are the varriables
// that manipulate the direction that the background scrolls in
OverworldX = m_nX;
OverworldY = m_nY;
}

void DrawOverworld(SpriteBatch spriteBatch)
{
for (int y = 0; y < 8; y++)
{
for (int x = 0; x < 16; x++)
{

int xx = x + m_nX;
while (xx >= 1)
{
xx -= 1;
}
while (xx < 0)
{
xx += 1;
}
int yy = y + m_nY;
while (yy >= 1)
{
yy -= 1;
}
while (yy < 0)
{
yy += 1;
}
spriteBatch.Draw(m_objTile[xx, yy], new Rectangle(x * m_nScreenWidth , y * m_nScreenHeight +128, m_nScreenWidth, m_nScreenHeight -128),
Color.White);
}
}
}
[/code]

Where I accessed OverworldX and OverworldY the main class file:
[code]

m_objBackground.Update(gameTime, m_nOverworldX, m_nOverworldY);
// Heroheight and HeroWidth are equal to m_objHero int the link class
[/code]



This where I pass the player sprite height and location data to the main class file.
[code]

public void Update(GameTime gameTime, int HeroHeight, int HeroWidth,
int HeroDirX, int HeroDirY)
{
// HeroHeight and HeroWidth pass the values for the m_objHero
// height and width to the draw function in Game1's draw function.
HeroHeight = m_objHero[m_nDirection * 3 + m_nFrame + m_nPlayerAttack].Width;
HeroWidth = m_objHero[m_nDirection * 3 + m_nFrame + m_nPlayerAttack].Height;

// sets HeroDirX and HeroDirY to m_nHeroDirX and HeroDirY
// So those varibles can be accessed by the game1 class
HeroDirX = m_nHeroDirX;
HeroDirY = m_nHeroDirY;
[/code]


This is where it returns to:
[code]

m_objLink.Update(gameTime, m_nHeroWidth, m_nHeroHeight,
m_nHeroDirX, m_nHeroDirY);
[/code]

This is the code that check to see if the player is at the edge of the play area.
Its supposed to return a value for m_nOverworldX and m_nOverworldY.
Then that valued is passed to the a background so that it can change in the direction that the player is heading in.
[code]

// when m_nHeroHeight is equal to window's height and with
// Draw m_objhero on the tile next of the current one on screen
if (m_nHeroWidth + m_nHeroDirX > Window.ClientBounds.Width)
{
m_nOverworldX++;
}
if (m_nHeroDirY == 0)
{
m_nOverworldX--;
}
if (m_nHeroHeight + m_nHeroDirY == Window.ClientBounds.Width)
{
m_nOverworldY++;
}
if (m_nHeroHeight == 128)
{
m_nOverworldY--;
}
}
[/code]


To be honest I'm just trying to pass the variable accross the class files.

Share this post


Link to post
Share on other sites
OK, it's a pass-by-value problem.

When you call a function, and reassign a value to any of the parameters, the value of the parameter does not (by default) return to the caller. By default, function parameters go "in only".

[code]void Example(int asdf)
{
asdf = 5; // this change will only affect this function, not the caller!
}

void Main()
{
int someNumber = 0;
Example(someNumber);
Console.WriteLine(someNumber); // It will still be zero!
}
[/code]

One workaround is to use the "ref" keyword. ref lets the variable go in and out of the function.

[code]void Example(ref int asdf)
{
asdf = 5;
}

void Main()
{
int someNumber = 0;
Example(ref someNumber);
Console.WriteLine(someNumber); // now it will be 5!
}
[/code]


Another, slightly different problem happens when you try to pass a 'struct' type and modify its contents:

[code]
void Example(Vector2 vector) // In this case I mean XNA's Vector2, which is a struct.
{
vector.X += 100; // This will not modify the caller's vector!
}
[/code]

In the case of structs, the solution again is to add the 'ref' keyword.


Classes do not have the same problem as structs. When you pass them to a function, you can modify their fields and the caller will see your changes. However, if you reassign the variable "pointing" to the class, you will need to use 'ref' again:

[code]
class Vector2_Class
{
public int X, Y;
}

void Example1(Vector2_Class vector)
{
vector.X += 100; // This will work properly.

vector = new Vector(); // This will not!
}

void Example2(ref Vector2_Class vector)
{
vector = new Vector(); // This will work since the variable was passed with the 'ref' keyword.
}
[/code]

There is another keyword similar to 'ref', called 'out'. This is the 'out only' parameter. You can use this as a workaround when you need multiple "return values".

[code]
void Example(out int x, out int y)
{
x = 10; // this will work. x += 10; would not, though.
// You must also assign y, or else there will be an error!
}
[/code]


All of these rules apply the same way if the functions are in the same class OR in different classes.

I hope this helps...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this