Perfect collision exemple

Post here your demos and examples with the source files.
Forum rules
Always post the games with a screenshot.
The file must have the ged and data files (complete game source)
Use the forum attachment to post the files.
It is always better to use the first post to put the game files

Re: Perfect collision exemple

Postby lverona » Fri May 04, 2012 6:45 pm

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.
lverona
 
Posts: 221
Joined: Tue Apr 24, 2012 11:54 am
Score: 1 Give a positive score

Re: Perfect collision exemple

Postby skydereign » Fri May 04, 2012 7:37 pm

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).
User avatar
skydereign
 
Posts: 3510
Joined: Mon Jul 28, 2008 8:29 am
Score: 589 Give a positive score

Re: Perfect collision exemple

Postby lverona » Sat May 05, 2012 6:20 am

Okay, understood.

I did design a way to have collisions using this method. Will post code later today.
lverona
 
Posts: 221
Joined: Tue Apr 24, 2012 11:54 am
Score: 1 Give a positive score

Re: Perfect collision exemple

Postby lverona » Sat May 05, 2012 1:00 pm

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.
lverona
 
Posts: 221
Joined: Tue Apr 24, 2012 11:54 am
Score: 1 Give a positive score

Re: Perfect collision exemple

Postby phyzix5761 » Sun May 06, 2012 6:26 pm

How do you detect a collision with a specific actor with this method?
phyzix5761
 
Posts: 261
Joined: Sun Feb 27, 2011 4:28 am
Score: 18 Give a positive score

Re: Perfect collision exemple

Postby lverona » Mon May 07, 2012 7:50 am

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.
lverona
 
Posts: 221
Joined: Tue Apr 24, 2012 11:54 am
Score: 1 Give a positive score

Re: Perfect collision exemple

Postby phyzix5761 » Mon May 07, 2012 8:22 am

I am using the original method and collision events don't work.
phyzix5761
 
Posts: 261
Joined: Sun Feb 27, 2011 4:28 am
Score: 18 Give a positive score

Re: Perfect collision exemple

Postby lverona » Mon May 07, 2012 9:05 am

Hehe. Indeed. This is why you need to use my method which I described in the above post to achieve that.
lverona
 
Posts: 221
Joined: Tue Apr 24, 2012 11:54 am
Score: 1 Give a positive score

Re: Perfect collision exemple

Postby Game A Gogo » Mon May 07, 2012 3:48 pm

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
Programming games is an art,
    Respect it.
User avatar
Game A Gogo
 
Posts: 3466
Joined: Wed Jun 29, 2005 10:49 pm
Location: French Canada *laughs*
Score: 181 Give a positive score

Re: Perfect collision exemple

Postby lverona » Mon May 07, 2012 4:07 pm

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?
lverona
 
Posts: 221
Joined: Tue Apr 24, 2012 11:54 am
Score: 1 Give a positive score

Re: Perfect collision exemple

Postby Game A Gogo » Mon May 07, 2012 5:28 pm

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?

:)
Programming games is an art,
    Respect it.
User avatar
Game A Gogo
 
Posts: 3466
Joined: Wed Jun 29, 2005 10:49 pm
Location: French Canada *laughs*
Score: 181 Give a positive score

Re: Perfect collision exemple

Postby phyzix5761 » Sun May 27, 2012 3:02 pm

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.
phyzix5761
 
Posts: 261
Joined: Sun Feb 27, 2011 4:28 am
Score: 18 Give a positive score

Re: Perfect collision exemple

Postby lverona » Tue May 29, 2012 7:51 am

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.
lverona
 
Posts: 221
Joined: Tue Apr 24, 2012 11:54 am
Score: 1 Give a positive score

Re: Perfect collision exemple

Postby phyzix5761 » Fri Jun 01, 2012 4:08 pm

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.
phyzix5761
 
Posts: 261
Joined: Sun Feb 27, 2011 4:28 am
Score: 18 Give a positive score

Re: Perfect collision exemple

Postby Game A Gogo » Mon Jun 11, 2012 3:42 pm

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
Programming games is an art,
    Respect it.
User avatar
Game A Gogo
 
Posts: 3466
Joined: Wed Jun 29, 2005 10:49 pm
Location: French Canada *laughs*
Score: 181 Give a positive score

PreviousNext

Return to Game Demos

Who is online

Users browsing this forum: No registered users and 1 guest