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.
Related
Made progress on my game and now I need to make the second boss bounce up and down. I figured out how to make the boss go down, but once it touches the lower wall, it stops and won't bounce (move up).
void BossMove()
{
if((BOSS.Top + 10) <(this.Height - BOSS.Height))
{
BOSS.Top += 10;
}
if((BOSS.Height) > 0)
{
BOSS.Top -= 10;
}
}
Here's a simple example using a state variable to represent the direction:
private Boolean goingUp = true;
void BossMove()
{
if (goingUp)
{
if ((BOSS.Top + 10) < (this.Height - BOSS.Height))
{
BOSS.Top += 10;
}
else
{
// possibly force it to snap to specific position
// before going back down?
goingUp = false;
}
}
else
{
if (BOSS.Top > 450)
{
BOSS.Top -= 10;
}
else
{
// possibly force it to snap to specific position
// before going back up?
goingUp = true;
}
}
}
public class green : MonoBehaviour
{
private AudioSource source;
public AudioClip sound;
static int result = 0;
void Start()
{
StartCoroutine("RoutineCheckInputAfter3Minutes");
Debug.Log("a");
}
IEnumerator RoutineCheckInputAfter3Minutes()
{
System.Random ran = new System.Random();
int timeToWait = ran.Next(1, 50) * 1000;
Thread.Sleep(timeToWait);
source = this.gameObject.AddComponent<AudioSource>();
source.clip = sound;
source.loop = true;
source.Play();
System.Random r = new System.Random();
result = r.Next(1, 4);
Debug.Log("d");
yield return new WaitForSeconds(3f * 60f);
gm.life -= 1;
Debug.Log("z");
}
public void Update()
{
if (result == 1 && gm.checka == true)
{
Debug.Log("e");
StopCoroutine("RoutineCheckInputAfter3Minutes");
gm.life += 1;
source.Stop();
gm.checka = false;
Debug.Log("j");
}
if (result == 2 && gm.checkb == true)
{
Debug.Log("f");
StopCoroutine("RoutineCheckInputAfter3Minutes");
gm.life += 1;
source.Stop();
gm.checkb = false;
Debug.Log("z");
}
else if (result == 3 && gm.checkc == true)
{
StopCoroutine("RoutineCheckInputAfter3Minutes");
Debug.Log("g");
gm.life += 1;
source.Stop();
gm.checkc = false;
Debug.Log(gm.life);
}
}
}
There are two problems
I want to make music stop and life variable decrease -1, if the user doesn't push any buttons for 3 minutes. But if the user pushes the right button, life variable will be increased + 1. but I don't know how to get null input from the user for 3 minutes.
If I use while for this program, this shuts down… until life is below 0, I want to repeat music which is played on irregular time.
Edit: Don't use Thread in Unity
How Unity works
Alternative to Thread
Couroutine Example 1
Coroutine Example 2
* To put it simple, Thread.Sleep hangs to Unity and Unity can't operate for the time, and that's why it looks like running slow.
You can use coroutines for this problem.
void Start()
{
StartCoroutine("RoutineCheckInputAfter3Minutes");
}
IEnumerator RoutineCheckInputAfter3Minutes()
{
yield return new WaitForSeconds(3f*60f);
gm.life -= 1;
}
void RightButtonClicked()
{
gm.life += 1;
StopCoroutine("RoutineCheckInputAfter3Minutes");
StartCoroutine("RoutineCheckInputAfter3Minutes");
}
Or, you can just turn your a function into a coroutine, if the other code sections work.
void Start()
{
StartCoroutine(a());
}
public IEnumerator a()
{
while (gm.life >= 0)
{
System.Random ran = new System.Random();
int timeToWait = ran.Next(1, 50) * 1000;
yield return new WaitForSeconds(timeToWait);
source = this.gameObject.AddComponent<AudioSource>();
source.clip = sound;
source.loop = true;
source.Play();
System.Random r = new System.Random();
result = r.Next(1, 4);
Debug.Log("d");
}
}
This is an example usage of coroutine based on your code More than this is out of scope:
A pastebin link to code
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm writing a simple console based game. In the game, I have two functions that should move two things - A paddle and a ball.
But when I use two loops that have Thread.sleep, the game doesn't work. How can I use the two loops with Thread.sleep and get it to run properly?
My code:
class Program
{
static void Ball()
{
}
static void Main(string[] args)
{
int x = 10; int y = 10;
int dx = 1; int dy = 1;
ConsoleKeyInfo Exit = new ConsoleKeyInfo();
do
{
Console.SetCursorPosition(x, y);
Console.WriteLine(" ");
x += dx;
y += dy;
Console.SetCursorPosition(x, y);
Console.Write("*");
Thread.sleep(95);
if (x > 77) dx = -dx;
if (x < 2) dx = -dx;
if (y > 22) dy = -dy;
if (y < 2) dy = -dy;
} while (true);
int a = 2;
int b = 23;
int da = 1;
Console.SetCursorPosition(a, b);
Console.Write(" ");
if (Console.KeyAvailable)
{
ConsoleKeyInfo k = Console.ReadKey(true);
if (k.Key == ConsoleKey.LeftArrow) a = a - da;
else if (k.Key == ConsoleKey.RightArrow) a = a + da;
if (a > 78) a = -da;
if (a < 2) a = -da;
Thread.Sleep(200);
}
Console.SetCursorPosition(a, b);
Console.Write("~~~~~~~~~~");
}
}
When I run the example code you provided, the application will run. That is to say, the ball (*) will move around the screen. Are you expecting the ball to move on the screen, and the paddle to be drawn and move when an arrow is pressed? If so, you should look at how you are looping. The issue I see is that you have a loop that draws the ball and your loop will never ends, and therefore your code will not draw the paddle and/or reflect your arrow key changes. Is your expectation also for the Thread.Sleep to pause the loop and allow you to draw/move the paddle?
UPDATE:
namespace ConsoleGame
{
class Ball {
private static Ball _instance;
private int _a = 10, _b = 10;
private int _dx = 1, _dy = 1;
private int _timer = 0;
private int _milliseconds = 1000;
private Ball() { }
public static Ball Instance {
get {
if(_instance == null) {
_instance = new Ball();
}
return _instance;
}
}
/// <summary>
/// Move the ball on screen
/// </summary>
/// <param name="speed">The refresh/draw speed of the screen</param>
public void Move(int speed) {
if (_timer >= _milliseconds) {
// Set the cursor position to the current location of the ball
Console.SetCursorPosition(_a, _b);
// Clear the ball from the screen
Console.WriteLine(" ");
_a += _dx;
_b += _dy;
// Set a new locatio for the ball
Console.SetCursorPosition(_a, _b);
// Draw the new ball location on screen
Console.Write("*");
if (_a > 77) _dx = -_dx;
if (_a < 2) _dx = -_dx;
if (_b > 22) _dy = -_dy;
if (_b < 2) _dy = -_dy;
} else {
_timer = _timer + speed;
}
}
}
class Paddle {
private int _x = 2, _y = 23, _da = 1;
public int x {
get {
if (_x > (Console.BufferWidth - "~~~~~~~~~~".Length)) x = -_da;
if (_x < 2) x = -_da;
if (_x < 0) x = 2;
return _x;
}
set { _x = value; }
}
private static Paddle _instance;
private Paddle() { }
public static Paddle Instance {
get {
if (_instance == null) {
_instance = new Paddle();
}
return _instance;
}
}
/// <summary>
/// Move the Paddle on screen
/// </summary>
/// <param name="direction">Direction to move the paddle (Left = -1, Right = 1, Do Not Move = 0)</param>
public void Move(int direction) {
Console.SetCursorPosition(x, _y);
Console.Write(" ");
x = x - direction;
Console.SetCursorPosition(x, _y);
Console.Write("~~~~~~~~~~");
}
}
class Program {
private static int PaddleDirection = 0;
static void Main(string[] args) {
Thread ConsoleKeyListener = new Thread(new ThreadStart(ListerKeyBoardEvent));
ConsoleKeyListener.Name = "KeyListener";
ConsoleKeyListener.Start();
//ConsoleKeyListener.IsBackground = true;
int speed = 50;
do {
Console.Clear();
Ball.Instance.Move(speed);
Paddle.Instance.Move(PaddleDirection);
PaddleDirection = 0; // You can remove this line to make the paddle loop left/right on the screen after key press.
Thread.Sleep(speed);
} while (true);
}
private static void ListerKeyBoardEvent() {
do {
ConsoleKeyInfo k = Console.ReadKey(true);
if (k.Key == ConsoleKey.LeftArrow) PaddleDirection = 1;
else if (k.Key == ConsoleKey.RightArrow) PaddleDirection = -1;
else PaddleDirection = 0;
Console.ReadKey(false);
} while (true);
}
}
}
I'm working on a game app for windows phone.
I'm moving an image over the screen (which is a Map). The user can place a ball where he wants. My question is how can I not allow the ball to be placed on the image?
I think I could check for collision an move the ball out of the rectangle when if necessary.
I have 3 methods for moving my object (ManipulationStarted, OnManipulationDelta, and ManipulationOver).
The one I have a problem with is:
private void OnManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
Point A = new Point();
Point B = new Point();
e.Handled = true;
var transform = (sender as UIElement).RenderTransform as TranslateTransform;
A.X = transform.X += e.DeltaManipulation.Translation.X;
A.Y = transform.Y += e.DeltaManipulation.Translation.Y;
B.X = savx = transform.X;
B.Y = savy = transform.Y;
for (int i = 0; i < cur.lobst.Count(); i++)
{
if ((A.X > cur.lobst[i].px
&& A.X < (cur.lobst[i].px + cur.lobst[i].pw))
&& (A.Y > cur.lobst[i].py
&& A.Y < (cur.lobst[i].py + cur.lobst[i].ph)))
{
MessageBox.Show(
"Point inside the rectangle, so inside (under) my object ");
}
}
}
The message box is never shown. Why is that?
you can try this ...
public bool Intersects(Rect r1,Rect r2)
{
r1.Intersect(r2);
if(r1.IsEmpty)
{
return false;
}
else
{
return true;
}
}
then while checking ...
ismoveallowed = true;
for (int i = 0; i < cur.lobst.Count(); i++)
{
if(Intersects(r1,r2))
{
ismovallowed = false;
break;
}
}
if(ismovealoowed)
{
// move the object.
}
i hope this will help you ..
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.