Page 4 of 5

Re: Perfect collision exemple

PostPosted: Fri May 04, 2012 6:45 pm
by lverona
Hm. I see.

What if we take a different approach and have a function called Collision2 - which would be different from Collision in a way that it would not be disabled by CollisionState. So you would have an actor which approaches an object and which is CollisionState disabled, but would register on Collision2.

Re: Perfect collision exemple

PostPosted: Fri May 04, 2012 7:37 pm
by skydereign
If you do that, you are creating an exceptive case, and that generally is a bad way of structuring things. Also that isn't how collision works, and it wouldn't make sense to do it that way. The only way that would be possible is if we used collision groups (like the physics actors have in 1.5), but that would be a lot of restructuring, and might possibly break old games. Even making the CollisionFree2 that I'm trying to do requires tweaking of how gE figures out collisions (so it might not even be possible).

Re: Perfect collision exemple

PostPosted: Sat May 05, 2012 6:20 am
by lverona
Okay, understood.

I did design a way to have collisions using this method. Will post code later today.

Re: Perfect collision exemple

PostPosted: Sat May 05, 2012 1:00 pm
by lverona
Okay, the idea is simple - force the player to collide with the object in front of him and the next draw cycle drag him back out the same xvelocity he travelled in.
Here are the instructions.

1. Add global variables cmove=1 and touch=0.

2. Add this code to Draw Actor:

Code: Select all
float MSensor=1.2;
char*key=GetKeyState();

//xvelocity becomes either 2 or -2 depending on the key pressed
//if both or none are pressed it is 0
xvelocity=(key[KEY_RIGHT]-key[KEY_LEFT])*2;

//if there is nothing blocking the player
//we reset cmove
if(CollisionFree("Event Actor",x+xvelocity,y-5)) cmove=1;

//if the player was forced to collide previous draw cycle
//this code drags him back out
if(touch!=0){
x-=touch;
xvelocity=0;
touch=0;
}

//if we can walk
//but if we land too deep into ground, lift player up 2 pixels
if(abs(xvelocity)>0&&CollisionFree("Event Actor",x+xvelocity,y-5)&&
CollisionFree("Event Actor",x+xvelocity,y-2)==0){
y-=2;
}
//if floor too high or we face a wall, we cannot move
else if(CollisionFree("Event Actor",x+xvelocity,y-5)==0){

//if cmove (can move) is 1, then we force the player
//to collide with the object in front of him
if(cmove==1){
x+=xvelocity;
touch=xvelocity;
//by putting cmove to 0 we ensure the player
//is forced to collide just once and not repeatedly
cmove=0;
}

xvelocity=0;

}

//determine the direction of movement
//if "1" means key right is pressed, if "-1" key left
if(abs(xvelocity)>0)PlayerWD=xvelocity/abs(xvelocity);

//if xvelocity is larger-equal than movement sensor (we definitely move)
//and if yvelocity is smaller-equal to movement sensor (we are not falling too fast)
//we draw going right animation
if(xvelocity>=MSensor&&abs(yvelocity)<=MSensor)ChangeAnimation("cosmonaut", "goright1", NO_CHANGE);
//or if xvelocity is smaller-equal than negative movement sensor (we move another direction)
//and we are not falling too fast
//we draw going left animation
else if(xvelocity<=-MSensor&&abs(yvelocity)<=MSensor)ChangeAnimation("cosmonaut", "goleft1", NO_CHANGE);

//if we are not moving and not falling, we draw stand animation
if(abs(xvelocity)<MSensor&&abs(yvelocity)<=MSensor)
{
    //here we choose which direction to draw
    if(PlayerWD==1)ChangeAnimation("cosmonaut", "standright", NO_CHANGE);
    else ChangeAnimation("cosmonaut", "standleft", NO_CHANGE);
}

//if we are definitely falling
//we draw falling animation
if(yvelocity>=MSensor)
{
    if(PlayerWD==1)ChangeAnimation("cosmonaut", "standright", NO_CHANGE);
    else ChangeAnimation("cosmonaut", "standleft", NO_CHANGE);
}

//if we are "falling" the other direction, means we are jumping
else if(yvelocity<=-MSensor)
{
    if(Jump==1)PlaySound2("data/BUTTON01.WAV", 0.233333, 1, 0.000000);
    if(PlayerWD==1)ChangeAnimation("cosmonaut", "jumpright", NO_CHANGE);
    else ChangeAnimation("cosmonaut", "jumpleft", NO_CHANGE);
}

//if there is no collision immediately below us
//and no collision 1 pixel above where we will end after next draw cycle
//we turn gravity on and disallow jumping
if(CollisionFree("Event Actor",x,y+yvelocity)||
CollisionFree("Event Actor",x,y+yvelocity-1)){
yvelocity+=0.16;Jump=0;
}
//but if there is a collision, we turn gravity off
else {
//we turn off ability to jump if there is a
//collision near top of player;
if(CollisionFree("Event Actor",x,y+yvelocity-4)==0)Jump=0;
//if nothing is near top of player, we allow jumping
else {Jump=1;}
yvelocity=0;

}

yvelocity-=key['z']*Jump*jump_height;


What are the drawbacks?

A. If you encounter an item, which the player has to take, you will momentarily stop, since the code pushes you back from the object. This is not necessarily a bad effect, making taking objects being "felt". However, it is trivial to remove this effect if you want your player to just grab items and not have this affect his movement - just add a collision to the object and in a Script Editor write this: touch=0;
This will eliminate the effect completely - player will collide but not be pushed out. Don't do this with walls - or you'll stick to walls!

B. In the original code by Game A Gogo jumping is easier in a way - if the platform is a little bit higher than your jump, you sort of get smoothly dragged up. Not too realistic, but makes jumping effortless. Here, however, each time you encounter a wall, you collide with it and then get pushed back. So if your jump is not high enough - you won't get up. I did see a similar mechanic in a number of games and it feels fine. Also, since now you do collide with walls, it is possible to experiment and script the desired behaviour if necessary. I just began to place platforms at a different distance relative to each other.

C. This code does not deal with a vertical lift. I am yet to solve this problem.

All in all, I am very happy with this method, it works fine and I like it more than Physical Response, since it does not push the player from platform edges and generally requires less scripting and less events. Hope, this will be useful to someone else too.

Re: Perfect collision exemple

PostPosted: Sun May 06, 2012 6:26 pm
by phyzix5761
How do you detect a collision with a specific actor with this method?

Re: Perfect collision exemple

PostPosted: Mon May 07, 2012 7:50 am
by lverona
You add a collision just like always.

The achievement of this method is that you do not need to add a Physical Response just to have things be "solid" for the player. The rest you can do just the same.

Re: Perfect collision exemple

PostPosted: Mon May 07, 2012 8:22 am
by phyzix5761
I am using the original method and collision events don't work.

Re: Perfect collision exemple

PostPosted: Mon May 07, 2012 9:05 am
by lverona
Hehe. Indeed. This is why you need to use my method which I described in the above post to achieve that.

Re: Perfect collision exemple

PostPosted: Mon May 07, 2012 3:48 pm
by Game A Gogo
a simple way to mimic the collision event (But only for all actors) is this:
Code: Select all
if(CollisionFree("Event Actor",x+xvelocity,y+yvelocity))
{
    //Code to be repeated once collision with an object has been detected
}

if you only want the code to be run through once, add a toggle variable, for exemple "HasCollided" (Make it an integer)
Code: Select all
if(CollisionFree("Event Actor",x+xvelocity,y+yvelocity))
{
    if(!HasCollided)//Hasn't collided with anything before
    {
        HasCollided=1;
        //Code to be run once
    }
}
else HasCollide=false;


you may also notice that I am using x+xvelocity and y+yvelocity. Why? you may ask, the answer is simple: we want to know if it's GOING TO collide on the next frame, so we're moving ahead in time in theory.
That is what needs to be done with physic's collisions. But if you need a sensor of the sort, you can simply change it to just x and y instead.

EDIT:

When Box2D gets fully implemented in GE, my whole system will be completely obsolete :) I'm actually learning Box2D in my programming class atm, so I can't wait for GE to have this :D

Re: Perfect collision exemple

PostPosted: Mon May 07, 2012 4:07 pm
by lverona
Yes, I understand that x+xvelocity is checking. I am doing exactly what you say - I have a toggle variable, maybe its naming is less clear - in my code this is "touch". The reason I have yet another variable (cmove) is because I want to automatically drag the actor back and I want that to be done by default. As I explained, by envoking touch=0 in the code of another object I can nullify this effect.

I heard good things about Box2D and did see it in action in some Flash applications. I would welcome the day when GE implements it. But at the moment, this method is my choice.

By the way, am I correct in understanding that Box2D is cool in that it is a better Physical Response and it won't have all the artifacts GE currently has? Why do you say your method will be obsolete?
Or does Box2D itself offer functions to interact with itself?

Re: Perfect collision exemple

PostPosted: Mon May 07, 2012 5:28 pm
by Game A Gogo
To simply put it, box2D emulates (With amazing accuracy) real world physics with incredible speed!
With box2D you will be able to know which actor it hits against as well!

and my other reply was meant for
phyzix5761 wrote:How do you detect a collision with a specific actor with this method?

:)

Re: Perfect collision exemple

PostPosted: Sun May 27, 2012 3:02 pm
by phyzix5761
Iverona, I am very interested in your method. How would it work for a top-down game where you would need collision detection for the y-axis as well as the x-axis? I am talking about games that don't require gravity like a top-down RPG for example.

Re: Perfect collision exemple

PostPosted: Tue May 29, 2012 7:51 am
by lverona
I am doing a top-down maze game right now. Without gravity it is much-much easier. Just check for CollisionFree in the direction you are going to.

Now, to make your actor actually collide, I would go for another method. Instead of bumping him and then pulling back, you can simply have another shape be its child which will overlap your character. That shape, invisible in the game, can be 1 pixel larger (or whatever number of pixels your player "step" is) and thus detect collisions your player will not.

Re: Perfect collision exemple

PostPosted: Fri Jun 01, 2012 4:08 pm
by phyzix5761
Thank you for your suggestion Iverona but it doesn't work. In order to have the child collision detector actor active it would need to have it's collision state enabled. But this doesn't allow the heroC actor to move because it detects a collision with the child actor.

Re: Perfect collision exemple

PostPosted: Mon Jun 11, 2012 3:42 pm
by Game A Gogo
only the collision mask should have colliding enabled, the parents or the image holder shouldn't have colliding enabled

also, instead of having the colliding mask a bit larger than the parent, you can make it offset by the parent's speed, that way it should work with any velocity