AS3 HitTest between classes? - actionscript-3

I'm gonna trying to explain as good as I can but, it's really hard to explain. I'm new to AS3 so if you are gonna help me, please help me til we solve it. Please paste code examples instead of just saying how I should do.
Ok.
On the main timeline I saying like this.
TIMER HERE THAT ADDS THE ENEMY EVERY SECOND!
var Enemy:MovieClip = new Enemy();
addChild(Enemy);
Enemy.x = 200;
Enemy.y = 200;
ANOTHER TIME THAT ADDS BULLETS EVERY .5 SECONDS!
var Bullet:MovieClip = new Bullet();
addChild(Enemy);
Bullet.x = 400;
Bullet.y = 400;
And then inside Enemy.as and Bullet.as I have code that says how it should travels, what speed etc. But how do I make a hitTest between these? I've tried to do it inside the enemy or bullet class like this.
So I basic asking for how I can hitTest two classes agianst each other? Or the object of a class?

You need to keep a reference on those enemies and bullets. Dont do var enemy:MovieClip = new Enemy(); instead do this.
var myEnemyList:Array = new Array();
var myBulletList:Array = new Array();
function Init():void{
addEventListener(Event.OnEnterFrame, Update);
}
function Update(){
//this will create a bullet and an enemy at every frame
//Create a new enemy
var enemy:Enemy = new Enemy();
myEnemyList.push(enemy); //add enemy to the array
//Create a new bullet
var enemy:Bullet = new Bullet();
myBulletlist.push(bullet);
//Update the bullets
for(var i:int=0; i < myBulletlist.length; i++){
myBulletlist[i].Update(); //you must implement this function inside your class bullet
}
//Update the enemies
for(var i:int=0; i < myEnemyList.length; i++){
myEnemyListt[i].Update(); //you must implement this function inside your class enemy
}
CheckForCollision();
}
function CheckForCollision(){
for(var i:int=0; i < myEnemyList.length; i++){
for(var j:int =0; j < myBulletList.length; j++){
if( myEnemyList[i].collidesWith(myBulletList[j]) ){
//Collision
}
}
}
}
Btw do not try to compile this its pretty much pseudo code. I'll answer questions you have. There's also a lot of tutorials everywhere on this, a little google search would help you get more specific code.

Related

AS3 Drag and Drop

I want to make a pairing-ups by drag and drop. There are three items are supposed to move on corresponding other three items on the stage. However I can predict that adding children dynamically change the all indexes (z/depth/whatever). So when 'accidentally' someone hovers over a matched pair, mouse will be over item but dragged one stands behind. At that time 'dropping' will possibly ruin the programme.
Is there any way to avoid that situation? Any help will greatly appreciated.
You should set dragging object above all:
Sprite(draggingObject.parent).setChildIndex(draggingObject, Sprite(draggingObject.parent).numChildren - 1);
also you need to listen MOUSE_UP event at stage value.
Worked example:
import flash.display.Sprite;
import flash.events.MouseEvent;
var container:Sprite = new Sprite();
var dragged:Sprite;
addChild(container);
var card:Sprite;
for (var j:uint = 0; j < 10; j++) {
card = new Sprite();
container.addChild(card);
card.buttonMode = true;
card.graphics.beginFill(0x000000);
card.graphics.drawRect(0,0,30,30);
card.x = j*40;
card.addEventListener(MouseEvent.MOUSE_DOWN, stardDragListener);
}
stage.addEventListener(MouseEvent.MOUSE_UP, stopDragEvent);
function stardDragListener(e:MouseEvent):void {
dragged = Sprite(e.currentTarget);
Sprite(dragged.parent).setChildIndex(dragged, Sprite(dragged.parent).numChildren - 1)
dragged.startDrag();
}
function stopDragEvent(e:MouseEvent):void {
if (dragged) dragged.stopDrag();
}

Arranging items in an inventory

I'm working on an inventory system I made following a short tutorial that leaves you stranded. I've managed to get the items removed and rearrange to the correct order somewhat. For some reason though, if I click on the last item in my inventory, then on the first item, the items do not rearrange correctly.
public class Inventory {
var itemsInInventory:Array;
var inventorySprite:Sprite;
var itemNum:int;
public function Inventory(parentMC:MovieClip) {
itemNum=0;
itemsInInventory = new Array();
inventorySprite = new Sprite();
inventorySprite.x = 50;
inventorySprite.y = 360;
parentMC.addChild(inventorySprite);
}
public function makeInventoryItems(arrayOfItems:Array){
for(var i:int = 0; i < arrayOfItems.length; i++){
arrayOfItems[i].addEventListener(MouseEvent.CLICK, getItem);
arrayOfItems[i].buttonMode = true;
}
}
public function getItem(e:MouseEvent){
var item:MovieClip = MovieClip(e.currentTarget);
itemsInInventory.push(item);
inventorySprite.addChild(item);
item.x = (itemsInInventory.length-1)*40;
item.y = 0;
item.removeEventListener(MouseEvent.CLICK, getItem);
item.addEventListener(MouseEvent.CLICK, useItem);
}
public function useItem(e:MouseEvent){
var item:MovieClip = MovieClip(e.currentTarget);
itemNum = item.x;
inventorySprite.removeChild(item);
itemsInInventory.splice(item, 1);
sortInventory();
}
public function sortInventory(){
for(var i:int = 0; i < itemsInInventory.length; i++){
if(itemsInInventory[i].x > itemNum){
itemsInInventory[i].x -= 40;
}
}
itemNum=0;
}
}
I belive thats all the coding info I need to provide for help solving this mystery.
Also, a link to the game for testing. If you would like a link for a download of the game, please ask.
LINK
Instead of substracting 40px, just set their position again:
for(var i:int = 0; i < itemsInInventory.length; i++){
itemsInInventory[i].x = i*40;
}
Also, I did not even know that it is possible to give an object reference to the splice function, I would rather use:
itemsInInventory.splice(itemsInInventory.indexOf(item), 1);
And remove the event listener from the item when you delete it from the inventory in the useItem function.
item.removeEventListener(MouseEvent.CLICK, useItem);
EDIT:
With Flash Player 10, Adobe introduced the Vector class which is kind of the same as the Array class, but it can only store one data type. In your case it would be MovieClip or Sprite. The Vector class is singificantly faster and more developer friendly because you can see the help from the IDE when you are typing myVector[i].. I recommend using that instead, although there is nothing wrong with Array. It is just outdated a bit, but is helpful when you want to store more data types.
myVector:Vector.<MovieClip> = new Vector.<MovieClip>();

ActionScript: How to start something that has a method: .stop( );

Alright, so I'm making this little game in ActionScript using Flash Builder. The duck asset has an animation. I used duck.stop(); to stop the Movie Clip so the animation doesn't play.
However, when I click on the duck, I need to figure out a way to once against start the Movie Clip. Does anyone know a way I could go about doing this?
private function makeDucks(amount:uint):void
{
for(var j:int = 0; j < amount; j++){
var duck:Duck = new Duck();
addChild(duck);
duck.x = j * (duck.width + duck.width / 3);
// .stop stops the MovieClip
duck.stop();
}
}
duck.addEventListener(MouseEvent.CLICK, onDuckClicked);
private function onDuckClicked(e:MouseEvent):void
{
var duck:MovieClip = e.target as MovieClip;
if(duck)
duck.play();
}

ActionScript 3.0 Changing Direction

Alright let me make this clear. I am just doing out of interest. This is not a homework. I am doing it because I am interest in writing the ActionScript. I saw a guy website doing something amazing so I tried to copy and I want to do this:
Oh by the way you need to make a symbol and need to export for ActionScript and class name is "ball". And the button instant name is:bButton. So here's the script I wrote so far.
var boundaryRight:Number = stage.stageWidth;
var boundaryLeft:Number = 0;
var balls:Array;
var reverseRight:Number = 0;
var reverseLeft:Number = stage.stageWidth;
init();
function init(){
balls = new Array();
for(var i:Number = 0; i<10; i++){
var myBall:ball = new ball();
myBall.x=(Math.random()*boundaryRight);
myBall.y=50+i*40;
addChild(myBall);
balls.push(myBall);
}
}
addEventListener(Event.ENTER_FRAME,moveBall);
function moveBall(e:Event){
for(var i:Number = 0;i<10;i++){
var myBall:ball = balls[i];
myBall.x-=20;
if(myBall.x<boundaryLeft){
myBall.x=boundaryRight;
}
}
}
As you can see that code made the multiple ball go to left and looping over and over again. So here's what I want to do. I want to make a button and when I click the button it'll change direction like click and it change direction to right. I click it again and it'll go left again. How do I write the code for that?
Use two global variables direction and speed.
var direction:Number = 1;
var speed:Number = 20;
Instead of giving myBall.x-=20;
Give myBall.x += ( direction * speed );
In the click handling function of the button
Give direction *= -1;
You can also change speed like this.

Multiple movieclips all go to the same spot; What am i doing wrong?

So I'm trying to shoot multiple bullets out of my body and it all works except I have an odd problem of just one bullet showing up and updating to set position for the new ones.
I have a move able player thats supposed to shoot and I test this code by moving the player and shooting. Im taking it step by step in creating this.
The result of tracing the bulletContainer counts correctly in that its telling me that movieclips ARE being added to the stage; I Just know it comes down to some kind of logic that im forgetting.
Here's My Code (The Bullet it self is a class)
UPDATE*
Everything in this code works fine except for I stated earlier some code seems reduntned because I've resorted to a different approaches.
BulletGod Class:
public class bulletGod extends MovieClip{
//Register Variables
//~Global
var globalPath = "http://127.0.0.1/fleshvirusv3/serverside/"
//~MovieCLips
var newBullet:bulletClass = new bulletClass();
//~Boolean
var loadingBulletInProgress:Number = 0;
var shootingWeapon:Number = 0;
//~Timers
var fireBulletsInterval = setInterval(fireBullets, 1);
var bulletFireEvent;
//~Arrays
var bulletArray:Array = new Array();
var bulletType:Array = new Array();
var bulletContainer:Array = new Array();
//~Networking
var netBulletRequest:URLRequest = new URLRequest(globalPath+"bullets.php");
var netBulletVariables:URLVariables = new URLVariables();
var netBulletLoader:URLLoader = new URLLoader();
//~Bullet Image Loader
var mLoader:Loader = new Loader();
var mRequest:URLRequest = new URLRequest();
public function bulletGod() {
//Load every bullet for every gun
//Compile data to be requested
netBulletVariables.act = "loadBullets"
netBulletRequest.method = URLRequestMethod.POST
netBulletRequest.data = netBulletVariables;
netBulletLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
netBulletLoader.addEventListener(Event.COMPLETE, getBulletImages);
netBulletLoader.load(netBulletRequest);
}
private function getBulletImages(bulletImageData:Event){
//Request every bullet URL image
//Set vars
var bulletData = bulletImageData.target.data;
//Load images
for(var i:Number = 0; i < bulletData.numBullets; i++){
bulletArray.push(bulletData["id"+i.toString()]);
bulletType.push(bulletData["bullet"+i.toString()]);
//trace(bulletData["id"+i]+"-"+bulletData["bullet"+i]);
}
//All the arrays have been set start firing the image loader/replacer
var imageLoaderInterval = setInterval(imageReplacer, 10);
}
private function imageReplacer(){
//Check to see which image needs replacing
if(!loadingBulletInProgress){
//Begin loading the next image
//Search for the next "String" in the bulletType:Array, and replace it with an image
for(var i:Number = 0; i < bulletType.length; i++){
if(getQualifiedClassName(bulletType[i]) == "String"){
//Load this image
mRequest = new URLRequest(globalPath+"ammo/"+bulletType[i]);
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadImage);
mLoader.load(mRequest);
//Stop imageReplacer() while we load image
loadingBulletInProgress = 1;
//Stop this for() loop while we load image
i = 999;
}
}
}
}
private function loadImage(BlackHole:Event){
//Image has loaded; find which array slot it needs to go into
for(var i:Number = 0; i <= bulletType.length; i++){
if(getQualifiedClassName(bulletType[i]) == "String"){
//We found which array type it belongs to; now replace the text/url location with the actual image data
var tmpNewBullet:MovieClip = new MovieClip;
tmpNewBullet.addChild(mLoader);
//Add image to array
bulletType[i] = tmpNewBullet;
//Restart loadingBullets if there are more left
loadingBulletInProgress = 0;
//Stop for() loop
i = 999;
}
}
}
//###############################################################################################################################################
private function fireBullets(){
//If player is holding down mouse; Fire weapon at rate of fire.
if(shootingWeapon >= 1){
if(bulletFireEvent == null){
//Start shooting bullets
bulletFireEvent = setInterval(allowShooting, 500);
}
}
if(shootingWeapon == 0){
//The user is not shooting so stop all bullets from firing
if(bulletFireEvent != null){
//Strop firing bullets
clearInterval(bulletFireEvent);
bulletFireEvent = null
}
}
}
private function allowShooting(){
//This function actually adds the bullets on screen
//Search for correct bullet/ammo image to attach
var bulletId:Number = 0;
for(var i:Number = 0; i < bulletArray.length; i++){
if(bulletArray[i] == shootingWeapon){
//Bullet found
bulletId = i;
//End For() loop
i = 999;
}
}
//Create new bullet
//Create Tmp Bullet
var tmpBulletId:MovieClip = new MovieClip
tmpBulletId.addChild(newBullet);
tmpBulletId.addChild(bulletType[bulletId]);
//Add To Stage
addChild(tmpBulletId)
bulletContainer.push(tmpBulletId); //Add to array of bullets
//Orientate this bullet from players body
var bulletTmpId:Number = bulletContainer.length
bulletTmpId--;
bulletContainer[bulletTmpId].x = Object(root).localSurvivor.x
bulletContainer[bulletTmpId].y = Object(root).localSurvivor.y
//addChild(bulletContainer[bulletTmpId]);
}
//_______________EXTERNAL EVENTS_______________________
public function fireBullet(weaponId:Number){
shootingWeapon = weaponId;
}
public function stopFireBullets(){
shootingWeapon = 0;
}
}
}
BulletClass:
package com{
import flash.display.*
import flash.utils.*
import flash.net.*
import flash.events.*
public class bulletClass extends MovieClip {
public var damage:Number = 0;
public function bulletClass() {
//SOME MOVEMENT CODE HERE
}
public function addAvatar(Obj:MovieClip){
this.addChild(Obj);
}
}
}
Well ... if I may say so, this code looks quite wrong. Either something is missing from the code or this code will never make the bullets fly.
First off, you can set x and y of the new bullet directly (replace everything after "orientate this bullet from players body" with this):
tmpBulletId.x = Object(root).localSurvivor.x;
tmpBulletId.y = Object(root).localSurvivor.y;
Perhaps this already helps, but your code there should already do the same.
But to let these bullets fly into any direction, you also need to add an event listener, like so:
tmpBulletId.addEventListener(Event.ENTER_FRAME, moveBullet);
function moveBullet(e:Event) {
var movedBullet:MovieClip = MovieClip(e.currentTarget);
if (movedBullet.x < 0 || movedBullet.x > movedBullet.stage.width ||
movedBullet.y < 0 || movedBullet.y > movedBullet.stage.height) {
// remove move listener, because the bullet moved out of stage
movedBullet.removeEventListener(Event.ENTER_FRAME);
}
// remove the comment (the //) from the line that you need
MovieClip(e.currentTarget).x += 1; // move right
// MovieClip(e.currentTarget).y -= 1; // move up
// MovieClip(e.currentTarget).x -= 1; // move left
// MovieClip(e.currentTarget).y += 1; // move down
}
This example lets your bullet fly to the right. If you need it flying into another direction, just comment out the line with the "move right" comment and uncomment one of the other lines.
This is of course a very simple example, but it should get you started.
I hope this helps, and that my answer is not the wrong answer to the question.
As far as I have expirienced it you can have only one copy of MovieClip object added to specific child. Best approach is to use ByteArray for the clip source and instantiate new MovieClip and pass the ByteArray as a source. It have something to do with child/parent relation since a DisplayObject can have only one parent (and a way to detach the object from scene too).
Well i ended up writeing the whole code from scratch for a 3rd time and ran into a similar problem and just for reference to anybody else that comes to a problem thats random as this one i found that problem was likly does to a conversion error somewhere that doesn't necessarily break any compiling rules. Just that i was calling a movieclip and not the class it self.