Copy link to clipboard
Copied
Hi,
I want to add a scoring system to my game, so upon pickup of the coin, it disappears, +1 to the Score. I've got the coins inside my background symbol and then another symbol used for miscellaneous things on the bground and it doesn't work in there, as I get the error 2007 - Parameter hitTestObject must be non-null, but when I take it out of this symbol and onto the main game, it works, but as the player moves, so does the coin. How do I make it work inside the symbol?
This is the code that I've got for the coin. I've gotten this from another tutorial, and I tried to follow the layout of the code for the key below, however, the code for the key is working, and this isn't.
var score=0;
if (player.hitTestObject(back.other.coin)) {
score++;
coins_txt.text=score.toString();
back.other.coin.visible = false;
}
This here is showing something similiar that I've got, a key, which I'm able to collect and it disappears when I do. This is basically what I want with my coins, with the addition of adding +1 to the current score.
if(keyCollected == false){
if(player.hitTestObject(back.other.doorKey)){
back.other.doorKey.visible = false;
keyCollected = true;
trace("key collected");
}
}
So far, I've tried Googling the error but I couldn't find anything useful apart from the fact that adding a brace somewhere may fix it, but I don't really know where, and also looked at different ways of doing it. Originally, I had the code for the coin in a Class which I linked to my main game afterwards, but I had a similiar problem there. I've also made sure that the coin has an instance name of "coin".
Does anyone have any suggestions how to fix this?
Thank you
Great!
Is this code running inside of a Event.ENTER_FRAME handler function?
And, yeah, you should add a verification to check if the coin has already been taken because if not the code inside the hit test will continue to run.
Something like this:
...import flash.events.Event;
var score:uint = 0;
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
function enterFrameHandler(e:Event):void
{
if(!back.other.coin.collision)
{
if (player.hitTestObject(back.other.coin))
{
Copy link to clipboard
Copied
Hi.
Please double check if you really have an object called 'coin' inside of another object called 'other' inside of another object called 'back'.
And you should create a collected verification like in the door key example because if not your score will receive +1 as long as your player collides with the coin. This is because the invisiblitiy doesn't stop the hit test.
Copy link to clipboard
Copied
Hey,
Thanks for the reply.
I double checked it and it wasn't named as "coin", which did get rid of the parameter hitTestObject error, however, the actual function still doesn't work, as nothing happens when the player and coin collide 😕
How exactly would I go along doing the second part? Do you mean something like adding "if (coinCollected) = false?
Copy link to clipboard
Copied
Great!
Is this code running inside of a Event.ENTER_FRAME handler function?
And, yeah, you should add a verification to check if the coin has already been taken because if not the code inside the hit test will continue to run.
Something like this:
import flash.events.Event;
var score:uint = 0;
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
function enterFrameHandler(e:Event):void
{
if(!back.other.coin.collision)
{
if (player.hitTestObject(back.other.coin))
{
score++;
coins_txt.text = score.toString();
back.other.coin.visible = false;
back.other.coin.collision = true;
}
}
}
Copy link to clipboard
Copied
Thanks a lot! This worked
However I tested it on multiple levels as I've got 3, and the coins cannot be picked up on levels 2 and 3. Do you know why this may be?
Thanks again!
EDIT: I forgot to give the coins on different levels the "coin" instance name. After doing this it started working Thanks!
Copy link to clipboard
Copied
This is great! You're welcome!
Copy link to clipboard
Copied
I've just got another question, not really related to this, but saves me creating a separate thread.
Do you know if there is a way to insert music on a single frame and have it play all the way through on a single frame? I've got my game set into three frames, with frame 1 being the start screen, frame 2 being the game and frame 3 being the game over screen, and I want frame 2 to have continuous music playing. Would this be possible, or is there some other way to do it?
Thanks for all the help!
Copy link to clipboard
Copied
Sure there is!
You can use a code like this to play and stop sounds:
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.net.URLRequest;
var soundList:Vector.<String> = new <String>
[
"bgm/Beat_Your_Competition.mp3",
"bgm/Chess_Pieces.mp3",
"bgm/Walking_the_Dog.mp3",
"sfx/264446__kickhat__open-button-1.mp3"
];
var sfxChannel:SoundChannel = new SoundChannel();
var bgmChannel:SoundChannel = new SoundChannel();
function playSound(path:String, soundChannel:String, stopSound:Boolean = false, volume:Number = 1, start:Number = 0, loops:int = 0):void
{
var sound:Sound = new Sound();
var sTransform:SoundTransform = new SoundTransform();
if (stopSound && this[soundChannel])
this[soundChannel].stop();
sound.load(new URLRequest(path));
this[soundChannel] = sound.play(start, loops);
sTransform.volume = volume;
this[soundChannel].soundTransform = sTransform;
}
function stopSound(soundChannel:String):void
{
if (this[soundChannel])
this[soundChannel].stop();
}
Then you just have to call the play and stop functions like in these examples:
playSound(soundList[0], "bgmChannel", true, 1, 0, 0);
playSound(soundList[0], "bgmChannel");
playSound(soundList[0], "sfxChannel", false, 0.5);
stopSound("bgmChannel");
Please don't hesitate to ask if you still have any more questions.
Regards,
JC
Copy link to clipboard
Copied
Would all of this go into my current code? Or would I need to create a separate ActionScript file for it?
Copy link to clipboard
Copied
It can go in your code. Just copy and paste the first big part into the top of your code in frame 1.
Then just control the playback of your sounds calling the functions like in the examples in the second part.
Copy link to clipboard
Copied
Ok so I've pasted it in under where I declare all of my variables and included the import bits along with the ones I had there already.
var soundList:Vector.<String> = new <String>
[
"bgm/Blackbird.mp3",
];
var sfxChannel:SoundChannel = new SoundChannel();
var bgmChannel:SoundChannel = new SoundChannel();
function playSound(path:String, soundChannel:String, stopSound:Boolean = false, volume:Number = 1, start:Number = 0, loops:int = 0):void
{
var sound:Sound = new Sound();
var sTransform:SoundTransform = new SoundTransform();
if (stopSound && this[soundChannel])
this[soundChannel].stop();
sound.load(new URLRequest(path));
this[soundChannel] = sound.play(start, loops);
sTransform.volume = volume;
this[soundChannel].soundTransform = sTransform;
}
function stopSound(soundChannel:String):void
{
if (this[soundChannel])
this[soundChannel].stop();
}
playSound(soundList[0], "bgmChannel", true, 1, 0, 0);
playSound(soundList[0], "bgmChannel");
playSound(soundList[0], "sfxChannel", false, 0.5);
stopSound("bgmChannel");
This is what I've got there. I assumed the first bit is the songs that will be playing, and I only want 1 song to be played, but I'm not entirely sure if I'm understanding this right.
When I launched this, there was no bugs so the game played, but there was no sound & I got this error:
Error #2044: Unhandled IOErrorEvent:. text=Error #2032: Stream Error.
EDIT: I've just inserted the soundtrack into the first three frames and it somehow does what I want, however, when the player loses the game and goes onto the third frame (the last frame), the song starts playing again on top of the same song that is already playing. Do you have any idea how to fix it?
Copy link to clipboard
Copied
The error is saying that there's a problem loading the song. The path may be wrong. Please double check if there's a file called 'Blackbird.mp3' inside of a folder called 'bgm'.
And you don't have to make all these functions call. They are only examples of usage.
You can make a call per frame only or in anyway you like.
For example:
Frame 1:
playSound(soundList[0], "bgmChannel", true, 1, 0, 0);
Frame 2:
playSound(soundList[0], "bgmChannel");
Frame 3:
stopSound("bgmChannel");
Copy link to clipboard
Copied
Thanks ! again Fixed it now
Just one more question. I'm doing this whole thing for an assignment, and the last requirement I need to meet is to make use of a loop of some sort, such as For next etc. Do you have any ideas on how I could easily implement this into my game?
Thank you!
EDIT: I've found something and implemented it in my game Thank you for all the help regarding this, literally a lifesaver!
Copy link to clipboard
Copied
Excellent! You're welcome!
Anyway, you have a perfect situation to use a reverse for loop in your game. Because I'm wondering if you really want to hardcode the collision of dozens or hundred of coins. Haha
With the code below, you can copy and paste as many coins as you want inside of your levels.
- First set your coin Movie Clip to be exported for ActionScript with a class name of 'Coin';
- Then update your code with the one below (make the adjustments where needed). Notice that now we're gonna really remove the coins from the stage instead of just setting them to be invisble.
import flash.events.Event;
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;
var score:uint = 0;
var coins:Vector.<Coin> = new Vector.<Coin>();
var level:MovieClip;
function loop(e:Event):void
{
for (var i:int = coins.length - 1; i >= 0; i--)
{
if (player.hitTestObject(coins))
{
score++;
coins_txt.text = score.toString();
level.removeChild(coins);
coins.splice(i, 1);
}
}
}
function getCoins(container:DisplayObjectContainer):Vector.<Coin>
{
var vec:Vector.<Coin> = new Vector.<Coin>();
for (var i:int = 0, total = container.numChildren; i < total; i++)
if (container.getChildAt(i) is Coin)
vec = container.getChildAt(i) as Coin;
return vec;
}
level = back.other;
coins = getCoins(level);
stage.addEventListener(Event.ENTER_FRAME, loop);
Copy link to clipboard
Copied
Thanks for the reply!
Regarding this, I'm assuming I can just drag & drop the coins from the library and put them anywhere? If so, would I need to put them into the background and then other symbol like I have currently, with the back.other.coin ?
Also, in the For loop, would there be a termination condition? I'm doing all of this for an assignment and I think my teacher wants us to include a termination condition, but both on Your version and the one I've got, I'm not sure where I'd put it.
And finally, all of this code would go into the same place as my current code, or would I create a new ActionScript file and paste it in there and link the two?
Thanks again!
Copy link to clipboard
Copied
Yeah! You can drag and drop coins from the library and/or copy and paste instances alredy on stage and/or alt + drag instances that are also on stage.
They all can live inside the back.other Movie Clip. If you have to check each one separately, you would have to access them like these:
- back.other.coin0;
- back.other.coin1;
- back.other.coin2;
.
.
.
But you're not gonna do this.
About the termination condition... Hmmm... You could, I don't know, change the name of one of the coins to "special" and say that if the player hits the special one, the level is clared.
Like this:
if (player.hitTestObject(coins))
{
score++;
coins_txt.text = score.toString();
level.removeChild(coins);
if (coins.name == "special")
{
coins.splice(i, 1);
stage.removeEventListener(Event.ENTER_FRAME, loop);
break;
}
else
coins.splice(i, 1);
}
Because if you hit the special coin, the level is over and so there is no need to continue the loop to check for other collisions.
And, yes, you have to insert this code in the one you already have.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now