I am creating a Board-Game style game in XNA Game Studio. One of the "mini-games" inside of it requires a timer. I have tried various methods but, I am stumped. If anyone can help, I would also like it to be activated by a button. This is the code I have currently:
if (orbStart)
{
int counter = 10;
int limit = 50;
float countDuration = 2f; //every 2s.
float currentTime = 0f;
currentTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (currentTime >= countDuration)
{
counter++;
currentTime -= countDuration;
}
if (counter >= limit)
{
//Stuff
}
}
}
OrbStart being the boolean activated by the button. Any help will be great!
Okay, first create global variables, for example:
bool isTimerOn = false;
float counter = 10; // 10 seconds
Then you should change isTimerOn to true when user presses your button, hope you know how to do it. Next step- inside your update method, substract elapsed time from the last tick from counter's value and check whether the time is up:
if (isTimerOn)
{
counter -= gameTime.ElapsedGameTime.Seconds;
if (counter <= 0)
doSomething();
}
Oh, I've noticed you wanted help with your button too. So first of all, you should create a Recentagle inside which your button will be placed:
Rectangle button = new Rectangle(50, 60, 100, 30);
This code means your buttons upper left point is located at (50, 60), it's width is 100 and it's height is 30. You can really read how to drawsprite at this location everywhere, as it was discussed for a couple of times here.
To check whether user clicks our button, just read about how to handle gestures and check whether tap's position is inside our rectangle, here's the code:
while (TouchPanel.IsGestureAvailable)
{
GestureSample gs = TouchPanel.ReadGesture();
switch (gs.GestureType)
{
case GestureType.Tap:
if (button.Contains((int) gs.Position.X, (int) gs.Position.Y))
isTimerOn = true;
break;
}
}
To make it work there's just one more thing- you have to enable tap gesture. Inside LoadContent() method add:
TouchPanel.EnabledGestures = GestureType.Tap;
Related
I have a joystick display picture for my game. Currently, when the player touches the screen the image disappears and when the player is not touching the screen, it reappears. I wrote that using an if else statement.
if (indicator.inputIndicator.x != 0)
{
joystick.SetActive(false);
}
else
{
joystick.SetActive(true);
}
The problem is, I want the image to reappear after some time like 2 seconds. I want to delay the "else", but I do not want to use a coroutine. I want "else" to work after 2 seconds since the player takes his hand off the screen but I couldn't figure out how to do it. any help will be great.
Setting a timer is a pretty common problem you have to solve in Unity. One basic approach is to have a variable that you add Time.deltaTime every update. That way you can tell how long it has been since some condition was met.
Every Update iteration that meets the condition, add Time.deltaTime to the variable. If at some point the condition fails, reset the variable to 0. Then you can just base your joystick.SetActive() call on the value of your variable.
For example, your script might become:
float thresholdTimeToShowPrompt = 2;
// By starting at the threshold, the image is hidden at the start until a touch
float timeSincePlayerTouch = 2;
void Update()
{
// Rather than calling SetActive directly, just update the timer
if (indicator.inputIndicator.x != 0)
{
timeSincePlayerTouch = 0;
}
else
{
timeSincePlayerTouch += Time.deltaTime;
}
// Now we can base visibility on the time since the last user touch
bool shouldShowIcon = timeSincePlayerTouch >= thresholdTimeToShowPrompt;
// Only call SetActive when needed, in case of overhead
if (shouldShowIcon && !joystick.activeSelf)
{
joystick.SetActive(true);
}
else if (!shouldShowIcon && joystick.activeSelf)
{
joystick.SetActive(false);
}
}
I am very new to programming so please have patience with me. I am trying to add a delay to pressing a button in Unity. For example when i press "S" there should be a specified number of seconds that has to pass before i can press it again. Can anyone help me out ???
How can i add a delay to pressing buttons in Unity
If you want to achieve that you can set a delayTime and count it down in the Update Method and make the button do nothing on press until the time has passed.
Example:
float time = 0f;
void Update() {
if (time > 0f){
// Subtract the difference of the last time the method has been called
time -= Time.deltatime;
}
if (Input.GetKeyDown("S") && time <= 0) {
// Exectue Code you had in your Button Click function before
time = 2f;
}
}
If we want to elaborate on your answer we could also make the buttons enabled property disabled as long as the timer is not down to 0.
Example 2:
float time = 0f;
Button btn; // The Button you want to be unpressable
void Update() {
if (time > 0f){
// Subtract the difference of the last time the method has been called
time -= Time.deltatime;
btn.enabled = false;
}
else {
btn.enabled = true;
}
if (Input.GetKeyDown("S") && time <= 0) {
// Exectue Code you had in your Button Click function before
time = 2f;
}
}
I'm going to have to recall from memory here, but I believe you want to create an enumerator function, something along the lines of:
IEnumerator OnButtonClicked()
{
}
and when your button is clicked, you want to start this coroutine using:
StartCoroutine(OnButtonClicked());
And inside the OnButtonClicked() (or whatever you choose to name it), simply call:
yield return new WaitForSeconds(1);
and then do whatever you want it to do after the delay, after this.
I have some troubles with creating a timer for my c# monogame. I already red the other timer questions on stack overflow, but I didn't get it.
I want to collect gold in my mine. But the gold is limited, every 5 seconds there should be new gold.
I tried to do it like How to create a timer/counter in C# XNA
But it isn't working. I get a System.NullReferenceException. Is there a better way to do a timer? Or how can I fix the Exception?
Here is the most important part of my code:
private GameTime gameTime;
int counter = 1;
int limit = 50;
float countDuration = 10f; //every 2s.
float currentTime = 0f;
private void CollectGold(ObjectFactory.ObjectType type)
{
currentTime += (float)gameTime.ElapsedGameTime.TotalSeconds; //Time passed since last Update()
if (currentTime >= countDuration)
{
counter++;
currentTime -= countDuration;
// maxGold limits the Mine
if (mMaxGold > 0)
{
mGold += 5;
mMaxGold -= 10;
}
}
}
thank. I did it. Just assign the value of GameTime wrong. Didn't know that it have to be in an update function. Thanks.
So when my character gets hit by the enemies fire breath, I want to create the feel of the character being set on fire. So while the character is on fire I want him to lose a specific amount of health for a specific amount of time.
For example; lets say he is on fire for 3 seconds and I want to make him lose 30 health for being on fire, how would I evenly distribute losing 30 health for 3 seconds? I dont want the 30 damage to be applied instantly to the health, I want it to slowly tick away at the players health so that at the 3 second mark 30 damage has been dealt.
The game is being made with c#.
Thanks.
This is just like moving Gameobject over time or doing something over time. The only difference is that you have to use Mathf.Lerp instead of Vector3.Lerp. You also need to calculate the end value by subtracting the value you want to lose over time from the current value of the player's life. You pass this into the b or second parameter of the Mathf.Lerp function.
bool isRunning = false;
IEnumerator loseLifeOvertime(float currentLife, float lifeToLose, float duration)
{
//Make sure there is only one instance of this function running
if (isRunning)
{
yield break; ///exit if this is still running
}
isRunning = true;
float counter = 0;
//Get the current life of the player
float startLife = currentLife;
//Calculate how much to lose
float endLife = currentLife - lifeToLose;
//Stores the new player life
float newPlayerLife = currentLife;
while (counter < duration)
{
counter += Time.deltaTime;
newPlayerLife = Mathf.Lerp(startLife, endLife, counter / duration);
Debug.Log("Current Life: " + newPlayerLife);
yield return null;
}
//The latest life is stored in newPlayerLife variable
//yourLife = newPlayerLife; //????
isRunning = false;
}
Usage:
Let's say that player's life is 50 and we want to remove 2 from it within 3 seconds. The new player's life should be 48 after 3 seconds.
StartCoroutine(loseLifeOvertime(50, 2, 3));
Note that the player's life is stored in the newPlayerLife variable. At the end of the coroutine function, you will have to manually assign your player's life with the value from the newPlayerLife variable.
I suppose, what you are looking for is a Coroutine. Check out here and here for the documentation. It will allow you to do your custom health reducing actions separately from update function. Using coroutines you can make something happening by ticks, and you can determine how much time the tick is.
You could use couroutines. Something like this:
void OnHitByFire()
{
StartCoroutine(DoFireDamage(5f, 4, 10f));
}
IEnumerator DoFireDamage(float damageDuration, int damageCount, float damageAmount)
{
int currentCount = 0;
while (currentCount < damageCount)
{
HP -= damageAmount;
yield return new WaitForSeconds(damageDuration);
currentCount++;
}
}
So this is what I ended up doing. It causes the character on fire to lose 30 health and you can see the health ticking down instead of it happening over intervals.
IEnumerator OnFire()
{
bool burning = true;
float timer = 0;
while (burning)
{
yield return new WaitForSeconds(0.1f);
hp -= 1;
timer += 0.1f;
if (timer >= 3)
{
burning = false;
}
}
}
So, I have a rectangle "rectangle1", at 160,160.
I want it to move smoothly to cordinates 160,30, with a duration of about 1 second. (time delay)
I've figured out that some basic code to move the shape is
rectangle1.Location = new Point(160,30);
However, when I tried doing a for loop with
rectangle1.Location = new Point(160, rectangle1.Location.Y - 100);
it just moved there instantly. Which I should have expected really. Same occurred with
int count = 0;
while(count != 300)
{
rectangle1.Location = new Point(160, rectangle1.Location.Y -1);
count += 2;
}
So, I assume I need some sort of clock / timer loop, that moves it by x pixels every x milliseconds. Not sure how to do this, so help would be appreciated.
Also, I'm going to be animating two other rectangles horizontally, which will then move up at the same time/speed as rectangle1. I think I'll have to "delay" rectangle1's movement until they are in position, correct?
Thanks.
PS: I've googled a fair bit, but since I'm not entirely sure what I'm looking for, it wasn't very fruitful.
If you need smooth movements, it's great to use timers, threads, backgroundworkers.
Here is what you need to do. Assuming you have the code that increment/decrement x,y points for the shape.
Steps:
set timer interval to for e.g. 100
set an integer int count=0; *
in timer_tick event do the moving work
private void timer1_Tick(object sender, EventArgs e)
// no need to use your while loop anymore :))
{
If(count< 300) //set to your own criteria
{
//e.g. myrect.location=new point(x,y);
// rectangle1.Location = new Point(160, rectangle1.Location.Y -1);
}
count += 2;
}