I'm programming a game in Processing3 and I have a problem with the sound file. I'm playing song.play(); on draw() and every frame the program is playing again and again, anyone know a way to make it play the background music just once?
You haven't told us what library you're using- is it Minim?
If so, check out the Minim documentation for a list of classes and functions that you might find useful.
For example the AudioPlayer class has an isPlaying() function that you might use to check whether the song is playing before you play it.
You might also want to rearrange your program so that the song is only triggered once, either from the setup() function, or using the frameCount variable, or in response to user input.
I've found a way to make it work. I've created a variable: int x; and wrote
void draw()
{
x++;
If(x == 1)
song.play();
}
This way the song will play only when x is 1, and as x is growing every frame, it's not gonna be played again.
Related
Hello this is my first time posting on here and am relatively new to coding. I've been playing around with java and libgdx for a month or two and I'm confused about one thing for screens.
If I have a GameScreen class that is active when playing the game, and then wanted to switch momentarily to another screen for inventory or a pause screen or something, if I make the game switch back to the game screen it seems everything resets and a new game starts. What would be the correct way to make sure the screen reloads in the same state it was just in?
If you want to keep a screen alive in the background such as you described, you need to make sure you separate your game initialization code so it is only called when you are starting a new level. There are a million ways you could do this. Here's an example:
public class MyGameScreen {
public MyGameScreen (){
//load textures and sounds here if you aren't managing them somewhere else.
startNewGameRound();
}
#Override
public void show (){
//this is only for stuff you need to reset every time the screen comes back.
//Generally, you would undo stuff that you did in `hide()`.
}
public void startNewGameRound (){
//Reset all your variables and reinitialize state for a new game round.
//This is called in the constructor for first time setup, and then it
//can also be called by a button anywhere that starts a new round.
//But do not load textures and sounds here. Do that in the constructor
//so it only happens once.
}
}
Then in your Game class, you also need to make sure you keep your game screen instance and reuse it.
Don't do this:
setScreen(new MyGameScreen());
Do this instead:
//member variable:
private MyGameScreen myGameScreen;
//In some method:
if (myGameScreen == null)
myGameScreen = new MyGameScreen();
setScreen(myGameScreen);
I want to create a music loop pad, something like this: https://www.youtube.com/watch?v=fwBPYwiYp-Y
Right now, i am using MediaPlayer to play the sounds. I have a global variable that stores the current time (position) of the first audio that is playing, and when i press another button the corresponding audio file starts playing at the position given by the global variable.
My proble is: the sounds are playing out of sync.
can you give me some help? How can i sync the sounds? like this app https://www.youtube.com/watch?v=fwBPYwiYp-Y
Can you point me some info or tutorials about how to create a loop pad?
Thanks
Richardd
Programming something like this is harder than you think. Here are two things you must do to have the sounds play in sync:
Make sure all you sounds are at the same tempo, and are cropped properly - that means that the starting and ending of the sound clip must be exactly on beat - another solution would be to store the starting and ending time for each clip (very easy with OOP)
Use a timer to make sure the sound starts playing on beat. For example, if you wanted to make your music run at 120 bpm, you would need to have your timer fire every 500 ms.
Here is some code (only concept, won't compile):
Timer beatTimer;
boolean isDrumLoopEnabled;
boolean isDrumLoopCurrentlyPlaying;
Sound drumloop;
public void startMusic(){
//prepare timer
beatTimer=new Timer();
beatTimer.interval=500;//for 120 bpm
beatTimer.onTick+=onTickHandler;
isDrumLoopPlaying=false;
isDrumLoopCurrentlyPlaying=false;
//load sounds
Sound drumloop=new Sound("/storage/emulated/drumloop.ogg");
//start music
beatTiemr.start();
}
//this method will run on every beat:
public void onTickHandler(){
if(isDrumLoopEnabled){
//make sure drum loop isn't already playing
if(!isDrumLoopCurrentlyPlaying){
//begin looping drumloop in background
drumloop.startloop();
isDrumLoopCurrentlyPlaying=true;
}
}else{
if(isDrumLoopCurrentlyPlaying){
//stop playing drumloop
drumloop.stopPlaying();
}
}
}
//when the button is pressed...
public void drumloop_buttonpressed(){
//this will toggle whether to play the drum loop:
isDrumLoopEnabled=!isDrumLoopEnabled;
}
In a 2D game, that is being developed with libGDX, what is the most effective way to make the footsteps of the player, for example -
if(player.isWalking) {
Timer.schedule(new Task(){
public void run(){
play(single_footstep);
}
}, 0.5f);
}
This code isn't effective at all.. actually it's not working, the sound comes in a bad way, and no matter how much you will play with the delay value its still not effective.
BTW - I am using the Timer class of libgdx, which is very similiar to the util one.
So maybe you have a better idea to implement? I am kinda new to libGDX, so maybe I am missing something.
Thanks in advance :)
Is that code simply in your draw loop? If so, it is going to schedule the sound to play every frame, so you'll be starting 30 or 60 sounds a second (each of which is delayed from when you called it, but still played concurrently). You need to make sure that once you schedule the task, you don't do it again until you're ready to play the sound again.
I would do it without scheduling. Something like this:
if (player.isWalking){
mTimeToNextStep -= deltaTime;
if (mTimeToNextStep < 0){
play(single_footstep);
while (mTimeToNextStep < 0){ //in case of a really slow frame,
//make sure we don't fall too far behind
mTimeToNextStep += TIME_BETWEEN_STEP_SOUNDS;
}
}
} else {
mTimeToNextStep = 0; //or whatever delay you want for the first sound when
//you start walking
}
In a simple card game (human vs. CPU) the logic works, but I want to delay the computer's turn.
I have tried using Thread.sleep(int milliseconds) which works, but it messes up the order images are displayed. I'm not using a game loop, I am just dynamically updating ImageViews whenever cards are changed. The problem with Thread.sleep is all the images only update after Thread.sleep, there is no displaying only the human card before Thread.sleep. The human's card and computer's card display after Thread.sleep.
I've used Thread.sleep like so:
playPlayerCard(player); // Human first
displayPile(); // Display card pile (ImageView's)
player = nextPlayer(player); // Get's next player in Player mPlayers List<Player>
// Wait for computer to 'Think'
Thread.sleep(500);
playPlayerCard(player); //Computer's turn
displayPile(); // Display card pile (ImageView's)
Am I using Thread.sleep() wrong? Is there a better/correct way? I've searched online and tried using new Thread(), using handler.postDelayed(Runnable r, long milliseconds) and also CountDownTimer but none work since my variables: playPlayerCard(player); aren't final variables.
I've always had problems delaying actions and the images appearing at the correct times. Any suggestions? Thanks in advance.
Couldn't you just implement the Computer Playing logic in a AsyncTask and fire it when the human turn is done ?
I think it would make much more sense, that way, as soon as the computer is done "playing" you can determine the actions to take in the onPostExecute() method, in your case I think that would be dealing cards.
It would also be really simple to block user inputs while the computer is playing, either with a progress dialog (which isn't all that pleasent for a game I understand) or simply by disabling buttons :)
Here's the documentation for it.
Hope this helps!
I used the solution from #Jakar and changed my variables to class-scope in order to use the Handler and Runnable correctly. This worked, the delay works correctly using
Runnable r = new Runnable() {
public void run() {
playPlayerCard();
}
};
mHandler.postDelayed(r, 500);
To clarify the solution, I had to take out the arguments from playPlayerCard(Player player) and use a class-scope Player mPlayer; variable in playPlayerCard() instead.
I have been experimenting with PulpCore, trying to create my own tower defence game (not-playable yet), and I am enjoying it very much I ran into a problem that I can't quite figure out. I extended PulpCore with the JOrbis thing to allow OGG files to be played. Works fine. However, pulpCore seems to have a problem with looping the sound WHILE animating the volume level. I tried this with wav file too, to make sure it isn't jOrbis that breaks it. The code is like this:
Sound bgMusic = Sound.load("music/music.ogg");
Playback musicPlayback;
...
musicVolume = new Fixed(0.75);
musicPlayback = bgMusic.loop(musicVolume);
//TODO figure out why it's NOT looping when volume is animated
// musicVolume.animate(0, musicVolume.get(), FADE_IN_TIME);
This code, for as long as the last line is commented out, plays the music.ogg again and again in an endless loop (which I can stop by calling stop on the Playback object returned from loop(). However, I would like the music to fade in smoothly, so following the advice of the PulpCore API docs, I added the last line which will create the fade-in but the music will only play once and then stop. I wonder why is that? Here is a bit of the documentation:
Playback
pulpcore.sound.Sound.loop(Fixed level)
Loops this sound clip with the
specified volume level (0.0 to 1.0).
The level may have a property
animation attached.
Parameters: level
Returns: a Playback object for this
unique sound playback (one Sound can
have many simultaneous Playback
objects) or null if the sound could
not be played.
So what could be the problem? I repeat, with the last line, the sound fades in but doesn't loop, without it it loops but starts with the specified 0.75 volume level.
Why can't I animate the volume of the looped music playback? What am I doing wrong? Anyone has any experience with pulpCore and has come across this problem? Anyone could please download PulpCore and try to loop music which fades-in (out)?
note: I need to keep a reference to the Playback object returned so I can kill music later.
If the animate method only sets the option, it can work unpredictably - try switching this line with the loop itself, so the animation applies first.
Can you animate the volume on an unlooped playback, and then, at the end of that playback, start the loop at the fixed level?
Finally I managed to get an explanation and a simple work-around for this issue from the pulp core author. So here it is:
It is a PulpCore bug. When the output
volume is zero, the sound player stops
looping the sound.
To work around it, animate from a
value that is not zero, like this:
musicVolume.animate(0.0001, 1, FADE_IN_TIME);
Link to this on pulpcore Google groups