Collision not detecting multiple instances of the same Sprite

I’m fairly new to Flash and have stumbled through it so far with varying levels of success.

Application:

I’m trying to develop a simple drum beat maker for a Uni project. The idea is that the user will select a note and place it onto the stave (the music score lines). On pressing a play button a play line will animate along the staves and on collision with the notes play the appropriate sound.

To view the current progress go here and select Create Mode.

The major problem I am having is that the MovieClip of the playline is only detecting collision with the last note that I place for a particular container. I’m not sure if this is a display object issue or just bad coding. I’ve been tackling Flash and AS3 without much tutor tuition, so the basics and good practices aren’t clear to me.

Below is the code I’ve come up with:

Selecting and adding a note:

//Variables

var greenNote:Sprite;	
var container_greenNote:MovieClip = new MovieClip();	

//Listening for note selection
floortom.addEventListener(MouseEvent.CLICK, greenNoteSelected);

//Note function
function greenNoteSelected(e:MouseEvent):void{

// The GreenDrumNote is the linkage ID of the actual image for the note	
var addGreenNote:GreenDrumNote = new GreenDrumNote();	//Creates child of drum note

//I've add all of the same type of notes to a single container	
container_greenNote.addChild(addGreenNote);
addChild(container_greenNote);

//Used for removing containers	
numberGreenNotes++						 //Increase when a green note is added

//This is could be where the issue is occurring as every note has the same name.
greenNote = Sprite(addGreenNote);		//Becomes the refered to sprite for all related notes

//However I have additional code checking for mouseover of the notes and it works for ALL notes placed, so Flash is recognising each note on mouseover, but not for collision between another movieclip
greenNote.name = "Floor Tom";	
	
greenNote.startDrag(true); 				//Sets child as mouse cursor
	
Mouse.hide();							//Hides the mouse pointer
	
	stage.addEventListener(MouseEvent.CLICK, placeGreenNote);
}
 
//Placing note on a single stave
function placeGreenNote(e:MouseEvent):void{

  //Checks to see if note is positioned on timeline		
    if(stave1.hitTestObject(greenNote)){				

      //Places note on timeline	
      greenNote.x = stave1.x && stage.mouseX;		
      greenNote.y = stave1.y;
      
      dropNote=new add_sound();
      dropNoteChannel=dropNote.play();
      
      stage.removeEventListener(MouseEvent.CLICK, greenNoteEdit);
      stage.removeEventListener(MouseEvent.CLICK, placeGreenNote);
      
      greenNote.stopDrag();
      Mouse.show();

      //Deleting the note by dragging to trash
      }else if(trashcan.hitTestObject(greenNote)){
      
      stage.removeEventListener(MouseEvent.CLICK, placeGreenNote);

      container_greenNote.removeChild(MovieClip(e.target));
      numberGreenNotes--
      Mouse.show();
      
      Deleted=new recycle_sound();
      DeletedChannel=Deleted.play();	
		
      if (numberGreenNotes == 0){
        removeEventListener(Event.ENTER_FRAME,greenNoteDetection);
      }
    }
      greenNote.addEventListener(MouseEvent.MOUSE_DOWN, greenNoteEdit);
      greenNote.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
      greenNote.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
}

Play button code. Not so important as it just animated the movieclip and at the moment will start checking for collision

timeline_play.addEventListener(MouseEvent.CLICK, playStart);

function playStart (e:MouseEvent):void{
//The event listener which will start producing my tracing command repeatedly. 
	addEventListener(Event.ENTER_FRAME, greenNoteDetection);
	playline.gotoAndPlay("Speed_1");
}

My attempt at the collision detection code

function greenNoteDetection(e:Event):void {
		
	if (playline.hitTestObject(greenNote)){
		trace ("Green Note collision");
	} else{
		trace ("Off");
	}
}

Sorry if this is long winded, but it may help to visit the link and give it a play to see how it works.

because the next greennote overrides the action of previous note. you will have to access the objects as object array to uniquely identify each greennote.

Thats for the response, I had a feeling it would be something like that. Strange because the mouseover action still works fine.

Any advice, or tips for using this array object you speak of?

Instead of setting a single variable equal to the new thing, make the variable be an array (new Array()) and then use greennote.push(myNewNote).

Then when you do playback, you’ll have to loop through each one and play all of their notes.

I’m currently working on implementing the array, but it’s not as simple as using push.

My code won’t allow it to work correctly as notes can also be deleted and I’ll need a way of tracking each note and corresponding index of the array so as not to overwrite any, and also be able to remove the correct index as the note is removed.

The below code adds the X coordinate of the current note within the index that relates to the sprites display list ID. This obviously causes issues as when a sprite is removed, the display list ID’s reduce by 1, meaning that a value in the array is going to get overwritten.

greenNoteArray[container_greenNote.getChildIndex(MovieClip(e.target))] = greenNote.x;

If there was a way to stop the display list IDs from changing it would resolve my issue.

I can’t manually increase a number to replace the use ID’s as I won’t be able to know which index of the array to remove.

My attempt at removing an index of the array using the sprite ID’s doesn’t seem to work anyhow, the code is below but produces no errors it just doesn’t delete the value.

greenNoteArray.splice(container_greenNote.getChildIndex(MovieClip(e.target)),container_greenNote.getChildIndex(MovieClip(e.target)));

I was thinking, is there not a way to use a slightly different name for greenNote each time the user places one?

For example:
i++
“greenNote_”+i

So each greenNote would become greenNote_1, greenNote_2 etc

I was thinking I could do something like that using integers and use an if statement to check where the values lay. So if the value is less than 100 play a certain sound. But obviously the above method converts it into a string so that wouldn’t be possible.

Another simple way is to use timers instead of hittest. like when you create a new note assign it start and end variables. then start a main timer which will check every note’s start and end times everytime and compare it with its own time. lets say main timer is on 4th second and it detects that one of the note also has a starting time set to 4, it will play the relevant music and generate another timer which will keep playing independently until it reaches the end time of the note.
logic is a main timer will keep playing and will create independent threads.
this way even if you change your graphics your music will remain same.

Thanks for the response.

I actually stated work on using arrays before I saw your response, felt good!

Have updated the website with the current build. Each block has an array index which stores the value of the note. I had to use a few variables instead of the hittest command as that wouldn’t work with my current code.

I plan to cycle through the indexes of the arrays using a loop and a timer to control the speed at which each index is read.

So for example there are 40 indexes in an array, so I hope I can use math to work out at what timer intervals to cycle onto the next index.

If index[12] == 2 I would play the sound corresponding to the number 2 etc

I fairly confident the end is near.

great to hear that your work is near to end. do share it when its 100% ready and sorry for not being quick responsive, just due to the weekend and urgent tasks at wor :slight_smile:
all the best