Solved When do you NOT use NULL with changedrawmethod? Screens question

Question that is answered or resolved.

ipkevin

Member
So I finally dug into scripting to try to make use of screens, but I'm confused about a few things:

1. Changedrawmethod (and Setdrawmethod) functions always on NULL()

In practice, do the above drawmethods always use NULL() for the scr parameter? The reference manual says they can be applied to any entity, but I tried to apply them to both a sprite and a separate screen containing that sprite (followed by drawing them to the main screen), but that resulted in highly distorted or non-existent image. Is that normal? If it is, then when would you ever use drawmethods on other kinds of entities besides the main screen / NULL?
I looked at both Damon Caskey's World Heroes Timeless airship scripts and the Avengers United Battle Force zoom scripts and they both seem to use drawmethods with NULL() only.
And how come changing a changedrawmethod(NULL) property only affects the thing you're drawing to the screen and not the rest of the main screen?


2. Referencing things created from a file / Entity pointers

I would like to get the handle/reference to a background layer that I created with the bglayer command in the level's txt file. Is that possible? Or do I need to skip the txt file entirely and manually loadsprite the image from within the script?
Essentially, I have an affine bglayer that I want to stack 20x with each layer separated by 1px of z height. I tried to do that purely thru bglayer commands in the level's txt file, but the whole game became unplayably slow. So I thought I could use screens to just redraw that bglayer 'entity' (?) 20x without having to calculate the affine effect on each new one. But I don't seem to be able to find the reference to that bglayer from the script. Is that possible? (All openbor docs are painfully thin on the sprite/entity arrays as well)

And what do you think would be the best way to repeat an affine layer 20x without slowing down the game?


3. Why is everyone using drawspriteq and drawscreenq when those functions aren't even in the manual? Is there something better?
 
Last edited:
Solution
I have leaving for the evening so I can't answer in full detail, but I can explain the NULL() issue.

I looked at both Damon Caskey's World Heroes Timeless airship scripts and the Avengers United Battle Force zoom scripts and they both seem to use drawmethods with NULL() only.

To modify drawmethod properties to pretty much anything other than entities, you need to use the global drawmethod. It just happens that to target the global drawmethod you pass NULL() as the entity parameter. Once you draw the item or place it in a screen, you reset immediately after to restore the globaldrawmethod for the next item in sprite que.

And how come changing a changedrawmethod(NULL) property only affects the thing you're drawing to the...
I have leaving for the evening so I can't answer in full detail, but I can explain the NULL() issue.

I looked at both Damon Caskey's World Heroes Timeless airship scripts and the Avengers United Battle Force zoom scripts and they both seem to use drawmethods with NULL() only.

To modify drawmethod properties to pretty much anything other than entities, you need to use the global drawmethod. It just happens that to target the global drawmethod you pass NULL() as the entity parameter. Once you draw the item or place it in a screen, you reset immediately after to restore the globaldrawmethod for the next item in sprite que.

And how come changing a changedrawmethod(NULL) property only affects the thing you're drawing to the screen and not the rest of the main screen?

The main screen ignores most drawmethod settings for various reasons I don't have time to get into. That's why you use screens for a full screen zoom.

So I thought I could use screens to just redraw that bglayer 'entity' (?) 20x without having to calculate the affine effect on each new one. But I don't seem to be able to find the reference to that bglayer from the script. Is that possible?

First, stop using bglayers. It's a legacy feature long since replaced with fglayer. Fglayer gives you Z layer control, which you are going to need. You can't reference a layer directly like you would an entity, but you can reference sprite in a given Z range. So all you do is grab the Z range your layer is in. The math that determines Z position of a layer is rather complex, so it can take some experimentation to get it right.

For instance, the clouds in this video use a screen to give them an affine effect moving toward the player while also having left/right scrolling. In text the Z layer is set to -400, but to capture the layer for drawing its sprite to screenque I am getting -85 (see drawspriteq() below).


Using screens to redraw the layer isn't a bad idea at all.

Why is everyone using drawspriteq and drawscreenq when those functions aren't even in the manual? Is there something better?

It's called Legacy Manual for a reason. It's the best overall resource, but it doesn't have everything, and a lot of things it does have are out of date. It simply isn't possible to have a single 100% comprehensive resource that stays fully up to date. That's why we have a wiki and this forum.

drawspriteq(<screen>, <new sprites only>, <z min>, <z max>, <offset x>, <offset y);

This function grabs everything between <Z min> and <z max> and draws it to <screen>. It's super handy for capturing areas of the screen for things like zoom or insets, and it's the only way at all to capture layers.

DC
 
Solution
Thank you, Damon! That was hugely helpful for all points. My understanding of openbor scripting has grown so much in one day already.

For instance, the clouds in this video use a screen to give them an affine effect moving toward the player while also having left/right scrolling. In text the Z layer is set to -400, but to capture the layer for drawing its sprite to screenque I am getting -85 (see drawspriteq() below).


Using screens to redraw the layer isn't a bad idea at all.

Whoa, the entire effect of that stage is incredibly impressive. How was the cloud moving toward player effect accomplished? Is that like progressively displaying a different portion of a larger cloud image while applying an affine effect?
 
How was the cloud moving toward player effect accomplished? Is that like progressively displaying a different portion of a larger cloud image while applying an affine effect?

It's much simpler than that. The cloud is a normal layer auto-scrolling vertically, hidden from view. The screen captures it and applies an affine transform almost identical to the native "watermode" available for layers, and that's it. You can see how it works in another prototype video. There's a portion of the sky layer partially exposed.


...and what it looks like with a bit more progress and layers hidden properly...

 
That's brilliant! So simple and effective. But now you've made me curious about the tree sidewalls. Their horizontal movement seems like it's in-sync with the ground's affine transformation, but obviously they are not being transformed themselves. I thought maybe a bunch of layers (eg, a strip with a tree on each side) with different xratios, but that doesn't explain how they are scrolling vertically infinitely. How was that all done??
 
The trees are just ordinary entities. There's a script function that continuously spawns the tree entities, moves them toward the player's viewpoint at appropriate speed, and destroys them once they pass by.

Another function checks the Z position of all entities on screen and applies drawmethod to scale them accordingly. It's easier to see in these development progress videos:



DC
 
Ah, I see! It's also clear in the new vids that I was wrong about the trees' horizontal mvmts being in sync with the ground affine layer. So much to learn! :) Anyways, thanks again. Marking this as solved.
 
Yeah, they're not in sync at all. They will be in the finished version, but that will require some script control of X axis positions.

DC
 
Back
Top Bottom