I have created a click function for Kinect without using any gestures.. its simple and it works.. however i want the function to wait.. my counter isnt seem to be working .. what I want to do is.. IF my hand is on the button for lets say more than 3 seconds.. then return true ..any method to do it? Counter doesnt seem to be working
public bool KinectClick(int x,int y)
{
if ((x >= position.X && x <= position.X +position.Width) && (y >= position.Y && y <= position.Y + position.Height))
{
// time.Start();
int counter = 0;
while (true)
{
counter++;
if (counter >= 8000)
{
return true;
counter = 0;
}
}
}
I use a DispatcherTimer to accomplish the same thing you are trying to do. A simple form could look something like this:
private DispatcherTimer hitTestTimer = new DispatcherTimer();
private int timerCount = 5;
public MyConstructor() {
hitTestTimer.Tick += OnHitTestTimerTick;
hitTestTimer.Interval = new TimeSpan(0, 0, 1);
}
private void OnHitTestTimerTick(object sender, EventArgs e)
{
if (timerCount > 1)
{
timerCount--;
}
else
{
// CLICK!
}
}
You can add flags that toggle when you first enter your object, and check that to verify if you have (or haven't) left the object since the last timer tick.
Related
I'm trying to make a code that allows me to swipe pages in my level selection menĂº with a scrollview, using buttons that modify the scrollbar value. It works perfectly when I press the button to go right, but using the same principle on the left button it doesn't work and it even make Unity freeze completely without giving me any error message.
Here right function:
public void ScrollRight(Button button)
{
for (int i = 0; i < button.transform.parent.transform.parent.transform.childCount; i++)
{
if(button.transform.parent.transform.parent.transform.GetChild(i).transform.name == button.transform.parent.transform.name)
{
i++;
scrollPos = pos[i];
Swipe(pos, i);
}
}
}
This is the left:
public void ScrollLeft(Button button)
{
for (int i = 0; i < button.transform.parent.transform.parent.transform.childCount; i++)
{
if (button.transform.parent.transform.parent.transform.GetChild(i).transform.name == button.transform.parent.transform.name)
{
i--;
scrollPos = pos[i];
Swipe(pos, i);
}
}
}
Here the Swipe:
private void Swipe(float[] pos, int nextPosIndex)
{
for (int i = 0; i < pos.Length; i++)
{
if(scrollPos < pos[i] + (distance/2) && scrollPos > pos[i] - (distance / 2))
{
scrollbar.GetComponent<Scrollbar>().value = Mathf.Lerp(scrollbar.GetComponent<Scrollbar>().value, pos[nextPosIndex], 1f * Time.deltaTime);
}
}
}
Also the needed variables:
pos = new float[transform.childCount];
distance = 1f / (pos.Length - 1f);
In your code for left scroll, you increment i inside for statement, but then decrement it inside for body. As a result, your i is always equals 0, and for loop runs eternally.
In general, if you have unity freezed without error messages, and you dealing with loops, in most cases, it means that your loop set up not properly, and runs eternally.
Try something like this:
public void ScrollLeft(Button button)
{
for (int i = button.transform.parent.transform.parent.transform.childCount - 1; i > 0; i--)
{
if(button.transform.parent.transform.parent.transform.GetChild(i).transform.name == button.transform.parent.transform.name)
{
i--;
scrollPos = pos[i];
Swipe(pos, i);
}
}
}
I've made a paint clone and want to clear the bord when you shake the form, (so by holding mouse1 down on the top bar and moving it right and left fast).
I tried to compare two points on the x-axis, the points are set based on the mouse position and tested against a treshold. And I added a combo so you need to overcome the treshold multiple times to avoid accidental activation, to help with this there is also a timer that resets the combo.
The problem is that it sees fast movement to one side as a shake I still want the user to be able to move the form without clearing the canvas.
int firstpos = 0;
int secondpos = 0;
bool isfirst = true;
int combo = 0;
int threshold = 50;
Point lastPoint;
private void TopBar_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)//to move the form
{
this.Left += e.X - lastPoint.X;
this.Top += e.Y - lastPoint.Y;
}
if (isfirst)
{
firstpos = e.X;
isfirst = false;
}
else
{
secondpos = e.X;
int diff = secondpos - firstpos;
if (diff < 0) diff *= -1;//make positive
if (diff >= threshold)
{
combo++;
Thread t = new Thread(startdecay);
t.Start();
}
if (combo == 4)
{
canvas.Invalidate();//clear the canvas
combo = 0;
}
isfirst = true;
}
}
void startdecay()
{
Thread.Sleep(1000);
combo = 0;
}
private void TopBar_MouseDown(object sender, MouseEventArgs e)
{
lastPoint = new Point(e.X, e.Y);
}
the form
isfirst == true: Save firstpos.
Set isfirst = false.
isfirst == false: Get secondpos.
Get diff.
if Math.Sign(diff) != saveddiff {
increment shakecounter.
Set saveddiff = Math.Sign(diff).
}
Set firstpos = secondpos.
Accept when shakecounter over some value desired.
Don't forget to reset everything when Mouse Button goes up.
So I am trying to add several images (Music Notes) in the form of PictureBox to a form, but despite all my efforts, only the first music note is being displayed, and all preceding music notes are not.
Key_MouseUp Event (occurs when the mouse is lifted up after a piano key is pressed):
private void Key_MouseUp(object sender, MouseEventArgs e)
{
foreach (MusKey mk in panel1.Controls)
{
if (sender == mk) //true for the specific key pressed on the Music Keyboard
{
if (e.Button == MouseButtons.Left)
{
timer1.Enabled = false;
sp.Stop();
string bNoteShape = null;
// ticks -> milliseconds
if (count > 15)
{
bNoteShape = "SemiBreve";
duration = 2000;
}
else if (count > 10 && count <= 15)
{
bNoteShape = "DotMinim";
duration = 1000;
}
else if (count > 5 && count <= 10)
{
bNoteShape = "Minim";
duration = 500;
}
else if (count > 2 && count <= 5)
{
bNoteShape = "Crotchet";
duration = 250;
}
else if (count >= 1.25 && count <= 2)
{
bNoteShape = "Quaver";
duration = 125;
}
else
{
bNoteShape = "Semi-Quaver";
duration = 63;
}
MusicNote mn = new MusicNote(mk.getMusicNote(), duration, bNoteShape, mk.getNote());
Notes.Add(mn);
panel2.Controls.Add(mn); //adding MusicNote component to MusicStaff (panel2) collection
}
}
}
}
Music Note Class and Constructor:
class MusicNote : PictureBox
{
public int notepitch;
public int noteduration;
public String noteshape;
public String note;
enum Accid { sharp, flat, sole };
String NoteImage_path = "C:\\Users\\Luke Xuereb\\Documents\\University\\Year 2\\Semester 1\\Object Oriented Programming\\Piano Assignment\\Notes-Images\\";
static int xLoc = 50;
static int yLoc = 30;
bool dragging = false;
System.Timers.Timer timer1 = new System.Timers.Timer();
public MusicNote(int iNotepitch, int iDuration, String iBnoteShape, String iNote)
{
notepitch = iNotepitch;
noteduration = iDuration;
noteshape = iBnoteShape;
note = iNote;
ImageLocation = NoteImage_path + noteshape + ".bmp";
BackColor = Color.Beige;
Location = new Point(xLoc, yLoc);
xLoc += 15;
}
I have been several days stuck on this problem, and am quite convinced that the logic of the code is correct (which is in fact why the first Music Note is always displayed).
Is there a problem when it comes to displaying several pictureboxes? A new picturebox is created everytime a new music note is created, since class MusicNote inherits from class PictureBox.
Alternatively, is there a better option for my current problem, instead of using PictureBox?
Any help would be massively appreciated. Thank you!
Background: first of all I know some of my code is messy, please don't hate me. Basically I want to animate the movement of a TextBox object on a Windows Forms window. I have managed to do this by using a Timer. However, the rest of my code executes whilst the timer is running (and so the TextBox is still moving). How do I stop this from happening.
Here is some of my code:
move method:
private void move(int x, int y)
{
xValue = x;
yValue = y;
// Check to see if x co-ord needs moving up or down
if (xValue > txtData.Location.X) // UP
{
xDir = 1;
}
else if (xValue < box.Location.X) // DOWN
{
xDir = -1;
}
else // No change
{
.xDir = 0;
}
if (yValue > box.Location.Y) // RIGHT
{
yDir = 1;
}
else if (yValue < Location.Y) // LEFT
{
yDir = -1;
}
else // No change
{
yDir = 0;
}
timer.Start();
}
Timer Tick method:
private void timer_Tick(object sender, EventArgs e)
{
while (xValue != box.Location.X && yValue != box.Location.Y)
{
if (yDir == 0)
{
box.SetBounds(box.Location.X + xDir, box.Location.Y, box.Width, box.Height);
}
else
{
box.SetBounds(box.Location.X, box.Location.Y + yDir, box.Width, box.Height);
}
}
}
move calls:
move(478, 267);
move(647, 267);
move(647, 257);
I'm not sure exactly what you're asking, but if you're trying to force the program to stop running code until the animation is done, you could try using async await. You'll need at least .Net 4.5 to use async await, however.
private async void moveData(int x, int y)
{
Variables.xValue = x;
Variables.yValue = y;
// Check to see if x co-ord needs moving up or down
if (Variables.xValue > txtData.Location.X) // UP
{
Variables.xDir = 1;
}
else if (Variables.xValue < txtData.Location.X) // DOWN
{
Variables.xDir = -1;
}
else // No change
{
Variables.xDir = 0;
}
// Check to see if y co-ord needs moving left or right
if (Variables.yValue > txtData.Location.Y) // RIGHT
{
Variables.yDir = 1;
}
else if (Variables.yValue < txtData.Location.Y) // LEFT
{
Variables.yDir = -1;
}
else // No change
{
Variables.yDir = 0;
}
await Animate();
}
private async Task Animate()
{
while (Variables.xValue != txtData.Location.X && Variables.yValue != txtData.Location.Y)
{
if (Variables.yDir == 0) // If we are moving in the x direction
{
txtData.SetBounds(txtData.Location.X + Variables.xDir, txtData.Location.Y, txtData.Width, txtData.Height);
}
else // We are moving in the y direction
{
txtData.SetBounds(txtData.Location.X, txtData.Location.Y + Variables.yDir, txtData.Width, txtData.Height);
}
await Task.Delay(intervalBetweenMovements);
}
}
This way it will wait for move(x, y) to complete before moving to the next line.
My friends I made some parts of this game but I have two problems in this game.
1)Problem about distinguishing ball collision with obstacles
1-1)A first problem is related to complex guidelines that I used them for simulation of ball collision with board or ball collision with blocks. These guidelines are not accurate especially when the ball meets with block corner or bottom.
If it is not better for collision distinguish I use a better code. I wrote this code. Are you think that are there better way?
2)How I can do a work that if the ball collision with any obstacle, the obstacle report the collision.
My aim is about using of events.
Are you thinking that I make obstacles as runtime?
If I make as a runtime, how I can make collision event for them?
With best regards
private Point MouseDownLocation;
int step = 2;
int stepleft = 2;
bool flagBottom;
bool flagTop;
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 10;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
ball.Top += step;
ball.Left += stepleft;
//board simulate collision
bool collisonX = ball.Location.X + ball.Width > board.Location.X && ball.Location.X < board.Location.X + board.Width;
bool collisonY = ball.Top + ball.Height == board.Location.Y || ball.Top + ball.Height - 1 == board.Location.Y;
//board2(button1) simulate collision
bool collisonX2 = ball.Location.X + ball.Width > board2.Location.X && ball.Location.X < board2.Location.X + board2.Width;
bool collisonY2 = ball.Top + ball.Height == board2.Location.Y || ball.Top + ball.Height - 1 == board2.Location.Y;
//Collision the ball with under buttons
bool collsionButtonY = ball.Top - ball.Height == board2.Location.Y || ball.Top - ball.Height == board2.Location.Y - 1;
//collision leftwall
bool leftWall = ball.Left == 0 || ball.Left == -1 || ball.Left == 1;
//collision rightwall
bool topWall = ball.Top == 0 || ball.Top == -1 || ball.Top == 1;
bool bottomWall = collisonX && collisonY;
bool toppWall = collisonX2 && collisonY2;
//collision
bool barrier = collisonX2 && collsionButtonY;
//rightwall
bool rightWall = ball.Left + ball.Width == this.ClientSize.Width || ball.Left + ball.Width == this.ClientSize.Width - 1;
// sidewall = collision rightwall or leftwall
bool sideWall = leftWall || rightWall;
//Check the ball hit the ground
bool check = ball.Top + ball.Height < this.ClientSize.Height;
//if topWall true,This means that the ball is hit to the topwall
if (topWall)
{
flagBottom = false;
flagTop = true;
if (stepleft > 0)
{
step = 2;
}
else if (stepleft < 0)
{
step = 2;
}
}
//if bottomWall true,This means that the ball is hit to the board
else if (bottomWall)
{
flagBottom = true;
flagTop = false;
if (stepleft > 0)
{
step = step * -1;
}
else if (stepleft < 0)
{
step = step * -1;
}
}
//if barrier true and flagbottom true,This means that the ball is hit to the board2(button1)
else if (barrier && flagBottom)
{
if (stepleft > 0)
{
step = step * -1;
}
else if (stepleft < 0)
{
step = step * -1;
}
}
//if toppWall true and flagTop true,This means that the ball is hit to The top button is hit
else if (toppWall && flagTop)
{
if (stepleft > 0)
{
step = step * -1;
}
else if (stepleft < 0)
{
step = step * -1;
}
}
else if (sideWall)
{
//if leftwall true,This means that the ball is hit to the left side wall
if (leftWall)
{
if (flagTop)
{
stepleft = 2;
}
else if (flagBottom)
{
stepleft = 2;
}
}
//if rightWall true,This means that the ball is hit to the left side wall
else if (rightWall)
{
if (flagTop)
{
stepleft = -2;
}
else if (flagBottom)
{
stepleft = -2;
}
}
}
//check if ckeck==ture,this mean the ball is hit the ground
else if (!check)
{
timer1.Enabled = false;
}
}
private void board_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
MouseDownLocation = e.Location;
}
}
private void board_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
board.Left = e.X + board.Left - MouseDownLocation.X;
}
}
Define each "Wall" as an Object, this will increase your codes readablility. it will also allow you to define an Event for each wall, Listen to t. that way you know which wall has been hit
N.b. this is pseudo code. It wont compile :P
public class Wall
{
int X,Y,W,H;
//Define an event, add a listener to this, becuase we will fire this when there is a collision
public event EventHandler OnCollision;
public void CollisionCheck(Ball playerBall)
{
//1 Check for a collision with the "Ball" object
if(Ball.Rectangle().Intersects(this.Rectangle))
this.OnCollision(this, EventArgs.Empty); //Fire the event, null check might be requried
}
}
I do not know your game but (suspect 2D brick-like game)
Objects/Obstacles
all objects/obstacles can be simplified to rectangular objects
so make list of them with defined parameters like size and position
if they are movable/dropable then also speed and state...
type of object (affects color,scoring,capabilities...)
create member function like update(dt),draw()
create events you like OnHIt,OnCollision,...
for example (C++ pseudo code):
// game object types ...
enum _game_object_type_enum
{
_game_object_type_none=0,
_game_object_type_wall,
_game_object_type_brick1,
_game_object_type_brick2,
_game_object_type_brick3,
_game_object_type_bomb,
_game_object_type_joker1,
_game_object_type_joker2,
...
};
// game object class
class game_object
{
public;
int type; // type of object
float x,y,vx,vy,hx,hy; // position,speed,half size of rectangle
void update(float dt); // this call periodicaly in some timer updates positions,... and call events, dt is time passed
void draw(); // can add some rendering device context ...
};
// whole game class holds the game world/board/map and player(s) ...
class game_board
{
public;
game_object *go; int gos; // list of all objects in game
void update(float dt) { for (int i=0;i<gos;i++) go[i].update(dt); }
void draw() { for (int i=0;i<gos;i++) go[i].draw(); }
}
events and flow control
first define some events you need
either you use global function/pointers for that or as members
depends on your platform and to what you are used to
for example like this:
void OnCollisionFX(game_object o1,game_object o2)
{
// do something ...
}
void (*OnCollision)(game_object o1,game_object o2)=OnCollisionFX;
for player interactions only (like player controlled object collisions test only)
is better to handle this in game_object::update(dt) but you need to add player context
something like game_object::update(dt,plr)
where plr is pointer to player controlled object or player class
if you have massive interactivity between game objects (like brick/brick collisions)
then is better to handle this in game_board::update(dt)
because otherwise you will need to provide references for everything into update call
and that will quickly lead to heap/stack trashing and very slow performance
also more advanced multiple object collision/interaction approaches are better in main game class
here is an example for first case:
void game_object::update(float dt,game_object &plr)
{
// update position
x+=vx*dt;
y+=vy*dt;
// here you should make your own collision test of coarse
if (fabs(x-plr.x)<=hx+plr.hx)
if (fabs(y-plr.y)<=hy+plr.hy)
{
... do what you need like mirror or stop speed or clamp position ...
if (OnCollision) OnCollision(this,plr);
}
}
in second case you should check each object against each other
void game_board::update(float dt)
{
int i,j;
// update position
for (i=0;i<gos;i++)
{
go[i].x+=go[i].vx*dt;
go[i].y+=go[i].vy*dt;
}
// here you should make your own collision test of coarse
for (i=0;i<gos;i++)
for (j=i+1;j<gos;j++) // the lower indexes are already tested
if (fabs(go[i].x-go[j].x)<=go[i].hx+go[j].hx)
if (fabs(go[i].y-go[j].y)<=go[i].hy+go[j].hy)
{
... do what you need like mirror or stop speed or clamp position ...
if (OnCollision) OnCollision(go[i],go[j]);
}
}
performance
you can improve performance by use of type property
for example if some game objets are static then the do not need to update position
if some are indestructible then there can be also some processing avoided and so on ...
[notes]
dt/fps/speed should be combined
so in each frame your player controlled object or any moving object does not move further
then the half size of smallest object
if this is not true then you need better collision test
use line intersection algorithm
last position and actual position gives you one line
and object edge gives you the other one
if booth objects are moving then that is even more complicated :)