I am making small java game, and I am trying to set enemies x coordinate through array of coordinates.
public Enemy()
{
int[] xcoordinate = new int[]{40,60,80,100,120,140,160,180,200,220,240,260};
for(int i = 0;i <= xcoordinate.length;i++){
addObject(new enemy(5,5),*sets enemy's x coordinate to a number from an array*,180);
}
}
Basically what I am trying to do, is to automatically add 12 enemies, and their x coordinates will be taken from an array, but I am not sure how to do it. So enemy number 5, will have an x coordinate of 120. Any help will be useful. Thank you
You use a counter in your loop.
To access an array at position x, just use xcoordinate[x].
Related
So, I have a school project that has 2 players and uses classes for weapons, traps and food and randomly places them on a specific part of the array. I have constructed a 2d array with the corresponding class type for each one of them, each one respectively called WeaponAreaLimits, FoodAreaLimits and TrapAreaLimits.
public class Board{
int[][] weaponAreaLimits = { {-2,2}, {2, 2}, {-2, -2}, {2, -2} };
int[][] foodAreaLimits = { {-3, 3}, {3, 3}, {-3, -3}, {3, -3} };
int[][] trapAreaLimits = { {-4, 4}, {4, 4}, {-4, -4}, {4, -4} }; //These are the specific coordinates that limit the placement of said weapons etc.
....
The catch is, weapons can be inside the box made from those points, but, food must be on the points surrounding weapons, not inside the box made from -3,3 3,3 -3,-3 and 3,-3.
I constructed a method called createRandomFood() that randomly gives properties to Food objects. The ones I'm stuck on are the x and y ones, and how to only use those surrounding points and don't put them in a place they shouldn't be. Take a look at what I've written:
....
public void createRandomFood(){
for(int i = 1; i < food.length; i++){
food[i].setId(i + 1);
food[i].setX;
food[i].setY;
food[i].setPoints(rand.nextInt(10) + 1); //Ignore the other setters
}
}
My question is, is there a method or way to eliminate those points?
In your example you have to generate a point in outer area (foodAreaLimits) that is not part of inner area (weaponAreaLimits). The right approach will probably depend on the area shape e.g. what if inner area is a circle while the outer area is a triangle?
You could approach the problem with this algorithm:
Generate a random point inside the foodAreaLimits
If it's outside weaponAreaLimits that's good enough.
Otherwise randomly pick direction. You are dealing with int only so it's simple: west, east, north, south.
Change the direction coordinate in the new point until you move outside the weaponAreaLimits. You are dealing with int so e.g. west would mean move by {-1, 0} so perform food[i].x--.
You probably have to think how big are the areas and what is an item distribution. It could be tricky if inner and outer areas are close in size.
Okay, assuming I now understand, first...
Your limits data can be simpler, as long as they represent rectangular limits. You only need minX, maxX, minY, maxY. I would create an object to store those:
public class Limits {
int minX;
int minY;
int maxX;
int maxY;
public Limits(int x1, y1, x2, y2) {
minX = x1;
minY = y1;
maxX = x2;
maxY = y2;
}
}
Then your objects become
Limits weaponAreaLimits = new Limits(-2, -2, 2, 2);
Limits foodAreaLimits = new Limits(-3, -3, 3, 3);
Limits trapAreaLimits = new Limits(-4, -4, 4, 4);
This works because a rectangle can be defined by two diagonal corners. In this case, we're using the lower left and upper right corners. You don't need each vertex.
Now, you need a method like this:
public boolean setPoints(Item item, Limits includeRange, Limits excludeRange) {
// These two variables hold the width & height of the box where things can be
int width = includeRange.maxX - includeRange.minX + 1;
int height = includeRange.maxY - includeRange.minY + 1;
int x;
int y;
do {
x = includeRange.minX + (rand() % width);
y = includeRange.minY + (rand() % height);
// At this point, x and y are inside the includeRange.
// We need to make sure they aren't in the disallowed area
} while ( (excludeRange == null) ||
(x >= excludeRange.minX && x <= excludeRange.maxX &&
y >= excludeRange.minY && y <= excludeRange.maxY) );
// When the above loop exits, you have an x and y that works.
item.x = x;
item.y = y;
return true;
}
I'm not running this through the java compiler, so there might be syntax errors. But basically, we loop, randomly setting x and y inside the outer box until we get a random value that isn't inside the inner box. But we also allow a null inner box so that we can handle weapons with the same method.
Now, what's missing from this -- I'm not checking to make sure this spot isn't occupied by something else. This method should return false if it's unable to work because the entire area is already full. I'll leave that for you. Imagine that you tried to add 50 weapons in an area that can only hold 25.
There are a bunch of important things in here. Aside from the basic structure of the code, there's an understanding of the definition of a rectangle. There's generating random numbers inside that rectangle. And there's the exclusion code.
Hopefully this gives you enough to move forward.
I am trying to write a small program that has a given number of balls (in the example code below it's 3) travel back and forth across the screen at different speeds and phases (start offset).
This much has been achieved in the code. Although I want to be able to select the balls (one at a time) using a mouse click.
I have used the word "HIT!!!" to signify in the console that a ball has been clicked.
My problem is that when I run the code below, I only get a "HIT!" in the console when I click the top ball. That is when the first element y[0] matches with the click_Y variable. When I am sure (but obviously mistaken somehow) that there should be matches when I click in the vicinity of y[1] & y[2].
I'd really be grateful for any help with these. As it's gotten to the point where I am starting to stare blankly at the screen. Thanks.
int noCircles; // the number of items in the array (# of circles)
float[] y; // y-position of each circle (fixed)
float[] speed; // speed of each circle
float[] phase; // phase of each circle
float red = 120;
float green = 120;
float blue = 120;
float click_X;
float click_Y;
void setup() {
size(500, 500);
noCircles = 3;
// allocate space for each array
y = new float[noCircles];
speed = new float[noCircles];
phase = new float[noCircles];
// calculate the vertical gap between each circle based on the total number
// of circles
float gap = height / (noCircles + 1);
//setup an initial value for each item in the array
for (int i=0; i<noCircles; i++) {
y[i] = gap * (i + 1);
// y is constant for each so can be calculated once
speed[i] = random(10);
phase[i] = random(TWO_PI);
}
}
void draw() {
background(155);
for (int i=0; i<noCircles; i++) {
// calculate the x-position of each ball based on the speed, phase and
//current frame
float x = width/2 + sin(radians(frameCount*speed[i] ) + phase[i])* 200;
if (dist(x, y[i], click_X, click_Y) <= 20){
println("HIT!!!!!!!!!!!!!!!!!!");
}
ellipse(x, y[i], 20, 20);
click_X = 0;
click_Y = 0;
}
}
void mousePressed() {
println("You clicked******************************************");
click_X = mouseX;
click_Y = mouseY;
println("click_X =" + click_X);
println("click_Y =" + click_Y);
}
Problems like these are best solved by debugging your program. Start by tracing through the code by hand, then add print statements (more than you've already added), and if that doesn't work then don't be afraid to use the debugger.
You're using the click_X and click_Y variables to check the position of the mouse against the position of each ball. Trace through the for loop in your draw() function. What happens at the end of the first iteration?
You reset the values of click_X and click_Y. That's why you aren't detecting any hits on the other circles.
You could probably refactor your code to only reset those variables if something has been hit, but really, I would stop using them altogether.
I'm guessing that you're using those variables because you only want to check when the mouse is pressed? Just use the mousePressed variable for that. Then you can use the mouseX and mouseY variables directly.
Then your if statement would look like this:
if (mousePressed && dist(x, y[i], mouseX, mouseY) <= 20) {
println("HIT: " + i);
}
Also, using separate arrays like this is called parallel arrays, and is general a bad habit to get into. You should probably use classes instead.
An exercise in Shiffman's Nature of Code asks me to create Perlin Noise using Processing's noise() function. Here's my code I made to create Perlin Noise
float xSpace = 0; // Signifies "space" between noise() values on the x coordinate.
float ySpace = 0; // Signifies "space" between noise() values on the y coordinate.
void setup(){
size(500,500);
background(0);
loadPixels();
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
float bright = map(noise(xSpace,ySpace),0,1,0,255);
pixels[(y * width) + x] = color(bright);
//Each pixel in the pixels[] array is a color element.
ySpace = ySpace + 0.01;
}
xSpace = xSpace + 0.01 ;
}
updatePixels();
}
And when I run my code, it creates an image like this
I looked at the solution in the textbook. The textbook's solution and my solution are almost identical except the textbook reinitializes ySpace back to 0 with every iteration of the outer loop.
// Textbook's solution
for(int x = 0; x < width; x++) {
ySpace = 0;
for(int y = 0; y < height; y++) {
float bright = map(noise(xSpace,ySpace),0,1,0,255);
pixels[(y * width) + x] = color(bright);
ySpace = ySpace + 0.01;
}
xSpace = xSpace + 0.01 ;
}
However, when I run the textbook's code, the code creates a much smoother image like this
Why, when ySpace is reinitialized in the outer loop, does the image come out much smoother than the when its not? In other words, why is the textbook's code create a much smoother image than my code?
I noticed that the ySpace in my code will be significantly larger than the ySpace in the textbook's code once the for loop is complete. But I'm not sure if that's the reason why my code's image is not as smooth. From my understanding, noise(x,y) creates 2d Perlin Noise. When applied to a pixel, the pixel should be a similar color to the pixels around it, but it doesn't look like its happening in my code.
The noise() function essentially takes a 2D coordinate (or a 3D coordinate, or a single number, but in your case a 2D coordinate) and returns a random number based on that coordinate. Coordinates that are closer together will generate random numbers that are closer together.
With that in mind, think about what your code is doing and what the textbook is doing. The textbook is feeding in an x,y coordinate based on the position in the window, which makes sense since that's where the resulting random value is being drawn.
But your code keeps increasing the y coordinate no matter what. This might make sense if you only had a single column of pixels that just kept going down, but you're trying to loop over the pixels on the screen.
Let's say that I have code like this:
private void actuallyDrawGraphics(Canvas canvas) {
canvas.drawColor(Color.WHITE);
for(Ball ball : balls){
canvas.drawBitmap(ballBitmap,
-16 + (ball.x / 100f) * canvas.getWidth(),
-16 + (ball.y / 100f) * canvas.getHeight(),
paint
);
}
}
Every ball is registered in an array. I need to make a collision (when one collides with the second) and everything goes well, until I have more balls, for example 10. It's not efficient to make a check like:
ball 1 with 2, 3, 4...
ball 2 with 1, 3, 4...
Is there any way that this can be done?
for (int i = 0; i < balls.size(); i++) {
Ball ball = balls[i];
for (int a = i + 1; a < balls.size(); a++) {
Ball ball2 = balls[a];
// check for collision with ball and ball2.
}
}
Like Nacho was saying, I believe that this would be a better way to check every possible collision, but if you have a very large number of balls, then you may need to do something to reduce the number of checks you are making here. Or, you may need to improve your code that checks for a collision.
You need another data structure. For example an object Collision containing a List<Ball> ballsThatCollide; or something similar. Or for each Ball to have List<Ball> inCollisionWith. If you want simple arrays, then you'll need a N dimensional array where the dimensions are the balls and the intersection are collisions.
I'm using the method of dividing the x and y coordinates by the z value, then rendering it just like you would a 2D game/thing to create 3D looking thing. The problem is when the z value is less then 0 it flips the quadrants for the coordinate and looks very weird. At the moment there is only movement if someone could help me fix the negative z value thing and show me how to rotate. I'm not using and matrices only vectors that take in x,y and z for the maths if that helps. I'm making this using Java with no extra libraries.
Thanks for the help.
I used the perspective matrix and multiplied it by my vector but it didn't work here is my code there might be something wrong with it. I just turned the vector into a 1 by 3 matrix and then did this.
public Matrix multiply(Matrix matrix)
{
Matrix result = new Matrix(getWidth(),getHeight());
for(int y = 0; y < getHeight()-1; y++)
{
for(int x = 0; x < getWidth()-1; x++)
{
float sum = 0.0f;
for(int e = 0; e < this.getWidth()-1; e++)
{
sum += this.matrix[e + y * getWidth()] * matrix.matrix[x + e * matrix.getWidth()];
}
result.matrix[x + y * getWidth()] = sum;
}
}
return result;
}
Just guessing here, but it sounds like you are trying to do a projection transform: You are modeling 3D objects (things with X, Y, and Z coordinates) and you want to project them onto a 2D window (i.e., the screen).
The meaning of Z in the naive projection transform is the distance between the point and a plane parallel to the screen, that passes through your eyeball. If you have points with -Z, those represent points that are behind your head.
Sounds like you need to translate the Z coordinates so that Z=0 is the plane of the screen, or a plane parallel to and behind the screen. (In other words, Add a constant to all of your Zs, so that none of them is negative.)
http://en.wikipedia.org/wiki/3D_projection