I'm playing around with phasers invaders example game.
When the object is shot, instead of killing it I'm changing the sprite and moving it to the bottom of the screen. However, it can now be shot again. I don't want it to be shootable a 2nd time. I'm thinking that because the gamephysics are on the group 'aliens', there are probably two options.
a) Either I can take the single shot alien out of the group 'aliens' and hope that stops it from being shot a 2nd time.
b) Or there's some way of saying ' alien just shot = now protected from being shot again' , I tried the following to no avail.
alien.physicsBodyType = null;
This is my collision handler right now
function collisionHandler (bullet, alien) {
// When a bullet hits an alien we kill them both
bullet.kill();
alien.loadTexture("cured");
// move alien to bottom
var tween2 = game.add.tween(alien).to( { y: 300 }, 1000, Phaser.Easing.Linear.EaseIn, true);
tween2.onComplete.add(doNext, this);
tween2.start();
So, basically the changed sprite can still be shot at, I need to make it so it cannot be shot at.
I tried this.
game.world.add(happy);
It changed the position of the sprite and it was still shootable. Hmmm...
Is there a way to take collision off the single shot alien?
Ok, I figured out my answer, just deactivate the body of the sprite, you don't need to take it out of the group.
sprite.body.enable = false;
Where 'sprite' is the name of your actual sprite. Tested and works.
Related
I am having problem figure out how the normal work.
I am using godot4 RC1.
I created a staticbody3D and want to place a 3dobject standing upright like how we stand on earth.
this is my code for the staticbody3d:
func _on_input_event(camera, event, position, normal, shape_idx):
player.global_position = position
var q = Quaternion.from_euler(normal)
player.basis = q
basically I use the code to capture the mouse_over position on the staticbody3d and place my player(Mesh3d) at the position, and align the player basis to the normal.
if mouse at the top of the planet, it turn out ok.
but anywhere else, it just gone hay wire:
How can I resolve this?
What i am trying to accomplish is to have a user click on the canvas and the sprite(player) will move to that location and STOP once it reaches that location.
Currently i have the player can click and it will continue in that path which is the default function.
update: function() {
this.player.rotation = this.game.physics.arcade.angleToPointer(this.player);
if (this.game.input.activePointer.justPressed()) {
// move on the direction of input
this.game.physics.arcade.moveToPointer(this.player, this.playerSpeed);
}
}
Maybe its simpler than i think but i cant seem to find a solution.
point in the right direction would be useful :)
I think you look for something like this:
Using Tweens (something very interesting about Phaser)
OR
Using
Arcade Physics (which is an example similar to yours)
Ok, I hope I don't mess this up, I have had a look for some answers but can't find anything. I am trying to make a simple sampler in openframeworks using the FMOD sound player in 3D mode. I can make a single instance work fine (recording a new file using libsndfilerecorder and then playing it back and moving it in surround.
However I want to have 8 layers of looping audio that I can record and replace one layer at a time in a live show. I get a lot of problems as soon as I have more than 1 layer.
The first part of my question relates to the FMOD 3D modes, it is listener relative, so I have to define the position of my listener for every sound (I would prefer to have head relative mode but I cannot make this work at all. Again this works fine when I am using a single player but with multiple players only the last listener I update actually works.
The main problem I have is that when I use multiple players I get distortion, and often a mix of other currently playing sounds (even when the microphone cannot hear them) in my new recordings. Is there an incompatability with libsndfilerecorder and FMOD?
Here I initialise the players
for (int i=0; i<CHANNEL_COUNT; i++) {
lvelocity[i].set(1, 1, 1);
lup[i].set(0, 1, 0);
lforward[i].set(0, 0, 1);
lposition[i].set(0, 0, 0);
sposition[i].set(3, 3, 2);
svelocity[i].set(1, 1, 1);
//player[1].initializeFmod();
//player[i].loadSound( "1.wav" );
player[i].setVolume(0.75);
player[i].setMultiPlay(true);
player[i].play();
setupHold[i]==false;
recording[i]=false;
channelHasFile[i]=false;
settingOsc[i]=false;
}
When I am recording I unload the file and make sure the positions of the player that is not loaded are not updating.
void fmodApp::recordingStart( int recordingId ){
if (recording[recordingId]==false) {
setupHold[recordingId]=true; //this stops the position updating
cout<<"Start recording Channel " + ofToString(recordingId+1)+" setup hold is true \n";
pt=getDateName() +".wav";
player[recordingId].stop();
player[recordingId].unloadSound();
audioRecorder.setup(pt);
audioRecorder.setFormat(SF_FORMAT_WAV | SF_FORMAT_PCM_16);
recording[recordingId]=true; //this starts the libSndFIleRecorder
}
else {
cout<<"Channel" + ofToString(recordingId+1)+" is already recording \n";
}
}
And I stop the recording like this.
void fmodApp::recordingEnd( int recordingId ){
if (recording[recordingId]=true) {
recording[recordingId]=false;
cout<<"Stop recording" + ofToString(recordingId+1)+" \n";
audioRecorder.finalize();
audioRecorder.close();
player[recordingId].loadSound(pt);
setupHold[recordingId]=false;
channelHasFile[recordingId]=true;
cout<< "File recorded channel " + ofToString(recordingId+1) + " file is called " + pt + "\n";
}
else {
cout << "Sorry track" + ofToString(recordingId+1) + "is not recording";
}
}
I am careful not to interrupt the updating process but I cannot see where I am going wrong.
Many Thanks
to deal with the distortion, i think you will need to lower the volume of each channel on playback, try setting the volume to 1/8 of the max volume. there isn't any clipping going on so if the sum of sounds > 1.0f you will clip and it will sound bad.
to deal with crosstalk when recording: i guess you have some sort of feedback going on with the output, ie the output sound is being fed back into the input channel, probably by the operating system. if you run another app that makes sound do you also get that in your recording as well? if so then that is probably your problem.
if it works with one channel, try it with just 2, instead of jumping straight up to 8 channels.
in general i would try to abstract out the playback/record logic and soundPlayer/recorder into a separate class. you have a couple of booleans there and it's really easy to make mistakes with >1 boolean. is there any way you can replace the booleans with an enum or an integer state variable?
EDIT: I didn't see the date on your question :D Suppose you managed to do it by now. Maybe it helps somebody else..
I'm not sure if I can answer everything of your question, but I can share how I've worked with 3D sound in FMOD. I haven't worked with recording though.
For my own application a user can place sounds in 3D space around himself. For this I only have one Listener and multiple Sounds. In your code you're making a listener for every sound, are you sure that is necessary? I would imagine that this causes the multiple listeners to pick up multiple sounds and output that to your soundcard. So from the second sound+listener, both listeners pick up both sounds? I'm not a 100% sure but it sounds plausible to me.
I made a class to create sound objects (and one listener). Then I use a vector to store the objects and move trough them to render them.
My class SoundBox basically holds all the necessary things for FMOD
Making a "SoundBox" object and adding it to my soundboxes vector:
SoundBox * box = new SoundBox(box_loc, box_rotation, box_color);
box->loadVideo(ofToDataPath(video_files[soundboxes.size()]));
box->loadSound(ofToDataPath(sound_files[soundboxes.size()]));
box->setVolume(1);
box->setMultiPlay(true);
box->updateSound(box_loc, box_vel);"
box->play();
soundboxes.push_back(box);
Constructor for the SoundBox. I use a similar constructor in the same class for the listener, but since the listener will always be at the origin for me, it doesn't take any arguments and just sets all the listener locations to 0. The constructor for the listener only gets called once, while the one for the Sound gets called whenever I want to make a new one. (don't mind the box_color. I'm drawing physical boxes in this case..):
SoundBox::SoundBox(ofVec3f box_location, ofVec3f box_rotation, ofColor box_color) {
_box_location = box_location;
_box_rotation = box_rotation;
_box_color = box_color;
sound_position.x = _box_location.x;
sound_position.y = _box_location.y;
sound_position.z = _box_location.z;
sound_velocity.x = 0;
sound_velocity.y = 0;
sound_velocity.z = 0;
Then I just use a for loop to loop trough them and play them if they're not playing. I also have some similar code to select them and move then around.
for(auto box = soundboxes.begin(); box != soundboxes.end(); box++){
if(!(*box)->getIsPlaying())
(*box)->play();
}
I really hoped this helped. I'm not a very experienced programmer but this is how I got FMOD with multiple sounds to work in OpenFrameworks and hope you can use some of it. I just dumped as much of my code as I could :D
My main suggestion is to make one listener instead of more. Also having a class for making the sounds is useful if you, for instance, want to relocate the sounds after the initial placement.
Hope it helps and good luck :)
I'm new in games development, am trying to create a simple game in flash-cs5. I created 3 motion tweens in timeline. i'm trying to stop a specific motion tween, when that tween's movieclip is clicked while other tweeens are running and also when the stopped movieclip is clicked again i want to resume the tween while other tweeens are running.
thanking in advanced.
The following is assuming you have each motion tween inside its own movieclip. I am not aware of any method of stopping one tween while leaving the other playing on a single movieclip (or if they are each on the main stage).
That said, you can stop and start animations fairly easily. Below is an example of how to stop a motion tween where it is in playback, and then resume it from that point.
In the example, "myMovieClip" is the movie clip we're working with. We're going to leave the rest of the movieclips alone, as they'll keep playing on their own. I'm also assuming that myMovieClip is playing by default.
The following is in AS3. Place it on the Actions panel for your main stage (first frame if you have multiple frames.)
Also, ensure you have named your MovieClip. To do this, click the MovieClip on your stage in design mode, and then click Properties. There should be a text entry box towards the box. Write the name you want for your MovieClip there.
//Declare a boolean variable that determines whether or not the movieclip timeline is playing.
var ClipPlaying:Boolean = true;
//Add the mouse click event listener to the movie clip.
myMovieClip.addEventListener(MouseEvent.CLICK, StopOrStartClip);
//Declare the function for the above event listener.
function StopOrStartClip(evt:MouseEvent):void
{
//Switch statements are my personal favorites...they're more streamlined than if statements.
switch(ClipPlaying)
{
//If the clip is playing it, we stop it and set ClipPlaying to false.
case true:
myMovieClip.stop();
ClipPlaying = false;
break;
//If the clip is not playing, we start it and set ClipPlaying to true.
case false:
myMovieClip.play();
ClipPlaying = true;
break;
}
}
The most important functions to remember here are:
myMovieClip.stop();
This freezes your animation at its current position.
myMovieClip.play();
This resumes your animation playback from its current position.
When you use either, remember to replace "myMovieClip" with the name of your movie clip!
By the way, slightly unrelated, I highly recommend the book ActionScript 3.0 Game Programming University to learn how to create Flash games.
You wouldn't actually need 5 different event listeners, or functions, or variables; you could just make one function to handle it all:
stage.addEventListener(MouseEvent.CLICK, stageClick);
function stageClick(event:MouseEvent):void {
//I prefer "if" statements
if (event.target == myMovieClip1) stuff here;
else if (event.target == myMovieClip2) stuff here;
else if (event.target == myMovieClip3) stuff here;
else if (event.target == myMovieClip4) stuff here;
else if (event.target == myMovieClip5) stuff here;
}
I can add more details if needed, but this question was from three years ago so probably not.
Hi I am totally confused with CGAffineTransform animations. All I want to do is move a sprite from a position on the right to a position on the left. When it has stopped I want to "reset" it i.e. move it back to where it started. If the app exits (with multitasking) I want to reset the position again on start and repeat the animation.
This is what I am using to make the animation..
[UIImageView animateWithDuration:1.5
delay:0.0
options:(UIViewAnimationOptionAllowUserInteraction |
UIViewAnimationOptionCurveLinear
)
animations:^(void){
ufo.transform = CGAffineTransformTranslate(ufo.transform, -270, 100);
}
completion:^(BOOL finished){
if(finished){
NSLog(#"ufo finished");
[self ufoAnimationDidStop];
}
}];
As I understand it the CGAffineTransforms just visually makes the sprite look like it's moved but doesn't actually move it. Therefore when I try and "reset" the position using
ufo.center = CGPointMake(355, 70);
it doesn't do anything.
I do have something working, if I call
ufo.transform = CGAffineTransformTranslate(ufo.transform, 270, -100);
it resets. The problem is if I exit the app half way through the animation then when it restarts it doesn't necessarily start from the beginning and it doesn't go the the right place, it basically goes crazy!
Is there a way to just remove any transforms applied to it? I'm considering just using a timer but this seems silly when this method should work. I;ve been struggling with this for some time so any help would be much appreciated.
Thanks
Applying a transform to a view doesn't actually change the center or the bounds of the view; it just changes the way the view is shown on the screen. You want to set your transform back to CGAffineTransformIdentity to ensure that it looks like "normal." You can set it to that before you start your animation and set it to what you want it to animate to.