I am trying to figure out how to use "sound off" and "sound on" images to control game sound. The code below displays a sound button but when you click on it, it mutes the sounds but adds a shaded circle over the button.
I would like some guide or how to make it switch from a sound on to a sound off image button as I am new to Unity.
Image File Names: SoundButton.psd and WhiteCircle.psd
var whiteCircle : GameObject;
var numberOfTouch : int = 0;
private var a : float = 1;
function Start() {
if (PlayerPrefs.GetInt("SoundBoolean") == 0) {
//check whether the sound is included, if turned on, then play sound.
numberOfTouch = 0;
whiteCircle.GetComponent(SpriteRenderer).enabled = false;
}
if (PlayerPrefs.GetInt("SoundBoolean") == 1) {
//check whether the sound is included, if turned off, then turn off the sound.
numberOfTouch = 1;
whiteCircle.GetComponent(SpriteRenderer).enabled = true;
}
}
function OnMouseDown () {
if (a <= 0) {
if (numberOfTouch == 0) {
//completely turn off the music.
a = 1;
numberOfTouch = 1;
gameObject.GetComponent.<AudioSource>().Play();
whiteCircle.GetComponent(SpriteRenderer).enabled = true;
PlayerPrefs.SetInt("SoundBoolean", 1);
PlayerPrefs.Save();
}
}
if (a <= 0) {
if (numberOfTouch == 1) {
//a fully turn on the music.
a = 1;
numberOfTouch = 0;
whiteCircle.GetComponent(SpriteRenderer).enabled = false;
PlayerPrefs.SetInt("SoundBoolean", 0);
PlayerPrefs.Save();
}
}
}
function Update() {
if (a >= 0) {
a -= 0.1;
}
}
As I understood correctly, you're looking for something to change the sprite on an object you have. I'm not testing my code or anything, but perhaps it can help you solve your problem.
var sprite1 : Sprite; // Drag your first sprite here
var sprite2 : Sprite; // Drag your second sprite here
var spriteRenderer : SpriteRenderer = whiteCircle.GetComponent(SpriteRenderer);
var whiteCircle : GameObject;
var numberOfTouch : int = 0;
private var a : float = 1;
function Start() {
if (PlayerPrefs.GetInt("SoundBoolean") == 0) {
//check whether the sound is included, if turned on, then play sound.
numberOfTouch = 0;
spriteRenderer.sprite = sprite2;
}
if (PlayerPrefs.GetInt("SoundBoolean") == 1) {
//check whether the sound is included, if turned off, then turn off the sound.
numberOfTouch = 1;
spriteRenderer.sprite = sprite1;
}
}
function OnMouseDown () {
if (a <= 0) {
if (numberOfTouch == 0) {
//completely turn off the music.
a = 1;
numberOfTouch = 1;
gameObject.GetComponent.<AudioSource>().Play();
spriteRenderer.sprite = sprite1;
PlayerPrefs.SetInt("SoundBoolean", 1);
PlayerPrefs.Save();
}
}
if (a <= 0) {
if (numberOfTouch == 1) {
//a fully turn on the music.
a = 1;
numberOfTouch = 0;
spriteRenderer.sprite = sprite2;
PlayerPrefs.SetInt("SoundBoolean", 0);
PlayerPrefs.Save();
}
}
}
function Update() {
if (a >= 0) {
a -= 0.1;
}
}
Basically, add two sprite points to where you can drag your image files, then replace the sprite on a certain spriterenderer (instead of turning it on and off).
Related
I'm trying to make a sound play when the mouse moves over a button in Processing. Currently, it is playing over and over again because my button class is in the draw() function. I understand why this is happening, but I can't think of a way to only play the sound once while still being tied to my overRect() function.
main:
import processing.sound.*;
PlayButton playButton;
SoundFile mouseOverSound;
SoundFile clickSound;
color white = color(255);
color gray = color(241, 241, 241);
PFont verdanabold;
void setup()
{
size(720, 1280);
textAlign(CENTER);
rectMode(CENTER);
verdanabold = createFont("Verdana Bold", 60, true);
playButton = new PlayButton();
mouseOverSound = new SoundFile(this, "mouseover.wav");
clickSound = new SoundFile(this, "click.mp3");
}
void draw()
{
background(gray);
playButton.display(); // draw play button
}
playButton class:
class PlayButton // play button
{
float rectX = width/2; // button x position
float rectY = height-height/4; // button y position
int rectWidth = 275; // button width
int rectHeight = 75; // button height
boolean rectOver = false; // boolean determining if mouse is over button
void display() // draws play button and controls its function
{
update(mouseX, mouseY);
if(rectOver) // controls button color when mouse over
{
fill(white);
mouseOverSound.play(); // play mouse over sound
}
else
{
fill(gray);
}
strokeWeight(5); // button
stroke(black);
rect(rectX, rectY, rectWidth, rectHeight);
textFont(verdanabold, 48); // button text
fill(black);
text("PLAY", rectX, rectY+15);
if(mousePressed && rectOver) // if mouse over and clicked, change to state 1
{
state = 1;
clickSound.play(); // play click sound
}
}
void update(float x, float y) // determines if mouse is over button using overRect(), changes boolean rectOver accordingly
{
if(overRect(rectX, rectY, rectWidth, rectHeight))
{
rectOver = true;
}
else
{
rectOver = false;
}
}
boolean overRect(float rectX, float rectY, int rectWidth, int rectHeight) // compares mouse pos to button pos and returns true if =
{
if(mouseX >= rectX-rectWidth/2 && mouseX <= rectX+rectWidth/2 && mouseY >= rectY-rectHeight/2 && mouseY <= rectY+rectHeight/2)
{
return true;
}
else
{
return false;
}
}
}
Figured it out.
Initialized int i = 0. While mouse is over the button, plays sound while i < 1, then increments i by 1 inside the while loop so it stops playing. When mouse is not over the button, i is set back to 0.
Edited playButton class:
class HowToButton // how to button
{
float rectX = width/2; // button x position
float rectY = height-height/8; // button y position
int rectWidth = 275; // button width
int rectHeight = 75; // button height
boolean rectOver = false; // boolean determining if mouse is over button
int i = 0;
void display() // draws how to button and controls its function
{
update(mouseX, mouseY);
if (rectOver) // controls button color when mouse over
{
fill(white);
while(i < 1) // play sound while i < 1
{
mouseOverSound.play(); // play mouse over sound
i++; // increment i so sound only plays once
}
}
else
{
fill(gray);
i = 0; // set i back to 0 when mouse leaves bounds of button
}
strokeWeight(5); // button
stroke(black);
rect(rectX, rectY, rectWidth, rectHeight);
textFont(verdanabold, 48); // button text
fill(black);
text("HOW TO", rectX, rectY+15);
if(mousePressed && rectOver) // if mouse over and clicked, change to state 2
{
state = 2;
clickSound.play(); // play click sound
}
}
void update(float x, float y) // determines if mouse is over button using overRect(), changes boolean rectOver accordingly
{
if(overRect(rectX, rectY, rectWidth, rectHeight))
{
rectOver = true;
}
else
{
rectOver = false;
}
}
boolean overRect(float rectX, float rectY, int rectWidth, int rectHeight) // compares mouse pos to button pos and returns true if =
{
if(mouseX >= rectX-rectWidth/2 && mouseX <= rectX+rectWidth/2 && mouseY >= rectY-rectHeight/2 && mouseY <= rectY+rectHeight/2)
{
return true;
}
else
{
return false;
}
}
}
You could use a boolean variable that indicates whether the sound is already playing. Something like this:
if(mousePressed && rectOver && !alreadyPlaying)
{
alreadyPlaying = true;
state = 1;
clickSound.play(); // play click sound
}
In fact, you might be able to use the state variable:
if(mousePressed && rectOver && state != 1)
{
state = 1;
clickSound.play(); // play click sound
}
You could also look into the sound library you're using, it might have a function that tells you whether the sound is already playing, which you could use in the same way.
I am using below code to create tooltips.
m_ctrlToolTip.Create(this, TTS_ALWAYSTIP|TTS_BALLOON);
m_ti.cbSize = sizeof(TOOLINFO);
m_ti.uFlags = TTF_IDISHWND|TTF_TRACK|TTF_TRANSPARENT|TTF_ABSOLUTE;
m_ti.hwnd = m_hWnd;
m_ti.hinst = NULL;
m_ti.uId = (UINT)1;
m_ti.lpszText = "";;
m_ti.rect=CRect(0,0,0,0);
m_ctrlToolTip.SetMaxTipWidth(SHRT_MAX);
m_ctrlToolTip.SetDelayTime(TTDT_AUTOPOP,5000);
m_ctrlToolTip.Activate(TRUE);
void CLadIOView::OnMouseMove(UINT nFlags, CPoint point)
{
static CPoint prevPoint =0;
static CLadRemoteIOModule* pLastIO=NULL;
CLadRemoteIOModule* pLastIO1=pLastIO;
pLastIO=NULL;
bool bToolTipSet = false;
// Go thru each module already added
POSITION pos = gobjEztouchApp.m_objLadderLogic.m_objSysAttr.m_objRemoteIOModuleLst.GetHeadPosition();
for( ; pos != NULL; )
{
CLadRemoteIOModule* pIO = gobjEztouchApp.m_objLadderLogic.m_objSysAttr.m_objRemoteIOModuleLst.GetNext(pos);
// Get the rectangle for the module
CRect rectModule = GetIOModuleRect(pIO->m_nModulePosition);
if(!rectModule.PtInRect(pt)) continue;
pLastIO=pIO;
if(pLastIO1==pIO) break;
if(!m_bMouseDown && !m_bPlacingANewModule && prevPoint != pt)
{
CString sDescription, sPartNumber, sAddressRange;
GetIOModuleText2(pIO,sDescription, sPartNumber, sAddressRange);
sPartNumber.Remove('[');
sPartNumber.Remove(']');
CString sModuleDetails;
sModuleDetails.Format(_T("Position: M%d\nModule Type: %s\nModule Part No: %s"), pIO->m_nModulePosition+1, sDescription,sPartNumber);
if(pIO->GetIPSize() > 0)
sModuleDetails+=_T("\nInput Address: ")+ pIO->GetInputAdr()+_T(" - ")+pIO->GetEndInputAdr();
if(pIO->GetOPSize() > 0)
sModuleDetails+=_T("\nOutput Address: ")+ pIO->GetOutputAdr()+_T(" - ")+pIO->GetEndOutputAdr();
CPoint pp = pt-GetScrollPosition();
ClientToScreen(&pp);
m_ctrlToolTip.UpdateTipText(sModuleDetails,this,1);
m_ctrlToolTip.SendMessage(TTM_TRACKPOSITION, 0, (LPARAM)MAKELPARAM(pp.x, pp.y+16));//+16 to move the tooltip stem down
m_ctrlToolTip.SendMessage(TTM_TRACKACTIVATE, TRUE, (LPARAM)&m_ti);
//to track mouse leave abd there we can remove tooltip
TRACKMOUSEEVENT tk;
tk.cbSize = sizeof(tk);
tk.dwFlags = TME_LEAVE;
tk.hwndTrack = m_hWnd;
_TrackMouseEvent(&tk);
prevPoint = pt;
bToolTipSet = true;
}
bToolTipSet = true;
break;
}
if(!bToolTipSet)
{
m_ctrlToolTip.SendMessage(TTM_TRACKACTIVATE, FALSE, (LPARAM)&m_ti);
m_ctrlToolTip.UpdateTipText("",this,1);
m_ctrlToolTip.Pop();
}
The tooltip remains visible for very few seconds and then they disappear. I find this time too short to read some of the longer tooltips. Is there a way to increase the time they remain visible?
I tried to increase the time using setdelaytime function but it doesn't help me.
Thanks in advance.
Here's the basic code:
In the html I have a button that calls playInterval.
In the script I have the playInterval script that creates and connects four oscillators, then plays two oscillators together for 1s, waits 0.5 seconds and plays the 2nd two oscillators together for 1s.
The problem is, I can't get the interval pairs to play more than 6 times. I've searched and tried everything I can think of.
I know I shouldn't have the AudioContext in the function - that's why it is being called six+ times, but it doesn't work if I take the AudioContext declaration out of the function.
I know there must be a simple solution for this. Any help would be greatly appreciated.
The code below works for the first two levels.
Also, I have had to fake a button choice with the confirm window because I couldn't figure out how to do it with regular buttons.
Note: this is being tested in Chrome.
HTML:
<table border="1" cellspacing ="10" align = "left">
<tr align = "right">
<td>Testing Beat Speed Difference Sensitivity (BSDS) of:</td>
<td align = "left" id ="beatSpeedDifference"></td>
</tr>
<tr align = "right">
<td>Current level (out of 13 levels):</td>
<td align = "left" id ="currentLevel"></td>
</tr>
<tr align = "right">
<td>Consecutive correct answers at this BSDS:</td>
<td align = "left" id ="curConCorrect"></td>
</tr>
</table>
SCRIPT:
// define and assign variables
var faster = [447.5, 447, 446.5, 446, 445.75, 445.63, 445.5, 445.4, 445.3, 445.25, 445.2, 445.15, 445.1];
var slower = [436.67, 436.43, 436.15, 435.83, 435.65, 435.56, 435.45, 435.37, 435.28, 435.24, 435.19, 435.15, 435.1];
var bsd = [0.5, 0.4, 0.3, 0.2, 0.15, 0.13, 0.1, 0.08, 0.06, 0.05, 0.04, 0.03, 0.02];
var passed = [0,0,0,0,0,0,0,0,0,0,0,0,0];
var conCorrect = 0; //concurrent correct answers
var level = 0;
var setup = 0;
var quit = 0;
var playing = 0;
var pitch;
var choice = "empty";
moveableA440 = 440;
document.getElementById("beatSpeedDifference").innerHTML = bsd[level]*100 + "%";
document.getElementById("currentLevel").innerHTML = level + 1;
document.getElementById("curConCorrect").innerHTML = conCorrect;
alert("BEAT SPEED DIFFERENCE SENSIVITY TEST. \n\
You will hear two beat speeds. \n\
The first one will be beating at 5bps. \n\
The second one will be beating faster or slower. \n\
Click OK to accept if the 2nd beat speed is faster.\n\
Click CANCEL if the 2nd beat speed is not faster than the first.");
while (quit === 0) {
//setup chooses a new beat speed if first or previous has been answered
if (setup === 0) {
pitch = getPitch();
if (pitch < 445) { // to elliminate slower BSD sounding flatter
pitch = pitch + 5;
moveableA440 = moveableA440 + 5;
}
setup = 1;
}
//playing plays the two beat speeds once
if (playing === 0) {
playInterval();
playing = 1;
}
//Enter user choice if no choice has been made
if (choice === "empty") {
var r = confirm("OK = Sped Up\n\Cancel = Slowed Down");
if (r === true) {
choice = "faster";
} else {
choice = "slower";
}
}
//Once choice has been made
if (choice !== "empty") { //reset everything for next beat speed
setup = 0; //reset for a new beat speed
playing = 0; //reset to play new beat speed
//Do if correct choice
if (choice === "faster" && pitch > 445 || choice === "slower" && pitch < 445) {
// Stop beats if user selects ok before beats finish
constRef.stop();
moveablePitch.stop();
conCorrect = conCorrect + 1; //Advance and display concurrent correct choices
document.getElementById("curConCorrect").innerHTML = conCorrect;
//Do if three correct answers
if (conCorrect > 2) {
if (passed[level] === 1) { // Do if three correct and has passed this level already
alert("Your Beat Speed Sensitivity is " + bsd[level]*100 + "%");
quit = 1; //stop script
}
// Do if three correct but not passed level yet
conCorrect = 0; //Reset concurrent correct choices
passed[level] = 1;//record level passed
level = level + 1; //advance and display level
document.getElementById("currentLevel").innerHTML = level + 1;
document.getElementById("beatSpeedDifference").innerHTML = bsd[level]*100 + "%";
conCorrect = 0; //reset and display conCorrect
document.getElementById("curConCorrect").innerHTML = conCorrect;
if (level > 12) {// No more levels
alert("Your Beat Speed Sensitivity is " + bsd[12]*100 + "%");
quit = 1;
}
};
} else { //Do if choice is wrong
// Stop beats if user selects ok before beats finish
constRef.stop();
moveablePitch.stop();
level = level - 1;
if (level < 0) {
alert("Your Beat Speed Sensitivity is " + bsd[0]*100 + "%");
quit = 1;
}
document.getElementById("currentLevel").innerHTML = level + 1;
document.getElementById("beatSpeedDifference").innerHTML = bsd[level]*100 + "%";
conCorrect = 0; //reset and display conCorrect
document.getElementById("curConCorrect").innerHTML = conCorrect;
}
choice = "empty" //reset choice
}
}
var r = confirm("Play Again?");
if (r === true) {
window.location.reload()
} else {
alert("Thanks for playing.\n\Please subscribe to howtotunepianos.com");
}
//Functions
function getPitch() {
var coin = Math.random();
if (coin > 0.5) {
return faster[level];
} else {
return slower[level];
}
}
function playInterval() {
context = new webkitAudioContext();
// Create oscillators
constRef = context.createOscillator();
moveablePitch = context.createOscillator();
a440 = context.createOscillator();
a445 = context.createOscillator();
// Connect to output
constRef.connect(context.destination);
moveablePitch.connect(context.destination);
a440.connect(context.destination);
a445.connect(context.destination);
// Define values for oscillators
constRef.type = "sine";
constRef.frequency.value = moveableA440;
moveablePitch.type = "sine";
moveablePitch.frequency.value = pitch;
a440.type = "sine";
a440.frequency.value = 440;
a445.type = "sine";
a445.frequency.value = 445;
// Play
a440.start(0);
a445.start(0);
a440.stop(1);
a445.stop(1);
constRef.start(1);
moveablePitch.start(1);
constRef.stop(2);
moveablePitch.stop(2);
moveableA440 = 440;// reset
}
Ok. I figured it out.
I had to define the oscillator and gain as variables outside the function as well as call the audioContext.
var osc, oscGain
Then the function.
function playIntervals()
I also figured out how to use buttons instead of the clunky confirm window; each button calls it's own function.
I was using a while (quit=o) loop, but that created too many problems. Now the whole thing is done using functions.
Thanks for your help.
I am playing around with SDL, trying to make a simple fighting game like street fighter or such, but I don't understand how to make more than one animation at once on the screen without flickering. For some reason while both players are idle on the screen they don't flicker, but for other animations the second player flickers. The code looks something like this:
Class player1:
...
void setrects_idle(SDL_Rect* clip) //loads the frames from a bmp image
{
for(int i = 0; i < 10; i ++) {
clip[i].x = 0 + i*224;
clip[i].y = 0;
clip[i].w = 224;
clip[i].h = 226;
}
}
void setrects_walkf(SDL_Rect* clip)
{
for(int i = 0; i < 11; i ++) {
clip[i].x = 0 + i*224;
clip[i].y = 0;
clip[i].w = 224;
clip[i].h = 226;
}
}
void player::idle(SDL_Surface* screen)
{
if (!other_action)
{
SDL_BlitSurface(player1_idle, &frames_idle[static_cast<int>(frame_idle)], screen, &offset);
SDL_Flip(screen);
if(frame_idle > 8)
frame_idle = 0;
else
frame_idle ++;
}
}
void player::walkf(SDL_Surface* screen)
{
other_action = true;
SDL_BlitSurface(player1_walkf, &frames_walkf[static_cast<int>(frame_walkf)], screen, &offset);
SDL_Flip(screen);
if(frame_walkf > 9)
frame_walkf = 0;
else
frame_walkf ++;
}
********************
Class player2:
void player2::idle(SDL_Surface* screen)
{
if (!other_action)
{
SDL_BlitSurface(player2_idle, &frames_idle[static_cast<int>(frame_idle)], screen, &offset);
//SDL_Flip(screen); //with this commented, there is no flicker on both players idle
if(frame_idle > 8)
frame_idle = 0;
else
frame_idle ++;
}
}
void player2::walkf(SDL_Surface* screen)
{
other_action = true;
SDL_BlitSurface(player2_walkf, &frames_walkf[static_cast<int>(frame_walkf)], screen, &offset);
SDL_Flip(screen); //if I comment this there is no animation for player2 at all. with it on, it flickers.
if(frame_walkf > 9)
frame_walkf = 0;
else
frame_walkf ++;
}
*****************************
SDL_Surface *screen;
screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
In the main loop:
player1.idle(screen);
player2.idle(screen);
...
case SDLK_d:
player1.b[1] = 1;
break;
case SDLK_j:
player2.b[1] = 1;
break;
...
if(player1.b[0])
player1.walkb(screen);
else
player1.return_to_idle();
if(player2.b[0])
player2.walkb(screen);
else
player2.return_to_idle();
You call several time SDL_Flip.
Into your main loop, call it juste once.
Erase background
Draw ALL objects.
Flip Once
Do not flip in your function walkf
There is a requirement of updating image in image boxes of WPF. I am thinking of creating a list with all the paths and then using a timer control checking the 10 seconds. After the 10 seconds has elapsed the next id from list is taken and bound to the image box. I am new to WPF. Can any one help me with a working example.
Use a DispatcherTimer to invoke a method at regular intervalls. In this method change the bound image, remember to raise the INotifyPropertyChanged event to let WPF know it should query the bound property again.
Hi i have made thig running with the below code .
private void timer_Elapsed(object sender,System.Timers.ElapsedEventArgs e)
{
Action action1 = () => this.BeginStoryboard((Storyboard)this.FindResource("BlinkStoryboardFed"));
Dispatcher.BeginInvoke(action1);
Action action = () => BindToImages(lststr);
Dispatcher.BeginInvoke(action);
//BindToImages(lststr);
_timer.Start();
}
public void BindToImages(List<string> lststrpath)
{
lock (_locker)
{
for (int i = 0; i < lststrpath.Count; i++)
{
if (count == 0)
{
startindex = i;
this.BindToImgIndx = startindex;
AppState.Index = i;
BitmapImage img = new BitmapImage();
img.BeginInit();
img.UriSource = new Uri(lststrpath[startindex].ToString(), UriKind.Relative);
img.CacheOption = BitmapCacheOption.OnLoad;
img.EndInit();
image1.Source = img;
count++;
}
else
{
int k = AppState.Index;
k = ++k;
this.BindToImgIndx = startindex;
if (k < lststrpath.Count)
{
BitmapImage img = new BitmapImage();
img.BeginInit();
img.UriSource = new Uri(lststrpath[k].ToString(), UriKind.Relative);
img.CacheOption = BitmapCacheOption.OnLoad;
img.EndInit();
image1.Source = img;
}
AppState.Index = k;
}
this.BeginStoryboard((Storyboard)this.FindResource("BlinkStoryboardUnFed"));
break;
}
}
}