Game issue (Fixed!)

Posted by anthonyloprimo on Aug. 25, 2011, 4:37 p.m.

So I need some help. I finally added damage calculation to a game, and somehow movement broke.

I partly fixed it (allowing horizontal movement) however one major issue remains.

Whenever the ship has one wing damaged (ship_wingDamage_left or ship_wingDamage_right) with the other in good shape (1 is damaged, 0 is undamaged), it won't properly decellerate left or right. It'll hold it speed, and sometimes tapping quickly, will make it stop. But one it's moving normally it won't stop.

I don't remember touching anything, but perhaps there's an issue here that I missed…?

// Core Movement Engine

// Movement Containers / Modifyers
if  ship_engineDamage = 1 {  // Vertical movement modifyer
    ship_yMove = ship_yPan*.50;
}
else if ship_engineDamage = 0 {
    ship_yMove = ship_yPan;
}

if ship_wingDamage_left = 1 && ship_wingDamage_right = 0 {  // Left movement modifyer
    if keyboard_check(vk_left) {
        ship_xMove = ship_xPan*.50;
    }
    else if keyboard_check(vk_right) {
        ship_xMove = ship_xPan;
    }
}

if ship_wingDamage_left = 0 && ship_wingDamage_right = 1 {  // Right movement modifyer
    if keyboard_check(vk_left) {
        ship_xMove = ship_xPan;
    }
    else if keyboard_check(vk_right) {
        ship_xMove = ship_xPan*.50;
    }
}

if ship_wingDamage_left = 1 && ship_wingDamage_right = 1 {  // Horizontal (left and right damage) modifyer
    ship_xMove = ship_xPan*.50;
}

if ship_wingDamage_left = 0 && ship_wingDamage_right = 0 {
    ship_xMove = ship_xPan;
}


// Movement
    y += ship_yMove;
    x += ship_xMove;


// Exact Pixel precision
if ship_yPan = 0 && ship_xPan = 0 {
    x=round(x);
    y=round(y);
}


// Accelleration
if keyboard_check(vk_down) {  // down
    if ship_mDown = 1 {
        if ship_yPan<ship_shipSpeed {
            ship_yPan += .25;
        }
    }
}

if keyboard_check(vk_up) {  // up
    if ship_mUp = 1 {
        if ship_yPan>0-ship_shipSpeed {
            ship_yPan -= .25;
        }
    }
}

if keyboard_check(vk_right) {  // right
    if ship_mRight = 1 {
        if ship_xPan<ship_shipSpeed {
            ship_xPan += .25;
        }
    }
}

if keyboard_check(vk_left) {  // left
    if ship_mLeft = 1 {
        if ship_xPan>0-ship_shipSpeed {
            ship_xPan -= .25;
        }
    }
}


// Decelleration
if !keyboard_check(vk_down)  && !keyboard_check(vk_up) {  // Vertical decelleration
    if ship_yPan>0 {
        ship_yPan -= .25;
    }
    else if ship_yPan<0 {
        ship_yPan += .25;
    }
}
else if keyboard_check(vk_down)  && keyboard_check(vk_up) {
    if ship_yPan>0 {
        ship_yPan -= .25;
    }
    else if ship_yPan<0 {
        ship_yPan += .25;
    }
}

if !keyboard_check(vk_right)  && !keyboard_check(vk_left) {  // Horizontal decelleration
    if ship_xPan>0 {
        ship_xPan -= .25;
    }
    else if ship_xPan<0 {
        ship_xPan += .25;
    }
}
else if keyboard_check(vk_right)  && keyboard_check(vk_left) {
    if ship_xPan>0 {
        ship_xPan -= .25;
    }
    else if ship_xPan<0 {
        ship_xPan += .25;
    }
}


// Boundary check
if collision_rectangle(0,0,800,8,obj_Player,true,false) {  // Top boundary
    ship_mUp = 0;
    y = yprevious;
}
else {ship_mUp = 1;}

if collision_rectangle(0,0,8,450,obj_Player,true,false) {  // Left boundary
    ship_mLeft = 0;
    x = xprevious;
}
else {ship_mLeft = 1;}

if collision_rectangle(0,442,800,450,obj_Player,true,false) {  // Bottom boundary
    ship_mDown = 0;
    y = yprevious;
}
else {ship_mDown = 1;}

if collision_rectangle(792,0,800,450,obj_Player,true,false) {  // Right boundary
    ship_mRight = 0;
    x = xprevious;
}
else {ship_mRight = 1;}

Comments

anthonyloprimo 13 years, 3 months ago

Tinkering around did nothing but make it worse. can anyone give me a hand? D:

panzercretin 13 years, 3 months ago

K dude

But really, make the wings be different objects. If the left wing doesn't exist, it spins right. If the right wing doesn't exist, it spins left. Or the other way around.

firestormx 13 years, 3 months ago

Okay, I'm going to just dump in here what I'm thinking as I'm reading through the code (so sorry if it's not a very flowing comment)

It looks like a little cluttered, so I rewrote a little bit of it for you. The left/right movement was simplified, and the horizontal movement part is not needed at all. =)

Also, I don't think GM requires you to use proper comparison signs (== instead of just =) and brackets, but I added that to the parts I edit out of habbit/good practice.

//Left movement modifier
if (keyboard_check(vk_left) {
	if (ship_wingDamage_left == 1) {
		ship_xMove = ship_xPan*.5;
	}
	else if (ship_wingDamage_left == 0) {
		ship_xMove = ship_xPan;
	}
}

//Right movement modifier
if (keyboard_check(vk_left) {
	if (ship_wingDamage_left == 1) {
		ship_xMove = ship_xPan*.5;
	}
	else if (ship_wingDamage_left == 0) {
		ship_xMove = ship_xPan;
	}
}

//Horizontal modifier
//Not needed

Your decelleration could be simplified as well by combining the else/if into one big if statement.

// Decelleration
if ((!keyboard_check(vk_down)  && !keyboard_check(vk_up)) || (keyboard_check(vk_down)  && keyboard_check(vk_up))) {  // Vertical decelleration
    if ship_yPan>0 {
        ship_yPan -= .25;
    }
    else if ship_yPan<0 {
        ship_yPan += .25;
    }
}


if ((!keyboard_check(vk_right)  && !keyboard_check(vk_left)) || (keyboard_check(vk_right)  && keyboard_check(vk_left))) {  // Horizontal decelleration
    if ship_xPan>0 {
        ship_xPan -= .25;
    }
    else if ship_xPan<0 {
        ship_xPan += .25;
    }
}

Now that that's out of the way, try something like this in the draw event for debugging (this is strictly from memory, so if the code doesn't work,…well…fix it =P)

//Watch/check if x/yPan is decellerating
draw_text(10, 10, "ship_xPan: " + str(ship_xPan));
draw_text(10, 20, "ship_yPan: " + str(ship_yPan));

//Check if the game recognizes that it SHOULD be decellerating
if ((!keyboard_check(vk_down)  && !keyboard_check(vk_up)) || (keyboard_check(vk_down)  && keyboard_check(vk_up)))  // Vertical decelleration
{draw_text(10, 30, "YES VERTICAL DECELLERATION SHOULD OCCUR");}
else
{{draw_text(10, 30, "no, vertical decelleration should not occur");}}

if ((!keyboard_check(vk_right)  && !keyboard_check(vk_left)) || (keyboard_check(vk_right)  && keyboard_check(vk_left)))  // Horizontal decelleration
{draw_text(10, 40, "YES HORIZONTAL DECELLERATION SHOULD OCCUR");}
else
{{draw_text(10, 40, "no, horizontal decelleration should not occur");}}

And just output whatever other variables you can think of. Then you should turn the room speed down quite a bit so you can actually see these values.

Basically if you see that horizontal decelleration should occur, but ship_xPan is holding steady, then you have a problem somewhere.

If you can't get figure it out past this point, comment back here, and if I don't reply fairly quickly, send me an email at my work email. =)

anthonyloprimo 13 years, 3 months ago

@twinsoul: I didn't even make my damage system yet. I'm just working on the flags that will be toggled to alter the movement of the player's ship.

anthonyloprimo 13 years, 3 months ago

I had to alter a couple of things (copy and paste fail it seems, forgetting to change a variable or two) but otherwise I ended up at where I started

I also tested with your deceleration test - vertical works right but horizontal holds steady.

I'm gonna try to copy/paste and edit the vertical deceleration code and see if that does anything.

LOL and of course that would be too easy if that worked. So never mind THAT.

If not, I'll just re-work a new movement engine… which is going to suck but meh.

firestormx 13 years, 3 months ago

Did you try that debug stuff?

Also, what I would do is make a show_message() or something in the area of the code where it should be decellerating. That way you can see if it's trying to reduce the pan variable or not.

anthonyloprimo 13 years, 3 months ago

I did try the "debug" stuff. No diece.

However, interestingly enough, placing that show_message() function did work - something is up with the deceleration code for some reason. It shows the message but it's not decelerating the values. I'm gonna try to switch something up…. One moment.

DAMMIT. :/

firestormx 13 years, 3 months ago

You said this only happens if the wing is damaged, but not when it is not damaged? The only difference when that occurs, is that ship_xPan is being cut in half.

Have you tried this when a damaged engine as well? My theory below only works if this occurs with both a damaged wing and a damaged engine.

In the acceleration code, it tries to increase the speed by .25, and in the movement modifiers, it cuts that acceleration in half (to 0.125). In the deceleration code, however, it does not take that into account, and it always decreases the speed by .25. It will decrease the speed only if x/yPan != 0. So if x/yPan is not in increments of .25 (eg if it was at 0.125 * 3 = 0.375) it will subtract .25 from it until it's -0.125, then it will increase to +0.125, and so on.

However, you said it is holding a constant speed, and not that it is slowing down to an almost-stop, so I don't know if this is what is causing the problem…It's something you should keep in mind though.

Other than that, the code looks fine…

So based on the show_message, if you release vk_right, ship_xPan should be decreasing (because the message pops up in the if statement). But according to the debug information shown on the screen, ship_XPan does not decrease?

This indicates that the ship is constantly accelerating - since the show_message occurs, ship_xPan has to decrease as well, because it occurs in the same if block as the show_message.

One thing you could try is in the decelleration code, is set "ship_mRight = 0". Though I don't think that would help, since the aceleration only occurs if keyboard_check(vk_right).

You're gonna have to do quite a bit of debugging on this. You'll have to make it output when it is acellerating and when it is decellerating, and see if there are ever conflicts where it is trying to do both.

Search through your code to find if there's any other point where the accelleration would be occuring as well, because like I said, if the show_message is popping up in the same block as when the decelleration is occuring, there has to be somewhere else in the code that is forcing it to continue to acellerate.

Edit: wow, I cannot spell accelerate

anthonyloprimo 13 years, 3 months ago

For once the YYG forums was a great help. See the following WORKING code: (Including some of your stuff, FSX)

// Core Movement Engine

// Movement Containers / Modifyers
if  ship_engineDamage = 1 {  // Vertical movement modifyer
    ship_yMove = ship_yPan*.50;
}
else if ship_engineDamage = 0 {
    ship_yMove = ship_yPan;
}

ship_xMove = ship_xPan;
if ((ship_xMove < 0 && ship_wingDamage_left) || (ship_xMove > 0 && ship_wingDamage_right)) {
    // Halve the speed when the wing in the moving direction is damaged.
    ship_xMove *= 0.5;
}


//Left movement modifier
if (keyboard_check(vk_left)) {
    if (ship_wingDamage_left == 1) {
        ship_xMove = ship_xPan*.5;
    }
    else if (ship_wingDamage_left == 0) {
        ship_xMove = ship_xPan;
    }
}

//Right movement modifier
if (keyboard_check(vk_right)) {
    if (ship_wingDamage_right == 1) {
        ship_xMove = ship_xPan*.5;
    }
    else if (ship_wingDamage_right == 0) {
        ship_xMove = ship_xPan;
    }
}


// Movement
    y += ship_yMove;
    x += ship_xMove;


// Exact Pixel precision
if ship_yPan = 0 && ship_xPan = 0 {
    x=round(x);
    y=round(y);
}


// Accelleration
if keyboard_check(vk_down) {  // down
    if ship_mDown = 1 {
        if ship_yPan<ship_shipSpeed {
            ship_yPan += .25;
        }
    }
}

if keyboard_check(vk_up) {  // up
    if ship_mUp = 1 {
        if ship_yPan>0-ship_shipSpeed {
            ship_yPan -= .25;
        }
    }
}

if keyboard_check(vk_right) {  // right
    if ship_mRight = 1 {
        if ship_xPan<ship_shipSpeed {
            ship_xPan += .25;
        }
    }
}

if keyboard_check(vk_left) {  // left
    if ship_mLeft = 1 {
        if ship_xPan>0-ship_shipSpeed {
            ship_xPan -= .25;
        }
    }
}


// Decelleration
if ((!keyboard_check(vk_down)  && !keyboard_check(vk_up)) || (keyboard_check(vk_down)  && keyboard_check(vk_up))) {  // Vertical decelleration
    if ship_yPan>0 {
        ship_yPan -= .25;
    }
    else if ship_yPan<0 {
        ship_yPan += .25;
    }
    if -.25<ship_yPan<.25 {
        ship_yPan = 0;
    }
}


if ((!keyboard_check(vk_right)  && !keyboard_check(vk_left)) || (keyboard_check(vk_right)  && keyboard_check(vk_left))) {  // Horizontal decelleration
    if ship_xPan>=0 {
        ship_xPan -= .25;
    }
    else if ship_xPan<=0 {
        ship_xPan += .25;
    }
    
    if -.25<ship_xPan<.25 {
        ship_xPan = 0;
    }
}


// Boundary check
if collision_rectangle(0,0,800,8,obj_Player,true,false) {  // Top boundary
    ship_mUp = 0;
    y = yprevious;
}
else {ship_mUp = 1;}

if collision_rectangle(0,0,8,450,obj_Player,true,false) {  // Left boundary
    ship_mLeft = 0;
    x = xprevious;
}
else {ship_mLeft = 1;}

if collision_rectangle(0,442,800,450,obj_Player,true,false) {  // Bottom boundary
    ship_mDown = 0;
    y = yprevious;
}
else {ship_mDown = 1;}

if collision_rectangle(792,0,800,450,obj_Player,true,false) {  // Right boundary
    ship_mRight = 0;
    x = xprevious;
}
else {ship_mRight = 1;}

In the container category, I might have never added the stuff for ship_xMove although I don't think it was there when it worked

Fixing deceleration also corrected everything. So everything is working

firestormx 13 years, 3 months ago

Yay! I helped, I hope.

It looks like I was kind of right about my theory about the decelleration, since they had you put in the part about setting the ship_xPan to an absolute 0.

I DEMAND THAT YOU ATTRIBUTE THAT TO 64D, NOT YYG!