showing attack effect with alpha(light, trace of sword, etc)

  • Thread starter Thread starter doranikofu
  • Start date Start date
D

doranikofu

Guest
just curious to see if anyone has smart ideas of applying attack effects with transparency.

I'm doing it with the stupid way by using throwframe

Basically I make a “none" type entity for the attack effect with "nomove", in this case showing in the pic it is the trace of the sword.
Then I set the idle animation and match the frames in the attack animation (also matching with start throwing frame).
It works fine but kinda tedious. The downside is that only one throwing entity can be used. If I need to make a magic attack throwing a fire ball, I can't add effect on the player with another "knife" entity.
Also it gets tricky if the character is moving during the animation. Need to offset the "knife" animation accordingly to match.

Normally the effect is already included in the animation gif image. But if I want to use the effect with alpha I can't do this because the character has different transparency settings.

maybe someone has better ideas? :)


[attachment deleted by admin]
 
I suggest you to call that effect by script, so you don't need to care with throwframe, knife, etc.
plus, if you call it using a function with bindentity, you will need just one entity for all the effects from your character.
 
O Ilusionista said:
I suggest you to call that effect by script, so you don't need to care with throwframe, knife, etc.
plus, if you call it using a function with bindentity, you will need just one entity for all the effects from your character.

This. Technically, you could leave the effect drawn into the main sprite and use alpha channels, but I only mention that for posterity. It's just about the worst thing you could do.

I get to claim being the first OpenBOR author to have created transparent motion trails - had em' even before there was script (waves for applause). Seriously though, it's easy money. As O-Ill said, bind a second entity by animation. I also prefer to bind by frame. This way the main entity has full control, if say - you get hit while attacking, the blur doesn't stay on screen.

Here's a sample from the main entity. Bind0003 is a script function that spawns the effect entity at the same X and Y location, and 1 pixel in front. This allows the blur to pass in front of main entity if I want. If it passes behind, I'll have just drawn it with a shaped blank spot. Once spawned it is immediately bound by frame, with "kill on no match" option turned on. What this means is that if OpenBOR cannot match the animation and frames, it kills the bound entity immediately. That takes care of animation switching, combos, and interruptions for us:

Code:
anim  attackboth

	flipframe  12
	jumpframe  3  2.8  0  0 jumpm
	dropframe  10
	landframe  23 landm

	offset  60  98
	bbox  42  50  29  48
	delay  6
		frame  data/chars/ax/a21.png
	@cmd	bind0003 "ax0001" "blur" -1 1 0 0 1 1 7
	@cmd	soun0005 ENT_SELF SND_WIFFM -1 1 0 0
	@cmd	soun0005 ENT_SELF VOI_ATK -1 1 0 0
		frame  data/chars/ax/a23.png
		frame  data/chars/ax/a25.png
	delay	2
	attack10  64  27  33  58  8  1
	bbox  52  39  19  57
		frame  data/chars/ax/0096.png
		attack10  64  27  33  58  4  1
		frame  data/chars/ax/0096.png
		frame  data/chars/ax/0096.png
		frame  data/chars/ax/0096.png
		frame  data/chars/ax/0096.png
		frame  data/chars/ax/0096.png
	delay  -1000
		frame  data/chars/ax/0096.png
	delay  5
		Attack1  0
		frame  data/chars/ax/0036.png
		frame  data/chars/ax/0037.png
		frame  data/chars/ax/j2.png
	@cmd	soun0005 ENT_SELF SND_WIFFL -1 1 0 0
	@cmd	soun0005 ENT_SELF VOI_ATK -1 1 0 0
		frame  data/chars/ax/j3.png
	delay	1
	bbox  50  51  33  47
	attack10  72  39  39  59  8  1
		frame  data/chars/ax/ja3.png
	Attack1  0
		frame  data/chars/ax/ja3.png
		frame  data/chars/ax/ja3.png
		frame  data/chars/ax/ja3.png
		frame  data/chars/ax/ja3.png
		frame  data/chars/ax/ja3.png
		frame  data/chars/ax/ja3.png
		frame  data/chars/ax/ja3.png
	delay  -1000
		frame  data/chars/ax/ja3.png
	delay  6
	bbox  44  51  33  46
		frame  data/chars/ax/land.png
	bbox  46  41  27  58
		frame  data/chars/ax/j1.png

The bind0003 function. Needs updating but still does its job...

Code:
#include "data/scripts/vars/constants.h"	//http://www.caskeys.com/dc/?p=1314#constants
#import "data/scripts/com/draw0001.h"
#import "data/scripts/com/draw0002.h"

void bind0003(void vModel, int vAlias, int iMap, int iBlend, float fX, float fY, float fZ, int iDir, int iAniFlag){
	
    /*
    bind0003
    Damon Vaughn Caskey
    02/25/2008
	2008_02_25
	~2011_05_17
    Spawn an entity and then bind it to caller; primarily special effects.

    vName:      Model name of spawn.
    vAlias:     Display name of spawn. 
    vMap:       Color map of spawn.
    iBlend:     Transparency setting of spawn. 
    fX, fY, fZ: Location offset of binding.
    iDir:       Direction - 0 = no change, 1 = same target, -1 = opposite of target,  2 = right, -2 = left.
    iAniFlag:   See http://www.lavalit.com/index.php?topic=963.msg14445#msg14445
    */
    
    void  vSpawn;
    void  vSelf  = getlocalvar("self");                                     //Caller.
    void  vBinde = getentityvar(vSelf, IDXE_BINDE);                              //Previous bound entity.
    float fRatio = getentityvar(vSelf, IDXE_ADSCALER);                           //Caller's current scale ratio.
    int   iX     = getentityproperty(vSelf, "x") - openborvariant("xpos");  //Caller X location.
    int   iZ     = getentityproperty(vSelf, "z");                           //Caller Z location.
    int   iY     = getentityproperty(vSelf, "a");                           //Caller Y location.
    void  vAT	 = NULL();

    if (vBinde && getentityproperty(vBinde, "exists"))                      //Previously bound entity in place?
    {
        if (getentityproperty(vBinde, "name") == vAlias)                    //Alias of previous same as new?
        {
            killentity(vBinde);                                             //Kill previous.
        }
    }      
    
    clearspawnentry();                                                      //Clear current spawn entry.
    setspawnentry("name",   vModel);                                        //Aquire spawn entity by name.
    setspawnentry("alias",  vAlias);                                        //Set alias.
    setspawnentry("map",    iMap);                                          //Set color remap.
	setspawnentry("coords", iX, iZ, iY);                                    //Spawn location.
    vSpawn = spawn();                                                       //Spawn entity.
    clearspawnentry();                                                      //Clear current spawn entry.
        
    setentityvar(vSelf, IDXE_SPAWN, vSpawn);                                     //Store spawn into last spawn variant.
    setentityvar(vSelf, IDXE_BINDE, vSpawn);                                     //Store into bind variant.

    changeentityproperty(vSpawn, "parent", vSelf);                          //Set caller as parent of spawn.
    
	if(iMap == -1)															//Map "-1"?
	{
		vAT = getentityproperty(vSelf, "colourmap");						//Set vMap to callers current table.
		//setdrawmethod(vSpawn, 1, 256, 256, 0, 0, 0, iBlend, 0, 0, 0, 0, 0, vAT);		
		changedrawmethod(vSpawn, "table", vAT);	
		changedrawmethod(vSpawn, "alpha", iBlend);
	}
	else
	{
		changeentityproperty(vSpawn, "alpha", iBlend);							//Set transparency property.
	}

    if (fX){ fX = draw0002(fRatio, fX); }                                   //If X bind, apply scaling to fX.
    if (fY){ fY = draw0002(fRatio, fY); }                                   //If Y bind, apply scaling to fY.
        
    bindentity(vSpawn, vSelf, fX, fZ, fY, iDir, iAniFlag);                  //Execute bind.	
	
	draw0001(vSpawn);                                                       //Update draw for spawn.

    return vSpawn;                                                          //Return spawned entity.
}

And here's the same move from main entity in the effect file. Blan0001 is just a blank image for spots when there's no effect. There's one last extra frame with a kill command to make 100% certain the effect entity is destroyed. As above, bind should always do this, but there are rare special cases it might fail, so I like to have a failsafe.

Code:
anim attackboth
	
	delay	-1000
	offset  60  99
	
		frame  data/chars/ax/a21.png
		frame  	data/chars/ax/effects/0036
		frame  	data/chars/ax/effects/0037
	
		frame  	data/chars/ax/effects/0107
		frame  	data/chars/ax/effects/0108
		frame  	data/chars/ax/effects/0109
		frame  	data/chars/ax/effects/0110
		frame  	data/chars/ax/effects/0111
		frame  	data/chars/ax/effects/0112
	
		frame	data/chars/misc/blan0001
	
		frame	data/chars/misc/blan0001
		frame	data/chars/misc/blan0001
		frame	data/chars/misc/blan0001
		frame  	data/chars/ax/effects/0066
	
		frame  	data/chars/ax/effects/0067
		frame  	data/chars/ax/effects/0068
		frame  	data/chars/ax/effects/0069
		frame  	data/chars/ax/effects/0070
		frame  	data/chars/ax/effects/0071
		frame  	data/chars/ax/effects/0072
		frame  	data/chars/ax/effects/0073
		frame  	data/chars/ax/effects/0074
		frame	data/chars/misc/blan0001
	@cmd	killentity getlocalvar("self")
		frame	data/chars/misc/blan0001

And here's the end result. Pay attention to Ax Battler's sword swings and other weapon attacks.

http://youtu.be/JossdCHwwIw

[attachment deleted by admin]
 
Thanks a lot for the reply. It looks quite good.
I tried to put it in my project but I have some issues.
I put in the scripts from your webpage into my project but I'm getting compiling errors
http://www.caskeys.com/dc/?p=1314
#include "data/scripts/vars/constants.h"
#import "data/scripts/com/draw0001.h"
#import "data/scripts/com/draw0002.h"



The error message  is (omitted middle part)

Script compile error in '#import': ADSCALEX line 50, column 39
Script error: unable to import script file '#include "data/scripts/vars/constants.h" //http://www.caskeys.com/dc/?p=1314#constants
#include "data/scripts/com/draw0002.h" //http://www.caskeys.com/dc/?p=1314#draw0002

void draw0001(void vEnt){
.......omitted.......

    setdrawmethod(vEnt, 1, fScaleX, fScaleY, iFlipX, iFlipY, iShiftX, -1, -1, iFill, iRotate);  //Set final values to drawmethod.
}

'

********** An Error Occurred **********
*            Shutting Down            *

Can't compile script!


Maybe I just missed some script file. I tried to click on some links on your page but they expired(mostly the ones linked out to other places, http://www.caskeys.com/dc/?p=1314) I'm not clear what the dependency is between the all the files on the site but seems like most of them are only needed for specific use.

Sorry those might be stupid questions, I'm quite new to this engine(started the project ~1week ago). I used to make RPG with RPGMaker but not a professional programmer(knows some basics). When I was making RPG games I really like how they have downloads with very simple functions: either those only using commands offered by default in the engine or using advanced scripts to achieve on single goal. The good thing is that those sample projects are quite independent so it is easier for amateur to assemble a number of them together into his/her own project. I understand all those require hard work, but not sure if I missed something already posted here. I saw quite a number of tutorials here but I seem to miss the basics of how to connect and apply those things into a project.
 
found the problem...
the constants are defined with "IDXE_" as prefix, so all the name needs to be updated.

The other thing is that the #import does not seem to work. The compiler does not recognize the draw function until I change it to #include.

Now the game can be loaded, but when I test the attack animation I got the other error

Script function 'getentityvar' returned an exception, check the manual for details.

OpCode: 8

OpCode: 8

********** An Error Occurred **********
*            Shutting Down            *



it fixed after I put a script.txt file under data folder....lol
the script is working now, but I need to figure out the display. currently the picture is showing somewhat weird transparency and it stays even the attack animation is finished...
 
setup the color map and scaling, my effect gif is 100% and character is 75% with different colormap. Now everything works

One thing I do not completely understand is the last parameter
bindentity(vSpawn, vSelf, fX, fZ, fY, iDir, iAniFlag);

~bindanimation: 0 No effect. 1 Keep same animation as the target. 2 Also keep same frame as the target. 4 Kill the entity if the animation doesn't match.
~To unbind a entity, use bindentity(entity, NULL());
~Notice: You can combine those values for bindanimation, so it can be 6 which means 2 and 4.

does 7 mean 1+2+4? Not sure how this works but does it mean the effect entity has to match the character with exact animation name, frame number and frame delay settings?

Thanks again for the script :)
 
I saw quite a number of tutorials here but I seem to miss the basics of how to connect and apply those things into a project.
Not that true. There are many links speaking of almost every aspect of the basics. Applying scripts, bindentity, for example, are covered in both tutorials and on the manual.

does 7 mean 1+2+4? Not sure how this works but does it mean the effect entity has to match the character with exact animation name, frame number and frame delay settings?
Probabily, yes. Or won't make much sense to have a frame comparison without an animation comparison.
 
doranikofu said:
does 7 mean 1+2+4? Not sure how this works but does it mean the effect entity has to match the character with exact animation name, frame number and frame delay settings?

All but delay. Delay doesn't matter, since the bound entity will be forced to play same frame as the main entity. As a matter of fact, you'll usually want an infinite delay on the secondary entity so it doesn't move to the next frame before the main entity tells it to (that's why you see the -1000).

Good job figuring out the dependencies and adapting. I had only meant those to be an example, but looks like you rolled with it and made them work for you. Nice!

Also FYI, #import and #include are similar on the surface, but they do very different things.

#Import only brings in the function definitions, and makes sure to only bring them in once (if there is a duplicate, the latest #import wins). This makes #import a much, MUCH more memory efficient choice when you can use it.

#Include copies in the file verbatim, and doesn't care what's there already or not. It's best for things #import won't work with, like constants and macros.

One last FYI, stop using .gif before you get too deep in your project. OpenBOR supports 8-bit mode .png for sprites.

DC
 
O Ilusionista said:
I saw quite a number of tutorials here but I seem to miss the basics of how to connect and apply those things into a project.
Not that true. There are many links speaking of almost every aspect of the basics. Applying scripts, bindentity, for example, are covered in both tutorials and on the manual.

does 7 mean 1+2+4? Not sure how this works but does it mean the effect entity has to match the character with exact animation name, frame number and frame delay settings?
Probabily, yes. Or won't make much sense to have a frame comparison without an animation comparison.

yeah now that I know a little more basics, the manual becomes much more helpful. I feel the first step of getting into this is difficult
 
Damon Caskey said:
doranikofu said:
does 7 mean 1+2+4? Not sure how this works but does it mean the effect entity has to match the character with exact animation name, frame number and frame delay settings?

All but delay. Delay doesn't matter, since the bound entity will be forced to play same frame as the main entity. As a matter of fact, you'll usually want an infinite delay on the secondary entity so it doesn't move to the next frame before the main entity tells it to (that's why you see the -1000).

Good job figuring out the dependencies and adapting. I had only meant those to be an example, but looks like you rolled with it and made them work for you. Nice!

Also FYI, #import and #include are similar on the surface, but they do very different things.

#Import only brings in the function definitions, and makes sure to only bring them in once (if there is a duplicate, the latest #import wins). This makes #import a much, MUCH more memory efficient choice when you can use it.

#Include copies in the file verbatim, and doesn't care what's there already or not. It's best for things #import won't work with, like constants and macros.

One last FYI, stop using .gif before you get too deep in your project. OpenBOR supports 8-bit mode .png for sprites.

DC
thanks, I'm curious to see what is the benefit of using png? I'm guessing it still needs to be index color?
 
Back
Top Bottom