Twilight Princess like effect: need of dynamic sprites?

Started by abstauber, Thu 06/11/2008 10:24:44

Previous topic - Next topic

abstauber

Hi there,
first of all, if there's a tutorial about raw drawing in AGS 3.x I'm willing to read it and try again ;)

If you don't know the game, here's a screenshot showing what in a way I'll like to mimic.

courtesy of ign

This is basically the effect, I just want to use it one the whole screen in this way.

Repeatly execute {
- looking for a random pixel on the screen
- check if the pixel is black
- if the pixel is black, move the pixel to the top while fading out
}

What would be the best approach? Putting the pixel on an overlay and move it?
Drawing the pixel on the background and for the movement restoring the screen and drawing the pixel somewhere else? I'm a little lost here  ::)

Thanks for your help!



DoorKnobHandle

In that shot it only seems to affect one model - if you want the same (have that effect for one character/sprite only), couldn't you just draw a nice animation and use that?

EDIT: You say you want it on the whole screen but that would be very similar to the transitions that AGS comes with...

Khris

Are you going to use that effect on a singular object/character?

Ghost

abstauber said it: The effect  shown in the screenshot, but applied to the whole screen- I think this would defenitely look awesome...

You're going to need a dynamic sprite and paste a screenshot of the current game screen on it, that's for sure- that's the simplest way to affect everything on the screen, characters etc... you may also want to disable all GUIs before you take this screenshot, otherwise they will be affected to... So, "make a screenshot", and then "manipulate this screenshot" and "paste it to screen"...

Now the best way to do all that pixel drawing, I'm lost there. I think you should use a small (5x5, for example) black sprite instead of a single pixel to save some performance. Rawdraw seems to be the best way but would cost you dear, even with a 320x240 resolution.

abstauber

Actually I somehow want it both, I just didn't want to bother you with all details ;)

For single objects/characters, it would be really cool to have a dissolve effect, just like on the screenshot:
pixels, which detach from the sprite, rise and fade out.

For the fullscreen effect, imagine an underwater scenery, with bubbles rising to the surface. So the pixels don't get removed but only rise from places where the underlying pixel is black.
And since I don't want to use it underwater, it should give the scene a nice surrealistic look.

But back to technique on how to archive this. Do I get you right: (?)

- take a screenshot
- Draw my pixel on it
- Update the background
- Take a new screenshot
- remove my old pixel
- set a new one with a lower y-coordinate
- update the background and so on?

Would this be quite slow and result in flickering?

Ghost

You got me right, and I *do* think it would be terribly slow. Not too sure, though.

But, an idea: Why not create a single object of, say, screen's height*2 and screen's width, and make it look like this:



Then, instead of the whole screen capture / draw / refresh thing, just align the object's top with the bottom of the screen, make it visible, and then make it scroll from the bottom to the top. You'll defenitely gain speed with that method, and the effect looks quite nice too (I just tried it)- not exactly what you wanted of course, but a rather similar look.

abstauber

Nice workaround,  upside-down-rain would also work (SSH's rain module a little tweaked) :D

But still, this won't help me on a dissolve and won't teach a thing ;)

SSH

To be honest, I think the generic approach will be too CPU-intensive and you're better creating an animation manually. I bet that your game doesn't actually require that many things to dissolve...

But if you really want to, the latest AGS has a DynamicSprite Getpixel function that couild form the basis of this. You want to scan along the dynamic sprite line by line. Each line you then "explode" into a larger sprite a few pixels high to represent small delays between different pixels going up, then put that sprite on an overlay and move it up the screen (don't forget to modify the dynamic sprite to take out the moving pixel line, too). You'd have to make the dissolving sprites move fast enough that you don't run out of overlays.

A "re-solve" as opposed to dissolve would just work the same way, but backwards.

Other possibilities are to have multiple versions of the exploded sprite where you make the pixels move further out from their original position, or rotate somewhat or something to give a different visual effect.
12

abstauber

Quote from: SSH on Thu 06/11/2008 12:53:01
I bet that your game doesn't actually require that many things to dissolve...
Yup ;)

So far I've played a little with the simple rain module (SSH) and the lake module(SteveMcRea) - I can hardly imagine that my effect would consume more CPU power...

edit:
@SSH: haven't seen your update while writing these lines.  Hmm.. so I might really draw the dissolves for the sprites myself. But thanks for this explanation :)

Generally - if I want to move raw stuff, I have to create a dynamic sprite, put it on an overlay and move that?

SSH

Quote from: abstauber on Thu 06/11/2008 13:02:49
Generally - if I want to move raw stuff, I have to create a dynamic sprite, put it on an overlay and move that?

Yes. It may be worth having a look at the Credits module, which uses overlays for scrolling credits.
12

abstauber

Allright, I'll look into that. Thanks!

Btw. someone should really write a tutorial about this :)

Khris

Here we go:
http://db.tt/kYM6Ix9

ToDo
- add more options
- add object support
- add non-blocking version
- fix crash when height is considerably bigger than the sprite

Usage:
In game_start or at least before using it, call SetDissolveParams(height); where height should be something between 50 and 300 (determining how far above the character the particles will disappear).

Then call Character.Dissolve(blocking), e.g.
player.Dissolve(eBlock);
Currently, it'll always block the game.
Note: dissolving a character will leave them with their .Transparency set to 100.

EDIT:
version 0.2 up
-dissolving sprite is no longer an overlay but the actual viewframe thus walk-behinds etc. work now

EDIT:
This is still buggy, use at your own risk!
Set the height to charactersize x 2 for best results.

EDIT:
Fixed link

STILL BUGGY!! DO NOT USE :)

Ghost

Khris- superb work! A tiny bug report, though: I called player.dissolve after a cut-scene, placed in a room's "after_fadein" section, and got:



Obviously I used a too great "height" setting, but still...

Amazing work.

Khris

Thanks! :)

The thing is, right now, if the character sprite is, say, 100 pixels tall and height is set to 80, the top 20 pixels of the sprite aren't being dissolved.
If height is too big though, it gets stuck in the loop. I'll probably fix this during the weekend.

Ghost

My character's 62 pixels tall, and the error came up with SetDissolveParams(124); still, this doesn't dull your triumph- the speed and functionality of your module is amazing. One day I'll learn some proper scripting magic- your code looks like some arane runes ;)

I still don't believe you about the 30000+ lines for Metroid, though  :=

abstauber

Awesome!! Thanks a million, can't wait to try this out.  :=

@Ghost: So you were also looking for this effect  ;)

SMF spam blocked by CleanTalk