PDA

View Full Version : [AS2] Enemy Collision Detection, Movement


acetinski
05-04-2009, 12:19 AM
Hey guys, I'm new here and I'm making a zombie game for a school assessment. I look very forward to speaking with you guys regarding some issues and ideas for this game.

The game is a top down shooter, you move your player with the arrow keys, and zombies approach you, and when you meet them, you cannot run through them.

Eventually, I aim for the zombies to not be able to pass through eachother, so you eventually get swarmed (and it'll look much better if they haven't all merged into one super zombie...).

I have coded the Player movement system, the Zombie's movement system, and the Player's Hittests (see below) - yet I have come across some issues.


The player, depending on the order of the if statement (in the collision), has varied effectiveness with collisions - if I put the X-Axis detections first, it only works properly on this axis. Similar to if the Y-Axis is first.
The Zombies, when hitting the player, make him teleport away - due to the Player hit detections, and the way the Zombies moves - making them push him around.


Player Movement (in Player movie clip)
if (Key.isDown(Key.LEFT)){
this._x -= speed
_global.posq = {x: _x, y: _y}}
// _global.posq is used to allow the zombies to know the player's position
if (Key.isDown(Key.RIGHT)){
this._x += speed
_global.posq = {x: _x, y: _y}}
if (Key.isDown(Key.UP)){
this._y -= speed
_global.posq = {x: _x, y: _y}}
if (Key.isDown(Key.DOWN)){
this._y += speed
_global.posq = {x: _x, y: _y}}

Player Collision Detection (in Player movie clip)
for (i in _root.ZombieList){
if (this.hitTest(_root.ZombieList[i])){
PZomb = _root.ZombieList[i]
trace(PZomb)
if ((this._y + this._height >= PZomb._y) && (this._y <= PZomb._y)){
trace("Hit from top!")
this._y -= speed
_global.posq = {x: _x, y: _y}}
if ((this._y <= PZomb._y + PZomb._height) && (this._y >= PZomb._y)){
trace("Hit from bottom!")
this._y += speed
_global.posq = {x: _x, y: _y}}
if ((this._x <= PZomb._x + PZomb._width) && (this._x >= PZomb._x)) {
trace("Hit from right!")
this._x += speed
_global.posq = {x: _x, y: _y}}
if ((this._x + this._width >= PZomb._x) && (this._x <= PZomb._x )) {
trace("Hit from left!")
this._x -= speed
_global.posq = {x: _x, y: _y}}

Zombie Movement (in a movie clip, inside the main Zombie movie clip)
// Get distance.
var xdist:Number = Math.pow((_parent._x - posq.x), 2)
var ydist:Number = Math.pow((_parent._y - posq.y), 2)
var todist:Number = this.xdist + this.ydist
var totdist:Number = Math.sqrt(todist)

// Testing.
if (totdist > 12){
//Up + Right
var nuxdist:Number = Math.pow((_parent._x + 4 - posq.x), 2)
var nuydist:Number = Math.pow((_parent._y - 3 - posq.y), 2)
var nutodist:Number = this.nuxdist + this.nuydist
var nutotdist:Number = Math.sqrt(nutodist)
if (nutotdist < totdist){
_parent._x += 2
_parent._y -= 1.5}
// Up + Left
var nuxdist:Number = Math.pow((_parent._x - 4 - posq.x), 2)
var nuydist:Number = Math.pow((_parent._y - 3 - posq.y), 2)
var nutodist:Number = this.nuxdist + this.nuydist
var nutotdist:Number = Math.sqrt(nutodist)
if (nutotdist < totdist){
_parent._x -= 2
_parent._y -= 1.5}
// Down + Right
var nuxdist:Number = Math.pow((_parent._x + 4 - posq.x), 2)
var nuydist:Number = Math.pow((_parent._y + 3 - posq.y), 2)
var nutodist:Number = this.nuxdist + this.nuydist
var nutotdist:Number = Math.sqrt(nutodist)
if (nutotdist < totdist){
_parent._x += 2
_parent._y += 1.5}
// Down + Left
var nuxdist:Number = Math.pow((_parent._x - 4 - posq.x), 2)
var nuydist:Number = Math.pow((_parent._y + 3 - posq.y), 2)
var nutodist:Number = this.nuxdist + this.nuydist
var nutotdist:Number = Math.sqrt(nutodist)
if (nutotdist < totdist){
_parent._x -= 2
_parent._y += 1.5}


}

(I think I could really improve on the Zombie movement)

Thanks for the help, and tell me if you need anything else from me. I will upload the main swf soon.

acetinski
05-04-2009, 12:23 AM
Sorry for the double post, I'm posting this thread in school so the browsers are logging me out left right and centre - so I decided that I'd post the main post then upload if possible.

Here's the main file - in case you need to know more about structure, etc.

Playaction
05-06-2009, 09:33 AM
Let's see if i can help a little.

For the zombie collision, you could start by checking if the x or y axis is closer by comparing :

xdist = Math.abs(this._x - PZomb._x)
ydist = Math.abs(this._y - PZomb._y)

if xdist is smaller, the zombie is closer to the left or right. Then it's just a matter of checking if the PZomb._x is higher or lower than this._x to determine if it's to the left or right.

When the hittest returns true, you should probably tell the zombie to stop moving, and bite instead. And instead of bumping the character, you could make sure that he can't move in the zombies direction.

I hope this helps part of your problem.

acetinski
05-06-2009, 10:56 AM
Thank you so much for your help! :D

Using your method for player collision, I was able to not only get the collisions working correctly, but also clean up my code a lot!
I'm about to work on the zombies stopping as they meet the player - but there is a tiny issue with movement.

I changed the player movement code to read:
if ((Key.isDown(Key.LEFT)) && (Key.isDown(Key.UP))){
if ((dirall.left == true) && (dirall.up == true)){
this._x -= speed
this._y -= speed
dirall.right = true
dirall.down = true}}
else if ((Key.isDown(Key.LEFT)) && (Key.isDown(Key.DOWN))){
if ((dirall.left == true) && (dirall.down == true)){
this._x -= speed
this._y += speed
dirall.right = true
dirall.up = true}}
else if ((Key.isDown(Key.RIGHT)) && (Key.isDown(Key.UP))){
if ((dirall.left == true) && (dirall.up == true)){
this._x += speed
this._y -= speed
dirall.left = true
dirall.down = true}}
else if ((Key.isDown(Key.RIGHT)) && (Key.isDown(Key.DOWN))){
if ((dirall.left == true) && (dirall.down == true)){
this._x += speed
this._y += speed
dirall.left = true
dirall.up = true}}
else if (Key.isDown(Key.LEFT)){
if (dirall.left == true){
this._x -= speed
dirall.right = true
dirall.up = true
dirall.down = true}}
else if (Key.isDown(Key.RIGHT)){
if (dirall.right == true){
this._x += speed
dirall.left = true
dirall.up = true
dirall.down = true}}
else if (Key.isDown(Key.UP)){
if (dirall.up == true){
this._y -= speed
dirall.down = true
dirall.left = true
dirall.right = true}}
else if (Key.isDown(Key.DOWN)){
if (dirall.down == true){
this._y += speed
dirall.up = true
dirall.left = true
dirall.right = true}}

And the collision code to read:
for (i in _root.ZombieList){
if (this.hitTest(_root.ZombieList[i])){
PZomb = _root.ZombieList[i]
trace(PZomb)
xpri = Math.abs(this._x - PZomb._x)
ypri = Math.abs(this._y - PZomb._y)
if (xpri > ypri){
trace("xpri")
if (this._x > PZomb._x){
dirall.left = false}
else {
dirall.right = false}}
else {
trace("ypri")
if (this._y > PZomb._y ){
dirall.up = false}
else {
dirall.down = false}}
}
}

This works well, however, if the player hits Left and a Y-Direction at the same time, they can pass right through a zombie diagonally - despite the fact that I created special cases for multiple buttons being held (this did fix the right hand side, I think).
I can't really think of a way to fix this, sadly.

Any more help is much appreciated - you've been great so far :D

Playaction
05-07-2009, 08:30 AM
I can't see the exact problem, but i imagine it could be something like this.

If the zombie is approaching from the bottom right and hits the character. The zombie is slightly more down than right, you set dirall.down = false.

When the user presses right key first, and then down key, the right keypress sets dirall.down = true. That would allow the character to move freely.

You could try to set all dirall to true just before "for (i in _root.ZombieList){" and removing them from the keypress functions. That way he can be surrounded.

I hope that helps.

As for the zombies - you could do something like :

for (i in _root.ZombieList){
PZomb = _root.ZombieList[i]
PZombstopandbite = false;
if (this.hitTest(PZomb)){
PZomb.stopandbite = true;
trace(PZomb)

...


And when moving the zombie, you could check the stopandbite variable to see if it should move or bite.

Remember to post your final game, when you're done. I like nothing better than killing zombies! (actually i'm working on my own zombie game at the moment, which is tile- and turnbased)

acetinski
05-07-2009, 11:03 PM
I've actually realised that my code has been written poorly, with little focus on modularisation - and so I'm going to be restructuring it - I'll make sure to add in your recommendations while I'm in the process of re-coding :D

And it's cool that you're also making a zombie game! I'll check it out when it's done!

I'll post back with info soon ^_^