Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm creating an online-canvas-game with a tank as player object.

Now I have several structures in my canvas, that shouldn't be able to be overdriven by the tank...
My solution is to detect the collision like that:

if(hero.x > reactor[i]['x'] - 32 && hero.x <= reactor[i]['x'] + 32
   && hero.y > reactor[i]['y'] - 32 && hero.y <= reactor[i]['y']){
    collidetop = true;
}

if(hero.x > reactor[i]['x'] - 32 && hero.x <= reactor[i]['x'] + 32
   && hero.y >= reactor[i]['y'] && hero.y < reactor[i]['y'] + 32){
    collidebottom = true;
}

if(hero.x > reactor[i]['x'] - 32 && hero.x <= reactor[i]['x']
   && hero.y > reactor[i]['y'] - 32 && hero.y <= reactor[i]['y'] + 32){
    collideleft = true;
}

if(hero.x > reactor[i]['x'] && hero.x <= reactor[i]['x'] + 32
   && hero.y > reactor[i]['y'] - 32 && hero.y <= reactor[i]['y'] + 32){
    collideright = true;
}

The hero object is the tank, hero.x the x-coordinate, and so on...
Now I'd like to deactivate the keyboard input for the direction key, if the objects collide...
For this reason I have the variables wok, aok, sok and dok - they all contain booleans.
If wok = false, then the key "w" is deactivated...
I've connected the collide variables to the keyboard inputs:

if(collidetop == true){
    sok = false;
}
if(collidetop == false){
    sok = true;
}
if(collidebottom == true){
    wok = false;
}
if(collidebottom == false){
    wok = true;
}
if(collideright == true){
    aok = false;
}
if(collideright == false){
    aok = true;
}
if(collideleft == true){
    dok = false;
}
if(collideleft == false){
    dok = true;
} 

My problem is: if the tank doesn't collide the other object any more, the keys stay blocked... Could you help me with that?

share|improve this question
    
Welcome to gamedev SE! I've edited a bit your most so it looks better, that's a collaboratively-edited Q&A answer so this is usual around here. Check the FAQ for details. –  Laurent Couvidou May 22 '12 at 18:43
add comment

2 Answers

Say your tanks has driven into a wall. It shouldn't be able to move forward anymore. In this case you disable the key that gives the 'move forward' command however I think this is the wrong way of looking at it. You can still give the tank the move forward command, that shouldn't be a problem, what really is stopping it from moving forward is the wall.

I would take the following approach:

A tank/users should always be able to request to move however the physics system should decided if the tank moves. This means that you would have the following setup:

1: Tank wants to move forward
2: The physics system stores the old position of the tank
3: The physics system moves the tank forward
4: The physics system checks if the tank now collides with something
5: If the tank collides with something move it back to old position, if it didn't collide with something everything is good, keep it where it is.

Having the physics system do all the movements also has the added benefit that other things than user input can move the tank, for example explosions, as long as they request the physics system to move it everything should be OK and you only have to write the code once.

share|improve this answer
add comment

Deactivating input isn't the usual way to react to environment collisions. In a nutshell, it's probably a better idea to affect your tank position when a collision is detected. Roy T. just gave you one proper solution.

You could also do as follows without modifying too much code, just stick the tank to one of the reactor's edges when a collision is detected:

if(hero.x > reactor[i]['x'] - 32 && hero.x <= reactor[i]['x'] + 32 &&
   hero.y > reactor[i]['y'] - 32 && hero.y <= reactor[i]['y'] - 28){
    hero.y = reactor[i]['y'] -33;
}

if(hero.x > reactor[i]['x'] - 32 && hero.x <= reactor[i]['x'] + 32 &&
   hero.y >= reactor[i]['y'] + 28 && hero.y < reactor[i]['y'] + 32){
    hero.y = reactor[i]['y'] +33;
}

if(hero.x > reactor[i]['x'] - 32 && hero.x <= reactor[i]['x'] - 28 &&
   hero.y > reactor[i]['y'] - 32 && hero.y <= reactor[i]['y'] + 32){
    hero.x = reactor[i]['x'] -33;
}

if(hero.x > reactor[i]['x'] + 28 && hero.x <= reactor[i]['x'] + 32 &&
   hero.y > reactor[i]['y'] - 32 && hero.y <= reactor[i]['y'] + 32){
    hero.x = reactor[i]['x'] +33;
}

This glitches easily if your tank moves fast compared to the reactor's size, but it should at least give you the satisfaction of quickly seeing something that works.

The topic of game collisions and physics in general is huge, so I recommend you find a good resource to learn the basics. Or if you just want collisions but don't want to learn the details, you could try out an existing library, such as Box3DJS (I've not tested it personally so I don't know if it's a good one).

share|improve this answer
    
Yes, thats nice, but with that, my tank won't stay in the middle of the canvas element... –  Philip May 22 '12 at 19:59
    
maybe you like to look at my whole code: philip-maerz.de/game/canvastank/test.html –  Philip May 22 '12 at 20:00
    
Good suggestion to clip it. My quick example would have the tank hover near to the wall but not have it touch it, this fixes that! –  Roy T. May 22 '12 at 20:09
    
My Problem is, that there is nearly no "physics engine" :D Could you give a small example of how that would look like with my code? –  Philip May 22 '12 at 20:20
    
Ah indeed, on second thought, this just couldn't work. As this was splitting the bounding box in halves, there was no way to know on which border to stick the tank without knowing where it's coming from. I've tweaked my answer to use strips on the bounding box sides instead, this does the trick. But it's still far from a perfect solution: glitches on the corners, and you'll get screwed with a faster moving tank. As an exercise, try implementing Roy's solution yourself ;) –  Laurent Couvidou May 22 '12 at 22:22
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.