Sign in to follow this  
mekrob

Public array values are not transfered between classes?

Recommended Posts

Hello again all, I have come across another strange problem in my fps game. Currently I have my game load in rectangular objects with the x,y,z coordinates of the four corners of the top face of the rectangle, as well as a value of the depth of the rectangle, from a map file. I have created an array that will hold the center point of every cube in the map as well as the distance from the center to each side (for collision detection). I have created this new struct / array in my Camera class, however it is necessary for me to atler it in my terrain class (when the rectangular objects are being loaded from the map file). I have set a break point at my code in my terrain class where it is setting the values in this array, and it seems to set everything correctly. Then after setting the values in the array, it returns to the camera class and starts checking the values in this array. I set a break point in my code at this point and I checked the values in this array, but for some reason all the values are set to 0! Is there any reason these values in the array would not transfer between classes? Here is where I set the values in the terrain class, I have determined that these values are set correctly by inserting a break point here.
 

_camera.collisionarray[on_cube] = new Camera.collision ((p1.X + ((p4.X - p1.X) / 2)), (pb1.Y + (((p1.Y - pb1.Y) / 2))),
                        (p1.Z + (((p2.Z - p1.Z) / 2))), ((p4.X - p1.X) / 2), ((p1.Y - pb1.Y) / 2), ((p2.Z - p1.Z) / 2));






Here is my collision check in my camera class. Once the values are set the program starts running this code. I set a break point here and all the values in the array are now 0!

public bool checkCollision()
        {
            _collision = false;

            for (int i = 0; i < collisionarray.Length; i++)
            {
                
                if ((_position.X < (collisionarray[i].X + collisionarray[i].DX))
                    &&
                    (_position.X > (collisionarray[i].X - collisionarray[i].DX))
                    &&
                    (_position.Y < (collisionarray[i].Y + collisionarray[i].DY))
                    &&
                    (_position.Y > (collisionarray[i].Y - collisionarray[i].DY))
                    &&
                    (_position.Z < (collisionarray[i].Z + collisionarray[i].DZ))
                    &&
                    (_position.Z > (collisionarray[i].Z - collisionarray[i].DZ)))
                {
                    _collision = true;
                }
                 

            }
return _collision;
}





And here is my struct in my camera class
 

   public struct collision
        {
            public float X, Y, Z;
            public float DX, DY, DZ;

            public collision(float _X, float _Y, float _Z, float _DX, float _DY, float _DZ)
            {
                X = _X; Y = _Y; Z = _Z;
                DX = _DX; DY = _DY; DZ = _DZ;
            }
        }





Am I not doing something correctly? Do I have to transfer the values in the array to the camera class, even though the public array exists in the camera class? Thanks again for everyones help.

Share this post


Link to post
Share on other sites
"struct" and "class" are not the same in C#, as they are in C++. A "struct" is a value type, and is thus copied by value. When you pass it to a function, the function manipulates a copy, and the original is not modified.

Although you have not posted enough code for me to be sure, I suspect this is ultimately the problem (or part of the problem). While arrays are reference types, the elements in the array might not be and depending on what you're doing and how things are defined, that fact might be causing you trouble. Can you post more code?

Taking a shot in the dark, you should either make the object a class type (if that makes sense) or pass the object using the "ref" keyword (void foo(ref collision c) and foo(ref someCollisionObject)).

Share this post


Link to post
Share on other sites
Ah thank you so much! I suspect this is my problem. When I get home tonight I will try this out and if it does not work I will definately post some more code for you to look at. Thanks again!

Share this post


Link to post
Share on other sites
Jpetrie, I appreciate the help. I am still a little stumped so I am going to try to post some more code, but the code I posted above is most of everything pertaining to the collisionarray.

First I initiate my collision array in Camera.cs



public collision[] collisionarray;





I create my collision array in Camera.cs like so



collisionarray = new collision[20];





I then later step into Terrain.cs in order to load the various cubes from a map file. Each time a cube is loaded into the cube array I also load the collisionarray data, like so..

( the variables throughout this next line of code are simpley the corner points of the current cube, I am attempting to store the center point of every cube as well as the distance from the center to each edge of the cube) (on_cube is the cube # that I am currently storing values for)




_camera.collisionarray[on_cube] = new Camera.collision ((p1.X + ((p4.X - p1.X) / 2)), (pb1.Y + (((p1.Y - pb1.Y) / 2))),
(p1.Z + (((p2.Z - p1.Z) / 2))), ((p4.X - p1.X) / 2), ((p1.Y - pb1.Y) / 2), ((p2.Z - p1.Z) / 2));





Then the program eventually returns to Camera.cs where all those values I set are now 0. I suspect you are correct in thinking that I am either referencing this wrong or I am incorrectly using a struct when I shouldn't be. How would you recomend I go about referencing collisionarray[] to Terrain.cs so that I can actually alter the values?

Thanks again!

Share this post


Link to post
Share on other sites
Ok, I am really having some problems with this. I am going to try to post as much code as I can in the hopes that someone may be able to help me with my problem.

I have now placed my collision struct and array into GameEngine.cs, you can view the code for it posted above. Now, in GameEngine.cs, I am going to enter Terrain.cs and I need to pass the collisionarray variable to it...



_terrain.LoadHeightMapFromRAW("Heightmap256.raw", ref collisionarray);





Here is LoadHeightMapFromRAW (or at least some of it)


public void LoadHeightMapFromRAW(string fileName, ref GameEngine.collision collisionarray_eng)
{
// I have not included the loading code here as it is very long and I don't think it needs to be posted...


collisionarray_eng[on_cube] = new GameEngine.collision ((p1.X + ((p4.X - p1.X) / 2)), (pb1.Y + (((p1.Y - pb1.Y) / 2))),
(p1.Z + (((p2.Z - p1.Z) / 2))), ((p4.X - p1.X) / 2), ((p1.Y - pb1.Y) / 2), ((p2.Z - p1.Z) / 2));
}





When I attempt to run the debugger I get an error at LoadHeightMapFromRAW that states...

"Inconsistent accessibility: parameter type 'ArcaneStorm.GameEngine.collision' is less accessible than method 'ArcaneStorm.Terrain.LoadHeightMapFromRAW (string, Microsoft.DirectX.Direct3D.Direct3D.Device, ArcaneStorm.GameEngine.collision)'

What is causing this error? How can I fix it?

Besides for this error, does it look like I am passing collisionarray correctly? When I alter collisionarray_eng in Terrain.cs, is it going to alter collisionarray in GameEngine.cs?

Thank you for your time and help with this!

Share this post


Link to post
Share on other sites
The 'collision' struct/class needs to be public so that you can create it in your application. For example:



// For this line to compile, collision needs to be public inside
// GameEngine
GameEngine.collision c = new GameEngine.collision(...);

myTerrain.LoadHeightMapFromRAW("Heightmap256.raw", ref c);




Also, use the 'out' modifier instead of 'ref', because the function must always fill the parameter with data and this way the compiler will enforce it (it will also mean that you don't have to initialize it before passing it to the function). It also makes it more explicit that the function will only write to the variable, not read from it.

Share this post


Link to post
Share on other sites
Thanks for the help! I think I am getting closer to finally solving this. Now however, when I try to reference my collision array from GameEngine.cs to Terrain.cs I get

"Inconsistent accessibility: parameter type 'ref ArcaneStorm.GameEngine.collision' is less accessible than method 'ArcaneStorm.Terrain.LoadHeightMapFromRAW(string, ref ArcaneStorm.GameEngine.collision)'

GameEngine is a partial class..



namespace ArcaneStorm
{
//partial class GameEngine : System.Windows.Forms.Form
partial class GameEngine : System.Windows.Forms.Form
{
// The collision structure, holds the x,y,z coords of the center point of a cube
// as well as the distance from that point to each of the sides.
public struct collision
{
public float X, Y, Z;
public float DX, DY, DZ;

public collision(float _X, float _Y, float _Z, float _DX, float _DY, float _DZ)
{
X = _X; Y = _Y; Z = _Z;
DX = _DX; DY = _DY; DZ = _DZ;
}
}




Is a partial class less accessible than a public class? If I try to change

partial class GameEngine : System.Windows.Forms.Form

to

public class GameEngine : System.Windows.Forms.Form


I get "Missing partial modifier on declaration of type 'ArcaneStorm.GameEngine'; another partial declaration of this type exists"

The only other partial declaration I can find in my code is in GameEngine.Designer.cs



namespace ArcaneStorm
{
//partial class GameEngine
partial class GameEngine
{

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}

base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout ( );
//
// GameEngine
//
this.ClientSize = new System.Drawing.Size ( 392, 366 );
this.Name = "GameEngine";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "GameEngine";
this.ResumeLayout ( false );

}

#endregion
}
}



But if I try to change partial class GameEngine to...

public class GameEngine

I get, "The namespace 'ArcaneStorm' already contains a definition for 'GameEngine'.

Whats going on?

Share this post


Link to post
Share on other sites
I dont have time to read your post fully so i'll take a wild guess.
You pass a value to a class (public value to the class) Then in another class you pass the same variable value thinking it will have the same effect. To do this you must pass it by reference... otherwise it modifys a local copy of the data.
hope this helps,
durfy

Share this post


Link to post
Share on other sites
Quote:

Original post by mekrob
Is a partial class less accessible than a public class?


partial is not a visibility specifier, so that question doesn't make sense. If the class is partial (i.e., defined in several files), mark it as partial (in all files that contain a partial definition fot it). If it needs to be publicly visible, mark it as public. In your case it seems like you need both, so just write:



public partial class GameEngine : System.Windows.Forms.Form
{
// ...
}




If you don't specify visibility for a class, than it is private or internal by default (can't remember which).

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