Jump to content
A 2021 backup has been restored. Forums are closed and work in progress. Join our Discord server for more updates! ×
SoaH City Message Board

Crumbling Platforms in GM7


OverbounD

Recommended Posts

So I've been trying to make platforms that break apart when you step on them but I seem to be having trouble. They work sometimes but the left and right crumbling platforms seem to interfere with how the other works even though they don't share any variables or relevant objects. Here's my code though if someone has a better way to do it I'm all ears as I'm not the greatest coder in the world.

the platform starts as one big object and once Sonic steps on it splits with the code below:

// ==== FUNCTION ====================================================================
// scrPlayerHandleObjectFallingCliffLeft()
// ==================================================================================
//

_ObjectHandle = instance_nearest(x, y, objFallingClifLeft);
//if(_ObjectHandle != noone)
//{
if (scrPlayerCollisionBottomObject(sprPlayerMask15, 1, _ObjectHandle))
{
xCliffDropL = _ObjectHandle.x
yCliffDropL = _ObjectHandle.y

cliffL1 = instance_create(xCliffDropL+256,yCliffDropL,objFallingCliffPiece);
cliffL2 = instance_create(xCliffDropL+240,yCliffDropL,objFallingCliffPiece);
cliffL3 = instance_create(xCliffDropL+224,yCliffDropL,objFallingCliffPiece);
cliffL4 = instance_create(xCliffDropL+208,yCliffDropL,objFallingCliffPiece);
cliffL5 = instance_create(xCliffDropL+192,yCliffDropL,objFallingCliffPiece);
cliffL6 = instance_create(xCliffDropL+176,yCliffDropL,objFallingCliffPiece);
cliffL7 = instance_create(xCliffDropL+160,yCliffDropL,objFallingCliffPiece);
cliffL8 = instance_create(xCliffDropL+144,yCliffDropL,objFallingCliffPiece);
cliffL9 = instance_create(xCliffDropL+128,yCliffDropL,objFallingCliffPiece);
cliffL10 = instance_create(xCliffDropL+112,yCliffDropL,objFallingCliffPiece);
cliffL11 = instance_create(xCliffDropL+96,yCliffDropL,objFallingCliffPiece);
cliffL12 = instance_create(xCliffDropL+80,yCliffDropL,objFallingCliffPiece);
cliffL13 = instance_create(xCliffDropL+64,yCliffDropL,objFallingCliffPiece);
cliffL14 = instance_create(xCliffDropL+48,yCliffDropL,objFallingCliffPiece);
cliffL15 = instance_create(xCliffDropL+32,yCliffDropL,objFallingCliffPiece);
cliffL16 = instance_create(xCliffDropL+16,yCliffDropL,objFallingCliffPiece);

timeline_index = tmlCliffDropL;

with(_ObjectHandle)instance_destroy();

}[/CODE]

Once that happens a timeline runs that is supposed to drop each object in the correct order (right to left) that uses this basic code for 16 different timeline steps:

[CODE]with(cliffL1)instance_change(objFallingCliffPieceBg,true);[/CODE]

The problem is the timeline doesn't always drop them correctly or at all sometimes especially when a parallel Right dropping cliff is also present even though the right Cliff has a separate set of objects, variables, and timelines.

Anyway if anyone can either help fix this or preferably give me a better option I'm sure this is not the best way to get this done I'm just not a very good coder.

Link to comment
Share on other sites

Ah. There it is.

You're performing this code in the Sonic object, correct? Well, in any event you're perming this code in a single object, and you're probably performing the scrPlayerHandleObjectFallingCliffRight code in the same object. And since an object can only have one timeline, naturally they're going to conflict.

What you should do is have an empty object (if you don't have one already; for the same empty object type can be used to different ends), named oEmpty or something. Anyway, what you do is create an empty object when Sonic lands on it and set all the variables and the timeline inside the empty object. That way not only will the left and right not interfere, but the lefts won't interfere with other lefts.

Also you should add the code "instance_destroy()" at the end of your timelines so the emty objects don't stick around after they're necessary.

// ==== FUNCTION ====================================================================
// scrPlayerHandleObjectFallingCliffLeft()
// ==================================================================================
//

_ObjectHandle = instance_nearest(x, y, objFallingClifLeft);
//if(_ObjectHandle != noone)
    //{
if (scrPlayerCollisionBottomObject(sprPlayerMask15, 1, _ObjectHandle))
{
    var t;

    t = instance_create( _ObjectHandle.x, _ObjectHandle.y, oEmpty);

    with( t) {
        xCliffDropL = _ObjectHandle.x
        yCliffDropL = _ObjectHandle.y

        cliffL1 = instance_create(xCliffDropL+256,yCliffDropL,objFallingCliffPiece);
        cliffL2 = instance_create(xCliffDropL+240,yCliffDropL,objFallingCliffPiece);
        cliffL3 = instance_create(xCliffDropL+224,yCliffDropL,objFallingCliffPiece);
        cliffL4 = instance_create(xCliffDropL+208,yCliffDropL,objFallingCliffPiece);
        cliffL5 = instance_create(xCliffDropL+192,yCliffDropL,objFallingCliffPiece);
        cliffL6 = instance_create(xCliffDropL+176,yCliffDropL,objFallingCliffPiece);
        cliffL7 = instance_create(xCliffDropL+160,yCliffDropL,objFallingCliffPiece);
        cliffL8 = instance_create(xCliffDropL+144,yCliffDropL,objFallingCliffPiece);
        cliffL9 = instance_create(xCliffDropL+128,yCliffDropL,objFallingCliffPiece);
        cliffL10 = instance_create(xCliffDropL+112,yCliffDropL,objFallingCliffPiece);
        cliffL11 = instance_create(xCliffDropL+96,yCliffDropL,objFallingCliffPiece);
        cliffL12 = instance_create(xCliffDropL+80,yCliffDropL,objFallingCliffPiece);
        cliffL13 = instance_create(xCliffDropL+64,yCliffDropL,objFallingCliffPiece);
        cliffL14 = instance_create(xCliffDropL+48,yCliffDropL,objFallingCliffPiece);
        cliffL15 = instance_create(xCliffDropL+32,yCliffDropL,objFallingCliffPiece);
        cliffL16 = instance_create(xCliffDropL+16,yCliffDropL,objFallingCliffPiece);

        timeline_index = tmlCliffDropL;

        with(_ObjectHandle)instance_destroy();
    }
}

I believe that's what's going on, anyway. As troublesome as it is to do this in timelines, it's pretty much how it should be done. The only way you could really "improve" upon the code is to use for loops (and arrays) and that would really just cut down on the amount of code and coding time. It'd also make it a little more dynamic in that you could define the width and (if you had it) height. But other than that, it'd be pretty much the same timing concept.

Another potential problem is that using "instance_nearest" to decide which object to choose might not be a pixel-perfect method, but since you have left and right falling cliffs separate objects, it's not likely to matter (so long as this is called from the Sonic object, of course).

(also, with regards to your PM, I'll get back to you on that; but I have been and will be too busy to think about it 'til after the Nov 8th)

  • Like 1
Link to comment
Share on other sites

This is going to get long:

objGimmickWeakPlatform (parent)

Create:

    ObjectActivated = false;
    ObjectTimer     = 0;

Normal Step:

    // ---- Check if the collapse is activated ----------------------
    if (ObjectActivated == true) {
        // ---- Count down timer for collapse -----------------------
        ObjectTimer = max(ObjectTimer - (1000/60)*global.GameplayInterval, 0);
        if (ObjectTimer == 0) instance_destroy();

    } else if (collision_rectangle(x-3, y-1, x+sprite_width+3, y+1, objPlayer, false, true)) {
        ObjectTimer = 300;
        ObjectActivated = true;
    }

Destroy: (the heart of the code)

    // --- Setup falling platforms ---
    var _ObjectHandle, _offset, _timing, _left, _top;
    for (_offset=0; _offset<(sprite_width/16)+(sprite_height/16-1); _offset+=1) {
        _left = _offset;
        _top = (sprite_height/16-1);
        _timing = 0;
        repeat (min(_offset+1, sprite_height/16)) {
            if (_left<(sprite_width/16)) {
                _ObjectHandle = instance_create(x+(_left*16), y+(_top*16), objGimmickWeakPlatformPiece);
                _ObjectHandle.sprite_index  = sprite_index;
                _ObjectHandle.Left          = _left;
                _ObjectHandle.Top           = _top;
                if (PlatformOrientation==consObjectOrientationLeft) //consObjectOrientationLeft = 1
                        _ObjectHandle.ObjectTimer   = 50*((sprite_width/16)-_left)+(_timing*25);
                else    _ObjectHandle.ObjectTimer   = 50*(_left)+(_timing*25);
            }
            _left = max(_left-1, 0);
            _top = max(_top-1, 0);
            _timing += 1;
        }
    }

This will bound to any shape, but it looks the most natural when the platform is rectangular. Make your crumbling platform a child of this parent object, and remember to define the orientation in the Create event.

Example:

// ----------------------------------------------------------------------------
    event_inherited();
    PlatformOrientation = consObjectOrientationLeft; //consObjectOrientationLeft = 1

objGimmickWeakPlatformPiece (component)

Create:

    Speed           = 0;
    Gravity         = 0;
    GravityForce    = 0.2; // 0.2 when active
    TopGravity      = 8;
    ObjectTimer     = 0;
    Left            = 0;
    Top             = 0;

Step:

   
    // ---- Count down timer for collapse -----------------------
    ObjectTimer = max(ObjectTimer - (1000/60), 0);
    if (ObjectTimer == 0) {
        x += Speed;
        y += Gravity;
        Gravity = min(Gravity+GravityForce, TopGravity);
    }

Outside Room:

Destroy the Instance

Draw:

draw_sprite_part(sprite_index, floor(image_index), Left, Top, 16, 16, x, y);

These are the pieces of the platform that crumble. Do with them what you want.

  • Like 1
Link to comment
Share on other sites

  • Recently Browsing   0 members

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