Author Topic: How to do a replica of this in SGDK2?  (Read 14285 times)

Vincent

  • SGDK2 Addict
  • Expert
  • Fanatic
  • *****
  • Posts: 612
  • Legacy of Kain: Revival is completed!!!
    • View Profile
    • Chivalrous Games
    • Email
How to do a replica of this in SGDK2?
« on: 2010-10-07, 07:57:34 AM »
Hi guys! :)

Still working on my game.  I'm designing the final boss of the game: it is supposed to be a gigantic octopus so with tentacles moving around, etc.  It is a difficult task to reproduce a natural tentacle movement.  So I looked at similar games to see if something that looks like moving tentacle was already done.  Here's what I found:
http://www.youtube.com/watch?v=4maZHlmgOeY

It looks pretty much like what I want to accomplish.  In this case, there are no tentacles, but dragon heads with their heads moving around a central point: the base of their necks.  I guess the heads and each "joint" are separate sprites and they really move well around the center point.  Of course, my final boss won't be exactly the same, but I would really like to remake the head movement of the dragons into tentacles.

Anyone has an idea how to accomplish this?  I'm going to try different things, but it will be a lot of trials and errors.  So I was wondering if someone could suggest me an approach.

Thanks guys!  ;D
Legacy of Kain: Revival completed!
http://lokrevival.webs.com

See also my company website:
http://chivalrousgames.com

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #1 on: 2010-10-07, 06:05:35 PM »
I don't have much experience with it, but I have some ideas.  My first thought was to start by making the tips of the tentacles move where you want them to move, then make a bunch of sprites that "follow" the tips.  For example, T1_1 is the tip of tentacle number 1.  T1_2 is the next bit closer to the body and it follows T1_1.  T1_3 is the next one closer to the body, and it follows T1_2.  But I don't think that's very good because I don't know how to make sure the tentacle stays attached to the body in a natural looking way.  My next idea is to have 4 control points to form a curve.  Make the tip of the tentacle follow a path up and down, then make 1 or more invisible sprites that follow other paths up and down between the tip and the body.  Finally make a point that attaches to the body.  Now you can write a function that generates many more points on a smooth curve from the body to the tip of the tentacle with some tendency to the point(s) in between.  Use the formulas for bezier curves described here: http://en.wikipedia.org/wiki/B%C3%A9zier_curve.

Vincent

  • SGDK2 Addict
  • Expert
  • Fanatic
  • *****
  • Posts: 612
  • Legacy of Kain: Revival is completed!!!
    • View Profile
    • Chivalrous Games
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #2 on: 2010-10-07, 09:04:05 PM »
Hi bluemonkmn!

I'll try to make a POC with the bezier curve idea.  I thought there should be a way to express this mathematically, but since I'm not so good at maths, I preferred to ask.

Thanks a lot!  ;D

Legacy of Kain: Revival completed!
http://lokrevival.webs.com

See also my company website:
http://chivalrousgames.com

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #3 on: 2010-10-08, 11:50:44 AM »
Half day at work today (all our servers are moving to another state) so I took the time to write some code to demonstrate:

Code: [Select]
public partial class Form1 : Form
{
    Point[] bezPoints;
    Point[] keyPoints = new Point[] {
        new Point(50,20),
        new Point(200, 40),
        new Point(100, 150),
        new Point(200, 200)};

    public Form1()
    {
        bezPoints = GenerateBezierPoints(keyPoints, 40);
    }

    Point[] GenerateBezierPoints(Point[] keyPoints, int totalPoints)
    {
        Point[] result = new Point[totalPoints];
        int degree = keyPoints.Length - 1;
        int[] factorials = new int[degree]; // i! is at factorials[i-1]
        int[] binomialCoefficients = new int[degree + 1];
        factorials[0] = 1; // 1! = 1
        binomialCoefficients[0] = binomialCoefficients[degree] = 1;

        for(int i = 1; i < degree; i++)
            factorials[i] = factorials[i - 1] * (i + 1);
        for (int keyIndex = 1; keyIndex < degree; keyIndex++)
        {
            binomialCoefficients[keyIndex] = factorials[degree - 1] /
                (factorials[keyIndex - 1] * factorials[degree - 1 - keyIndex]);
        }
        for (int ptIndex = 0; ptIndex < totalPoints; ptIndex++)
        {
            for (int keyIndex = 0; keyIndex < keyPoints.Length; keyIndex++)
            {
                double t = (double)ptIndex / (double)(totalPoints - 1);
                double weight = Math.Pow(1 - t, keyPoints.Length - 1 - keyIndex) *
                    Math.Pow(t, keyIndex);
                weight *= binomialCoefficients[keyIndex];
                result[ptIndex].X += (int)(weight * keyPoints[keyIndex].X);
                result[ptIndex].Y += (int)(weight * keyPoints[keyIndex].Y);
            }
        }
        return result;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        for (int i = 0; i < keyPoints.Length; i++)
            e.Graphics.FillEllipse(SystemBrushes.Highlight, keyPoints[i].X-3, keyPoints[i].Y-3, 6, 6);
        for (int i = 0; i < bezPoints.Length; i++)
            e.Graphics.FillEllipse(SystemBrushes.GrayText, bezPoints[i].X - 2, bezPoints[i].Y - 2, 2, 2);
    }
}
you can probably copy the GenerateBezierPoints function directly to SGDK2 code.

Vincent

  • SGDK2 Addict
  • Expert
  • Fanatic
  • *****
  • Posts: 612
  • Legacy of Kain: Revival is completed!!!
    • View Profile
    • Chivalrous Games
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #4 on: 2010-10-09, 07:42:22 AM »
Hi bluemonkmn!

Thanks a lot for the code!  ;D

Maybe I'll write a function that "teleports" a sprite to a point.  This way, with many points in the curve, the sprite will look like it moves along the curve by teleporting to each point one after the other.  For the other joints, I will generate smaller curves, but with as many points and will delay the movement of the smaller joints to make them follow, but a little late, so the tentacle will look like it bends.

What do you think?  Does it make sense?

Thanks again!  :)
Legacy of Kain: Revival completed!
http://lokrevival.webs.com

See also my company website:
http://chivalrousgames.com

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #5 on: 2010-10-09, 10:31:20 AM »
Are you implying that you will use curves to define the shape of the tentacle and the path of its motion?  I thought the path for its motion would just be regular SGDK2 (linear) paths.

Vincent

  • SGDK2 Addict
  • Expert
  • Fanatic
  • *****
  • Posts: 612
  • Legacy of Kain: Revival is completed!!!
    • View Profile
    • Chivalrous Games
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #6 on: 2010-10-09, 12:45:52 PM »
Oh!  Then I must have misunderstood.  I thought I would use the bezier curve to make the path on which the tentacle would travel, not for the shape of the tentacle at all...  Are you suggesting to use a single sprite to make the whole tentacle and "bend" it following a bezier curve?

Is there a way in sgdk2 to make a sprite follow a path in reverse?  To make it stop at a precise point?  I mainly used plans to detect the presence of a sprite, to spawn sprites and t make sprites follow a path.  But I admit the the sprites folliwing the path so it very simply, always in the same direction and never going backward.
Legacy of Kain: Revival completed!
http://lokrevival.webs.com

See also my company website:
http://chivalrousgames.com

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #7 on: 2010-10-10, 07:36:45 AM »
1. My suggestion, like the dragon necks in your example, is to create a number of circular sprites, and put one at each point along the curve to make it look like one sprite that represents a tentacle.  Then when you move the key points of the curve, the tentacle will remain curved and look like it is waving/moving.  The example code I provided shows a number of dots along the curve.  Assume each dot is a sprite, but it's large enough to touch the neighboring sprites.  And assume that the highlighted dots will move following a path.  Of course you would have to write a function to do this because it's not easy to place a large number of sprites at specified points using SGDK2 rules.  Maybe you could adjust the GenerateBezierPoints function to take a SpriteCollection parameter (Sprite Category) and move each sprite in that collection to a point along a generated curve (instead of accepting an array of points and returning an array of points).

2. FollowPath is a relatively simple function in PlanBase.cs, which you can replace with two other functions: PushSpriteTowardCoordinate and CheckNextCoordinate.  But you could replace CheckNextCoordinate with your own function if you want to follow the points of the path in a different sequence or stop at some coordinate.  Also notice that FollowPath already does support pausing as a coordinate if you use WaitCounter.  CheckNextCoordinate is also responsible for adjusting WaitCounter to decide when the sprite is ready to move to the next coordinate.


Vincent

  • SGDK2 Addict
  • Expert
  • Fanatic
  • *****
  • Posts: 612
  • Legacy of Kain: Revival is completed!!!
    • View Profile
    • Chivalrous Games
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #8 on: 2010-10-10, 08:11:16 AM »
Oh!  I get it now. :)

Thanks for the explanation! :)  I'll try this when I make my POC.
Legacy of Kain: Revival completed!
http://lokrevival.webs.com

See also my company website:
http://chivalrousgames.com

tprime

  • Fanatic
  • ***
  • Posts: 395
    • View Profile
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #9 on: 2010-10-14, 09:59:21 PM »
Hi guys! :)

Still working on my game.  I'm designing the final boss of the game: it is supposed to be a gigantic octopus so with tentacles moving around, etc.  It is a difficult task to reproduce a natural tentacle movement.  So I looked at similar games to see if something that looks like moving tentacle was already done.  Here's what I found:
http://www.youtube.com/watch?v=4maZHlmgOeY


Love that game!  ;D

Vincent

  • SGDK2 Addict
  • Expert
  • Fanatic
  • *****
  • Posts: 612
  • Legacy of Kain: Revival is completed!!!
    • View Profile
    • Chivalrous Games
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #10 on: 2010-11-06, 02:12:24 PM »
Hi guys!

I worked on my proof of concept form some time now.  The result is not too bad I think.  I made good use of bluemonkmn's GenerateBezierPoints function.  I'm glad I didn't have to write this one myself!  lolol!

Anyway, here is what it looks like.  All the movement is made with a function that manages points...  but I'm not sure I want to use this approach in the game.  For the moment, the tentacle does some good movements I think.

I wondered if any of you guys wanted to give a look at it and improve it or give me other pointers and clues to make it even better.  Any help is very appreciated. :)

I attached an archive containing the SGDK2 file of the most recent version of my POC.

Thanks guys!   ;D
Legacy of Kain: Revival completed!
http://lokrevival.webs.com

See also my company website:
http://chivalrousgames.com

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #11 on: 2010-11-06, 05:51:02 PM »
Did you consider making the tip of the tentacle be a sprite that follows a path?  Instead of writing all your movements into the code, you could define the movements by using paths.  The tip of the tentacle could follow a path, and the position of that sprite could be used as one of the key points for generating the curve.  You could also create two other (invisible) sprites for the "influence" points and make them follow paths too.  It might be easier to design the movements using paths than it is to write them in code.  Then you can just copy the positions of those "key" sprites into the "point" variables used to generate the curve.  The movement might be more natural and have more variety if you 1) move these points/sprites with rules like "PushTowardCoordinate" instead of simply using "+1" and "-1" like you are doing in the code now, and 2) See what happens if you allow the movement timing of the key points to be un-synchronized from each other (if the first influence point takes 500 frames per cycle, but the second influence point takes 530 frames per cycle, and the tip takes 700 frames per , you will get a very large variety of tentacle shapes).

Vincent

  • SGDK2 Addict
  • Expert
  • Fanatic
  • *****
  • Posts: 612
  • Legacy of Kain: Revival is completed!!!
    • View Profile
    • Chivalrous Games
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #12 on: 2010-11-06, 06:30:11 PM »
Thanks bluemonkmn!

I'll try that!  ;D
Legacy of Kain: Revival completed!
http://lokrevival.webs.com

See also my company website:
http://chivalrousgames.com

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #13 on: 2010-11-06, 06:30:51 PM »
I made a sample demonstrating some of my suggestions (based on your sample).  Maybe it's not so good to let the influence points be on different cycles because they can stretch the parts of the tentacle too far, but here's what it looks like.  Maybe there is a good way to synchronize the influence point sprites so they don't get too far from each other if you don't like the stretched tentacle look.

Vincent

  • SGDK2 Addict
  • Expert
  • Fanatic
  • *****
  • Posts: 612
  • Legacy of Kain: Revival is completed!!!
    • View Profile
    • Chivalrous Games
    • Email
Re: How to do a replica of this in SGDK2?
« Reply #14 on: 2010-11-06, 06:31:40 PM »
Cool!  I'll give a look right away!  :)
Legacy of Kain: Revival completed!
http://lokrevival.webs.com

See also my company website:
http://chivalrousgames.com