|
[SHMUP] Spline based movement |
ngiacomelli
Member #5,114
October 2004
|
I've been working on a SHMUP in my free time but it's all coming together now. One of the last things I have chosen to address is enemy AI and movement. At first I was hesitant about incorporating a spine-based movement system for two reasons:
While the first point is still relevant, the second point no longer is. The more I thought about having to hardcode various movement routines for each enemy type or incorporate a scripting engine, the more splines came to seem logical. What I'm looking for is some kind of spline implementation that will let me:
When I consider this system, it seems like most of my problems solve themselves. I would be able to make enemies carry out sophisticated loops and formations, while keeping a generic format for movement across all enemy types (which could then be stored in a map file). Currently, I'm planning to have enemy waves appear via a simple timing system. Whereby various waves are defined and then activated after a certain amount of time has elapsed. The question is, what type of spline implementation am I look at? I'm really looking for a minimal solution. Any example code is appreciated (I'm working in C). Any suggestions?
|
ixilom
Member #7,167
April 2006
|
I'm currently at work so I can't provide any real code, but I can tell you what I've done for my SHMUP (which will never be finished ) What I did was pre-calculate 1000 bezier spline paths and store them in x and y array pairs: int spline_path_x[MAX_PATHS][MAX_SPLINE_STEPS]; int spline_path_y[MAX_PATHS][MAX_SPLINE_STEPS]; This way each enemy just needs an float index which points out where in the spline path it is. // e->spline_path ... Which path is this enemy using ? // e->spline_index ... where in the path is this enemy ? e->spline_index += 0.1f; // the larger the number, the faster it will travel e->x = spline_path_x[e->spline_path][(int)e->spline_index]; e->y = spline_path_x[e->spline_path][(int)e->spline_index]; Can't really remember how I did the precalculations as my math skills are worthless and I probably just stole it from someone ___________________________________________ |
ngiacomelli
Member #5,114
October 2004
|
The only thing I struggle to really understand from exspline.c is how the object is walked around the spline. Here's the method provided:
The questions I have:
|
Northburns
Member #8,821
July 2007
|
Quote:
1) void calc_spline(const int points[8], int npts, int *x, int *y);
says that it calculates npts points to x and y arrays. This is done to each curve in the exspline.c, one curve at a time (calculate one curve, move the ball to those points, repeat to all curves). I hope my observations prove at least a bit useful. Offtopic: The example is pretty messy, there's a raptor-danger: goto EDIT--- |
Wilson Saunders
Member #5,872
May 2005
|
The basic concept of a spline is: Since you are using this to calculate position not draw a line you don't need to store points. Instead have the enemy calculate its position based on a timed index that ranges from 0 to 1. The faster the enemy goes from 0 to 1 the faster it will move on the screen. I will post code if you need it when I get home. ________________________________________________ |
ngiacomelli
Member #5,114
October 2004
|
Wilson, I'm not sure I follow. What does the value between 0-1 signify? Is that calculated between each node, or from the first node to the last? Any example code you have would be helpful!
|
Wilson Saunders
Member #5,872
May 2005
|
Nial Giacomelli said: Wilson, I'm not sure I follow. What does the value between 0-1 signify? Is that calculated between each node, or from the first node to the last? A spline travels from Point A to Point B, using Points C and D to calculate a curving path. When the value I talk about is 0 the calculated spline point is at point A. When the value is 1 the calculated spline point is at Point B. Of course the points between are generated by fractional numbers. You will have to wait for me to get home in 5 hours before I can show you code. ________________________________________________ |
Northburns
Member #8,821
July 2007
|
In the mean time, check out this article on Wikipedia: |
ngiacomelli
Member #5,114
October 2004
|
After reading the Wikipedia article I feel I understand the concept slightly more. What confuses me is the fact that a spline can contain any number of nodes, yet the article only mentions 4 points. Is this because a Bezier spline needs at least four points? Or is it because easy curve in a spline needs 4 points (two nodes and two directional points)? Source code is certainly appreciated!
|
23yrold3yrold
Member #1,134
March 2001
|
Basically you interpolate along the spline to move the ship. In my old shmup I would interpolate one point, and then one point beyond, so the ship always knew where "forward" was and turned as it travelled the path. I guess I could try to dig up some source code ... this is going back like 5 years here. -- |
Wilson Saunders
Member #5,872
May 2005
|
As promised here are two functions used to calculate a point along a spline. Explanation of variables: frac: must be between 0 and 1, so if your enemy will be on the screen for 200 frames and it is currently the 150th frame frac will be 150/200 or 0.75.
Any way experiment with setting start end, mid1, and mid2 at various parts of the screen then having frac go from 0.0 to 1.0 based on timer updates. ________________________________________________ |
ngiacomelli
Member #5,114
October 2004
|
EDIT 2: Now that I have my spline implementation working, I've added a speed float to each node. When an enemy reaches a node, it checks its speed value and then adds that value to the frac value each logic tick until frac >= 1 (it has reached the next node). This works nicely, but I've realised that if two nodes are close together, the enemy will move slower at the same speed value than if the the two nodes were further apart. It's just a case of tweaking the speed value for these nodes to get a seemingly constant speed, but is this the standard way of doing things? -- The code helped, but I still have some questions (is it like hitting your head on a brick wall?) Your ship travels from Point A to Point B. You have a variable between 0 and 1, 0 meaning the ship is at Point A and 1 meaning it has arrived at Point B. So I assume you would want to regulate the increase of this number (frac) to control your ships speed? Supposing I have a spline made up of 10 nodes, and I want my ship to walk that spline. I assume that rather than making Point A the first node and Point B the 10th, I would make Point B the second? Then, when frac reached 1, I would update the value of Point A and Point B until Point B > the maximum node count? Pseudo code: if( frac >= 1 && pointb < node_count ) { pointa++; pointb++; frac=0; } Point C and D are purely for directional information, to tell the ship how to move from A to B. In exspline.c I've found the following function:
Would I be right to assume that this is a method of taking two nodes (Point A, B) and returning their control points (Point C, D)? EDIT: It seems to be working ! Hurray! Thanks to all who helped out.
|
|