CheatCat's picture

Rayman 2 2D

Table of contest:

The beginning
Drawing images
Player movement

------
The beginning

The background to this project is this YouTube video:
http://www.youtube.com/watch?v=LW-fpwjT9I0&feature=PlayList&p=A047FCF1E8...
I want to do a fan-game to this game because it was canceled before the game was done!

First I have to decide what I should do the game with..
CsGL http://csgl.sourceforge.net : The page hasn't be updated since 2003. I want something newer.
Allegro http://www.talula.demon.co.uk/allegro : Hard to install and you cannot use it for C#. There is wrappers, but they are old.
AgateLib http://www.agatelib.org : It's slow, I want something faster!
SDL.NET http://cs-sdl.sourceforge.net : The forum is dead, I can look in the sky for help..
OpenTK http... Wait, it is this page! xD : It seems to be a great wrapper, let us try! :D

------
Drawing images

First I run the QuickStart example and get a stupid MS-DOS window in front of the program and I ask for help: http://www.opentk.com/node/890

Now I try to make a simple game!
The first program I use was GameMaker. I just need to load a sprite/image, make a object for the sprite, put the object i a room and hit the play button. Then I have a cute window with the image. Simple.

I want do something harder so I switch to C++ with The Game Creators DarkGDK library (using DirectX). To draw a image to the screen I only need write this code:

#include "DarkGDK.h"
 
void DarkGDK()
{
  dbSyncOn();
  dbLoadImage("img.png", 1);
  dbSprite(1, 10, 20, 1);
 
  while(LoopGDK())
  {
     dbSync();
  }
}

And I have a image at the position 10x20 in a window.
I also try XNA and it was little harder to draw a image but it was something similar as DarkGDK. Of course I have tried other programs and libraries and you draw images with them calling simple functions.

Okey, back to OpenGL and OpenTK. To draw a image you first need to load the image. It's hard and I don't understand what the loading function do in the NeHe Examples (google it). However it load a image and it's all I need to know. I get help at http://www.opentk.com/node/899 and learned that I can use Objarni's TexUtil class to load images.

Now I try to draw the image and to do that you must put it on a sort of plain. You can read more at http://www.opentk.com/node/909 and http://www.opentk.com/node/919

At last I want to put a transparent image in front of another image. But the transparent image get a blue border and cut of the red rectangle! I search for help again.

Well, it is not a very big problem. Moving on..

------
Player movement

Okey, let's move a image! I want add some keyboard functions that check what key the user press down. It's time for search!

Get it, Keyboard[] checks the keys! I add a wall sprite and try to check collision between it and the player. A collision function would be great and it can be inverted by myself if I don't find a pre-done function.
I do the collision function by myself since I cannot find any other. Now I should make the player to fall down if there are walls under the player. Done! (I am almost done! xD) The game go very fast, I must find a way to change the framerate or maybe move the sprite with smaller steps.

It's time to make the sprite jump when pressing Ctrl. Then I can make a level!

I get collision error now: When the player collide with a wall it cannot move! I should try to fix this...


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
CheatCat's picture

But if I have lots of blocks that the player should collide with, should I loop through all blocks then?
Like this:

for(a = 0; a < 100; a++)
{
if(block[a].xmin <= x <= block[a].xmax && block[a].ymin <= y <= block[a].ymax)
{
//Collide 
}
}

It will go slow, I think...

objarni's picture

Yes, that is the easiest approach. And it will NOT be slow, that is really simple arithmetics operations!

There are a lot of algorithms for speeding this up, if you have more than say 10000 tests*. Testing a point-inside-rectangle is a REALLY fast operation!

* My advice is wait for the performance to drop before doing anything more advanced; as the algorithmics guru Donald Knuth said: "Premature optimization is the root of all evil". Don't walk down the optimization lane until you have experienced a slowdown for sure!

CheatCat's picture

Thank you! Now I try to make the player to jump! First I tried to use a timer but the sprite bounce back very fast and it look like it hit something . Then I skip the timer and increase the yspeed until it fall down again. Maybe I should combine the timer and yspeed increasing?

objarni's picture

Are you using GameWindow?

CheatCat's picture

Yes.
I have another question: How I make arrays that look like this?:

array[0].x = 10;
array[0].y = 20;
array[0].width = 32;
array[1].x = 41;
...

In C++ you use structs, but it didn't work at C#. I get a 'Sprite.h' is inaccessible due to its protection level' - error when I try this code:

struct Sprite
{
        int h;
        int img;
        int w;
        int x;
        int y;
};
 
public override void OnLoad(EventArgs e)
{
Sprite s;
s.h = 2;
 
 TexLib.TexUtil.InitTexturing();
GL.ClearColor(System.Drawing.Color.CornflowerBlue);
GL.Enable(EnableCap.DepthTest);
GL.Enable(EnableCap.AlphaTest);
}
Inertia's picture

Declare all 5 fields in the struct as public (assuming you have no problem that people reading your source code might get a stroke) or use get|set properties. The little sadist in me votes for public.

Interesting project, looking forward to see it in action :)

objarni's picture

Declare all 5 fields in the struct as public (assuming you have no problem that people reading your source code might get a stroke) or use get|set properties. The little sadist in me votes for public.

Haha +1 on that.

Entropy's picture

I don't think you'd need a timer for a jumping motion.

Consider running something like this in the character class' update method:

Vector2 Position {get; set};
Vector2 Velocity {get; set;};
Vector2 Acceleration {get; set; }
 
public void Update()
{
   ...
   Position.Add(ref Velocity);
   Velocity.Add(ref Acceleration);
 
   //Update Acceleration.X based on left-right controls
   //Acceleration.Y should be zero unless the character is in midair, in which case it's constant and negative (OpenGL Convention being that down is negative) - this is downward acceleration due to gravity.
   //Cap Velocity at a set maximum length (or this will get ridiculous) with something like this:
   //if (Velocity >= MAX_VELOCITY) Velocity.Mult(MAX_VELOCITY / Velocity.Length) 
  // that might give some wierd effects though - consider capping Velocity.X and .Y separately.
   //If you want the player to stop when not pressing left/right, apply "friction" with
   //Velocity.Mult(0.9f); //OR Velocity.X *= (0.9f); // or similar value.
   //Correct Position Vector2 (to make sure the player doen't walk/fall through solid objects)
 
   //When the player hits 'jump', directly assign Velocity.Y with an upward value then let your preprogrammed 'gravity' do the rest of the work.
   ...
}

Note that I haven't specified any values (except an example value for 'friction'), as these values are entirely arbitrary and depend on the coordinate system you're using. It might take a while to play around and figure out what makes a good set of values, but bear in mind that it's best to think small with these, especially with the acceleration.

This is a rough approximation of how displacement, velocity, friction and acceleration work IRL, and if you're careful with it, it should serve your purposes for a platform game reasonably well. You'll certainly get a smoother jumping animation.

You might not want to use acceleration for left-right motion, but if you pick good values with relatively high friction when stopping, you should end up with a more pleasing effect.

Good luck!

CheatCat's picture

Well, I don't know anything about physic or friction, velocity or acceleration.. :(
And I don't know how to get|set properties. I have read the page but not really understand...

Mincus's picture

CheatCat: I hate to say this really, but I get the impression you'd benefit from reading through a book on C# before progressing to OpenTK.
That you seem to be struggling with protection levels and get/set methods indicates to me that your knowledge of the language is pretty small.

Please don't take this as a personal attack, I just think you'd be solving many of these smaller problems on your own with a little reading up on the language. OpenTK is adding a wealth of additional problems and it seems to be overwhelming you a little.
You've hinted that you know C++ so it should be fairly trivial to make the transition if this is the case.
Feel free to tell me if I'm wrong on this point though. :o)

As to the physics/friction: A full physics engine would be overkill for most platformers, so don't worry about it. All you need is something small for the friction as Entropy pointed out, multiplying the velocity vertex by 0.9 every update is a good start.
Getting things working just how you want them requires trial and error though.
I would suggest using the velocity/position vectors as Entropy described:
- For moving left subtract an amount from the X velocity axis.
- For moving right add an amount to the X velocity axis.
- For jumping add an amount to the Y velocity axis.
- For gravity, if the player isn't on a platform subtract an amount from the Y velocity axis.

Provided you then limit the maximum velocity in any direction you should have a fairly nice looking left/right/jump/fall movement. The exact values you want will depend on other factors in your code. I suggest trying small values at first and increment them, also build a debugging console of some description in the top-right or top-left that shows the FPS, position and velocity vector.
Hope that all helps. :o)