CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    May 2013
    Posts
    7

    Jump'n'Run Game - 2 parallel for-Loops needed?

    Hello.

    I have the following problem:

    We are currently learing C# in school (first year) and now we have to make a project (GAME PROGRAMMING).
    Me and my friend decided to do something similar to Super Mario.

    Our teacher provided us a self-programmed graphics dll which allows us to "draw" many things and move them etc..
    Here's a picture how we want the things to be:

    http://puu.sh/2XZzX.png (Made in Paint)

    We don't know how to let that lines come from the right side. We only know how to let one come but if we want another one to come after 10 seconds for example we don't know how to program it.
    We thought of parallel for-Loops but is that even possible?

    Is there any other oppurtunity?

    Greets

  2. #2
    Join Date
    May 2013
    Posts
    7

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    Forgot to mention:
    The dll basically is just about coordinates. (Lines,...)

  3. #3
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    It is not that hard - you don't need parallel loops, or any kind of multithreading/parallelism - generally speaking, most games use a main loop (a.k.a. game loop) to do all their processing. On each loop iteration, or cycle, the game updates the state of the objects, player, world, etc., updates physics, based on elapsed time, and if necessary, performs collision detection, etc., and in the end renders the image (shows a frame), and then repeats this process over and over until game (or gameplay) ends. So, all the relevant objects and states are updated before the frame is drawn.

    So, what you need to do is create a simple game level, by specifying the position of those lines (your platforms) in "world"-coordinates.
    For example, assuming positive x-left, and positive y-up:
    (40, 10)-(80, 10),
    (100, 20)-(140, 20),
    (160, 30)-(200, 30),
    etc.

    Or, if you have more complicated objects, you can specify their "construction" with local-coordinates (with respect to some origin), and their position with an additional Position property which will store the global location of the shape's origin.
    Then, during rendering, you would temporarily translate the rendering origin to the shape's origin, and draw the shape as normal, it will, however, appear at the appropriate position.
    If the graphics library provided by your teacher doesn't support this, you can still achieve the second scenario by making a copy of the shape (it is important that the original points remain preserved!), and then translating each of the points in the copy by adding the coordinates of the origin, and then drawing the copy.

    Similar approach enables you to animate the objects themselves (for example, by moving the origin by a small amount on every cycle). You either move them by some fixed amount, or you obtain the time elapsed since the last cycle (frame), and calculate how much to move based on that (the objects could have a certain speed; like, 50pixels/second, or in some other unit).

    You can also define a camera object in a similar way - for a simple game like yours, it's enough to just store x-location in global (world) coordinates, with 0 being the start of the level. This x-location would determine what part of the level the window "sees". This way, you can leave all the platforms static, and only update the player and the camera. When drawing, if camera position is x, you would translate everything by -x, and draw.

    If you want us to help you in a more specific way, tell us a little bit more about this library you're gonna be using. Is there a list of classes/methods available, that explain what their do? If not, can you make a short one? What have you got so far?

  4. #4
    Join Date
    May 2013
    Posts
    7

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    Hey, can we write on private please?

    Cheers

  5. #5
    Join Date
    May 2013
    Posts
    7

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    Hey,

    so I tried the most things in the tutorial you provided but I don't understand how to add more Lines into the list.

    Bit of a rule change, we'll firstly not move the objects. We'll try to finish the program without that and if we have enaugh time we'll try to make another level where the objects move..

    This is our final decision how we want things to be since it seems to be a bit too compliacted to move everything etc etc.
    We guess it's easier if the Objects and Coins have fixed points

    Mario goes right/left (with the arrow keys, don't even know yet how to make it..) until the end of the window,.. then we clear it and he arrives in level 1-2 and so on. I think we should leave it like this for now..
    Ofc he can also take Coins and he'll stay on the objects he jumps on or stops if an object is in front of him..

    I always have problems in thinking how to make those things at the same time..
    How should I make him able to move with the arrows (basically we always have to refresh and clear the screen) without the objects to dissapear, take the coins when he touches them etc. AT THE SAME TIME?

    Sorry for asking so much,...
    I got a headache from this .. I'm sitting since hours
    Last edited by Trankey; May 25th, 2013 at 03:47 PM.

  6. #6
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    No. To add a line, you first create a line:
    Line l = new Line();
    l.StartPoint = new Point() { X = x_value, Y = y_value };
    l.EndPoint = new Point() { X = x_value, Y = y_value };

    And then add the line to the GameObject you want it added to:
    someGameObject.Lines.Add(l);

    If you want to create a lot of lines, you can use a for loop and some formula for the points:
    Code:
    Line l = new Line();
    
    for (int i = 0; i < 50; ++i)
    {
        l.StartPoint = new Point() { X = (2 * i), Y = (2 * i) };
        l.EndPoint = new Point() { X = (2*i + 100), Y = (2 * i) };
    
        someGameObject.Lines.Add(l);
    }
    That will add 50 lines.


    Once the lines are added, one call to a function like DrawGameObject() will draw all the lines contained within a game object.
    That function should really be a member of the GameObject class, but, since you're not familiar with classes, and are with static functions, maybe it's better doing it this way for now. You need to learn a quite a bit more before you can create even a simple game, but don't give up.

    Here are some C# tutorials that should help you out:
    http://www.tutorialspoint.com/csharp/
    http://msdn.microsoft.com/en-us/libr...=vs.71%29.aspx

    Check these in particular:

    Loops:
    http://www.tutorialspoint.com/csharp/csharp_loops.htm

    Structs:
    http://www.tutorialspoint.com/csharp/csharp_struct.htm
    http://msdn.microsoft.com/en-us/libr...=vs.71%29.aspx

    Properties (those get/set things):
    http://msdn.microsoft.com/en-us/libr...=vs.71%29.aspx

    Something called encapsulation (should explain what all that public/private means):
    http://www.tutorialspoint.com/csharp...apsulation.htm

    Static members (methods and fields):
    http://csharp.net-tutorials.com/classes/static-members/

    Also, check your PM inbox.
    Last edited by TheGreatCthulhu; May 25th, 2013 at 03:54 PM.

  7. #7
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    Didn't see that last post. OK, the environment can be static, but still, in order to move your "Mario" around, you'll need to use that loop. I'll make a sample VS2010 project to show you the principles. Again, your teacher's library is not really meant for games, so you can only get the last key the user pressed - there's no way to know if a button has been released. I mean, the way it's made introduces a lot of problems, but I'll think of something. In the loop, you'll check what button was pressed last, and if the right one was, you'll move the player character a bit, etc.

    These things don't really happen all at the same time, it's just an illusion, 'cause computers are so fast. As you're doing all these calculations and updates, you aren't showing any of it to the player; all the player sees is the last rendered frame. Then you do things one by one, and only when you're all done do you show the image.

  8. #8
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    I see that you've been trying to get things working, judging by that code in the PM you sent me. I may have time to check it out in more detail later, and provide some comments. Meanwhile, I've prepared a few example projects for you, so that you can see how things are supposed to work, and try some things out as well.

    The fact that your teacher's dll was not meant for games poses a number of problems, but I've made some workarounds. Also, I simplified some of the code for various user types, so that it is easier for you to work with (considering your current knowledge level). I've removed getters and setters except where necessary, etc.

    There are 3 projects - the first is the basic setup, which you've already seen and tried, with a small change; for the main loop, I introduced a try block, to avoid the dll's insistence on crashing the game when you try to draw outside the bounds of the window. It just features an ellipse going left-right-left-right... over time. Search for comments labeled TODO (which will also automatically appear in the Task List window, if you have it open and set to "Comments"), to find places you might want to tweak, etc.

    The second projects explains how to process user input (I used WASD buttons, in the style of FPS games). Basically, it builds upon the code of the previous project. Changes are marked with comments starting with NEW_FEATURE, which you can search for to quickly find out what are the differences. It "upgrades" the ellipse from the first project with a stickman figure, which you can move around. (Luckily, I was wrong when I said the dll prevents you to tell if a key has been released, as the getLastKey() method always returns -1 when no keys are pressed.)
    However, you can still go off-screen.

    The third project fixes this, by introducing simple collision detection capabilities. I added a new type, Rectangle, which can check for things like if it is intersecting another rectangle, if it contains a point, etc. These are then used as invisible collision shapes for game objects. The code uses them to prevent the player to disappear off-screen, and to let the player pick up some coins. Oh, yeah, there are 5 coins, randomly scattered on the screen.

    That's it so far. Go through the code and try to learn from it. The "game" is in bird's eye view, but you can turn it into a side-view based game relatively easily. Try to do that; you might want to use another Rectangle to define the ground level. Remember, all objects that are static (all other than player and coins, and maybe platforms), you can stick in a single list, regardless of what they represent in the game (houses, clouds). If you succeed, try also to implement jumping. Jumping is tricky because it extends over several frames, but you could do it using a formula that gives you position based on the total time elapsed since the start of the jump.

    Personally, I would do some things differently (and would definitely not use that dll for the game), but I had to take into consideration that you are only starting out and that there are many things you don't know or quite understand yet.

    If you have some questions, post here.
    Attached Files Attached Files

  9. #9
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    Oh, BTW, I recommend compiling the games yourself, but If you wanna try and run the exe-s that are in the rar archive, go for the ones in the Release folder (those in the Debug folder are probably out of date - you'll need to compile them first, before they can work).

  10. #10
    Join Date
    May 2013
    Posts
    7

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    THANK you SO MUCH. I will try to get this.. I still haveproblems with the struct thing tho ...... I will try my best to get it. I bet it's easier than I think....

    Let's see what I can do now.. the main thing is the struct thing.
    Last edited by Trankey; May 27th, 2013 at 08:23 AM.

  11. #11
    Join Date
    May 2013
    Posts
    7

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    Hey, got a question.. why did you use a GameObject class and did not make a struct?

    Okey and one more thing: When I'm moving Mario,
    Code:
    static void MovePlayer(int keycode)
            {
                int xDirection = 0;      // 1 for right, -1 for left, because <---(-1)----(0)----(+1)--->
                int yDirection = 0;      // 1 for down, -1 for up (because positive y-axis points down)
                                            // 0 means stay in place
    
                if (keycode == KEY_LEFT)
                {
                    xDirection = -1;
                }
                else if (keycode == KEY_RIGHT)
                {
                    xDirection = 1;
                }
                else if (keycode == KEY_UP)
                {
                    yDirection = -1;
                }
                else if (keycode == KEY_DOWN)
                {
                    yDirection = 1;
                }
                else if (keycode == JUMP)
                {
                    yDirection = -1;
                    xDirection = 1;
                }
    
    
                int deltaX = xDirection * PLAYER_SPEED;
                int deltaY = yDirection * PLAYER_SPEED;
    
                // This will finally move the player
                player.Location.X += deltaX;
                player.Location.Y += deltaY;
            }
    How does he even know that he has to "move" his body? I'm sincerly too stupid to find that or to get it..
    Where is the GFX. ...(..)?
    Last edited by Trankey; May 30th, 2013 at 12:08 PM.

  12. #12
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    Oh, man, this is gonna be a long post...

    About structs vs classes:
    Well, let me first make sure you understand what they are before I explain the difference.
    Both are used to define new types. In C#, some of the "predefined" types, like int and double are actually structs. For example, int is an alias for the Int32 struct (32 just stands for how many bits it takes up in memory - 32bits = 4 bytes).

    So, when you write something like
    int x = 0;

    the C# compiler pretty much sees this:
    Int32 x = new Int32();

    In fact, you can write it that way yourself, and there will be no difference in the program. So, you see, you've been using structs all along.

    Now, what you need to understand is the difference between a type, and a specific instance of that type. In the example above, the type is, as you know, int. It represents integer numbers, and it also guarantees that you can apply various operations on them, like +, -, *, /, etc. These operations are actually defined as (special purpose) methods within the Int32 struct.

    An instance of an integer type is some concrete integer number, like 0, 1, 12, -5, or whatever. So, a type represents all integers, while an instance is some specific integer. Instances are also called object (thus "object-oriented programming").
    Hope I'm making sense.

    But, what if you need something more sophisticated then numbers for your application? It is inconvenient to represent everything as numbers and strings, isn't it? It would be helpful if you could make new types to represent more complicated things, like cars, pictures, bank accounts, user information, ui windows, etc., or if you are making a game, things like the player, dragons, weapons, loot chests, items, and so on.

    That is what structs and classes are for. For example, you can use one of them to create a new type, say Item, that will represent game items and will define operations you can do with them (by defining some methods). Then you can create concrete items out of that type, items that will actually appear in the game. This is called instantiating a type. To instantiate (create an object of) the Item type, you'd simply write:
    Item someItem = new Item();

    So, this is what structs and classes are on a conceptual level. But in code, they are nothing more than a collection of variables and methods that need to do something on those variables. Data and operations on that data (more or less). Each separate instance gets its own copy of the data. When you want to modify some data on a specific instance, you call the appropriate method, and only the data of that instance is changed.
    Assume for the moment that the Item type contains an internal string member that stores its name. Let's say that you can set the name of an Item by calling a method SetName(string):
    Item item1 = new Item();
    Item item2 = new Item();
    item2.SetName("Blah");

    Only the name of item2 is changed, because you called that method through the item2 variable. So, think of it like this: instead of having a bunch of variables laying around your code trying to work together to represent several different items, making a complete mess, now you have all of them neatly packed into Item objects; item1 contains within it all the variables related to item 1, and item2 contains all related to item 2. The rest is the same. To make the code do something, you call some methods.

    THE DIFFERENCE between the two (in C#; in C++, there's almost no difference):
    It's a fairly important one. After you read this, you should probably create a simple console application just so that you can test it in practice - best way to learn. This is something your teacher should explain eventually. Anyway, while, when used, both structs and classes mostly "feel" exactly the same, there's a difference in where the data itself is stored, and how it's passed around.

    You can think of it like this; when you create a variable of a struct, the variable directly contains the instance (the value). A class variable does not, instead, it contains a "pointer" (a.k.a. a reference) to some memory location where the computer actually keeps it.
    This is important because of the following; if you do this:

    Item item1 = new Item();
    Item item2 = item1;

    what happens depends on whether Item is a struct or a class.

    If it's a struct, item2 will contain a separate, independent copy of item1. Because item1 directly contained its value, the value itself got copied.

    If Item is a class, item2 will "point" to the same instance as item1; they will basically be two names for the same data. If you do something to item2, you'll see the change if you check it via item1. This is because item1 contained a "pointer" to the value, not the value itself, so what got copied was this "pointer".

    These exact same rules apply when you pass variables as function parameters. You'll find on the web that structs are passed by value (copied), while classes are passed by reference ("pointers" are passed).

    This might seem strange, but it is actually very usefull, and you'll get used to it. In fact, when coding in C#, for the most part you'll be creating and working with classes, not with structs. And often, when you have big objects, containing a lot of data (for example, a bitmap image), you don't want a new copy to be made every time you pass it to a function. The class behavior prevents this.

    Structs are normally used for small types, often relatively simple types, containing only a few data members, like it was the case with Point, Line, Ellipse, Rectangle. Classes are used for everything else, or if you need that "pointer" behavior.

    In Visual Studio, when you hover the mouse over a type name (such as int or Item), you'll get a popup that will tell you if it's a struct or a class. Create a test project in VS (console app) and mess around to see all this in action, and to get a better understanding.

    But, this doesn't really answer why I made GameObject be a class, and not a struct. The reason has to do with default values. Structs all have predefined default values, and you cannot change this. For example, if you write

    int x;

    x will have the default value of 0 (all numeric types default to zero).

    If you have a struct composed of several other simpler types, when you create a variable, with in the default way, all internal data will be initialized to their own default values. This is why, in the attached examples from a few posts back, when you see:

    Point p; //--> which is the same as:
    Point p = new Point();

    both p.X and p.Y will initially be zero.

    Now, the default value for a class variable is null; this simply means that it "points" to nothing, it has no value associated with it.

    GameObject o; //--> is the same as:
    GameObject o = null;

    Now, just as a struct may contain ints, bools, doubles, strings and other structs, it may also contain classes. They will all be initialized to their default values. This behavior cannot be changed for structs, but you are allowed to change it for classes.

    GameObject contains two List<T> members, and List<T> is a class. If GameObject was a struct, both the list of lines and the list of ellipses would be null (would not "point" to any list object), and you wouldn't be able to add and remove things from it. I could have written additional code to make up for this, but this would make the GameObject type more complicated and more dificult for you to understand, and I was trying to keep things as simple as possible, considering that you haven't yet studied any of this.


    How does he even know that he has to "move" his body? I'm sincerly too stupid to find that or to get it..
    Where is the GFX. ...(..)?
    Don't get confused by all these new types. The code functions in the exact same way as before - the way you're familiar with already. The execution starts in the Main() method, and then within it things happen, variables are set and method calls are made that make it all happen. It's exactly the same basic flow as before.

    He doesn't "know" anything, unless you (the programmer) "tell" him, and this is where you do that:

    Look (some code omitted):
    Code:
            static void Main(string[] args)
            {
                // ====== (1) IT ALL STARTS HERE ======
    
                GFX.CreateDrawing(WIDTH, HEIGHT, Color.Black);
    
                //...
    
                while (lastKey != (int)'Q')
                {
                // ===== (2) IT STARTS TO LOOP FROM HERE ON, OVER AND OVER ========
                // =====     ONE CYCLE PER FRAME, UNTILL YOU PRESS 'Q'     ========
    
                    GFX.Clear();
    
                    lastKey = GFX.getLastKeyDown(); // <=== (3) THIS gets last key
                    MovePlayer(lastKey);      // <====  (4) THIS "tells" the player to move
    
                    // ...
                    
                    player.Draw();    // <=== (5) THIS Draw() calls GFX. ...(..)?
    
                    // ...
    
                    GFX.Refresh();    // <==== (6) THIS actually shows the drawing
    
                    // ...
    
                    // ===== (7) HERE IT JUMPS BACK TO (2) ========
                }
    
                // ===== (8) IT GETS TO HERE ONLY AFTER YOU PRESS 'Q'
    
                GFX.Close();   // <===  (9) THIS closes the window
    
                // ====== (10) THE PROGRAM ENDS RIGHT HERE
            }
    So, when it gets to (3), the code can get the key you're currently pressing. At (4) the code calles the MovePlayer() method, which is how the code knows when to move the player. This method is called every time (for every frame), even if no keys are pressed. It updates the player variable which is defined as static at the bottom of the Game.cs file, which means that the player exists the entire time the program runs. Inside MovePlayer(), the keycode is checked, and if it's a keycode for one of the control buttons, the player's Location variable is updated. This, in effect, moves the player, but [i]nothing is drawn yet[/t].

    When MovePlayer() returns, the code continues from where it left off in the while loop, and then it reaches the line (5). There, the Draw() method of the GameObject class is called (remember player is a variable of the GameObject class!).
    Draw() doesn't know, nor does it need to know, anything about what key was pressed, or if the player should move or not. It just draws the player at the place player.Location says the player is now.

    Code:
            public void Draw()
            {
                foreach (Ellipse el in Ellipses)
                {
                    Ellipse copy = el;
                    copy.Center = Point.Add(el.Center, Location);
                    copy.Draw();      // <==== FOLLOW THIS METHOD CALL (in the Ellipse struct)
                }
    
                foreach (Line line in Lines)
                {
                    Line copy = line;
                    copy.Start = Point.Add(line.Start, Location);
                    copy.End = Point.Add(line.End, Location);
                    copy.Draw();    // <==== FOLLOW THIS METHOD CALL (in the Line struct)
                }
            }
    In GameObject's Draw() method, a copy of each shape if first moved to the player.Location, by moving it's defining points (via the Point.Add() method). Since this is inside the GameObject class, and since Draw() was called via the player variable, in this code Location means player.Location.

    Each of the shape structs defines its own Draw() method. For example, in the Line struct, you have:
    Code:
            public void Draw()
            {
                GFX.AddLine(Start.X, Start.Y, End.X, End.Y);
            }
    This is finally where your "GFX. ...(..)" calls are made.
    After all that's done, it returns all the way back to the main while loop, shows the drawing, and repeats all that over and over and over and over, ..., and over, until you tell the application to exit.

  13. #13
    Join Date
    May 2013
    Posts
    7

    Re: Jump'n'Run Game - 2 parallel for-Loops needed?

    Hello.
    Sorry for replying so late but I did not have much time.

    Is there a possibilty to change the class into a struct?
    When you have a function in the structs/classes, do they automatically get called when you use the members in the respective struct/class?

    Code:
    player.Location.X += deltaX;
    player.Location.Y += deltaY;
    To be honest I still do not really understand how he knows to draw himself nor to move.
    I understand the -1/+1 part and why you add deltaX to the player.Location.X/Y but I don't see where he draws that/moves. I just understand WHY you do that but not HOW you draw it.

    And, if a function is static, does that mean that the things in there work without even calling the function? static Game()
    Last edited by Trankey; June 3rd, 2013 at 11:33 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured