Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Mekuri

Member Since 25 Feb 2011
Offline Last Active Oct 21 2014 01:13 PM

Topics I've Started

Horror Game - The Creep (WIP)

22 March 2014 - 07:59 PM

A while ago I participated in Ludum Dare 28, where my entry was a far from finished horror game. I decided that I would continue on that project, and before I knew it I had a completely new project on my hands.

I've made a small video showing some basic gameplay from the game- The game is far from done, I estimate around 10-15% done, but I think it's time to get a video out there to hear peoples opinion.

I've been working on it in my spare time for a few month now, and during that time I've picked up Blender to do some 3D modelling.

Every 3D model in my game, except for the trees, is made by me- Some are better than others, since I am still fairly new to modelling.

Anyways I'll stop now and show you the video. Thanks for reading- And thanks for watching!

 


How should I structure my game code?

07 August 2013 - 02:23 AM

For about a year I was working on a game, on a learning by doing basis. This worked well for me, and the result, so far, isn't that bad. I shelved that project for now though, and I started working on a new one, with a somewhat smaller scale.

A question that has been bothering me for a very long time, is surfacing again. Let me explain...

 

When I make a game, I make several "Screen" classes, that each contain a screen, like the menu screen or the playscreen, etc. When the game is playing the playscreen is of course shown. The playscreen then has an instance of a level class, that contains the level array, lists with mobs and items, and the starting location for the player. Each type of mob has it's own class, that derives from a base class (to make it possible to keep them all in the same list). Now this is all well and good, but my problem arises, when I start doing the movement logic for either the player or the mobs. Since each mob has its own movement logic, it will need to check its surroundings for obstacles and such. 

And here is the problem - What would be the best way to do this, while maintaining a solid code structure?

In my first project, each mob that was created received a reference to the world array, which fixed the problem. This time I was thinking about making the level array static, and then use a public static property to access it from wherever I would need it, but both of those solutions seems.. wrong somehow to me? I mean making my mobs dependent on a static variable in another class, doesn't that somehow break the whole idea of object oriented programming?

Passing down a reference somehow seems more preferable, but again, it seems wrong. I would then make the mobs dependent on the level class to be initialized, before it would even be possible to initialize it properly...

 

Am I seeing ghosts here? Or did I miss a much smoother option? 

 

Thanks for reading.


Pixel based intersection depth?

24 June 2013 - 01:22 AM

I recently started playing around with pixel based collision detection, and it is working as I expected. Currently I use the pixel based collision to determine whether or not the player has hit a dangerous object (like a spike or such). All other "tiles" in my world are still being handled by rectangle based collisions. I would like to change that though. 

What I do currently for collision with solid tiles is that I check the intersection depth, one axis at a time, and adjust accordingly. This works fine so far. But now I would like to be able to do pixel based collision responses on my tiles, which means that I can no longer use the intersection depth of two rectangles, because this would clearly give some weird results.

 

I can't seem to find much about pixel based collision responses online. All I actually want to know is how I get the intersection depth between two images...

 

The code I use for pixel based collision detection is the following:

private bool PixelbasedCollision(Rectangle rect1, Color[] data1, Rectangle rect2, Color[] data2)
        {
            int top = Math.Max(rect1.Top, rect2.Top);
            int bottom = Math.Min(rect1.Bottom, rect2.Bottom);
            int left = Math.Max(rect1.Left, rect2.Left);
            int right = Math.Min(rect1.Right, rect2.Right);

            for (int y = top; y < bottom; y++)
            {
                for (int x = left; x < right; x++)
                {
                    Color color1 = data1[(x - rect1.Left) + (y - rect1.Top) * rect1.Width];
                    Color color2 = data2[(x - rect2.Left) + (y - rect2.Top) * rect2.Width];

                    if (color1.A != 0 && color2.A != 0)
                        return true;
                }
            }
            return false;
        }

        private Color[] GetTileColorData(int x, int y)
        {
            Color[] tmp = new Color[TILE_SIZE * TILE_SIZE];
            _tileSheet.GetData<Color>(0 * TILE_SIZE, new Rectangle(_world[x,y].Variant * TILE_SIZE, (int)(_world[x,y].Type - 1) * TILE_SIZE, TILE_SIZE, TILE_SIZE), tmp, 0, tmp.Length);
            return tmp;
        }

Basically the GetTileColorData method creates an array of the Color based on an image. These are then given as arguments to the PixelbasedCollision method.

 

I was hoping that it was somehow possible to get the exact collision depth based on what happens in the PixelbasedCollision method, but I'm kind of stuck.

 

My question in short is:

 

How can I get the intersection depth between two images in a pixel based collision? - And is the information I need somewhere inside my PixelbasedCollision method?

 

Thanks for reading! :-)

 


Collision Jitters on some occasions

07 June 2013 - 04:19 PM

Hey there.

I recently began on a new project, inspired by my Ludum Dare entry, and I decided to some more solid collision detection than in my other project.

 

I've finally reached a result that I am fairly happy with, but I experience jitters, that I don't fully understand. When I move right and collide with something, my sprite jitters.. But when going left, it works exactly as intended. Also there are a few corner cases where there's some small jitter.

 

I do the collision detection and seperation like this:

 

1. Do horizontal movement.

2. Check and resolve horizontal collisions.

3. Do vertical movement.

4. Check and resolve vertical movement.

 

For both the horizontal and vertical step, I first check for rectangular collision, and then pixel based within the rectangle.

Since I divide both movement and collision handling up in horizontal and vertical, I have a hard time understanding why it jitters.

 

The code I am using is the following:

 

Player class handles movement and velocity

private void Movement()
        {
            PreviousPosition = position;
            //TODO: Add custom controls, by saving keys in a list or something, and then compare pressed keys to that list, and act accordingly.
            if (InputController.CurrentKeyboardState.IsKeyDown(Keys.A) || InputController.CurrentKeyboardState.IsKeyDown(Keys.Left))
                movement = -1.0f;
            else if (InputController.CurrentKeyboardState.IsKeyDown(Keys.D) || InputController.CurrentKeyboardState.IsKeyDown(Keys.Right))
                movement = 1.0f;
            else
                movement = 0f;

            //For testing jump strength - Final version will have a fixed strength!
            if(InputController.IsKeyPressed(Keys.OemPlus))
                BASE_JUMP_POWER++;
            else if (InputController.IsKeyPressed(Keys.OemMinus))
                BASE_JUMP_POWER--;
            
            //Velocity
            velocity.X += movement * BASE_SPEED;
            velocity.X *= AIR_DRAG;

            velocity.Y += GRAVITY;
            velocity.X = MathHelper.Clamp((float)Math.Round(velocity.X, 4, MidpointRounding.ToEven), -MAX_MOVE_SPEED, MAX_MOVE_SPEED);

            if (isOnGround)
            {
                velocity.Y = MathHelper.Clamp(-velocity.Y * .8f, -MAX_JUMP_SPEED, -BASE_JUMP_POWER);
                isOnGround = false;
            }
            velocity.Y = MathHelper.Clamp((float)Math.Round(velocity.Y, 4, MidpointRounding.ToEven), -MAX_JUMP_SPEED, MAX_FALL_SPEED);
        }

        public override void ApplyHorizontalMovement()
        {
            position.X += velocity.X;
            position.X = (float)Math.Round(position.X);
        }

        public override void ApplyVerticalMovement()
        {
            position.Y += velocity.Y;
            position.Y = (float)Math.Round(position.Y);        
        }

Movement() is called every update cycle.

Notice the apply movement methods, those are called by the "playfield" class, during collision handling, as you can see in the following code:

blic void WorldCollision(Sprite sprite, bool verticalMovement)
        {
            if (verticalMovement)
                sprite.ApplyVerticalMovement();
            else
                sprite.ApplyHorizontalMovement();
            for (int x = sprite.Bounds.X / TILE_SIZE - 1; x < sprite.Bounds.X / TILE_SIZE + 2; x++)
            {
                for (int y = sprite.Bounds.Y / TILE_SIZE - 1; y < sprite.Bounds.Y / TILE_SIZE + 2; y++)
                {
                    Rectangle tmp = new Rectangle(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);                    
                    if (sprite.Bounds.Intersects(tmp))
                   {
                       if (StaticTileInfo.GetCollisionType(_world[x, y].Type) != Collision.Passable)
                       {
                           if (PixelbasedCollision(sprite.Bounds, sprite.GetTextureData, tmp, GetTileColorData(x, y)))
                           {
                               if (StaticTileInfo.GetCollisionType(_world[x, y].Type) == Collision.Spike)
                               {
                                   sprite.IsDying = true;
                                   return;
                               }
                               else
                               {
                                   if (verticalMovement)
                                   {
                                       float intersectionDepth = RectangleExtensions.GetVerticalIntersectionDepth(sprite.Bounds, tmp);
                                       sprite.Position += new Vector2(0, intersectionDepth);
                                       if (StaticTileInfo.GetCollisionType(_world[sprite.Bounds.Center.X / TILE_SIZE, (sprite.Bounds.Bottom + 1) / TILE_SIZE].Type) == Collision.Impassable ||
                                           StaticTileInfo.GetCollisionType(_world[sprite.Bounds.Left / TILE_SIZE, (sprite.Bounds.Bottom + 1) / TILE_SIZE].Type) == Collision.Impassable ||
                                           StaticTileInfo.GetCollisionType(_world[sprite.Bounds.Right / TILE_SIZE, (sprite.Bounds.Bottom + 1) / TILE_SIZE].Type) == Collision.Impassable)
                                           sprite.IsOnGround = true;
                                       else
                                           sprite.Velocity = new Vector2(sprite.Velocity.X, 0);
                                   }
                                   else
                                   {
                                       float intersectionDepth = RectangleExtensions.GetHorizontalIntersectionDepth(sprite.Bounds, tmp); 
                                       sprite.Position += new Vector2(intersectionDepth, 0);
                                       sprite.Velocity = new Vector2(0, sprite.Velocity.Y);
                                   }
                                   break;
                               }
                           }
                       }
                       else
                           continue;
                   }
                }
            }
            if(!verticalMovement)
                WorldCollision(sprite, true);
        }

private bool PixelbasedCollision(Rectangle rect1, Color[] data1, Rectangle rect2, Color[] data2)
        {
            int top = Math.Max(rect1.Top, rect2.Top);
            int bottom = Math.Min(rect1.Bottom, rect2.Bottom);
            int left = Math.Max(rect1.Left, rect2.Left);
            int right = Math.Min(rect1.Right, rect2.Right);

            for (int y = top; y < bottom; y++)
            {
                for (int x = left; x < right; x++)
                {
                    Color color1 = data1[(x - rect1.Left) + (y - rect1.Top) * rect1.Width];
                    Color color2 = data2[(x - rect2.Left) + (y - rect2.Top) * rect2.Width];

                    if (color1.A != 0 && color2.A != 0)
                        return true;
                }
            }
            
            return false;
        }

        private Color[] GetTileColorData(int x, int y)
        {
            Color[] tmp = new Color[TILE_SIZE * TILE_SIZE];
            _tileSheet.GetData<Color>(0 * TILE_SIZE, new Rectangle(_world[x,y].Variant * TILE_SIZE, (int)(_world[x,y].Type - 1) * TILE_SIZE, TILE_SIZE, TILE_SIZE), tmp, 0, tmp.Length);
            return tmp;
        }

 

I've also made a small video showing the issues I am having:

 

I hope I provided all the information necessary. I know there's a lot of code, but I was hoping someone with experience might immediately know the error just from seeing the movie :-)

 

Thanks for reading!


How to update a lot of random tiles in a 2D array?

28 March 2013 - 03:20 AM

In the tile based game I am making I sometimes need to update several tiles at once. Since I keep my world in a 2D tile array, I can't seem to find a good way to update the specific tiles I want updated.

 

An example:

When grass grows, I periodically need to check if it is time for it to grow. Since there are a lot of dirt tiles, there will be a lot of dirt tiles to go through. When searching for dirt tiles that needs to be updated, I search from top to bottom, until I hit a dirt tile, which needs to be updated. The part that gets taxing, is that since I don't necessarily know which tiles need updating, I have to iterate through a lot of them (Or at least all withing my Update Radius). Since the player can change the world, the tiles to be updated can change very quickly. I have considered adding the reference variables to a list, and then update the tiles on the list. But since the list can become quite long fast, I'm worried that I might be spending too many resources.

 

Solutions I've thought about:

- The first one is more or less just brute force. Periodically I iterate through the tiles within my Update radius, and update them. I've done this  and sometimes this causes a lag for a second or so when the updates are applied- So this is not a good solution.

- Every time I draw my world, I iterate through a lot of tiles (those within my Draw radius). I was thinking about simply doing the tile updates  there, since I already have an iteration going. I am pretty sure this is bad practice, and I know that Draw is potentially called fewer times than update, so I dropped the idea.

- The list idea I mentioned earlier, where I add tiles that needs to be updated to a list, and iterate through that list periodically. The problems I see with this method is that I still need to figure out which tiles to put on the list, which means I need to check for that every time the world changes somewhere. Another problem I see is if the list is getting too big. I don't think memory will be a big issue, but updating potentially thousands of tiles at once, will cause huge slowdowns. A fix could be to look at the list more often, and only update small parts of it- Like a queue system.

 

So my question is: What would be a good way to update "random" tiles in a 2D array?

 

Thanks for reading smile.png


PARTNERS