Jump to content

  • Log In with Google      Sign In   
  • Create Account


#Actualde_mattT

Posted 04 December 2012 - 05:12 PM

1) Public declared class variables vs class properties
Hopefully you've encountered Encapsulation and information hiding. As is described in the link, your first approach allows objects to control access to their data, which allows the object to ensure that the data is only ever set to valid values. In your "set" property you could perform some validation checks on value before updating tileRectangle. Also if you decided to change how the bounding box is stored, in the second method you would have to update every piece of code which uses bounding box, whereas in your first example you would only need to change the properties. This is related to Once and Only Once (DRY).

Note in your first example it would be good to declare tileRectangle as private. It may be by default but it's always good to be expressive.

2) Methods with multiple parameters vs overloaded methods.
Your first approach may cause issues with maintainability. If you decided to add other game object types that are also subject to collision checks (perhaps you add a Soldier class), you would have to add a new parameter to 'Collision' for each new game object type. Your parameter list could get very long. Even worse, every time you add a new collidable game object type you would have to modify every call to 'Collision' to specify the value for the new parameter (e.g. FALSE). Your second approach avoids this problem. I would probably go one step further though and give my methods more expressive names like "isTankColiding" and "isProjectileColiding".

3) Another "battle" question: List<T> vs Array
I would tend to use arrays only for very simple tasks. Anything slightly complicated requiring data structure management (e.g. inserting, sorting, removing an element in the middle of the structure) and I would use a list. Favor keeping your code simple and expressive over performance. Write good clean code first and then only change it if testing / profiling show that that piece of code is not fast enough. In 99% of cases the List will do just fine. Don't waste valubale time re-inventing the wheel, keep it simple.

4) Events and event handler.
Events are a way for a class to signal to other interested classes that something has happened. The Observer pattern is an example of a simple event handling architecture.
C# contains an event construct which makes it simple to create your own events. Maybe there are lots of classes in your game which will need to know when the bounding box of a tank is updated. Those classes can implement an event handler method (perhaps called boundingBoxUpdateHandler) to describe what they will do when they hear about the BoundingBoxUpdated event, and then can register this event handler method with the tank object which contains the bounding box. Then when the bounding box is updated, the tank object can loop through all the registered event handlers and let them know that the event has occurred.

5) And final, my most important question: collision detection.
I'm a bit confused on the way that you're calculating the offset variable. If the Tank is more than the totalWidth or totalHeight from the origin, won't your x and y indexes go out of range? E.g. in the following loop if tankBox.left > offset.X + totalWidth, x will not be a valid index for wallColor and tankColor. I've probably missed something, it's late :)

// Comparsion for collision
    for (int x = tankBox.Left - offset.X; x < tankBox.Right - offset.X; x++)
	    for (int y = tankBox.Top - offset.Y; y < tankBox.Bottom - offset.Y; y++)
		    if (wallColor[x, y].A != 0 &amp;&amp; tankColor[x, y].A != 0)
			    return true;

If your PixelPerfectCollision method is a problem performance-wise then you could combine the first two for loops together, and you could combine the last two for loops together.

I haven't done pixel-perfect collision detection before but I would start by comparing bounding boxes to check that the tank is colliding with a particular wall segment, and if the bounding boxes are colliding only check the area where the two bounding boxes overlap for a collision. Also I would check one wall at a time so that if you find a collision early on you can return true and don't have to check the other walls.

Hope this is useful

Matt

#1de_mattT

Posted 04 December 2012 - 05:05 PM

1) Public declared class variables vs class properties
Hopefully you've encountered Encapsulation and information hiding. As is described in the link, your first approach allows objects to control access to their data, which allows the object to ensure that the data is only ever set to valid values. In your "set" property you could perform some validation checks on value before updating tileRectangle. Also if you decided to change how the bounding box is stored, in the second method you would have to update every piece of code which uses bounding box, whereas in your first example you would only need to change the properties. This is related to Once and Only Once (DRY).

Note in your first example it would be good to declare tileRectangle as private. It may be by default but it's always good to be expressive.

2) Methods with multiple parameters vs overloaded methods.
Your first approach may cause issues with maintainability. If you decided to add other game object types that are also subject to collision checks (perhaps you add a Soldier class), you would have to add a new parameter to 'Collision' for each new game object type. Your parameter list could get very long. Even worse, every time you add a new collidable game object type you would have to modify every call to 'Collision' to specify the value for the new parameter (e.g. FALSE). Your second approach avoids this problem. I would probably go one step further though and give my methods more expressive names like "isTankColiding" and "isProjectileColiding".

3) Another "battle" question: List<T> vs Array
I would tend to use arrays only for very simple tasks. Anything slightly complicated requiring data structure management (e.g. inserting, sorting, removing an element in the middle of the structure) and I would use a list. Favor keeping your code simple and expressive over performance. Write good clean code first and then only change it if testing / profiling show that that piece of code is not fast enough. In 99% of cases the List will do just fine. Don't waste valubale time re-inventing the wheel, keep it simple.

4) Events and event handler.
Events are a way for a class to signal to other interested classes that something has happened. The Observerpattern is an example of a simple event handling architecture.
C# contains an event construct which makes it simple to create your own events, such as a BoundingBoxUpdated event. Maybe there are lots of classes in your game which will need to know when the bounding box of a tank is updated. Those classes can implement an event handler method (perhaps called boundingBoxUpdateHandler) to describe what they will do when they hear about the BoundingBoxUpdated event, and then can register this event handler method with the subject class which contains the bounding box. Then when the bounding box is updated, the subject class can loop through all the registered event handlers and let them know that the event has occurred.

5) And final, my most important question: collision detection.
I'm a bit confused on the way that you're calculating the offset variable. If the Tank is more than the totalWidth or totalHeight from the origin, won't your x and y indexes go out of range? E.g. in the following loop if tankBox.left > offset.X + totalWidth, x will not be a valid index for wallColor and tankColor. I've probably missed something, it's late :)

// Comparsion for collision
    for (int x = tankBox.Left - offset.X; x < tankBox.Right - offset.X; x++)
	    for (int y = tankBox.Top - offset.Y; y < tankBox.Bottom - offset.Y; y++)
		    if (wallColor[x, y].A != 0 && tankColor[x, y].A != 0)
			    return true;

If your PixelPerfectCollision method is a problem performance-wise then you could combine the first two for loops together, and you could combine the last two for loops together.

I haven't done pixel-perfect collision detection before but I would start by comparing bounding boxes to check that the tank is colliding with a particular wall segment, and if the bounding boxes are colliding only check the area where the two bounding boxes overlap for a collision. Also I would check one wall at a time so that if you find a collision early on you can return true and don't have to check the other walls.

Hope this is useful

Matt

PARTNERS