Search code examples
actionscript-3flashflash-cs6

Please help me with this collision detection


I have created a game in Adobe Flash Professioanl CS6 and I would like some assistance.

I have two snakes that move around and leave a trail. Both snakes must die when they touch either their own or another snakes trail. Currently, they do die when they detect themselves, so that works, but it doesn't work when it detects one another.

Here is my code...

    var leftBorder:verticalwall = new verticalwall(); // defining a variable to hold the left wall
addChild(leftBorder); // adding the left wall to the stage
var rightBorder:verticalwall = new verticalwall(); // defining a variable to hold the left wall
rightBorder.x = 790; // pushing the right wall to the edge of the stage
addChild(rightBorder); // adding the right wall to the stage
var topBorder:horizontalwall = new horizontalwall(); // defining a variable to hold the left wall
addChild(topBorder); // adding the top wall to the stage
var bottomBorder:horizontalwall = new horizontalwall(); // defining a variable to hold the bottom wall
bottomBorder.y = 790;  // pushing the bottom wall to the base of the stage
addChild(bottomBorder); // adding the bottom wall to the stage

var Pspositions:Array = new Array(); // defining a new variable to hold the poistions of Player 1


stage.addEventListener(KeyboardEvent.KEY_DOWN,restartgame); // adding a listener to the stage
function restartgame(e:KeyboardEvent){ // defining a function that restarts the game
   if(e.keyCode==Keyboard.SPACE){ // listens for the SPACE button to be pressed
       //code here
   }
}

graphics.beginFill( 0x000000 ); // defining a colour for the background
graphics.drawRect( 0, 0, stage.stageWidth, stage.stageHeight);  // drawing a rectangle for background
graphics.endFill(); // ending the background creating process

// Player 1

var Player1:Shape = new Shape(); // defining a variable for Player 1
Player1.graphics.lineStyle(10,0xffff00); // defining the colour of the style
Player1.graphics.beginFill(0xffff00,3600); // begin filling the shape
//Player1.graphics.drawRoundRect(0,0,3,3,360);
Player1.graphics.drawCircle(Player1.x, Player1.y, 2.4) // draw a circle
Player1.graphics.endFill(); // finish the filling process
addChild(Player1); // add player 1 to stage

var P1leftPressed:Boolean = false; // boolean to check whether the left key for Player 1 was pressed
var P1rightPressed:Boolean = false; // boolean to check whether the right key for Player 1 was pressed
var P1speed = 3.5;  // variable to store the speed of which player 1 moves
var P1Dir = 45; // variable containing the direction in which player 1 moves
var P1position, P2position;

Player1.addEventListener(Event.ENTER_FRAME, P1fl_MoveInP1DirectionOfKey);  // adding a listener to the player
stage.addEventListener(KeyboardEvent.KEY_DOWN, P1fl_SetKeyPressed); // listener for a key to be pressed
stage.addEventListener(KeyboardEvent.KEY_UP, P1fl_UnsetKeyPressed); // listener for a key to be released

function P1fl_MoveInP1DirectionOfKey(event:Event) // Moves the player depedning on what key was pressed
{
    //var dead;
    /*if(dead == false){
        trace(P1position + " _____________ " + P2position);
    }*/
    if(Player1.hitTestObject(leftBorder) || Player1.hitTestObject(rightBorder) || Player1.hitTestObject(topBorder) || Player1.hitTestObject(bottomBorder)){ // checking to see whether Player 1 has hit the wall
        P1speed = 0; // stopping Player 1 from moving
        //dead = true;
    }
    for (var i = 0; i < Pspositions.length - 10; i++) { // a loop that opperates for as long as the array is receiving positions
        var P1x = Pspositions[i][0]; // saving x positions into array with a unique identifier
        var P1y = Pspositions[i][1]; // saving y positions into array with a unique identifier

        if (distanceBetween(P1x, P1y, Player1.x, Player1.y) < 15) { // checking distance between Player 1 and its trail
            P1speed = 0;
        }
        if (distanceBetween(P1x, P1y, Player2.x, Player2.y) < 15) { // checking distance between Player 1 and its trail
            P1speed = 0;
        }
    }

    if (P1leftPressed)
    {
        P1Dir -= 0.1; // changes the direction to make Player 1 rotate
    }
    if (P1rightPressed)
    {
        P1Dir += 0.1; // changes the direction to make Player 1 rotate
    }

    P1position = [Player1.x, Player1.y]; // defining a variable for Player 1's constant positions
    Pspositions.push(P1position); // pushes every position of Player 1 to the array
    trace(P1position + " _____________ " + P2position);

    Player1.x += P1speed * Math.cos(P1Dir); // this makes player 1 move forard
    Player1.y += P1speed * Math.sin(P1Dir); // this makes player 2 move forward

    var P1trail:Shape = new Shape; // defining a variable for player 1's trail
    graphics.lineStyle(8, 0xFF0000); // setting the format for the trail
    graphics.drawCircle(Player1.x, Player1.y, 1.4); // drawing the circles within the trail
    addChild(P1trail); // adding the circles to the stage
}

function P1fl_SetKeyPressed(event:KeyboardEvent):void
{
    switch (event.keyCode)
    {
        case Keyboard.LEFT:
        {
            P1leftPressed = true; // tells the computer that left has been pressed
            break;
        }
        case Keyboard.RIGHT:
        {
            P1rightPressed = true; // tells the computer that right has been pressed
            break;
        }
    }
}

function P1fl_UnsetKeyPressed(event:KeyboardEvent):void
{
    switch (event.keyCode)
    {
        case Keyboard.LEFT:
        {
            P1leftPressed = false; // tells the computer that left has been released
            break;
        }
        case Keyboard.RIGHT:
        {
            P1rightPressed = false; // tells the computer that left has been released
            break;
        }
    }
}

/*function object(x, y) {
    this.x = x;
    this.y = y;
}

function player(x, y) {

}*/

function distanceBetween (x1:Number, y1:Number, x2:Number, y2:Number) { // creating a function
    // return d = Math.sqrt(x2 - x1)^2 +(y2 - y1)^2);
    var diffX = x2 - x1; // creating variable to tidy up the pythagoras line below
    var diffY = y2 - y1; // creating variable to tidy up the pythagoras line below
    return Math.sqrt(diffX * diffX + diffY * diffY); // using pythagras theorem
}

// Player 2

var Player2:Shape = new Shape(); // Defining a variable
Player2.graphics.lineStyle(10,0xffff00);
Player2.graphics.beginFill(0xffff00,3600);
Player2.graphics.drawCircle(Player1.x, Player1.y, 2.4)
Player2.graphics.endFill();
addChild(Player2);

var P2leftPressed:Boolean = false;
var P2rightPressed:Boolean = false;
var P2speed = 3.5;
var P2Dir = 180;

Player2.addEventListener(Event.ENTER_FRAME, P2fl_MoveInP1DirectionOfKey);
stage.addEventListener(KeyboardEvent.KEY_DOWN, P2fl_SetKeyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, P2fl_UnsetKeyPressed);

function P2fl_MoveInP1DirectionOfKey(event:Event)
{
    if(Player2.hitTestObject(leftBorder) || Player2.hitTestObject(rightBorder) || Player2.hitTestObject(topBorder) || Player2.hitTestObject(bottomBorder)){
        P2speed = 0;
    }
    for (var a = 0; a < Pspositions.length - 10; a++) {
        var P2x = Pspositions[a][0];
        var P2y = Pspositions[a][1];

        if (distanceBetween(P2x, P2y, Player2.x, Player2.y) < 15) {
            P2speed = 0;
        }
    }
    if (P2leftPressed)
    {
        P2Dir -= 0.1;
    }
    if (P2rightPressed)
    {
        P2Dir += 0.1;
    }

    P2position = [Player2.x, Player2.y];
    //trace(P2position);
    Pspositions.push(P2position);



    Player2.x += P2speed * Math.cos(P2Dir);
    Player2.y += P2speed * Math.sin(P2Dir);

    var P2trail:Shape = new Shape;
    graphics.lineStyle(8, 0x0066CC);
    graphics.drawCircle(Player2.x, Player2.y, 1.4);
    addChild(P2trail);
}

function P2fl_SetKeyPressed(event:KeyboardEvent):void
{
    switch (event.keyCode)
    {
        case event.keyCode = 90:
        {
            P2leftPressed = true;
            break;
        }
        case event.keyCode = 67:
        {
            P2rightPressed = true;
            break;
        }
    }
}

function P2fl_UnsetKeyPressed(event:KeyboardEvent):void
{
    switch (event.keyCode)
    {
        case event.keyCode=90:
        {
            P2leftPressed = false;
            break;
        }
        case event.keyCode=67:
        {
            P2rightPressed = false;
            break;
        }
    }
}

This if for actionscript 3.0

Thans, any help would be appreciated :)


Solution

    1. Use single postions array for both players.
    2. Consequently incresse size of "heads" - PSpositions.length - 10
    3. Draw snakes where they actually are:

      Player1.graphics.drawCircle(Player1.x, Player1.x, 2.4)
      

      instead of

      Player1.graphics.drawCircle(Player1.x + ..., Player1.x + ..., 2.4)
      
    4. Set players different start position so they don't colide at first frame.

    You not paying attention... Here the working version:

    import flash.display.Shape;
    
    var leftBorder = verticalwall; // defining a variable to hold the left wall
    addChild(leftBorder); // adding the left wall to the stage
    var rightBorder = verticalwall; // defining a variable to hold the left wall
    rightBorder.x = 790; // pushing the right wall to the edge of the stage
    addChild(rightBorder); // adding the right wall to the stage
    var topBorder = horizontalwall;  //defining a variable to hold the left wall
    addChild(topBorder);  //adding the top wall to the stage
    var bottomBorder = horizontalwall;  //defining a variable to hold the bottom wall
    bottomBorder.y = 790;   //pushing the bottom wall to the base of the stage
    addChild(bottomBorder);  //adding the bottom wall to the stage
    
    var P1positions:Array = new Array();  //defining a new variable to hold the poistions of Player 1
    var P2positions:Array = new Array();  //defining a new variable to hold the poistions of Player 2
    
    
     //Player 1
    
    var Player1:Shape = new Shape();  //defining a variable for Player 1
    Player1.graphics.lineStyle(10,0xffff00);  //defining the colour of the style
    Player1.graphics.beginFill(0xffff00,3600);  //begin filling the shape
    Player1.graphics.drawRoundRect(0,0,3,3,360);
    Player1.graphics.drawCircle(Player1.x, Player1.x, 2.4) //draw a circle
    Player1.graphics.endFill();  //finish the filling process
    addChild(Player1);  //add player 1 to stage
    
    var P1leftPressed:Boolean = false;  //boolean to check whether the left key for Player 1 was pressed
    var P1rightPressed:Boolean = false;  //boolean to check whether the right key for Player 1 was pressed
    var P1speed = 3.5;   //variable to store the speed of which player 1 moves
    var P1Dir = 45;  //variable containing the direction in which player 1 moves
    var P1position, P2position;
    
    Player1.addEventListener(Event.ENTER_FRAME, P1fl_MoveInP1DirectionOfKey);   //adding a listener to the player
    stage.addEventListener(KeyboardEvent.KEY_DOWN, P1fl_SetKeyPressed);  //listener for a key to be pressed
    stage.addEventListener(KeyboardEvent.KEY_UP, P1fl_UnsetKeyPressed); // listener for a key to be released
    
    function P1fl_MoveInP1DirectionOfKey(event:Event)  //Moves the player depedning on what key was pressed
    {
        if(Player1.hitTestObject(leftBorder) || Player1.hitTestObject(rightBorder) || Player1.hitTestObject(topBorder) || Player1.hitTestObject(bottomBorder)){  //checking to see whether Player 1 has hit the wall
            P1speed = 0;  //stopping Player 1 from moving
        }
        if (P1leftPressed)
        {
            P1Dir -= 0.1;  //changes the direction to make Player 1 rotate
        }
        if (P1rightPressed)
        {
            P1Dir += 0.1;  //changes the direction to make Player 1 rotate
        }
    
        P1position = [Player1.x, Player1.y];  //defining a variable for Player 1's constant positions
        P1positions.push(P1position);  //pushes every position of Player 1 to the array
        trace(P1position + " _____________ " + P2position);
    
        for (var i = 0; i < P1positions.length - 10; i++) {  //a loop that opperates for as long as the array is receiving positions
            var P1x = P1positions[i][0];  //saving x positions into array with a unique identifier
            var P1y = P1positions[i][1];  //saving y positions into array with a unique identifier
    
            if (distanceBetween(P1x, P1y, Player1.x, Player1.y) < 15) {  //checking distance between Player 1 and its trail
                P1speed = 0;
            }
        }
    
        Player1.x += P1speed * Math.cos(P1Dir);  //this makes player 1 move forard
        Player1.y += P1speed * Math.sin(P1Dir);  //this makes player 2 move forward
    
        var P1trail:Shape = new Shape;  //defining a variable for player 1's trail
        graphics.lineStyle(8, 0xFF0000);  //setting the format for the trail
        graphics.drawCircle(Player1.x, Player1.y, 1.4);  //drawing the circles within the trail
        addChild(P1trail);  //adding the circles to the stage
    }
    
    function P1fl_SetKeyPressed(event:KeyboardEvent):void
    {
        switch (event.keyCode)
        {
            case Keyboard.LEFT:
            {
                P1leftPressed = true;  //tells the computer that left has been pressed
                break;
            }
            case Keyboard.RIGHT:
            {
                P1rightPressed = true;  //tells the computer that right has been pressed
                break;
            }
        }
    }
    
    function P1fl_UnsetKeyPressed(event:KeyboardEvent):void
    {
        switch (event.keyCode)
        {
            case Keyboard.LEFT:
            {
                P1leftPressed = false;  //tells the computer that left has been released
                break;
            }
            case Keyboard.RIGHT:
            {
                P1rightPressed = false;  //tells the computer that left has been released
                break;
            }
        }
    }
    
    function object(x, y) {
        this.x = x;
        this.y = y;
    }
    
    
    function distanceBetween (x1:Number, y1:Number, x2:Number, y2:Number) { // creating a function
        // return d = Math.sqrt(x2 - x1)^2 +(y2 - y1)^2);
        var diffX = x2 - x1; // creating variable to tidy up the pythagoras line below
        var diffY = y2 - y1; // creating variable to tidy up the pythagoras line below
        return Math.sqrt(diffX * diffX + diffY * diffY); // using pythagras theorem
    }
    
    // Player 2
    
    var Player2:Shape = new Shape(); // Defining a variable
    Player2.graphics.lineStyle(10,0xffff00);
    Player2.graphics.beginFill(0xffff00,3600);
    Player2.graphics.drawCircle(Player1.x, Player1.x, 2.4)
    Player2.graphics.endFill();
    addChild(Player2);
    Player2.x = 500;
    Player2.y = 500;
    
    var P2leftPressed:Boolean = false;
    var P2rightPressed:Boolean = false;
    var P2speed = 3.5;
    var P2Dir = 180;
    
    Player2.addEventListener(Event.ENTER_FRAME, P2fl_MoveInP1DirectionOfKey);
    stage.addEventListener(KeyboardEvent.KEY_DOWN, P2fl_SetKeyPressed);
    stage.addEventListener(KeyboardEvent.KEY_UP, P2fl_UnsetKeyPressed);
    
    function P2fl_MoveInP1DirectionOfKey(event:Event)
    {
        if(Player2.hitTestObject(leftBorder) || Player2.hitTestObject(rightBorder) || Player2.hitTestObject(topBorder) || Player2.hitTestObject(bottomBorder)){
            P2speed = 0;
        }
        if (P2leftPressed)
        {
            P2Dir -= 0.1;
        }
        if (P2rightPressed)
        {
            P2Dir += 0.1;
        }
    
        P2position = [Player2.x, Player2.y];
        //trace(P2position);
        P1positions.push(P2position);
    
        for (var a = 0; a < P1positions.length - 10; a++) {
            var P2x = P1positions[a][0];
            var P2y = P1positions[a][1];
    
            if (distanceBetween(P2x, P2y, Player2.x, Player2.y) < 15) {
                P2speed = 0;
            }
        }
    
        Player2.x += P2speed * Math.cos(P2Dir);
        Player2.y += P2speed * Math.sin(P2Dir);
    
        var P2trail:Shape = new Shape;
        graphics.lineStyle(8, 0x0066CC);
        graphics.drawCircle(Player2.x, Player2.y, 1.4);
        addChild(P2trail);
    }
    
    function P2fl_SetKeyPressed(event:KeyboardEvent):void
    {
        switch (event.keyCode)
        {
            case event.keyCode = 90:
            {
                P2leftPressed = true;
                break;
            }
            case event.keyCode = 67:
            {
                P2rightPressed = true;
                break;
            }
        }
    }
    
    function P2fl_UnsetKeyPressed(event:KeyboardEvent):void
    {
        switch (event.keyCode)
        {
            case event.keyCode=90:
            {
                P2leftPressed = false;
                break;
            }
            case event.keyCode=67:
            {
                P2rightPressed = false;
                break;
            }
        }
    }
    

    Also note that this is not very efficienty - U check every previous position of snake each frame and each frame you adding new positions to set - your game will slow down eventually. Think about some optimizations like slice your map into grid or something...