Passing in gameTime to BeforeDraw

Aug 29, 2013 at 12:10 AM
Edited Aug 29, 2013 at 12:10 AM
Sorry if this is a really basic question, but is there a way I can pass in the gameTime used in the XNA Draw method to the BeforeDraw handler? I want to draw my player, and the player's Draw method requires a GameTime.

This is the Draw and event handler in my game:
        public override void Draw(GameTime gameTime)
        {
            GameRef.spriteBatch.Begin(
                SpriteSortMode.Deferred,
                BlendState.AlphaBlend,
                SamplerState.PointClamp,
                null,
                null,
                null,
                Matrix.Identity);

            map.Draw(mapDisplayDevice, viewport);

            map.Layers[3].BeforeDraw += new xTile.Layers.LayerEventHandler(DrawPlayer);

            base.Draw(gameTime);

            GameRef.spriteBatch.End();
        }

        private void DrawPlayer(object sender, LayerEventArgs layerEventArgs)
        {
            SpriteBatch spriteBatch = mapDisplayDevice.SpriteBatchAlpha;

            sprite.Draw(gameTime, spriteBatch);             // gameTime undefined?

        }
GameRef is a reference to the main game class.
Coordinator
Aug 29, 2013 at 7:53 AM
Is sprite an instance of a class that you have defined? If yes, do you really need to pass gameTime to the sprite's Draw method? Alternatively, could you implement an overload for Draw that doesn't require gameTime?

Assuming that altering the sprite's class definition is not an option, you could keep a member variable of type GameTime in your game class and update it in the game class's Update method. You could then pass this regularly updated member variable to the sprite's Draw method.

Hope that helps.
Sep 2, 2013 at 4:35 AM
Edited Sep 2, 2013 at 5:47 AM
Thanks for the advice, I figured it out. gameTime wasn't being used by my AnimatedSprite (the class that sprite was) in the Draw function, so I just created an overload that didn't need it. I started working on collision detection, and I have a new problem. Collision doesn't work at all. It detects a collision a little below where the player's initial position is, even though there's nothing there on the layer. It also does not detect a collision where there's supposed to be a collision just above the player.
        public bool CheckCollision(AnimatedSprite sprite, Vector2 motion)
        {
            Vector2 nextLocation = sprite.Position + motion;

            Tile tile;
            Location tileLocation;
            bool collide = false;

            tileLocation = new Location((int)(nextLocation.X - 16) / 64, (int)(nextLocation.Y - 16) / 64);
            tile = collision.Tiles[tileLocation];
            if (tile != null)
            {
                collide = true;
                return collide;
            }

            tileLocation = new Location((int)(nextLocation.X + 16) / 64, (int)(nextLocation.Y - 16) / 64);
            tile = collision.Tiles[tileLocation];
            if (tile != null)
            {
                collide = true;
                return collide;
            }

            tileLocation = new Location((int)(nextLocation.X + 16) / 64, (int)(nextLocation.Y + 16) / 64);
            tile = collision.Tiles[tileLocation];
            if (tile != null)
            {
                collide = true;
                return collide;
            }

            tileLocation = new Location((int)(nextLocation.X - 16) / 64, (int)(nextLocation.Y + 16) / 64);
            tile = collision.Tiles[tileLocation];
            if (tile != null)
            {
                collide = true;
                return collide;
            }

            return collide;
        }
I grabbed the code from here and adapted it to fit my code. I didn't have collision box, and I assumed that it was the size of the sprite, so I took my sprite's size and divided it by 2, resulting in the 16.

Since I have an entire layer dedicated to collisions, I figured that all that mattered was that the tile occupied by the next position wasn't null. I know that defining collide then returning it was unnecessary, but it was there to help with my thought process.

Any idea what's wrong? I tried looking at it and couldn't come up with anything.
Coordinator
Sep 2, 2013 at 8:14 AM
For starters, you seem to be testing the 4 corners of your sprite (whose hotspot I assume is centred and is 32x32 pixels). I'm not sure that would work at all.

I would instead test a given sprite position (usually the centre bottom of your sprite for a platform game), against the bottom (testing involving Y coordinates only), and then also test for left and right (X coord tests - wall collisions). For testing against ceilings, I would get the position at the top centre of the sprite and test that (again, Y coord test only)

I suggest you start building one test at a time, starting with the bottom Y (to make sure that a falling character stops on a platform). Then you can implement the wall tests, and finally the ceiling test.
Sep 2, 2013 at 10:36 PM
The reason I took the code was because I'm working on a 2D tile-based RPG, and I figured the systems were similar enough that it would work. Since that's not the case, I guess I'll write my own.

Thanks again for all the help!