I'm working on a game where the player / enemy has a balance bar with 3 overlays. What i'm trying to do is manipulate the 1st overlay so it goes fully across the bar by percentages.
Example: first overlay is 50% of enemy's balance. Then moves into another 'phase' or 'state. Then that overlay is gone and the second overlay is triggered and starts to decrease as well.
The width of the bar is 200 pixels, so what i'm trying to do is say "hey, if 50% of the enemies balance is gone, THEN trigger/animate the 2nd overlay.
The problem i'm running into is the remainder line. When I hit the enemy for say.. 10 balance damage of 200. It will give me the proper percentage left AND the proper remainder left. But once I hit 50%, the remainder = 0! This is where that line or function no longer works properly and it breaks the design pattern of what I want to do. Here is a example in the console log.
balanceCounter: function (character, boss){
var percentage = Math.floor((boss.balance/200) * 100)
var remain = 100 % percentage; // <--- This is not working properly
console.log(percentage);
console.log(remain);
if (character.virtue == "hero"){
if (percentage > 49){
$("#bossbalanceoverlay2").animate({
width: percentage * 2 - (remain * 2)
}, 200)
}
else
$("#bossbalanceoverlay1").animate({
width: percentage * 2 - (remain * 2)
}, 200);
}
**click attack button**
97 // <--- Percent
3 // <--- Remainder
**click attack button**
95 // <--- Percent
5 // <--- Remainder
**click attack button**
92 // <--- Percent
8 // <--- Remainder
(When i hit the 50% mark)
**click attack button**
50 // <--- Percent
0 // <--- Remainder **Why 0?**
**click attack button**
47 // <--- Percent
6 // <--- Remainder **Why 6 instead of 3?**
**click attack button**
45 // <--- Percent
10 // <--- Remainder **Why 10 instead of 5?**
You probably want to do this, instead of %:
var remain = 100 - percentage;
You want remain + percentage to always add up to 100, so this is a subtraction you need, not a modulo operation.
It is normal that with % (modulo) you get zero when the percentage is 50, because 100 is a multiple of 50 and so there is no remainder.
The problem your facing is that % returns the remainder.
100 % 45 => divisible by 45 twice, remainder = 10.
100 % 50 => divisible by 50 twice, remainder = 0.
What you want is remain = 100 - percentage
For starters I would add missing semicolons.
Secondly it looks like your else bracket is missing curly braces { }, which could cause both blocks to be hit depending on how your code is formatted.
Thirdly I would read up on the % operator, you may be overthinking it ;)
Related
Hi friend i have a problem when solving our teacher assignment. Here is the problem:
You are tasked for implementing point system for your company upcoming hunting game. There is a rule for the game:
Point bracket
Bracket total kill 10 point multiplier x1
Bracket total kill 20 point multiplier x2
Bracket total kill 30 point multiplier x3
Bracket total kill 40 point multiplier x4
Bracket total kill 50 point multiplier x5
Bracket total kill above 50 point multiplier x6
Point bracket explanation:
*if total kill less or the same than 10, point will be 10
*if total kill between 10 and 20, point will be 2x of total kill between 10 and 20, plus 1x of 10 total kill
if total kill between 20 and 30, point will be 2x of total kill between 10 and 20, plus 3x of total kill over 20, plus 1x of 10 total kill
if total kill above 30, point will be 2x of total kill between 10 and 20, plus 3x of total kill between 20 and 30, plus 4x total kill over 30, plus 1x of 10 total kill
and so on
Ex:
total kill 10, point 10
total kill 27, point 51
total kill 33, point 72
total kill 120, point 570
total kill 60, point 210
I have tried to code it in js, but i think there is some missing logic. can you help me ?
function calculatePoint(totalKill){
if(totalKill <= 10){
return 10;
} else if ( totalKill >= 10 && totalKill <=20){
return 2*totalKill + 1*10*totalKill;
} else if ( totalKill>=20 && totalKill <=30){
return 3*totalKill + 1*10*totalKill;
} else if (totalKill>=30){
return 2*totalKill + 3*totalKill + 4*totalKill+1*10*totalKill;
}
}
well for starters you are overlapping >=10 and <=10 - and others. be clear about less than 10, between 10 and 20, etc..
next up is 2x for points between 10 and 20. you are just multiplying 2xtotalKill - you probably need something like 2x(totalKill-10), and 3x(totalKill-20), etc..
you don't say what is not working? if you provide more details about what you have tried, and what the problem is - you might get more assistance...
I am using map coordinates as a part of website logo. (2.378628, 48.853373).
What I want to do, is count both numbers from 0.000000 so they reach given points during the same time (3-5 seconds), incrementing by 0.000001. How is that possible? This crashes my computer, and setInterval does sth every ms, which is not enough.
while (i < 48.853373) {
i = i + 0.000001;
$('.js-center-lat').text(i);
}
Sounds like you want to "animate" the floating point number to count up to a defined value.
Have you considered third party libraries, like CountUp.js?
CountUp.js is a dependency-free, lightweight JavaScript "class" that can be used to quickly create animations that display numerical data in a more interesting way.
Quick example on how to use it:
var options = {
useEasing: true,
useGrouping: true,
separator: '',
decimal: '.',
};
var demo = new CountUp('myTargetElement', 0, 2.415543, 6, 2.5, options);
if (!demo.error) {
demo.start();
} else {
console.error(demo.error);
}
Hope this helps!
You take the time when you started the animation (startTime), and you have value how long the animation should last (duration).
For each animation step you can calculate the percentage of the animation.
And with that percentage you can count up multiple values.
let startTime = Date.now();
let duration = 3000;
function updateText() {
let percent = Math.min(1, (Date.now() - startTime) / duration);
// Math min ensures that percent does not become larger then 1
$('.val1').text(50 * percent); // 0 - 50
$('.val2').text(33 * percent); // 0 - 33
$('.val3').text(13 + 10 * percent); // 13 - 23
if (percent <= 1) {
requestAnimationFrame(updateText)
}
}
updateText();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="val1">
</div>
<div class="val2">
</div>
<div class="val3">
</div>
I have a div with some text which I would like to rotate 360 degrees for x amount of times but I would also like to modify the text every 180 degrees. how can I achieve this in Jquery or Javascript?
So far, I am stuck on this as I don't know of a way to monitor the rotation.
$('.pie_chart').css({'transform' : 'rotate(2000deg)'});
I looked at this post thinking that I could utilize the solution but it didn't work for me, or I might be just using it wrong: CSS rotation cross browser with jquery.animate()
This is very imprecise but it gets the idea across and should be enough to get you on the right track
function AnimateRotate(angle) {
// caching the object for performance reasons
var $elem = $('#square');
var texts = ['text', 'another thing', 'one more thing', 'finally']
var maxRotations = Math.floor(angle / 180);
var rotations = 0;
var lastRotation = 0;
// we use a pseudo object for the animation
// (starts from `0` to `angle`), you can name it as you want
$({deg: 0}).animate({deg: angle}, {
duration: 2000,
step: function(now) {
// in the step-callback (that is fired each step of the animation),
// you can use the `now` paramter which contains the current
// animation-position (`0` up to `angle`)
$elem.css({
transform: 'rotate(' + now + 'deg)'
});
// Here we must allow ourselves some margin for error
// We are making 4 rotations in 2 seconds, so in theory
// The box will be at the 180 degrees every half a second
// but in actuality it never is at exactly 180 degree except at the star and end
// Trial and error has shown that +6 degrees is more or less accurate,
// you could do some math to get a better precision
// We don't want to update the text at 0 degrees
if(now % 180 <= 6 && rotations > 0) {
// Shift off the first text and use that for the new text
$("#text").html(texts.shift());
rotations++;
} else if(now % 180 >= 177) {
$("#text").html(texts.shift());
rotations++;
}
}
})
};
AnimateRotate(720);
I'm trying to build a game somewhat like Wheel of Fortune, actually it's done but there seems to a weird issue I can't figure out.
Here's the wheel itself, as you can see the values are spaced evenly, each having a 15 ° slice.
To spin the wheel I generate a random number which will be the amount of rotation in degrees, I animate the wheel and everything is fine but when the rotation stops I have to get the value from the wheel which stops at the top-center position so I though this would solve it:
wheelValues = [
1000, 3250, 1800, 1000, 1200, 3750, 5000, 1000, 3000, 1600, 1000, 3500,
1000, 2000, 1000, 2750, 1000, 4000, -1, 1000, 2500, 1400, 1000, 2250
];
if (toAngle > 360)
{
toAngle = toAngle - (Math.floor(toAngle / 360) * 360);
}
arrIndex = Math.floor(toAngle / 15) + 1;
result = wheelValues[arrIndex];
where toAngle is the random spin I generate which can be between 370 and 1440.
This method works in about 8/9 times out of 10 and I can actually get the correct value the wheel stops at but I can't really understand why sometimes the value is off (and sometimes really off, not even near the correct value).
You're adding 1 to your array index for some reason.
array indexes start from 0.
Two problems I can see;
Firstly, this line:
if (toAngle > 360)
If toAngle == 360, I believe this will produce an error, as you will skip the 'modulus' section and toAngle will finally be 24 (larger than your dataset)
Second:
arrIndex = Math.floor(toAngle / 15) + 1;
No need to +1 this, as you will never get your first value, and on occasion you will exceed the array bounds.
Also, as to why you get odd values, have you tried to write some simple code to debug your assumptions? Write a loop, that iterates from 370 to 1440 (your stated input boundaries) and see what your calculation comes up with for each value. Print it to a file, or screen and you can quickly scan to see where the issues might be.
BTW, it's probably best if you make your random number an even multiple of 15 degrees in the first place, then you don't need all that rounding and flooring, e.g.
function randDeg() {
var epoch = 360; // minimum value
var max = 1440; // maximum value to return
var step = 15; // even multiple to return
var t = Math.random() * (max - epoch) | 0;
t -= t % 15;
return t + epoch;
}
Will return a number n where epoch <= n <= max and n%15 = 0.
So I have a hex grid that has a 100x100 grid... The Grid is recursive so when you scroll left past the '0,0' position it draws the '99,0' row etc... My issue is finding an algorithm that will let me calculate if I am looping back around...
Example:
96 - 97 - 98 - 99 - 0 - 1 - 2 - 3 - 4
Both of these have starting locations less then the ending location
If I was at row 2 and the screen panned to row 98:
2 to 98 WORKS (98) - 100 = -2 then -2-(2) = distance of 4
96 to 98 FAILS (98) - 100 = -2 then -2-(96) = distance of 98 (correct is 2)
Both of these have ending locations less then the starting location
However this doesn't work both directions... so we do this...
from row 98 to row 2:
98 to 2 WORKS (2) + 100 = 102 then 102-(98) = distance of 4
96 to 98 FAILS (96) + 100 = 196 then 196-(98) = distance of 98 (correct is 2)
As you can see I cant just say if start < end or start > end as the number loop screws that up. I need to detect when "Crossing the line" some how...
After Jonathan suggestions I realized that the client display and behind the scenes didn't have to line up. I have changed the engine so there are 2 hex values... one is the actual position like 98,2 0,0 2,1. The other is a literal position from the view port.
Looks like this:
Actual: 96 97 98 99 00 01 02 03 04 <= display in client & reference hexGridModel
Literal: -4 -3 -2 -1 00 01 02 03 04 <= use to calculate buffer position updates from camera
The literal is just from the "display" standpoint. I will need a fix later to see if we go passed -100 or +100 but this solved issue for now and map sizes are dynamic so will need later work on that
Now I just used this for any case.
var x, y = 0
x = this.buffer.coords.current.x - this.buffer.coords.last.x;
y = this.buffer.coords.current.y - this.buffer.coords.last.y;
I'd say it's not really possible without more information than you've given us. Take the example of moving from 2 to 98. You will not be able to tell whether the user moved from 2 -> 1 -> 0 -> 99 -> 98 or 2 -> 3 -> 4 -> ... -> 97 -> 98.
So the key to being able to determine this is knowing the direction in which the player or object is moving.
If you know that, you can say (assuming 0 is at the left boundary of the grid and 99 is at the right boundary of the grid):
if ((direction == LEFT && new_pos > old_pos) || (direction == RIGHT && new_pos < old_pos) {
// The "line" has been crossed.
} else {
// The "line" was not crossed.
}
If you also need to know the distance travelled, you can break it down like this:
GRID_SIZE = 100
if (direction == LEFT && new_pos > old_pos) {
distance = (GRID_SIZE - new_pos) + old_pos;
} else if (direction == RIGHT && new_pos < old_pos) {
distance = (GRID_SIZE - old_pos) + new_pos;
} else {
distance = abs(new_pos - old_pos)
}
Note: I posted the following before I saw the update to the question. It's what I guessed you might have meant in your original question. Maybe it'll still be helpful somehow.
I don't really understand the requirement as worded, so I'm guessing that it is "Find the shortest distance between two positions, allowing wrapping across the 99/0 boundary if it is shorter".
This function returns an object with three properties, the distance, the direction, and wrapAround (true/false). And I threw in a toString() for ease of testing it out.
function shortestDistance(startPosition, endPosition) {
var difference = startPosition > endPosition
? startPosition - endPosition
: endPosition - startPosition,
wrapped = difference > 50;
return {
distance : wrapped ? 100 - difference : difference,
direction : (startPosition < endPosition
? (wrapped ? "left" : "right")
: (wrapped ? "right" : "left")),
wrappedAround : wrapped,
toString : function() {
return (
this.distance === 0
? "Didn't move"
: "Travelled " + this.distance
+ " to the " + this.direction + ", and "
+ (this.wrappedAround ? "did" : "didn't")
+ " wrap around.");
}
};
}
var result = shortestDistance(2,98);
alert(result.distance); // 4
alert(result.direction); // "left"
alert(result.wrappedAround); // true
alert(shortestDistance(2,98));
// Travelled 4 to the left, and did wrap around.
alert(shortestDistance(98,2));
// Travelled 4 to the right, and did wrap around.
alert(shortestDistance(96,98));
// Travelled 2 to the right, and didn't wrap around.
alert(shortestDistance(98,96));
// Travelled 2 to the left, and didn't wrap around.
alert(shortestDistance(43, 43));
// Didn't move
alert(shortestDistance(1, 50));
// Travelled 49 to the right, and didn't wrap around.
alert(shortestDistance(1, 51));
// Travelled 50 to the right, and didn't wrap around.
alert(shortestDistance(1, 52));
// Travelled 49 to the left, and did wrap around.
alert(shortestDistance(50, 1));
// Travelled 49 to the left, and didn't wrap around.
alert(shortestDistance(51, 1));
// Travelled 50 to the left, and didn't wrap around.
alert(shortestDistance(52, 1));
// Travelled 49 to the right, and did wrap around.