Don't forget to read the rules of the forum. No current release restrictions. | Help Search Members Calendar

Logged in as: The Dreamslayer ( Log Out ) | My Controls · 0 New Messages · View New Posts · My Assistant

Mugen DEV Forum -> Development and Help Forums -> Development Discussion

CPS Parallax Tutorial
Track this topic | Email this topic | Print this topic

Winane | Posted: Jan 9 2003, 04:29 AM
MUGEN Grip Group: Members Posts: 314 Member No.: 122 Joined: 14-September 02
This is an updated version of what I originally posted at the old MugenDev in a response to Juan Carlos's release of Demitri's stage from Vampire Savior. As such, it uses JC's Demitri stage (available at http://eternalmugen.cjb.net/ ) as an example to help clarify things. It also uses Cammy's stage from Super Street Fighter 2 Turbo as an example, which I've released at ShinMugen.
I've noticed that a very common problem in stages released for Mugen is incorrect usage of parallax. Basically the problem is that when the stage scrolls left or right, the ground under the players' feet moves at a different rate than the feet do, making it look like it's sliding underneath the characters. And sometimes if a normal part of a stage is supposed to be attached to the floor, it will look like it too slides across it when the stage scrolls. So I've written up this tutorial in the hopes of helping people to convert Capcom stages with parallax floors correctly.
-CPS games have a horizontal screen resolution of 384 pixels.
-I believe that most (all?) stages with parallax floors/ceilings in CPS one-on-one fighting games are exactly two screens wide. So that's 2 x 384 = 768 pixels wide.
-Mugen's screen is 320 pixels wide. So (768-320)/2 = 224 = the left and right bounds for such CPS stages. So under [Camera] put:
boundleft = -224
boundright = 224
-In general, if a layer in a background is X pixels wide, then the correct delta value for Mugen can be calculated as (X - 320)/(stage width - 320). So for CPS stages with width of 768, that's (X-320)/448.
For parallax:
-There's a few possible ways to rip the parallax floor sprite. The rowscroll disabling method gives you a little more room for error than Shadow Dragon-X's method, but makes it a little more difficult to make the stage perfectly accurate if you're a perfectionist. But I'd say whichever way is fine.
*Shadow Dragon-X method (recommended if you want to make the stage as accurate as possible):
See Shadow Dragon-X's tutorial, available here: http://www.shinmugen.net/winane/ShadowDrag...X4_parallax.zip
(Note that this tutorial was made entirely by Shadow Dragon-X, not by me.)
With this method, you may also discover a change in the rate of distortion part way through the sprite. For example, in Cammy's SSF2 stage, I discovered that the sprite started spreading out faster after the top 5 lines, so I broke the sprite into two pieces with different parallax parameters for each.
*Nebula method (recommended if you're not too anal):
Go to shots factory while you're in the stage you want to rip from. Turn off RowScroll. Disable all sprites and layers other than what you want to rip. Rip the parallax sprite as you would any other sprite, using Scroll X to scroll back and forth to get the whole sprite.
*SFMAME method:
Pause the game while you're in the stage you want to rip from. Press tab, go to "Input (general)", and go down to:
Layer horiz. offset inc.
Layer horiz. offset dec.
Layer vert. offset inc.
Layer vert. offset dec.
Assign keys to these (the arrow keys should work fine) by hitting enter and pressing the key you want for each of the first two and, if necessary, for each of the last two. (Then, of course, hit escape twice to get out of the option menus and back to the paused game.)
Press Y to turn off linescroll. Disable all sprites and layers other than what you want to rip. Rip as you would any other sprite, using the keys you assigned to the layer offset functions to scroll back and forth to get the whole sprite. Note that if you can't scroll far enough in one direction to get the whole sprite, you can probably scroll in the other direction beyond the other end of the sprite to find the missing end piece (but if for some reason that doesn't work, you can just unpause, move the characters in the direction you need, repause, and try again).
*Kawaks method (might not work if the floor isn't symmetrical):
Press Alt+R to disable Rowscroll while in the stage you want to rip from. Disable all sprites and layers other than what you want to rip. Rip as you would any other sprite. You'll then probably need to mirror the left side of the sprite in order to complete the right side.
-Note: In the parallax sprite you rip, be sure not to include anything above or below where the parallax effect is in effect (sometimes the entire sprite is parallaxed, but other times (e.g. in Demitri's stage) the effect stops part way up or down and the rest of the sprite is displayed as a normal sprite), nor anything above the top or below the bottom of the screen (which Nebula and SFMAME let you do). Doing so will mess up the calculations below.
-When making the SFF, set the x axis for the parallax sprite to the horizontal center of the sprite. So, if the sprite is 800 pixels wide, set the x axis at 400. If it has an odd number of pixels, just divide the width by two and round up or down to the nearest integer (e.g. if it's 801 pixels wide, divide by two and round to 400 or 401.)

Winane | Posted: Jan 9 2003, 04:30 AM
MUGEN Grip Group: Members Posts: 314 Member No.: 122 Joined: 14-September 02
The tutorial wouldn't all fit into one post, so here's part 2:
-If you've used the Shadow Dragon-X method to rip the floor sprite, then just take note of how wide the sprite is at the top and at the bottom. (In Demitri's case, it would have been 679 pixels wide at the top and 831 pixels wide at the bottom.)
-If you've used one of the other methods:
*Take a screenshot of the floor at the left edge of the stage, and another at the right edge of the stage.
*Copy the right parallax sprite and copy it onto the left one such that the top row of pixels in the right sprite lines up with the top row of pixels in the left sprite. Then check how many pixels are in that top row. (In the case of Demitri's stage, it was 679 pixels.)
*Then start over with the leftmost screenshot again. Copy the middle section of your complete floor sprite and paste it onto your left screenshot such that the bottom row of pixels line up. Then copy the right screenshot's sprite and paste it onto the same image such that the bottom row of its sprites lines up with the bottom row of the middle portion. Then check how many pixels are in that bottom row. (In Demitri's case, it was 831 pixels.)
*While you're at it, you may want to use the left and right screenshots to determine which pixel should be the last ones displayed at the top and bottom left, and top and bottom right. Then open your floor sprite file, choose a color that contrasts the rest of the floor sprite, and temporarily paint those pixels with that color. This should make it easier to figure out the right values below if you have to use some trial and error. When you go to the edges of your stage in Mugen, you can then tell at a glance if the delta value for a row is too low (if the pixel isn't visible), too high (if the pixel is visible but not the last one in the row), or just right (if it is the last one displayed). (And if you choose to do this with every row of pixels, it'll probably take quite a while, but will be just as accurate as using the Shadow Dragon-X ripping method.) Then, when you're done figuring out the numbers to use in the DEF file, just switch the original unpainted sprite back into your SFF file.
-For the delta values of the parallax sprite, set it to delta = (top width - 320)/448, 1. (So with Demitri's stage, that's (679-320)/448 = .8013392.)
-For the xscale values, set it to xscale = 1, ((bottom width - 320)/448)/xdelta. (So with Demitri's stage, that would have been ((831-320)/448)/.8013392 = 1.140625/.8013392 = 1.4233984. However, because JC didn't crop the parallax sprite where it stops being parallaxed, I had to use a little trial and error to get it to match the bottom sprites.)
-Any sprites attached to the top of the parallax floor should use a delta value of (top width - 320)/448. (But there are none in Demitri's stage.)
-Any sprites attached to the bottom of the parallax floor should use a delta value of (bottom width - 320)/448. (Such as the [BG Z] elements in JC's Demitri stage.)
-In the original game, make a note of what line of pixels the middle of the widest part of the players' shadows fall on (use the lower one if there's two middle pixels). Set the zoffset to match, so that the bottom of KFM's feet are on the same line. Or alternatively, if you've used the Shadow Dragon-X sprite ripping method, just take note of which row of pixels is 768 pixels wide, and set the zoffset to that row. (But if your parallax stuff is off by just a little and it looks like the floor slides under the players just a little, it should be okay to move the zoffset up or down just a little to match.)
-Note that the above directions theoretically (I think) should result in a perfectly accurate translation of the stage into Mugen. However, when making Cammy's stage with (a less efficient version of) Shadow Dragon-X's parallax sprite ripping method, I found that it came close but didn't quite work, and I was left with some black pixels on the edges of the stage. So I just had to use a bit of trial and error with the delta and xscale settings to get the sprite to behave properly. But the method above should at least give you a good approximation of the correct values to start with, so the trial and error shouldn't be as hard.
Animated Parallax:
I haven't tried making any stages with animated parallax sprites, but I can think of two ways which should work:
1. Implement each frame of the animation as explained above, and use bgctrls to enable and disable each frame at the appropriate times.
2. Or, split the animated parallax sprites into separate rows of pixels, and just make each row a normal anim, using the formula (row width - 320)/(stage width - 320) to calculate the horizontal delta value for each row. According to VIB, you can do the splitting automatically by using Corel PHOTO-PAINT. I would recommend using the first method instead, but I felt like mentioning this one for completeness sake.
-And one final note about stage making in general (not just parallax ones): Don't forget to convert all your sprites to 256 colors. And unless Ses ever gets around to fixing it, DON'T use MCM to compile your SFF (or if you do, be sure to recompile it with Sprmaker or Z-CharCAD). Not converting your sprites to 256 colors will prevent bgpalfx from working on any of them, making many, many characters' moves look awful. And using MCM to compile will apparently prevent bgpalfx from working on random sprites, which looks even worse (e.g. everything gets blacked out by a super move except for a rectangle or two in the middle of the stage). I've been seeing this problem way too much. Furthermore, I believe I've heard that these problems will also crash Linux Mugen.
Any questions, comments, corrections, and suggestions are welcome.
Credit and thanks to:
Shadow Dragon-X for making that parallax sprite ripping tutorial.
Shin DIO for sending me said tutorial.
Shin ShadowH for hosting said tutorial.
The Immortal for reminding me that layer offset works with CPS games in SFMAME.
Juan Carlos for letting me use his stage as an example.
VIB for miscellaneous feedback.
P.S. I've noticed messed up parallax in stages from throughout the Mugen world, so if any bilingual people out there would be so kind as to translate this tutorial into other languages and post it somewhere, I would be very grateful.

The Immortal | Posted: Jan 9 2003, 12:47 PM
Member Group: Members Posts: 37 Member No.: 145 Joined: 14-September 02
Hey, great tutorial!
As soon as I have time, IŽll translate the tutorial into Portuguese.
Bye!
--------------------
[center][img]http://bmt.mgbr.net/images/immortal.gif[/img][/center]

VIB | Posted: Jan 20 2003, 05:26 AM
Member Group: Members Posts: 51 Member No.: 1457 Joined: 15-November 02
[quote author=Winane link=board=4;threadid=755;start=0#msg7745 date=1042086648]
-For the xscale values, set it to xscale = 1, ((bottom width - 320)/448)/xdelta. (So with Demitri's stage, that would have been ((831-320)/448)/.8013392 = 1.140625/.8013392 = 1.4233984. [/quote]
I did not understand this .. why did you used such values ?? why do you need the sprite width ?? what is that theory you used ??
forgive me if I am wrong, but it seems that your method worked in Dimitri's stage for coincidence (that would explain why you did not have a perfect result in Cammy's stage) .. xscale doesn't actually scales the sprite like width does .. xscale just changes delta (I think "xscale" was supposed to mean "delta X parameter SCALing" or something) ..
it also seems that you are doing things the opposite way, you calculate the z-offset from the bottom delta that you try to get from the emulator, you should get the z-offset from the emulator and calculate the bottom delta from it ..
anyway .. I'll try to show you the way I do .. it might help a little .. works perfectly in 100% of the cases .. its clear and makes sense to me =P
first take a look at this picture:
this is my version of chunli's china stage from ssf2 .. you can get it here:
http://www.vib.pop.com.br/mugen/stages/ssf2-China.rar
notice the blue line, that is your z-offset (char line) .. the floor sprite is between the red lines .. A is the distance between the top and the char line .. B is the distance between char line and bottom .. h is the sprite height (this is here just for reference, note that h=A+
your z-offset should be = 240 - B (240 is mugen screen height) .. and you should get the top delta of the floor from the emulator by calculating "between how much the top of the floor moves" / "how much a standing character moved" ..
then you calculate the xscale using:
xscale = 1, x
x = ((1-d)*B/A+1)/d
where A is the distance between the top and the char line
B is the distance between char line and bottom
d is the sprite delta, x parameter
in chunli's stage for example .. h = 64, A = 41, B = 23, zoffset = 217, d = .765
so it is like this:
delta = .765,1
xscale = 1, 1.479
; x = ((1-.765)*23/41+1)/.765
then, sprites in the top should have delta = floor's delta (.765 in chunli's) .. sprites in the bottom should have delta = (floor's delta * x) .. .765*1.479= 1.131 in chunli's stage
the characters won't slide and you won't have to adjust zoffset because the xscale was calculated in order to make that the delta in the char line to be = 1 (that line of the floor will move in the same speed as the characters)
you can see the final delta values in this picture to understanding it
notice that the deltas are proportional in the same ratio .. remember tales ?? =P
top delta = .765 * 1 = .765
char delta = 1 .. this is the reason of all the calculation, to keep this = to 1
bottom delta = .765 * 1.479 = 1.131
got it ?? the z-offset you get from the emulator, and then you calculate the bottom delta so that the char delta is equal to 1 ..
hope it helps =)
--------------------
the above message is ironic in its nature, please ignore it .. sorry for the incovenience ..

Winane | Posted: Jan 20 2003, 08:27 AM
MUGEN Grip Group: Members Posts: 314 Member No.: 122 Joined: 14-September 02
I'm afraid I still can't download those images or the stage.
[quote]it also seems that you are doing things the opposite way, you calculate the z-offset from the bottom delta that you try to get from the emulator, [/quote]
Huh? The way I said to set the zoffset doesn't have anything to do with the bottom delta.
When I said I didn't have perfect results in Cammy's stage, I meant some rows of pixels were off by one or two pixels, i.e. it was quite close, and possibly off just due to rounding error somewhere. But when I plugged my bridge sprite (which includes all the pixels visible in the original, and nothing more, so you can tell whether the parallax comes out right or not) into your stage, it was off by significantly more. I think your way works well enough, but is a bit less precise.
Also, how would you deal with parallax sprites which the characters don't stand on, or parallax sprites which change their rate of distortion partway down (e.g. with Cammy's stage)?
It's a little difficult to explain how I came up with my method (especially since I came up with it about a year ago, and haven't had to think too much about it since then), but it's basically just based on the correct horizontal delta value for any part of a stage being (layer width - 320)/(stage width - 320). I'll see if I can try to explain tomorrow when it's not quite so late.

VIB | Posted: Jan 20 2003, 04:46 PM
Member Group: Members Posts: 51 Member No.: 1457 Joined: 15-November 02
I uploaded it at geocities .. try http://www.geocities.com/vibhp/mugen/tuto/...o/parallax.html
what I mean with "calculating the z-offset" is to manually adjust the z-offset after you had the bottom delta, so that it matches the floor .. when you do that, you are setting the z-offset in function of the xscale ..
[quote]it should be okay to move the zoffset up or down just a little to match[/quote]
but, theorically, if you have the correct top delta, and the correct z-offset .. to "match" the char feet, you are actually matching the delta value of the char (that is equal to 1) and the line in the floor that they are on (the z-offset) .. so the delta in the z-offset should be 1 ..
my england stage floor is not accuratly close to the original .. the original floor delta is something between .9 and 1 .. but I used .9 instead to make the floor deeper, so the parallax would be more clear .. I just did it this way because I think it was more... cute =P .. but on chunli's stage I used the original delta, you can check it and I am sure that the parallax on it is exactly the as in the cps2 game ^^
I can also say that the parallax on your cammy stage is imperfect, because you can clearly see that you moved the z-offset up to macth the parallax .. this would not be necessary if the parallax were correct .. in that stage the characters foot are perfectly in the middle of the floor sprite ..
on any parallax, it doesn't matters if there are characters on the sprite or not, what you have to do is to match the delta values .. when you are doing the floor, it is because you can be 100% sure that the in the line that they are on is equal to 1 .. this is why I calculate the bottom delta from the z-offset, not the other way .. if there was not a character in the sprite for you to use as a reference, then you should get the top and bottom delta from the emulator .. this can be done taking 2 screenshots and calculating how much the top and the bottom moved from the camera, you can use the characters as a reference of the camera, since their deltas are 1 .. though, the delta you get this way is not 100% precise, but when you are making the floor the char line delta IS 100% preciselly equal to 1 ..
--------------------
the above message is ironic in its nature, please ignore it .. sorry for the incovenience ..

Winane | Posted: Jan 21 2003, 12:13 AM
MUGEN Grip Group: Members Posts: 314 Member No.: 122 Joined: 14-September 02
Whoops, thanks for noticing about my Cammy stage's zoffset being wrong. Must've moved it up to test it more easily, then forgot to move it down. It should've been 216 instead of 215. I'll ask Shin ShadowH to upload the fixed version. But your 217 I think is a pixel too low. I figured the zoffset should be set to the middle of the widest part of the characters' shadow. But as the shadows are 2 pixels tall at the widest part, I believe the lower of those two pixels is the correct one to align the zoffset with. In fact, when the zoffset is set to 216 in my stage, the parallax matches the characters' axes absolutely perfectly. I didn't change it to accommodate for bad parallax. I just threw in that comment about adjusting the zoffset to match the parallax in case anyone reading the tutorial was too lazy to get the parallax code just right, so that their stage could at least still look decent despite being a little inaccurate.
Your Chun Li stage looks okay, but since we're talking about accuracy here, I don't believe it's possible to have the parallax be accurate if you don't have the bounds set to -224 and 224.

VIB | Posted: Jan 21 2003, 04:58 AM
Member Group: Members Posts: 51 Member No.: 1457 Joined: 15-November 02
I set the z-offset to line where people to put the axis in their characters, that is the last line where the last pixel of the foot is in most characters of the original game .. so the character foot in mugen would be in the same place it is in the original game ..
I think the bound on my china stage is correct, look how I get the value here: http://www.geocities.com/vibhp/mugen/tuto/...o/chinabnd.html
getting back to the subject =P I think your tutorial is great, I liked it .. it has a lot of information .. a lot of things that I did not know about ripping .. but I think it's too confused, I mean, I can understand what I have to do, but it's hard to figured out why am I doing that .. and it would be hard for someone to solve a problem if he does not understand that he is doing ..
--------------------
the above message is ironic in its nature, please ignore it .. sorry for the incovenience ..

Winane | Posted: Jan 21 2003, 06:30 AM
MUGEN Grip Group: Members Posts: 314 Member No.: 122 Joined: 14-September 02
Ah, but you forget that Mugen's horizontal resolution is lower than Super Street Fighter 2's resolution. Your method for figuring out the bounds would work if they were the same, but they are not. So, you need to add (384-320)/2 to your result. 32+191=223, which is pretty darn close to 224. =P Not sure where that one-pixel error came from, but I'm pretty sure 224 is the correct value to use. For one thing, some other capcom games have a mix of parallax and non-parallax floors, and with the non-parallax ones it's easy to see that 224 is the correct bound, and I would assume they would have used the same bounds for all their stages. Plus, I figured it out for Cammy's stage way back when by finding the row of pixels with delta=1, and counting how many pixels were in that row, which turned out to be 768 (and therefore the bounds would be +-224).
Hm, I guess that makes sense about putting the zoffset down one pixel. After all, most feet have some depth, and I guess the delta should be zero in the middle of the bottom of the feet. I had just figured the zoffset should go on the line where the horizontal delta is zero. But I think I'll leave mine set at 216, though, as I think it looks just fine as is. And after looking at a small variety of characters, it looks to me like the axes vary quite a bit, and in the few cases where the two feet are even on the same level, the axes are one pixel up from the bottom almost as often as they're at the bottom. Nothing wrong with 217 though, I concur.
Good point about not really explaining things much. I'll try to add more explanation when I don't have a ton of homework due right away (i.e. probably sometime in the year 2060, but hopefully this weekend).
And I like your method too, I just suspect (not yet sure, though) that it's inherently slightly less accurate.
Many thanks for all the feedback and stuff.

Winane | Posted: Mar 24 2003, 11:59 AM
MUGEN Grip Group: Members Posts: 314 Member No.: 122 Joined: 14-September 02
(Yes, I know I'm posting twice in a row, and yes, I know I'm bumping an old topic, but it's worth it, gosh darn it.)
Mwahaha! I think I just figured out how to correct my formulas! I thought it seemed rather odd that changing the xscale affected the delta of the top row, and that led me to this:
-Extrapolate what the width of the top row would be if the parallax sprite were one pixel taller. E.g. if the width of each row of sprites is 3 pixels less than the width of the row below it, subtract 3 from the actual top row width.
-For the delta values of the parallax sprite, set it to delta = (extrapolated top width - 320)/448, 1.
-For the xscale values, set it to xscale = 1, ((bottom width - 320)/448)/xdelta. Or alternatively, xscale = 1, (bottom width - 320)/(extrapolated top width - 320).
You might still want to use a little trial and error to get it absolutely dead-on, but using the new formulas, I expect that no row would be off by more than one pixel (rounding errors). (Whereas with the old method, I found that rows would sometimes be off by several pixels at the sides of the stage.)
However, I've only tried this with a couple stages so far. So if anyone could report their own results with the method, either to confirm or refute, it would be much appreciated, especially in cases with very subtle or extreme parallax effects. And does everything work the same with parallaxed ceilings?

« Next Oldest | Development Discussion | Next Newest »

Close Topic Options
Track this topic
Receive email notification when a reply has been made to this topic and you are not active on the board.
Subscribe to this forum
Receive email notification when a new topic is posted in this forum and you are not active on the board.
Download / Print this Topic
Download this topic in different formats or view a printer friendly version.
- M.U.G.E.N Development Forum - Contact an admin - ELECBYTE - Shin Mugen -
Powered by Invision Power Board(U) v1.2 © 2003 IPS, Inc.