I am trying to program a joystick in which the user only sends his coordinates if he stopped moving his thumb (or at least only a little, shaking for example).
I cannot find an touchevent for that.
Further explanation: brown = thumb, red is the area/circle that gets tolerated (moving in that space the next 2 seconds will count as 1 coordinate)
int actionType = event.getAction();
if (actionType == MotionEvent.ACTION_MOVE){}
This is how i retrieve my toucheventdata. i would need something like ACTION_HOLD and a timer. Am i missing something?
Try to round the coordinates.
Divide the coordinates with an integer (ex. 10),
Cast the result into an integer (or round it) and multiply with the same integer in the next Step.
Example:
5,30 / 10 = 0,53
(int) 0,53 = 0
0 * 10 = 0
14,4 / 10 = 1,44
(int) 1,44 = 1
1 * 10 = 10
Related
I am trying to create a snake game where i have 400x400 pane and the snake moves by 20 at X and Y axis. By doing this i have created a grid that has step of 20 at X and Y axis.
I want to randomly spawn a fruit at the pane but i want the width and height to be in grid so it should spawn at steps of 20 (0, 20, 40, 60 , 80, ... , 400).
I can use Math.random()*400 to get range but i cant give it unit step.
I found this question which is exactly what i asked but the solution is for lua based math.random():
math.random function with step option?
Here is how i translate the snakes position:
if (input.equals(KeyCode.W.toString()) || input.equals(KeyCode.UP.toString()))
if (snakes.get(0).getY() == 0)
movement.stop();
else
snakes.get(0).setY(snakes.get(0).getY() - 20);
*Snakes is an Arraylist of rectangles that expand as it eats food and i want only the head to eat the food
*Food is a circle that spawns at random location
And here is how i check if they come in contact:
if (food.getCenterX() == snakes.get(0).getX() && food.getCenterY() == snakes.get(0).getY())
score++;
setScore();
I move my snake over the food but the x and y position don't ever match unless i spawn food myself at the grid (say [20,40] or [60, 200]).
Is there another alternative or random with unit step or some other question that i couldn't find here at stackoverflow that can help me?
if you need integer values you can use Random.nextInt(int bound). This will produce coordinates inside your 20x20 matrix.
Random r = new Random();
int x = r.nextInt(20)*20; // values from 0 to 19 inclusively
int y = r.nextInt(20)*20;
If you want a random number out of 0, 20, 40, 60 , 80, ... , 400, then first realize that there are 21 values in that list.
Which means you want a random integer value 0, 1, 2, ..., 20, and then multiply that by 20, to get the step of 20 you want.
Don't use Math.random() for this. Sure it's convenient, but mostly is you want double values. Instead, use one of the following:
new Random() - Use in single-threaded code. Recommended.
You should generally only allocate one, then share it throughout your code.
new SplittableRandom() - Use for parallel computations.
ThreadLocalRandom.current() - Use in multi-threaded code, e.g. web servers.
All 3 have a nextInt(int bound) which returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive).
Example
Random rnd = new Random();
// in some loop generating fruits:
int fruitX = rnd.nextInt(21) * 20;
int fruitY = rnd.nextInt(21) * 20;
Write a method named randomWalk that performs a random one-dimensional walk, reporting each position reached and the maximum position reached during the walk. The random walk should begin at position 0. On each step, you should either increase or decrease the position by 1 (with equal probability). The walk stops when 3 or -3 is hit. The output should look like this:
position = 0
position = 1
position = 0
position = -1
position = -2
position = -1
position = -2
position = -3
max position = 1
My code:
public static void randomWalk() {
Random rand = new Random();
int position = 0;
int max = 0;
System.out.println("position = " + position);
while (position != 3 && position != -3) {
int randomNumber = rand.nextInt(2) * 2 - 1;
position = position - randomNumber; //why the minus?
max = Math.max(max , position);
System.out.println("position = " + position);
}
System.out.println("max position = " + max);
}
I initially had the plus sign instead of the minus sign, and 3 out 4 outputs were incorrect (image attached). Is it something to do with the output console or is my code somewhere wrong?
I initially had the plus sign instead of the minus sign, and 3 out 4 outputs were incorrect (image attached). Is it something to do with the output console or is my code somewhere wrong?
It was not "incorrect", given the requirements that we know of. The max variable tracks the maximum value that was reached. It's inevitably a positive number. The highest positive number reached was 1 before reaching the -3 exit condition.
Your implementation works equally well regardless of plus or minus randomNumber. Just the direction of the walks will be flipped, that's all. You can observe this easily by initializing the Random instance with a seed, for example new Random(1), and then try a run with plus and minus. One of them will reach 3 and the other -3, taking opposite directions at every step.
On a second read I see now that you're probably running the program through some kind of judge system, and by "incorrect", you mean the printed values are opposites of what's expected by this judge. Changing the plus minus sign fixes that, for the reason I explained above. Whichever sign you use, I don't think your program is incorrect. The hidden requirement to use a specific sign is unreasonable and unnatural, as whether you plus or minus is irrelevant in terms of the principle of random walks.
I am using a 2 dimensional boolean array to check where an entity is inside of my 2D side scroller as well as for collision. I know I am not looking for how high or low an entity away is and that is intentional. When I run this code it says the closest entity is 15 cells away. However, when I run my code it says the closest entity away is 15 blocks. Also when I print out distanceX it prints out the following:
9
0
0
2
2
15
9
0
0
2
2
15. I don't know why it won't register 9 as the closest even though that's is the first closest distance it recieves.
I can't post pictures yet however the reason 0,0,2, and 2 get printed is because I have 4 rectangles in all four corners of my player that are considered true in the grid so it detects the two on top of eachother and the other 2 or 2 spots away in the grid. Since I cant upload pictures try to see what I mean with this image i made. https://lh3.googleusercontent.com/OLSDPshjeU0YMahcmc0MDk-NocBMoG-7iN2xFTeFsQ8mAfF-sEPD8NBqXP4ENoN4YWmfUQ=s114
Thanks for any help!!
//Loop through my grid of booleans
for (int x = 0; x < map.getMapGrid().length; x++) {
for (int y = 0; y < map.getMapGrid().length; y++) {
//For comparison
Long distance = Long.MAX_VALUE;
// The second part of the if statement is to make sure it is checking for
// entities that arent the floor, therefor one above the grid position of the player
if (map.getMapGrid()[x][y] && y > ((Player) player).getGridPositionLeft().y - 1){
// distanceX = where something true was found (x) - where the player is in the grid
// Ex: 1 - 4 = |-3|, there is an entity 3 away
distanceX = Math.abs((int)(x - ((Player) player).getGridPositionLeft().x));
// if the distance of the entity from the player is less then the comparison variable,
// the closest entity x coordinate is distanceX
if(distanceX < distance){
closestCoord.x = distanceX;
closestCoord.y = 0;
}
}
}
}
return closestCoord;
}
Long distance = Long.MAX_VALUE;
This variable is never re-assigned, so it will always have the value Long.MAX_VALUE.
Also it is declared inside the innermost loop, so it will reset on each iteration. If you want the value of a variable to be remembered between iterations you need to declare and initialize it outside the loops.
I'm trying to create a function that will translate float values to a color. I created a simple linear scale:
float value;
float maxValue;
float scaleStep = maxValue / 5;
if (value < scaleStep) {
color = blue
}
if (value > scaleStep && value <= scaleStep * 2) {
color = green
}
if (value > scaleStep * 2 && value <= scaleStep * 3) {
color = yellow
}
if (value > scaleStep * 3 && value <= scaleStep * 4) {
color = orange
}
if (value > scaleStep * 4 && value <= scaleStep * 5) {
color = red
}
but since most (but not all) of the values from the sets that I'm trying to represent are in close proximity from one particular value, graphical representation using linear scale isn't very useful (almost everything is translated to one color).
How can I create a non-linear scale so that differences between the values are more visible?
Interpolation is what you want. Interpolation generates samples between known samples in a dataset.
Here, your known samples are your colors; blue, green, yellow, orange, and red. The colors between those known colors are what you're looking for.
Here's a link to a nice visualizer of interpolation functions.
And here's a few interpolation functions for your convenience. Play with them, find the one that works best for you!
public float linearInterpolation(float start, float end, float normalizedValue) {
return start + (end - start) * normalizedValue;
}
public float sinInterpolation(float start, float end, float normalizedValue){
return (start+(end-start)* (1 - Math.cos(normalizedValue * Math.PI)) / 2;
}
//usage
linearInterpolation(red, green, .5f);//halfway between red and green.
//same with other demonstrations.
Edit:
Here, start and end refer to a starting and ending sample. The normalizedValue is some value between [0, 1] inclusive (that means it can equal exactly 0 or 1, or any value in between 0 and 1. That's what the term normalized means typically.)
So, for you, start and end will be two colors, and normalizedValue will represent how near you are to the starting or ending color.
Take linearInterpolation for example.
red = 1;
green = 2;
float midway = 1 + (2 - 1) * .5;
//midway = 1.5, which is halfway between red and green.
float allRed = 1 + (2 - 1) * 0;
//allRed = 1, which is the value of red (or start)
float allGreen = 1 + (2 - 1) * 1;
//allGreen = 2, which is the value of green (or end)
So, for linear interpolation, the closer the normalizedValue is to 1, the nearer the returned value it is to end. The closer normalizedValue is to 0, the closer the returned value is to start.
This isn't necessarily true for other interpolation functions. You can think linear interpolation as a simple line segment connecting values. Want a value halfway between those segments? Use a normalized value of .5, viola!
Other functions might have steeper slopes, or even oscillate between start and end!
Try and stop thinking in terms of color, and start thinking more abstractly. Colors are a certain distance apart. Interpolation helps you define what values lie in the distance between them.
Since the float values are in a set, you know how many there are and can calculate a color interval. You can then iterate over them, assigning colors and incrementing by the color interval.
Edit: The downside of this approach is that the same float value will not map to the same color when the number of values changes.
I suggest a logarithmic scale. If you use base 10 logs, the range will be from -39 to +39.
Depending on your distribution, a double or triple log can be better. I made a very quick test, and for the sample { 1.00, 1.20, 1.10, 1.05, 1.15, 9.70, 1.20, 2.00, 1.01, 1.03, 1.16, 1.02, 9.00, 1.20, 1.10, 1.50, 1.05, 1.15, 2.00, 3.00 }, function
int f(float x) {
return (int)(Math.log(Math.log(x)*100+1)*2.5) ;
}
Produces the following distribution:
f(x) color count
0 blue 4
1 green 4
2 yellow 6
3 orange 3
4 red 3
Not bad for 5 minutes of work. However, if you post a reasonable sample of numbers (say 100), a distribution graph, or, much better, a distribution histogram, we could help you better. The trick is to find the distribution function of the data. From that function it is very easy to come with a second function that makes the distribution uniform ("flat").
A second alternative in your case (which is relatively simple as you want to use just a few colors), is to use scaleSteps of different "width".
if( value < greenMin ) color= blue ;
else if( value < yellowMin ) color= green ;
else if( value < orangeMin ) color= yellow ;
else if( value < redMin ) color = orange ;
else color= red ;
I took the liberty of condensing the code a bit. Let me know if it's not clear. You need to determine the values of greenMin, yellowMin, orangeMin, and redMin, of course. For that, grab a big, representative data sample, sort it, and divide it in 5 groups of equal size. The first value of the second group is greenMin, first value of the third is yellowMin, and so on. You can use an office spreadsheet program to do this, as it's a one-time activity.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Pack squares into a rectangle
i need to calculate the most efficient size of squares will fill the the screen,
if you look at the below images, there are different screen sizes and square count.
I need a algorithm to calculate x axis square count and y axis square count which will fill the screen most efficiently (minimum empty area will be left after filling with squares).
i looked at the below post but it is not the answer that solves my question
Pack squares into a rectangle
1 - Square count can be changed (3-5-10 so on ...)
2 - Screen size can be different
For examples ,
on 1280 x 800 with 15 square ?
on 800 x 480 with 12 square ?
on 600x1024 with 9 square ?
on 720x1280 with 45 square ?
** I need a algorith which calculate the squares width (height is same with width) **
If you look at differencies beetween image 3 and Image 3-1 you will see that Image 3-1 uses the screen more efective because there are less unused area.
Image 3
Or maybe this is a better way to fill:
Image 3-1
If you look at differencies beetween image 4 and Image 4-1 you will see that Image 4-1 uses the screen more efective because there are less unused area.
Image 4
** 4. Image must be like below , because there are less unused area on the screen **
Image 4-1
I believe what you suggest by "efficient" is the larger the area covered by the squares the better.
let :
a : x axis square count
b : y axis square count
s : size of a square (length of one side)
w : width of screen
h : height of screen
c : number of squares to put
then we have
a * s <= w
b * s <= h
a * b >= c
With these inequalities it is possible to find an upper bound for s.
Examining the forth example given where c = 20, w = 1280 and h = 800
a * s <= 1280
b * s <= 800
a * b >= 20
a * b = (1280 / s) * (800 / s) >= 20 ---> s^2 <= (1280*800) / 20 ---> s <= 226,27..
With an upper bound for s, we can estimate a and b as;
a * s <= 1280 ---> a ~= 5,6568
b * s <= 800 ---> b ~= 3,53
with these values the inequality a * b >= 20 does not hold.
But both a and b must be whole numbers. Then we try the 4 possibilities that a and b can get :
a = 5, b = 3 // round down both
a = 5, b = 4 // one down, one up
a = 6, b = 3 // one down, one up
a = 6, b = 4 // round up both
since a * b >= 20 the first and third cases are eliminated to be a valid answer.
Choosing the answer where a = 5, b = 4 follows as the next step since their product is more close to the desired number of squares.
What you're looking for is the greatest common factor between the width and the height of the display.
Since most displays have a ratio of 4:3 or 16:9, the greatest common factor will give you the biggest square that you can use to fill the display area.
In your 400 x 400 pixel display, the greatest common factor is 400, and one square will fill the display.
In your 1280 X 800 pixel display, the greatest common factor is 160. You'll need 40 squares (8 x 5) to fill the display.
if you want to calculate one greatest common factor for all display sizes, the answer is 1. Every pixel is a square. You should calculate a separate greatest common factor for each display size you want to support.