I'm making a game with a score text and was wondering how I would write a script that doubles the points added to the score if some condition happens twice in a row? So far, I have a block that adds 2 points instead of 1 if the player gets the bullet in a certain region. The code is as follows:
if (-0.02f < transform.forward.x && transform.forward.x < 0.03f) {
perfectScoreText.GetComponent<Animator> ().Play ("PerfectHit");
currentScore += 2;
scoreText.text = "" + currentScore;
}
I was wondering how I'd make that code add two times as much as the user completes the condition twice/thrice/etc in a row.
Thanks.
Add a counter for perfect hit. Lets say perfectHitCounter. When perfect hit occurs increase this counter by one, if perfect hit fails make this counter zero. And when it reaches 2, add double score and reset the counter or if your game has the combo system you can increase the counter till you miss the perfect shot.
PSEUDO
I assume the code you provide is where the perfect hit happens.
if (-0.02f < transform.forward.x && transform.forward.x < 0.03f) //Perfect Hit
{
//Perfect hit
perfectHitCounter += 1;
//Add normal score if you wish
}
if('not perfect score condition')
{
perfectHitCounter = 0;
}
if(perfectHitCounter >= 2)
{
currentScore += 2;
//perfectHitCounter = 0; //If there is no combo system.
}
Hope this helps. Cheers!
Related
I'm working on a brickout game clone, so I'm trying to add a multiply the ball feature to the game. This Video shows the feature.
Here is my code:
//access to all active balls
Ball[] balls = FindObjectsOfType<Ball>();
//loop for the length of the balls
for (int i = 0; i <= balls.Length; i++)
{
if (balls.Length >= 1000)
{
return;
}
else
{
// here I'm trying to fix the issue by checking if the ball exists, so I will call the function if not. return. but console show me same message
if (balls[i] != null)
{
balls[i].CallM3x();
i++;
}
}
}
The unity console message is:
IndexOutOfRangeException: Index was outside the bounds of the array.
My code above is working fine, but the issue is some balls destroy before the for loop end its work by less than a second .
Any idea how to avoid this?
There are two fundamental issues with your loop:
you're looping up to i <= balls.Length which will always throw an error (there is no a[10] in an array of length 10).
you're incrementing i again within the loop, which will skip items
Change the loop condition to i < balls.Length and remove the i++ within the loop.
Also, you don't need to check if (balls.Length >= 1000) within the loop every time - you can check that before the loop (but what's the problem with a collection with more than 10,000 items?)
the issue is some balls destroy before the for loop end its work by less than a second
I don't see how this can be a problem. You're creating an array of references that you're looping over. Even if items are destroyed within the game, the object references still exist within your array. There may be some other flag to tell you that an object is destroyed (I am not a Unity expert), but they would not change to null inside your array.
A simple way to avoid the issue of re-referencing objects you have deleted in a loop is by counting i down from balls.Length to 0 instead of up from 0 to balls.Length.
for (int i = balls.Length - 1; i >= 0; i--)
Also, you might want to look again at your for-loop: you are going up to <= balls.Length, allowing the highest index to be = balls.Length. That index is out of bounds though, because we start counting at 0. I suggest using < instead of <= here.
Ball[] balls = FindObjectsOfType<Ball>();
for (int i = 0; i < balls.Length; i++)
{
if (balls.Length >= 1000)
{
return;
}
else
{
if (balls[i] != null)
{
balls[i].CallM3x();
// i++; <- This is your problem. Remove it.
}
}
}
I've been working on a slotmachine in C# for practise purposes, and the machine itself works as intentional. The points system, however, does not. The game starts at 100 points, and if, for example, the player lose three 5-point bets and wins 40 points on the fourth bet, the expected points would be 100-20+40=120 points. For some reason however, the code treats ALL the previous bets as being 40 point wins as well, bringing the total to 100-20+160=240 points. If the player then lose the fifth 5-point bet, the score jumps to 75.
I start by setting the 'points' value to 100, which should then update everytime the 'game()' function is called upon.
public static void Main()
{
int points = 100;
int num = 0;
Console.WriteLine("Welcome to 'Slotmachine'!\nThe aim of this game is to get a score of 1000 or higher.\nYou lose if you reach 0 or lower.\nPress enter to play");
Console.ReadLine();
Console.Clear();
points = points + game(100);
while(points<1000 && points>0)
{
num = num + 1;
Console.WriteLine("You've played for "+num+" number of round(s)");
points = points + game(points);
}
}
The 'game()' funtion returns the players winnings, which is used to update the 'points' value (Suspect nr 1?).
Inside the game function I have a 'usrbet' which takes an input from the user (1-10), which is then fed into the 'slots()' function to determine the winnings (the 'points' that are fed from 'Main()' are checked to see what the user can bet)
Console.WriteLine("Here are your current points: "+points+"\nHow much would you like to bet?\nmin bet: 1\nmax bet: 10");
try
{
usrbet = Convert.ToInt32(Console.ReadLine());
}
catch
{
usrbet = 1;
}
winnings = slots(usrbet);
int RetWin = winnings - usrbet;
return RetWin;
Here's what the 'slots()' function does, with some examples of the winnings calculations
public static int slots(int usrbet)
{
int Win;
int x;
int y;
int z;
Random slot = new Random();
x = slot.Next(2,10);
y = slot.Next(2,10);
z = slot.Next(2,10);
Console.WriteLine(x+""+y+""+z);
Example 1
if(x == y && y == z && x== 7)
{
Win = usrbet*250;
Console.WriteLine("WOW! That's incredible, you just won "+Win+"!");
}
Example 2
else if(x == z)
{
Win = usrbet*5;
Console.WriteLine("Congratulations, you win "+Win+".");
}
Example 3
else
{
Win = 0;
Console.WriteLine("Ah, bummer. You didn't win anything this time.");
}
After that, the 'Win' value is sent back to 'game()', updating 'winnings'.
I apologize for poor formatting of the question. I'll include a link to the code, in case my problem lies elsewhere in the code: https://dotnetfiddle.net/D5TwL0
I've tried making arrays of the 'bet' and 'usrbet' variables, in an attempt to have a "new" value to update the 'points' with at every run of 'game()', but that changed absolutely nothing other than limiting how many times 'game()' can run before getting an overflow error.
It turns out that the problem wasn't with the code, but with the compiler. Dotnetfiddle is where I made the code and had the issue, but trying it in another compiler, it managed to count just fine.
I have a car game when the car runs out the road, its healthbar will be decreased. But i want to slow down the decrease. How can I do it?
This is the current code.
for (int i = 20; i >= 0; i--)
{
if (car.getPosY() < 450 || car.getPosY() > 500)
{
car.hitPoints = car.hitPoints - 1;
// if (car.hitPoints <= 0) car.active = false;
}
}
But i want to slow down the decrease.
You will need to implement a timer for your car as follows: Whenever the car gets damaged, it has its health reduced and for a small time (say 1 second or 1000 ms) the car ignores all damage.
I have already questioned the use of the outer loop in the comments, so I won't dwell on that here. I am not using the loop as you have in your code.
Your car class needs to have a int variable for storing the time (in milliseconds) as shown
class Car
{
int Timer=0;
...//Other stuff you have already
}
Next change your logic as shown:
if (car.getPosY() < 450 || car.getPosY() > 500)
{
if(car.Timer==0) //This code happens once per second (according to the Timer value below)
{
car.hitPoints = car.hitPoints - 1;
// if (car.hitPoints <= 0) car.active = false;
}
car.Timer += gameTime.ElaspedGameTime.Milliseconds;//Value of time (in milliseconds) elasped from the previous frame
if(car.Timer >= 1000) //max value of time when damage is ignored. You can change this value as per your liking.
car.Timer = 0; //Reset the timer
}
else car.Timer = 0; //Reset the timer
I typed this code without testing. Let me know if there are any issues.
I'm aware (from similar posts) that infinite while loops are notorious for causing Unity3d to crash. I'm tring to impliment a while loop within something I'm working on, which I'm fairly sure isn't 'infinite', yet causes the game to crash.
The idea of the logic is to check a list of integers for consecutive numbers and use that as the basis to apply a bonus. The list contains 'effective shots', and has a new int added every time a shot is fired - the more consecutive effective shots, the higher the bonus.
Here's what I have:
int count = 0;
int firstItem = 0;
int multiples = 3;
int currentMultiple = 0;
int bonusX = 0;
foreach (int i in effectiveShots)
{
if (count == 0)
{
firstItem = i;
count = 1;
}
else if (i == firstItem + count)
{
count++;
}
}
while (count >= multiples)
{
currentMultiple = multiples;
if (count == currentMultiple + multiples)
{
bonusX += 1;
}
if (bonusX > 10 || gameOver)
break;
UnityEngine.Debug.Log(bonusX);
}
The logic to check for consective entries in the effectiveShots list was taken from #Jon Skeet's answer here. Though this appears to work, I think that this may be the issue. As soon as a shot is missed, count needs to be reset. Any ideas or suggestions?
The while loop should then be entered once the count of consecutive effective shots has reached the first multiple, i.e. 3 shots. Then, for every set of consequtive effective shots thereafter, increment the bonus, for example:
3 shots: bonusX = 1
6 shots: bonusX = 2
9 shots: bonusX = 3
12 shots: bonusX = 4
and repeat this until `count` is no longer >= 3, i.e. the player missed a shot.
The issue is that as soon as I hit 3 consequtive shots and enter this loop, the game crashes. I dont think I would call this an infinite loop, since missing a shot - setting count == 0 - would mean the while conditions are no longer true, so drop out of the loop (I think?). I also added an additional check to break out of the loop under certain circumstances, but this doesnt make a difference.
If you are able to give a steer as to how to fix this crashing, or have a suggestion on a better approach in general, it would be appreciated!
Nothing in your while loop changes the value of either count or multiples and so the condition will always evaluate to the same value => Infinite loop
Hey there, So I'm knocking together a random pattern generation thing.
My code so far:
int permutes = 100;
int y = 31;
int x = 63;
while (permutes > 0) {
int rndTurn = random(1, 4);
if (rndTurn == 1) { y = y - 1; } //go up
if (rndTurn == 2) { y = y + 1; } //go down
if (rndTurn == 3) { x = x - 1; } //go right
if (rndTurn == 4) { x = x + 1; } //go left
setP(x, y, 1);
delay(250);
}
My question is, how would I go about getting the code to not go back on itself?
e.g. The code says "Go Left" but the next loop through it says "Go Right", how can I stop this?
NOTE: setP turns a specific pixel on.
Cheers peoples!
It depends on what you mean.
If you mean "avoid going back to a step I was most previously on" then you have to remember the direction of the last movement. That is if you move up your next movement can't be down.
If you mean "avoid going back on a spot you've ever been on" then you're going to have to remember every spot you've been on. This can be implemented efficiently with a hash table using a key with a class representing a coordinate with appropriate Equals/HashCode functions.
Since each square corresponds to a pixel, your coordinate space must be finite, so you could keep track of coordinates you've already visited.
If there's a corresponding getP function to determine if a pixel has already been turned on, you could just use that.
You remember the last direction and, using random(1,3), pick either of the remaining three, then store that as the last one.
Not sure if this approach will work.
Create a new variable called lastRndTurn as int, and assign this after your if statements.
Then add a new while loop after your int rndTurn = random(1, 4).
while (lastRndTurn == rndTurn)
{
rndTurn = random(1, 4);
}