Jump to content

Gamemaker Studio Implementation Issues


hippyman

Recommended Posts

@hippyman
        

        // prefix 'parent' is the parent's absolute values that have already been transformed
        // prefix 'child' is the local child values you tweened from the keys before they've been transformed)
        // prefix 'absolute' is the final absolute values of the child object - the result of the transform
        

        absoluteScaleX=childScaleX*parentScaleX;
        absoluteScaleY=childScaleX*parentScaleY;


        if(parentScaleX*parentScaleY < 0)
        {
            absoluteAngle=-angle;
        }
        else
        {
            absoluteAngle=angle;
        }

        absoluteAngle+=parentAngle;


        float childScaledX=childX*parentScaleX;
        float childScaledY=childY*parentScaleY;

        float angleSin=sin(parentAngle);
        float angleCos=cos(parentAngle);
        
        absoluteX=(childScaledX*angleCos)-(childScaledY*angleSin);
        absoluteY=(childScaledX*angleSin)+(childScaledY*angleCos);


        absoluteX+=parentX;
        absoluteY+=parentY;
        
        
        absoluteAlpha=childAlpha*parentAlpha;

 

Link to comment
Share on other sites

*Quick note - Sorry for the wall of text. I didn't expect to write this much. It just kind of happened....*
Project GMZ file - Download this and import it into Gamemaker Studio if you'd like to see the whole project (be warned, it's a mess right now)

 

Well I think I'm having either an issue with drawing bones or I'm referencing the wrong things because it didn't really change much. I think I need to take another stab at my entity instance object. I know that I have it working up to the point where I find a mainline key from time. After that, things get a little unsure. I pass the mainline key to a script that is supposed to update the frame data.

Frame data follows this hierarchy

FrameData - ds_map
    CurrentFrames - ds_list
    NextFrames      - ds_list

Frames - ds_map
    Type
    X,Y,Angle,ScaleX,ScaleY,Alpha,Spin (spatial info)

CurrentFrames and NextFrames store a frame for each timeline. Next frames are obviously used for interpolating, but first I need to get the values right.

Here's the actual mess of code that makes up the frame update script

Quick note if you're not familiar with GML
When you see [?"key"], that's an accessor to get a value from a map data structure.
When you see [|number], that's an accessor to get a value from a list data structure.
Link to official GMS documentation

//Loop through bone refs in this mainline
for (var i = 0; i < boneRefCount; ++i) {
    var boneRef     = boneRefs[|i];			//get current bone ref
    var parent      = boneRef[?"parent"];		//get bone ref parent id
    var timelineID  = boneRef[?"timeline"];		//get bone ref timeline id
    var keyID       = boneRef[?"key"];			//get bone ref key id
    var timeline = spriter_get_timeline_by_id(currAnim,timelineID);				//get the actual timeline
    var currKey = spriter_get_timeline_key_by_id(timeline,keyID);				//get actual current key
    var nextKey = spriter_get_timeline_key_by_id(timeline,++keyID);				//try to get next key
    if (nextKey == noone) nextKey = spriter_get_timeline_key_by_id(timeline,0);			//if current key is the last key get first key
    
    //I haven't started updating next key frames yet
    //I need to get current keys working first then I can do the same for next keys
    
    var currFrame = currFrameList[|timelineID];//get current frame from current frame list
    currFrame[?"type"] = timeline[?"type"];//set current frame type (bone,image,box,etc)
    
    //The reason I check if these exist is because, when parsing, sometimes the scml file doesn't have these values
  	//If I don't I'm sure to get an undefined error
    if (ds_map_exists(currKey,"x"))        currFrame[?"x"]         = currKey[?"x"];
    if (ds_map_exists(currKey,"y"))        currFrame[?"y"]         = currKey[?"y"];
    if (ds_map_exists(currKey,"angle"))    currFrame[?"angle"]     = currKey[?"angle"];
    if (ds_map_exists(currKey,"scale x"))  currFrame[?"scale x"]   = currKey[?"scale x"];
    if (ds_map_exists(currKey,"scale y"))  currFrame[?"scale y"]   = currKey[?"scale y"];
    if (ds_map_exists(currKey,"alpha"))    currFrame[?"alpha"]     = currKey[?"alpha"];
                                           currFrame[?"spin"]      = currKey[?"spin"];
    
    var px,py,pscalex,pscaley,pangle,palpha;
    if (parent == noone) {//if this is the root bone, set parent spatial info to same as character info (stored in instance)
        px = characterInfo[?"x"]
        py = characterInfo[?"y"];
        pscalex = characterInfo[?"scale x"]
        pscaley = characterInfo[?"scale y"];
        pangle = characterInfo[?"angle"];
        palpha = characterInfo[?"alpha"];
    } else {//else if this is a child bone
        var parCurrFrame = currFrameList[|parent];//get the frame data from parent bone by parent id found in boneRef
        px = parCurrFrame[?"x"]//set parent spatial info to same as parent frame
        py = parCurrFrame[?"y"];
        pscalex = parCurrFrame[?"scale x"]
        pscaley = parCurrFrame[?"scale y"];
        pangle = parCurrFrame[?"angle"];
        palpha = parCurrFrame[?"alpha"];
    }
    
    //Then the code you gave me to map out the absolute values
    currFrame[?"scale x"] *= pscalex;
    currFrame[?"scale y"] *= pscaley;
    if (pscalex * pscaley < 0) {
        currFrame[?"angle"] *= -1;
    }
    currFrame[?"angle"] += pangle;
    
    var childScaledX = currFrame[?"x"]*pscalex;
    var childScaledY = currFrame[?"y"]*pscaley;
    
    var angleSin = sin(degtorad(pangle));
    var angleCos = cos(degtorad(pangle));
    
    currFrame[?"x"] = (childScaledX*angleCos)-(childScaledY*angleSin);
    currFrame[?"y"] = (childScaledX*angleSin)+(childScaledY*angleCos);
    currFrame[?"x"] += px;
    currFrame[?"y"] += py;
}

 

Am I possibly finding the incorrect parent or something? I updated the bone draw script to find the current bones length and now the gif looks like this. I went ahead and put it next to the actual Spriter project so you can see the game version in relation to what it should be. You may notice that the arms seem to be correct but they're switched and it also looks like the whole object is turned on it's side. Aside from a random bone that seems to go all over the place as I move the entity instance.

 

spriter_animtest2.gif?dl=0

spriter_example_lonebone.gif?dl=0

Here's code that draws the bones out

var bones = instance[?"bones"]//get entity bone info
var characterInfo = instance[?"character info"];
var cx = characterInfo[?"x"];
var cy = characterInfo[?"y"];
var j = 0;
for (var i = 0; i < currKeyCount; ++i) {//loop through all current frame list keys
    var currKey = currKeyList[|i];//get current key frame
    
    if (currKey[?"type"] == "bone") {//if this is a bone
        var bone = bones[|j++];//I use j since bones come after images in the timelines
        var x1 = currKey[?"x"]+cx;
        var y1 = currKey[?"y"]+cy;
      	//lengthdir_* function equivalents
      	/*These are GML functions
        	lengthdir_x(len,dir) -- value = cos(degtorad(dir))*len
            	lengthdir_y(len,dir) -- value = -sin(degtorad(dir))*len
        */
        var x2 = x1+lengthdir_x(bone[?"width"],currKey[?"angle"]);
        var y2 = y1+lengthdir_y(bone[?"width"],currKey[?"angle"]);
        draw_circle(x1,y1,4,false);
        draw_line(x1,y1,x2,y2);
    }
}

Sorry the huge dump of code I'm just really note sure what I'm doing wrong. I'm just a little overwhelmed and could really use a second pair of eyes. If you need anymore info please let me know and I'll add it right away. If I'm over-complicating things then please tell me how I can simplify this a little bit.

Link to comment
Share on other sites

  • 6 months later...

There is one serious issue that i have figured out. My spriter project runs well when i use it in Gamemaker studio v1.4 without creating a single texture page for all the images. However, whenever i generate a texture using "Generate spritesheet for project images" and then run it into gamemaker the position of the images get changed and my animations get badly messed up. Why gamemaker fails to detect the correct x and y positions after making a spritesheet? Please help me!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...