Jump to content


Photo

Growing sprite gets stuck in walls


  • Please log in to reply
9 replies to this topic

#1 Sonicia

Sonicia

    GMC Member

  • New Member
  • 8 posts

Posted 18 August 2010 - 11:20 PM

I solved this, here is how!

Problem: when resizing the sprite it would exit the room through the boundary wall. or get stuck in a wall.
Solution: Make 4 different boundary walls.
Example:

Information about object: obj_Rwall //note the R
Sprite: spr_wall
Solid: true
Visible: true
Depth: 0
Persistent: false
Parent: <no parent>
Mask: <same as sprite>

Collision Event with object obj_player:
for all obj_player: execute code:

move_outside_solid(180, 20)
                    ^    ^
//              Degrees  amount

Now, game maker is a little wonky when it comes to the direction, it uses degrees and 0 is right, 90 is up, 180 is left, and 270 is down, but it works :P Note, it needs some fine tuning, probably a size variable but the main problem is solved.
Note, the corners can NOT be solid, they must remain as a pass through item to work right.


I came up with the rather odd idea on a basic maze game where the sprite changes size depending on what it eats, the object of the game is to get through the maze before getting stuck. Currently I am in the collision testing mode. There are temporary bubbles as the sprites, with the clown resources, wall, and background.
I cleanded up the code I had before, now I have switched to coded movement via the step instance, here is the code within the step.
{
  if (keyboard_check(vk_left))   x -= 4 ;
  if (keyboard_check(vk_right))  x += 4 ;
  if (keyboard_check(vk_up))     y -= 4 ;
  if (keyboard_check(vk_down))   y += 4 ;

view_hborder=view_wview/2 -obj_player.sprite_width; //This is to ensure the border and growth bubble plays nice
view_vborder=view_hview/2 -obj_player.sprite_height;
}
This works beautifully
Now, the problem is this, if the sprite changes image size while against the wall it gets stuck there, unable to move. I could solve this by jump to a spot, but I wanted to be a little more clever. Instead I would like to have the player bounce off the wall a short distance and stop, even when a key is pressed, (and eventually a noise) I tried bounce against solid objects inside the step but it hasn't done anything.

Can someone please help me? please remember that I only have the very basics of coding and require an example of its use in simple (if possible) terms.

Breaking down the problem
Currently using Khelder's move out of solid code here
1: Player grows into the left wall
2: Player is pushed out of wall
3: Size increaser (currently bouncing around room) hits player while still in wall
4: Player grows and touches another left wall brick
5: Both bricks now push against the player, gets confused.
6: Player starts to slide down.
7: Player then slides through the bottom wall
8: Player exits room in undesired way

Possible fix:
1: Player grows into the left wall
2: Player is pushed out of wall to the right
3: Size increaser hits player while still in wall
4: Because this is the left wall the new brick pushes player to the right, popping it back into room.
5: Problem is solved.
========================
Current player info (I wish we had those dynamic collapsing containers to make it easy to browse the forum)

Information about object: obj_player

Sprite: spr_bubble
Solid: false
Visible: true
Depth: 0
Persistent: false
Parent: <no parent>
Mask: <same as sprite>

Create Event:
execute code:

script_execute (globals)
script_execute (stay_room)

play sound snd_music; looping: true
set Alarm 0 to 50
set Alarm 1 to 100
set Alarm 3 to 150
set Alarm 4 to 600

Alarm Event for alarm 3:
create instance of object obj_inflate at position (100,100)
set Alarm 3 to 100

Alarm Event for alarm 4:
if number of objects obj_big is Smaller than 1
      create instance of object obj_big at position (50,50)
set Alarm 4 relative to 500
else
      set Alarm 4 to 500

 Step Event:
execute code:

//movement, In my opinion easier to manage than using key events
{
  if (keyboard_check(vk_left))   x -= 4 ;
  if (keyboard_check(vk_right))  x += 4 ;
  if (keyboard_check(vk_up))     y -= 4 ;
  if (keyboard_check(vk_down))   y += 4 ;
}

bounce not precisely against solid objects

End Step Event:
execute code:

view_xview[0] = (obj_player.x )-(view_wview[0]/2);
view_yview[0] = (obj_player.y )-(view_hview[0]/2);


execute code:
//I have been trying to find the best place for this code
if !place_free(x, y) {
    var xold, yold, dir, len;
    xold = x;
    yold = y;
    for (len = 2; len < 10; len += 1) {
        for (dir = 90; dir < 360; dir += 45) {
            move_outside_solid(dir, len);
            if !(x == xold && y == yold) {
                len = 20;
                dir = 360;
            }
        }
    }
}


Collision Event with object obj_wall:
for all obj_player: execute code:

script_execute (collide)
/* commented out for further testing
if bsize > (2000)
{
    room_goto_next();
}
else
{
    
}*.


Collision Event with object obj_inflate:
play sound snd_bloow; looping: false
execute code:

script_execute (gr_check) //actually this one is currently empty
image_yscale += 10/100;
image_xscale += 10/100;
bsize += 10;


set the score relative to 1
jump relative to position (0,0)
execute code:

//this is to keep the bourder around the player
view_hborder=view_wview/2 -obj_player.sprite_width;
view_vborder=view_hview/2 -obj_player.sprite_height;



Collision Event with object obj_big:
play sound snd_inflate; looping: false
execute code:

script_execute (gr_check) //inactive
image_yscale += s1/100; //takes into account other collisions and changes size of player accordingly
image_xscale += s1/100;




set the score relative to s1
for all obj_player: set Alarm 4 relative to 1000
execute code:

view_hborder=view_wview/2 -obj_player.sprite_width;
view_vborder=view_hview/2 -obj_player.sprite_height;


Other Event: Outside Room:
play sound snd_pop; looping: false
display message: Undesirable exit
restart the current room with transition effect Fade out and in

Edited by Sonicia, 20 August 2010 - 04:57 PM.

  • 0

#2 Khelder

Khelder

    GMC Member

  • New Member
  • 2018 posts

Posted 18 August 2010 - 11:56 PM

You could use move_outside_solid(..) to move yourself outside the wall. Something like
if !place_free(x, y) {
    var xold, yold, dir, len;
    xold = x;
    yold = y;
    for (len = 2; len < 10; len += 1) {
        for (dir = 0; dir < 360; dir += 45) {
            move_outside_solid(dir, len);
            if !(x == xold && y == yold) {
                len = 20;
                dir = 360;
            }
        }
    }
}
{EDIT} Replaced "," with ";"

Edited by Khelder, 19 August 2010 - 01:39 PM.

  • 0

#3 Sonicia

Sonicia

    GMC Member

  • New Member
  • 8 posts

Posted 19 August 2010 - 07:10 AM

im sorry, Khelder, but there is an error :( and I have no idea what to do about this one. Can someone please help me about this one, thanks

FATAL ERROR in
action number 1
of  Step Event
for object obj_player:

COMPILATION ERROR in code action
Error in code at line 14:
       for (len = 2; len < 10, len += 1) {
                             ^
at position 28: Unexpected symbol in expression.
I place it in the step, not sure where else to place it.

Well, I removed the "," and the game runs now, ut if it grows against the side of a solid it still gets stuck so I would like it to push away a little bit, even if it resizes. although it does place the solids on top of it, similar to what I wanted.

I place it in the end step and it did do okay but then eventually it it got stuck against the bottom, drifted sideways, slipped under the right hand brick wall and exited the room. I'll have to toy with it once I return from work unless someone is nice enough to tell me where to put it and stuff.

Edited by Sonicia, 19 August 2010 - 07:59 AM.

  • 0

#4 blonde lama

blonde lama

    GMC Member

  • GMC Member
  • 71 posts

Posted 19 August 2010 - 07:48 AM

Well, I can explain why collision didn't work out for you. Collision only works by speed.
You just change the coordinate of the instance "placing" it on the new coordinate. Your instance does not actually move.


Anyway; I didn't try the code myself, but maybe it can give you the right step towards the answer

Before growing larger; check first of the place on the right, top, left and down is solid free.
If left & right aren't solid free or down and up aren't solid free then the instance is stuck.

a1= //sprite growth on the left side of sprite
a2= //sprite growth on the top side of sprite
a3= //sprite growth on the right side of sprite
a4= //sprite growth on the down side of sprite

upFree=true
downFree=true
leftFree=true
rightFree=true

//Check right
If (place_free(x+a1,y)=false) then
  {
  leftFree=false
  }

//Check up
If (place_free(x,y-a2)=false) then
  {
  upFree=false
  }

//Check left
If (place_free(x-a3,y)=false) then
  {
  leftFree=false
  }

//Check down
If (place_free(x,y+a4)=false) then
  {
  downFree=false
  downCode="y+a4"
  }

if (leftFee && rightFree or upFree && downFree) then
{// Player is stuck}
if (leftFree=false) then
{x+a1}
if (upFree=false) then
{y-a2}
if (rightFree=false) then
{x-a3}
if (downFree=false) then
{y+a4}

Edited by blonde lama, 19 August 2010 - 07:53 AM.

  • 0

#5 Sonicia

Sonicia

    GMC Member

  • New Member
  • 8 posts

Posted 19 August 2010 - 11:59 AM

Well, I can explain why collision didn't work out for you. Collision only works by speed.
You just change the coordinate of the instance "placing" it on the new coordinate. Your instance does not actually move.


Anyway; I didn't try the code myself, but maybe it can give you the right step towards the answer

Before growing larger; check first of the place on the right, top, left and down is solid free.
If left & right aren't solid free or down and up aren't solid free then the instance is stuck.


ummmmm I wish you would have been more precise on where to and how to use this code, a step in the right direction, maybe, but I honestly dont know which direction this is going to take me, or even if this will prevent the growing sprite (grows from a simple image_*scale = ##/100 command) from getting stuck in the wall. (You forgot that If and if means 2 different things, I had to lowercase the I) Once that is fixed it gives this error, and I have no idea whatsoever to fix it. (It is in a script that is called when a grow sprite collides with the player)
COMPILATION ERROR in Script: gr_check
Error in code at line 40:
   {x-a1}
     ^
at position 4: Assignment operator expected.

I'm not even sure that this code will actually just bounce the player away from the boundary wall and stop a grid square later, which, after I think about it, is the kind of fix I want.

Edited by Sonicia, 19 August 2010 - 12:05 PM.

  • 0

#6 Khelder

Khelder

    GMC Member

  • New Member
  • 2018 posts

Posted 19 August 2010 - 01:38 PM

im sorry, Khelder, but there is an error :( and I have no idea what to do about this one. Can someone please help me about this one, thanks

FATAL ERROR in
action number 1
of  Step Event
for object obj_player:

COMPILATION ERROR in code action
Error in code at line 14:
       for (len = 2; len < 10, len += 1) {
                             ^
at position 28: Unexpected symbol in expression.
I place it in the step, not sure where else to place it.

Well, I removed the "," and the game runs now, ut if it grows against the side of a solid it still gets stuck so I would like it to push away a little bit, even if it resizes. although it does place the solids on top of it, similar to what I wanted.

I place it in the end step and it did do okay but then eventually it it got stuck against the bottom, drifted sideways, slipped under the right hand brick wall and exited the room. I'll have to toy with it once I return from work unless someone is nice enough to tell me where to put it and stuff.

Oops.. That should be a ";", not a ","
  • 0

#7 Sonicia

Sonicia

    GMC Member

  • New Member
  • 8 posts

Posted 19 August 2010 - 03:59 PM

okay Khelder, that is getting warm, once placed inside the step in it's own code block for easy moving, it did move the player outside of the wall, but, it did not move the player back into the room, instead it moved me through the wall outside the room. I want it to move the player back into the room, not through the wall to outside, where it is destroyed.

I do not mind if I have to have right wall, top wall, ect, long as the walls contain the growing player sprite and make it stay in the room. There will eventually be other bricks for the maze itself, its just the containing bricks that need this code. Maze bricks will probably have their own code with a variable that informs the game if it is getting squished too bad and thus popping.

I'm pretty sure if I fiddle with it I can get it to do just 180 one way based upon the brick the player has overlapped, the corner bricks don't matter much, in my opinion, unless they do.

Which part can be safely edited to suit my needs? Thanks a mill. :D

Edited by Sonicia, 19 August 2010 - 04:17 PM.

  • 0

#8 Legendary the Elder

Legendary the Elder

    GMC Member

  • Validating
  • 228 posts

Posted 19 August 2010 - 04:36 PM

COMPILATION ERROR in Script: gr_check
Error in code at line 40:
{x-a1}
^
at position 4: Assignment operator expected.


This error came up because x-a1 needs to have an = sign (assignment operator) after it or before it. You can't just subtract something and do nothing with the value. I think what it is supposed to be is x-=a1 (Although I suppose it could be x=a1...). By the way, notice how the little carrot points exactly where the error was found. That can often given hints as to what needs fixing...

#9 Khelder

Khelder

    GMC Member

  • New Member
  • 2018 posts

Posted 19 August 2010 - 09:26 PM

okay Khelder, that is getting warm, once placed inside the step in it's own code block for easy moving, it did move the player outside of the wall, but, it did not move the player back into the room, instead it moved me through the wall outside the room. I want it to move the player back into the room, not through the wall to outside, where it is destroyed.

I do not mind if I have to have right wall, top wall, ect, long as the walls contain the growing player sprite and make it stay in the room. There will eventually be other bricks for the maze itself, its just the containing bricks that need this code. Maze bricks will probably have their own code with a variable that informs the game if it is getting squished too bad and thus popping.

I'm pretty sure if I fiddle with it I can get it to do just 180 one way based upon the brick the player has overlapped, the corner bricks don't matter much, in my opinion, unless they do.

Which part can be safely edited to suit my needs? Thanks a mill. :D

Well, the reason for the "dir" loop is that it's supposed to check in a spiral/check in a circle. So, if you can work out what the direction is, or at least work it out to inside a 90 degree angle, you could replace that part
  • 0

#10 Sonicia

Sonicia

    GMC Member

  • New Member
  • 8 posts

Posted 19 August 2010 - 09:46 PM

This error came up because x-a1 needs to have an = sign (assignment operator) after it or before it. You can't just subtract something and do nothing with the value. I think what it is supposed to be is x-=a1 (Although I suppose it could be x=a1...). By the way, notice how the little carrot points exactly where the error was found. That can often given hints as to what needs fixing...

yes, I have noticed how the little ^ points to the problem, it comes quite in handy for fixing things of that sort but I only have a basic grasp of scripting, and that's only rpg maker XP scripting, which is loosely based off of RUBY, another OOL, but I forgot quite a lot of it in the course of 4 years so I must say that I am back to being a novice, despite a little php language knowledge.

I was under the impression that the code was okay as is, so all I did was copy and paste it in, what I hoped was the right spot. I really have no idea what GML is based off of so I have no clue on what to look for. So until I wrap my mind around it expect a few "huh, say what?" moments out of me. I'll get it, but it will take some time.

Currently, blond lama's script looks sweet, and I can grasp some of it, but I have no idea what to store in the a1 variable for example, or how to make it work well, or even use it as a launch pad to perfect my bordering wall collision code. All I really want is if the sprite gets stuck in the wall then it is pushed back into the room, not outside the room, where it is sent to the next room.
================

Well, the reason for the "dir" loop is that it's supposed to check in a spiral/check in a circle. So, if you can work out what the direction is, or at least work it out to inside a 90 degree angle, you could replace that part


I would probably have to work out a dynamic way to have it move out of solid, currently if it happens to grow while too close to a corner then it can still get stuck, also it it grows while still moving it gets stuck and drifts along the wall through the next corner and out the room.


Edited the first post with pertaining information

==Testing==
fiddling with the "no stuck" code in the end step appears to have nice results. However once i set line 6 "for (dir = 0; dir < 360; dir += 45)" 45 to 180 it does not get stuck if in a corner. But if against the wall and it keeps growing then it will drift and exit the room. so I need a way for it to stop motion once it is moved out of the solid, besides to move, because if the player moves it does stop, providing that the player does not glide into the next wall.
New: after a lot of testing I find that it is only the right wall it slides through. hmm

Yet, I am afraid that I might have to do the maze bricks themselves differently. Simply because the maze bricks will eventually be added, and if the player sprite is too big it will either get stuck, or pop if it gets any bigger than that. This could make for some intense coding issues further down the line, especially if the player gets stuck in a border and a brick.

Edited by Sonicia, 20 August 2010 - 02:26 PM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users