Learning Monogame

Discussion in 'Programming' started by Remixful, Oct 23, 2014.

  1. Remixful

    Remixful Active Member

    Right now, I'm starting to delve into game developing. I've learned a lot of C#, I think at least the basics to at least get started on working on something, instead of text based games in a Console Application. I attempted Unity, but I just didn't feel comfortable, because I wanted to do 2D more than 3D. So I choose to finally go with Monogame, and work on Visual Studio... where I feel like home. Currently, I'm reading and watching some tutorials on XNA, since there are much more tutorials on XNA then there are on Monogame. (The amount of tutorials on Monogame are actually really low.)
    But no worries, if I learn XNA, I can use the same exact knowledge to use in Monogame (since Monogame implements XNA).

    I haven't done much yet, but reading, and doing a little experimenting on the side. One thing I'm trying hard to work on is my "spaghetti code", and logic.

    [​IMG]
    As you can see, I did add boundaries to where the character can walk. Also if I hold shift the character can run. I've also done sprite animation, as you can see.

    So far I haven't learnt collisions, I believe it's Rectangle collisions, but I'm only on the 3rd chapter of my book. XD

    Anyways.. this is the first step.. my first big project is going to be to recreate a Pokemon game.
    (Of course, I'm only going to do little steps of experimenting on the way for now though, and make small little games too.)

    Wish me luck! :)
  2. RHY3756547

    RHY3756547 FreeSO Developer Staff Member Moderator

    Are you reading the map directly from game files? Since the Pokemon RSE formats are pretty well documented I think it would be pretty interesting to read them to get the maps precisely the same, without repackaging them.
  3. Remixful

    Remixful Active Member

    Hmm no, I just use sprite sheets.
    Do you know where I can find this documentation, that you are talking about? And I was leaning more towards Fire Red style. ( Assuming RSE means Ruby, Sapphire, and Emerald yes..? o_O)
  4. RHY3756547

    RHY3756547 FreeSO Developer Staff Member Moderator

  5. Remixful

    Remixful Active Member

    This looks... very overwhelming and intimidating.... :eek:
    Meh. I might just do some other projects first before going to Pokemon.. lol. :p
    Last edited: Oct 23, 2014
  6. RHY3756547

    RHY3756547 FreeSO Developer Staff Member Moderator

    I was just suggesting something more functional but complicated. You can still continue the way you're going right now for the learning experience.
  7. Remixful

    Remixful Active Member

    Understood. It would still be nice to figure out my own methods to remake things in Pokemon, I'm not exactly trying to make a copy, but rather a remake (using my own methods like I said), the only thing I'm going to use are sprite sheets. But then again, I'm going to do little simple projects instead of jumping right to this.
  8. francot514

    francot514 Well-Known Member

    What do you mean spaghetti...
    Seems interesting, you want to post source code of this, by that way people can help you in development...
  9. Remixful

    Remixful Active Member

    It's nothing yet.. It's messy because I just started learning, It was just experimenting. I need to finish learning then I'm going to start working on projects.

  10. Remixful

    Remixful Active Member

    Hey, I found this in the book I'm reading.
    Code:
    abstract class Sprite
        {
            Texture2D textureImage;
            protected Point frameSize;
            Point currentFrame;
            Point sheetSize;
            int collisionOffset;
            int timeSinceLastFrame = 0;
            int millisecondsPerFrame;
            const int defaultMillisecondsPerFrame = 16;
            protected Vector2 speed;
            protected Vector2 position;
    
            public Sprite(Texture2D textureImage, Vector2 position, Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed)
            : this(textureImage, position, frameSize, collisionOffset, currentFrame, sheetSize, speed, defaultMillisecondsPerFrame)
            {
    
            }
    
            public Sprite(Texture2D textureImage, Vector2 position, Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed, int millisecondsPerFrame)
            {
                this.textureImage = textureImage;
                this.position = position;
                this.frameSize = frameSize;
                this.collisionOffset = collisionOffset;
                this.currentFrame = currentFrame;
                this.sheetSize = sheetSize;
                this.speed = speed;
                this.millisecondsPerFrame = millisecondsPerFrame;
            }
    
        }
    The author stated:
    I was thinking a better, more simple way, would be to create one constructor with an optional parameter.
    Code:
    public Sprite(Texture2D textureImage, Vector2 position, Point frameSize, int collisionOffset, Point currentFrame, Point sheetSize, Vector2 speed, int millisecondsPerFrame = defaultMillisecondsPerFrame)
    {
    this.textureImage = textureImage;
    this.position = position;
    this.frameSize = frameSize;
    this.collisionOffset = collisionOffset;
    this.currentFrame = currentFrame;
    this.sheetSize = sheetSize;
    this.speed = speed;
    this.millisecondsPerFrame = millisecondsPerFrame;
    }
    
    What do you guys think? I feel like adding another constructor to call the constructor in the same class a bit unnecessary, do any of you have any opinions, thoughts, or suggestions on this?
  11. RHY3756547

    RHY3756547 FreeSO Developer Staff Member Moderator

    Yep, that would still work. The reason they showed it as they did is to show the two distinct overloads and to allow you to add functionality to that overload of the constructor in future. Also, these were only recently introduced in Visual C# 2010, whereas the overloaded style shown by the example works even in Visual C# 2008.
    Remixful likes this.
  12. Remixful

    Remixful Active Member

    Thanks for the info!

    As in "these", I'm assuming you're talking about optional parameters, yes?
    Also, I would like to know, which way do you think I should go with if I were to use this for future use? Optional parameter, or two overloads of the constructor?
  13. RHY3756547

    RHY3756547 FreeSO Developer Staff Member Moderator

    Optional parameters make the most sense if you're not going to use any complex calculation or logics to generate the default ms per frame. Plus it saves writing out that crazy long constructor!
  14. Remixful

    Remixful Active Member

    Having a bit of a predicament here. I saw there was a option to make your window resizable. I wanted to test the game if by any chances, the size did ever change.
    I saw that when I changed the game size, the texture I was drawing in the center of the window width (Game.Window.ClientBounds.Width / 2 ) was definitely not going in the center of the window. I also decided to just test by having a little text to tell me the ClientBounds information.
    Code:
    spriteBatch.DrawString(debugTest, Game.Window.ClientBounds.ToString(), new Vector2(Game.Window.ClientBounds.Width - (Game.Window.ClientBounds.ToString().Length * 11), 0), Color.White);
    
    Indeed, the window size was changing, also the text changed with it and displayed the window width and height, but also the position of the SpriteFont was appearing at weird x positions like my texture was.
    Anyway to fix this? I need to really clear this up, because I know a lot of my games will be heavily dependent on the Window width and height.

    Note: This is also all in the Draw Method
    Last edited: Oct 31, 2014
  15. Remixful

    Remixful Active Member

    Fixed the problem.
    Seems like the graphics device was never applying changes, but it was changing PrefferedBackBufferWidth and PrefferedBackBufferHeight to the ClientBounds Width/Height.
    The simplest way was to do graphics.ApplyChanges() in my Update loop. I couldn't figure out a way to use the Window.ClientChanged event because it kept causing stack overflow (not sure why but it had to do with graphics.ApplyChanges())

    If there are any other solutions please do tell me, I'm a bit afraid that graphics.ApplyChanges() always being called in the Update loop, might not be efficient? Not sure.
  16. RHY3756547

    RHY3756547 FreeSO Developer Staff Member Moderator

    graphics.ApplyChanges() notifies listeners of window.ClientChanged that a change has occurred, which is why you got a stack overflow.
  17. Remixful

    Remixful Active Member

    Thanks for letting me know. I've been trying to recreate the easiest game.. pong.. for quite a while now (8+ hours sadly...). I've bumped into a lot of exceptions, lots of mistakes, but it's probably just good practice.
    One huge problem I have is the paddle and the ball collision. I use the intersects method on the rectangles, and it's really hard to get a smooth hit... Like without the ball getting stuck on the top, bottom, or any other weird things..
  18. Remixful

    Remixful Active Member

    This morning I spent 3 hours working on the ball velocity, fixing the ball from accelerating and such, then working a little on the Enemy AI, and adding some sounds to the game.
    Next I worked on the collisions, for a good 3 hours, and boy this took forever.. I was messing around with the collision rectangles, the ball speed, I tried making variables to keep everything in check, but I finally came up with my own collision system, because it just seems like Rectangle's Intersect method fucks up everything for me.
    Code:
     if (ballCollisionRect.X + ballCollisionRect.Width == playerCollisionRectTop.X && ((ballCollisionRect.Y <= playerCollisionRectTop.Height + playerCollisionRectTop.Y && ballCollisionRect.Y >= playerCollisionRectTop.Y) || (ballCollisionRect.Y + ballCollisionRect.Height <= playerCollisionRectTop.Height + playerCollisionRectTop.Y && ballCollisionRect.Y + ballCollisionRect.Height >= playerCollisionRectTop.Y)) )
    (This also only detects hits from the right, I believe, So I think I'm going to make an extra paremeter that takes the direction it is expected to come from.)
    Just slap that onto a method (I used "CollisionCheck", return type of bool), use two parameters of Rectangles (rect1, rect2), then rename everything in that if statement to work with the parameters instead, as so:
    Code:
    if (CheckCollision(ballCollisionRect, playerCollisionRectTop))
                    {
                        SoundManager.playSound(SoundManager.Sounds.playerHit);
                        Ball.Rebound(Ball.Direction.Top);
                        Ball.lastHit = Ball.Direction.Top;
                        UpdateBallPosition();
                    }
    The reason why I have "playerCollisionRectTop" is because I split the player's paddle into 3 different sections to determine the direction in which the ball rebounds, just saying, if you were wondering. To my surprise, this collision system actually fixed the problem with the ball "sitting on top" of the paddle, and doing that little glitchy dance.
    I actually was close to giving up few times, but my girlfriend was actually with me through it all (teamviewer) and praised, and encouraged me. (Woohoo! Praise and encouragement for a fucking pong game!)

    [​IMG]
    (The GIF captures at a certain amount of frames per second so the ball movement (including the collision rectangle) is not displayed smoothly, and the ball does hit the paddle, it's just not captured in the GIF. Also the reason why you see colors and text, is because I made an option where you press F12 to enable debug mode, allowing you see some extra details and collision rectangles.)
    I've probably spent about 20 hours or so on this game already, I'm really just trying to improve my weaknesses (my logic, and algorithm skills), and I'm trying my best to keep my code cleaner, and organized, and not TOO complicated or messy, but it's a bit hard for me to avoid over-complicating things, thus why I'm trying to improve it and try my best to redo things into a more simple manner when it's too complicated.
    Still not finished.. but progress is being made... Once I'm done, I'll upload the game, and source if you're interested.

    Also! Interesting fact: everything in the game is draw programmatically(if that is a word) using one sprite that is called whiteTexture (1 white pixel). Except for the Main menu picture, which is a .bmp I made in Paint.Net.

    EDIT: Yeah so.. my collision system doesn't help as much, not sure if it makes anything better, because the main problem is the ball which is moving at 20 pixels, will move 20 pixels before it actually hits the paddle.. Which makes it look like it's going in the paddle.. Not sure how to fix this..
    Last edited: Nov 2, 2014
  19. Remixful

    Remixful Active Member

    I'm going to recode my ball speed again.... My dad also helped me out with an idea of collision (because he's a game developer, and he said he's had to do this collision thing a million of times.)
    He suggested that I did a for loop that repeats 20 times and moves the ball's x by 1 each time. In the for loop, it will always do a collision check so it will never move further if it does get the collision.
  20. RHY3756547

    RHY3756547 FreeSO Developer Staff Member Moderator

    That's a very simple approach to collision - but past that things get quite mathematically complicated. One drawback of this method is that going too fast could potentially make you fly through the object you're colliding with, but for most games this is not a problem (especially with high tick rate)

    I used this method for both of my recent ld48 games to save time, but a more robust way of doing it for a game as fast paced as them would be to define walls as bounded lines and either detect collision with a swept circle or a swept set of lines. I do this in 3d for a recreation of the mkds engine i made a while back.

Share This Page