Detecting when the user is pressing the shift key - c#

Currently I am working on a Piano in Windows Form Application. What I did is when you press a certain key on the keyboard it plays a sound (technically it force a press of button). Now what I want to do is add that when the user is pressing a key as well as pressing the shift key, it will play a longer sound. For example if the A key is pressed it will play sound of the C chord, and if the A is pressed + the shift key is pressed it will play a longer version of the sound. This is the code for the key pressing and an example of one of the sounds playing:
private bool shiftPressed = false;
const int NOTE_LENGTH = 500;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
switch (keyData)
{
case Keys.A://C
C_Low.BackColor = Color.Gray;
C_Low.PerformClick();
break;
case Keys.S://D
D_Low.BackColor = Color.Gray;
D_Low.PerformClick();
break;
case Keys.D://E
E_Low.BackColor = Color.Gray;
E_Low.PerformClick();
break;
case Keys.F://F
F_Low.BackColor = Color.Gray;
F_Low.PerformClick();
break;
case Keys.G://F
G_Low.BackColor = Color.Gray;
G_Low.PerformClick();
break;
case Keys.H://A
A_Low.BackColor = Color.Gray;
A_Low.PerformClick();
break;
case Keys.J://B
B_Low.BackColor = Color.Gray;
B_Low.PerformClick();
break;
case Keys.W://C#
C_Diez_Low.BackColor = Color.Gray;
C_Diez_Low.PerformClick();
break;
case Keys.E://D#
D_Diez_Low.BackColor = Color.Gray;
D_Diez_Low.PerformClick();
break;
case Keys.T://F#
F_Diez_Low.BackColor = Color.Gray;
F_Diez_Low.PerformClick();
break;
case Keys.Y://G#
G_Diez_Low.BackColor = Color.Gray;
G_Diez_Low.PerformClick();
break;
case Keys.U://A#
A_Diez_Low.BackColor = Color.Gray;
A_Diez_Low.PerformClick();
break;
}
return base.ProcessCmdKey(ref msg, keyData);
}
As example the C_Low_Click_1 event:
private void C_Low_Click_1(object sender, EventArgs e) //Play C low
{
if (shiftPressed)
{
C_Low.BackColor = Color.White;
if (Low.Checked)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_Low_Long);
player.Load();
player.PlaySync();
}
if (Med.Checked)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_Medium_Long);
player.Load();
player.PlaySync();
}
if (High.Checked)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_High_Long);
player.Load();
player.PlaySync();
}
}
else
{
C_Low.BackColor = Color.White;
if (Low.Checked)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_Low);
player.Load();
player.PlaySync();
}
if (Med.Checked)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_Medium);
player.Load();
player.PlaySync();
}
if (High.Checked)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_High);
player.Load();
player.PlaySync();
}
}
}
Any help will be appreciated, and if I did not provide any information please tell me :D

You should consider to use the KeyEvents of your form, especially the KeyDown and KeyUp events. Important: to use the event properly, you must set the KeyPreview attribute to true first!
Then use following code within the KeyDown event:
shiftPressed = e.Shift;
and in the KeyUp event:
shiftPressed = false;
// also possible, although I won't recommend using the code below,
// as there could be some incorrect handling if shift is pressed
// shiftPressed = e.Shift;

Keys is a flags enum, so you would test for the shift key using:
var shiftPressed = keyData.HasFlag(Keys.Shift);
When shift is pressed your switch statement won't work (as the value isn't Keys.A, for example, it's Keys.Shift|Keys.A). You can remove the shift first so your switch statement will work:
var keyWithoutShift = keyData & ~Keys.Shift;
switch (keyWithoutShift)
{
// handle keys as normal
}

Related

How to make difference between click with moving with click without moving gameobject in unity

I have 2 2D gameobjects in unity.I want to achieve next but only with Input.GetTouch for android:
When i click on first or second object---play some sound.
When drag any of those game objets to each other combine them to one---without playing sound from first case.
Then be able to click on this combined object---without playing sound from first case
Problem is because I dont want to play sound from first case if object is dragging.
I already tried some code with couroutine but it doesnt work:
if (Input.touchCount > 0) {
touch = Input.GetTouch(0);
touchPos = Camera.main.ScreenToWorldPoint(touch.position);
RaycastHit2D hit = Physics2D.Raycast(touchPos, Camera.main.transform.forward);
switch (touch.phase) {
case TouchPhase.Began:
samoKlik = true;
if (samoKlik) {
StartCoroutine(korotinaKlika());
}
}
case TouchPhase.Moved:
isMoved = true;
if (!samoKlik) {
if (jedan) {
break;
case TouchPhase.Ended:
isMoved = false;
jedan = false;
break;
}
You need to write your switch case properly. This code will not compile. The proper switch case syntac would be somethink like the one described here:
switch (touch.phase) {
case TouchPhase.Began:
samoKlik = true;
//if (samoKlik) { // This is not needed
StartCoroutine(korotinaKlika());
//}
break;
case TouchPhase.Moved:
isMoved = true;
if (!samoKlik) { // samoKlik does not exist here
if (jedan) {
break;
}
}
break;
case TouchPhase.Ended:
isMoved = false;
jedan = false;
break;
}
Since you want to fall from one conditional to another, it looks like the switch statement is not right for you.
I would suggest to try the following:
Declare your variables before your logic
bool samoKlik = false;
bool isMoved = false;
bool jedan = false;
Start with if/else clauses.
I can identify one for you to help you going
if (touch.phase == touchPhase.Moved && !samoKlik && jedan)

Check if multiple buttons are pushed Windows IoT with Raspberry PI 3B

I'm currently working with the Raspberry PI 3 with Windows 10 IoT and I'm trying to make the game 'Simon Says' in Visual Studio 2015.
Everything is plugged in as followed:
Fritzing image
I got the LEDs working but I can't really figure out how to detect when a button is being pressed.
Parts of the source code:
Variables
private const int BTNRED = 5;
private const int BTNBLUE = 6;
private const int BTNYELLOW = 13;
private const int BTNGREEN = 19;
private GpioPin _btnRed;
private GpioPin _btnBlue;
private GpioPin _btnYellow;
private GpioPin _btnGreen;
private Random rnd;
private static GpioController _gpioController;
Method to recognize when a button is being pressed.
public static IList<Step> PressedButtons
{
get
{
List<Step> returnVal = new List<Step>();
if (GetMap._btnBlue.Read() == GpioPinValue.High)
{ returnVal.Add(Step.Blue); }
if (GetMap._btnGreen.Read() == GpioPinValue.High)
{ returnVal.Add(Step.Green); }
if (GetMap._btnRed.Read() == GpioPinValue.High)
{ returnVal.Add(Step.Red); }
if (GetMap._btnYellow.Read() == GpioPinValue.High)
{ returnVal.Add(Step.Yellow); }
return returnVal;
}
}
/// <summary>
/// Checks if any of the 4 buttons is pressed.
/// </summary>
/// <returns>Returns false if no button is pressed.</returns>
public static bool isButtonPressed
{
get
{
if (GetMap._btnBlue.Read() == GpioPinValue.Low)
{ return true; }
if (GetMap._btnGreen.Read() == GpioPinValue.Low)
{ return true; }
if (GetMap._btnRed.Read() == GpioPinValue.Low)
{ return true; }
if (GetMap._btnYellow.Read() == GpioPinValue.Low)
{ return true; ; }
return false;
}
}
Assigning the right pins on the GPIO to the corresponding variables
private GPIOMap()
{
rnd = new Random();
_gpioController = GpioController.GetDefault();
if (_gpioController == null) { return; }
_ledRed = _gpioController.OpenPin(LEDRED);
_ledRed.SetDriveMode(GpioPinDriveMode.Output);
_ledYellow = _gpioController.OpenPin(LEDYELLOW);
_ledYellow.SetDriveMode(GpioPinDriveMode.Output);
_ledGreen = _gpioController.OpenPin(LEDGREEN);
_ledGreen.SetDriveMode(GpioPinDriveMode.Output);
_ledBlue = _gpioController.OpenPin(LEDBLUE);
_ledBlue.SetDriveMode(GpioPinDriveMode.Output);
_btnBlue = _gpioController.OpenPin(BTNBLUE);
_btnGreen = _gpioController.OpenPin(BTNGREEN);
_btnRed = _gpioController.OpenPin(BTNRED);
_btnYellow = _gpioController.OpenPin(BTNYELLOW);
}
private static GPIOMap GPIOMapInstance;
public static GPIOMap GetMap
{
get
{
if (GPIOMapInstance == null || _gpioController == null)
{ GPIOMapInstance = new GPIOMap(); }
return GPIOMapInstance;
}
}
Run game, where as you can see it should bring me to state 2 whenever a button is being pressed. However this isn't quite the case as the idle animation keeps on going on.
private void RunGame()
{
while (_isRunning)
{
switch (_state)
{
//Idle state
case (0x01):
//If any button is pressed, start the game.
if (GPIOMap.isButtonPressed)
{
_state = 0x02;
Task.Delay(500).Wait();
GPIOMap.PlayStartAnimation();
Task.Delay(1000).Wait();
break;
}
//If nothing happens, continue playing the idle animation.
GPIOMap.PlayIdleAnimationOnce();
break;
//Playback state
case (0x02):
//Play all the currently existing steps.
for (int i = 0; i <= _gameInstance.TotalSteps; i++)
{ GPIOMap.BlinkLight(_gameInstance.GetNextStep(), 500); }
//Generate and play a new step.
GPIOMap.BlinkLight(_gameInstance.GetNextStep(), 500);
//Switch to the input state.
_state = 0x03;
//Set the start time for the input.
_answerPending = DateTime.UtcNow;
break;
//Input state
case (0x03):
if(_gameInstance.CurrentStep > MAXSTEPS)
{
//Win Game
ResetGame();
break;
}
//If the player waits too long before answering, lose the game.
if ((DateTime.UtcNow - _answerPending) > _timeout)
{
GPIOMap.ConfirmWrongAnswer();
ResetGame();
break;
}
//If there are no more steps to re-trace, go back to playback state.
if (_gameInstance.CurrentStep > _gameInstance.TotalSteps)
{ _gameInstance.ResetSteps(); _state = 0x02; break; }
//If no buttons are pressed, keep polling.
if (!GPIOMap.isButtonPressed) { break; }
IList<Step> pressedButtons = GPIOMap.PressedButtons;
//If anything but one button is pressed, lose the game.
if (pressedButtons.Count != 1)
{
GPIOMap.ConfirmWrongAnswer();
ResetGame();
break;
}
if (_gameInstance.VerifyStep(pressedButtons[0]))
{
GPIOMap.BlinkLight(pressedButtons[0], 500);
}
else//Wrong step, end game
{
GPIOMap.ConfirmWrongAnswer();
ResetGame();
break;
}
break;
}
}
}
How can I get my source code to recognize when a button is being pressed so I can go to the next state which involves getting user input on the buttons.
You can use GPIO ValueChanged to catch the button pressed event like this:
_btnBlue = _gpioController.OpenPin(BTNBLUE);
_btnBlue.ValueChanged += btnValueChanged;
public void btnValueChanged(GpioPin pin, GpioPinValueChangedEventArgs e)
{
if (_btnBlue.Read() == GpioPinValue.Low)
{
isBlueButtonPressed = true;
}
}

How do I set timer to making an on off button for 1000 milliseconds?

I am new to c# and I'm wanting to create a game that it has three button with different colors , I want to turn on and off each of them in random state for 1000 milisecond .. what should I do ? can anyone help me ? :)
there are three buttons including Red , Blue and Green colors , after click the "start" button they begin to blink randomly ... I want set 1000 millisecond for this blink !
switch (colorNum)
{
case 1:
btnRed.BackColor = Color.Red;
Thread.Sleep(milisecond);
//if (btn == btnRed)
//{
count++;
break;
//}
case 2:
btnBlue.BackColor = Color.Blue;
//{
count++;
break;
//}
case 3:
btnYellow.BackColor = Color.Yellow;
//{
count++;
break;
//}
}
private void Blink_Button()
{
Random rnd = new Random();
int colorNum = rnd.Next(1, 4);
switch (colorNum)
{
case 1:
btnRed.BackColor = Color.Red;
btnBlue.BackColor = Color.LightGray;
btnYellow.BackColor = Color.LightGray;
break;
case 2:
btnBlue.BackColor = Color.Blue;
btnRed.BackColor = Color.LightGray;
btnYellow.BackColor = Color.LightGray;
break;
case 3:
btnYellow.BackColor = Color.Yellow;
btnRed.BackColor = Color.LightGray;
btnBlue.BackColor = Color.LightGray;
break;
}
}
Call this method in the Timer tick event

Program skipping stages

So I have a Unity program, where it switches screens if the user presses ENTER.
However, whenever the user presses enter, instead of just going one screen forward, it skips all the way to the last screen.
Here is my OnGUI():
if (showScreen == true)
{
//this allows the screens to toggle
switch (pageNum)
{
case 1:
rectangle = GUI.Window(1,rectangle, Page1, "Computer");
break;
case 2:
rectangle = GUI.Window(1,rectangle, Page2, "Computer");
break;
case 3:
rectangle = GUI.Window(1,rectangle, Page3, "Computer");
break;
case 4:
rectangle = GUI.Window(1,rectangle, Page4, "Computer");
break;
case 5:
rectangle = GUI.Window(1,rectangle, Page5, "Computer");
GUILayout.Window (2,rect2, popUp, "Warning!");
break;
case 6:
rectangle = GUI.Window(1,rectangle, Page6, "Computer");
break;
case 7:
rectangle = GUILayout.Window(1,rectangle, Page7, "Computer");
break;
default:
break;
}
}
And here is where the GUIs are actually set up, and made to change:
void Page1(int windowID)
{ if (Input.GetKeyDown(KeyCode.Return))
{
GUI.FocusControl(null);
pageNum = 2;
}
}
void Page2(int windowID)
{
if (Input.GetKeyDown(KeyCode.Return))
{
pageNum = 3;
GUI.FocusControl(null);
}
}
//continue like this for 5 more Page#(int windowID)
So what can I insert into these classes to make my program stop skipping? should I put a pause into these if statements too?
So it looks like the easiest way to solve this problem is by changing how the program changes the stages. All you need to do is a boolean that changes to true once the return key has been pressed.
so just declare the boolean:
public class ClassName : MonoBehaviour
{
bool wasClicked = false;
Then to change the states just do this:
if (Input.GetKey(KeyCode.Return))
{
wasClicked = true;
}
if (wasClicked)
{
if (!Input.GetKey(KeyCode.Return))
{
GUI.FocusControl(null);
pageNum = next page number;
wasClicked = false;
}
}

How to keep picturebox in the form while moving it?

I'm trying to make a single game, but I got a little problem here...
I'm moving a picturebox with the arrow keys, to avoid other pictureboxes... The problem is, that my picturebox moves out of the form when I press the left key too many times... I succeeded in solving this problem with the right side(by blocking the picturebox with an another), but the left side version still doesn't works, and I don't know why...
Here is the code:
if (pictureBox7.Bounds.IntersectsWith(pictureBox1.Bounds))
switch (e.KeyCode)
{
case Keys.Escape: Application.Exit(); break;
case Keys.P: timerkunai1.Enabled = false;
timerkunai2.Enabled = false; timerkunai3.Enabled = false;
timerkunai4.Enabled = false; timerninja.Enabled = false;
timerlife.Enabled = false;
button3.Show(); break;
case Keys.Right: i = 6; dx = 25; press = true; break;
}
if (pictureBox8.Bounds.IntersectsWith(pictureBox1.Bounds))
switch (e.KeyCode)
{
case Keys.Escape: Application.Exit(); break;
case Keys.P: timerkunai1.Enabled = false;
timerkunai2.Enabled = false; timerkunai3.Enabled = false;
timerkunai4.Enabled = false; timerninja.Enabled = false;
timerlife.Enabled = false;
button3.Show(); break;
case Keys.Left: i = 0; dx = -25; press = true; break;
}
else
switch (e.KeyCode)
{
case Keys.Escape: Application.Exit(); break;
case Keys.P: timerkunai1.Enabled = false;
timerkunai2.Enabled = false; timerkunai3.Enabled = false;
timerkunai4.Enabled = false; timerninja.Enabled = false;
timerlife.Enabled = false;
button3.Show(); break;
case Keys.Left: i = 0; dx = -25; press = true; break;
case Keys.Right: i = 6; dx = 25; press = true; break;
}
You need code to check if the picturebox's bounds are outside of the form. If the picturebox movement will cause it to be outside the bounds then prevent the motion.
Something like this pseudocode:
if (pictureBoxZ + dx < 0 || pictureBoxZ + dx > pictureBoxZ.Parent.Width) { //Deny Motion }
Is your dx variable an offset to the new Location of the PictureBox?
Then limit the Location.x to 0:
if (pictureBox1.Location.x + dx > 0)
pictureBox1.Location += dx;
If you want to limit to left and right size, to the width of the Form use this code:
if ((pictureBox1.Location.x + dx > 0) && (pictureBox1.Location.x + dx < this.Size.Width - pictureBox1.Size.Width))
pictureBox1.Location += dx;

Categories