简体   繁体   中英

Pacman Game Organization (XNA) - Where/how should I check for collisions with ghosts/food?

I have my Pacman game working, and i'm trying to go back through it and "organize" my code better. Before, I had this "TopObject" which referenced the object in game1.cs which basically referenced every object in my game (pacman, ghosts, map, etc). I made it globally available from ANYWHERE so that I could access my Pacman object from my ghost objects, or my map/tile objects from my ghost objects, or even my ContentMananger from anywhere to load content.

I know this is bad practice, so i'm trying to eliminate it. For instance, I created LoadContent() methods on all my objects which take a "ContentManager" type, which eliminated the need for me to call ContentManager using my TopObject.

Proceeding further, i'm having a really hard time doing stuff without this global reference to all my objects. For instance: - From within my Pacman Update()..

  • I need to know if i'm going to run into a wall. I need references to my map/tiles.

  • I need to know if i've collided with a ghost, so i need references to my ghost objects.

  • I need to know if I collided with some food and then update the scoreboard, so i need have reference to my scoreboard object.

So essentially, it feels like i'm going to be making a giant mess passing so many object references around to all my objects, that it feels like doing a "global" topobject is much cleaner.

Does anyone know how to organize this better, so that i'm doing it cleanly? Should I even be checking for collisions inside my Pacman Update(), or should I be creating seperate "PacmanObject.CheckCollisionWith()" and calling that from my Game1 Update()? Should collision logic also be seperated out into a new class?

Thanks!

Having a central point that contain reference toward your objects isn't a bad thing per se. However, a good design will put the actions that are best related to each object in the correct class. For example, your player doesn't need to have reference towards the tiles and walls. While doing an Move method, the player could call a static method in the Map class that return true/false if the next move is valid. This way, the player doesn't have any reference toward the map itself.

public class Player
{
    public void Update()
    {
        //stuff to find nextTile position

        //Call static function toward a class that contains the map data.
        if (Map.TileIsWalkable(nextTile))
            Move();
    }
}

public class Map
{
    public static Map loadedMap; // Handling it as singleton, normally you only load one map at a time.

    public static bool TileIsWalkable(Vector2 position)
    {
        if (loadedMap == null) // Throw assert, shouldn't happen.

        return //whatever test needed in loadedMap structure
    }
}

You can also have a Ghost manager that keeps reference toward the ghost. The player would only need to call a method in that manager that would loop over all the ghost to see if he collides. Even better, that method could take a position and not a reference. That way, it can be reused to see if ghosts collide between each other. (random idea)

There's plenty of way to do something. The hardest in any code design is to put the stuff at the place that make the more sense and makes it the easiest to update and modify later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM