Remove object from 2D Array- Processing - processing

I'm creating a simple space invaders game. I'm looking to delete one of the invaders once they are hit by a bullet. The invaders are made up of a 2D array of images and I've tested the collision between the image and the bullet (in an ArrayList) and that works fine. So the game detects a collision, the next step is to delete the correct object that has been hit. I'm a little confused as to how to correctly correspond where the bullet hits to which object it has hit in the 2D array, and then deleting it from the Array and carrying on with the game.
Below is how I created the invader array in setup()
for(int i=0; i<2; i++){
for(int j=0; j<4; j++){
invArray[j][i]= new Taxi(taxiX, taxiY);
taxiX= taxiX+ 100;
}
taxiX=20;
taxiY= taxiY+ 140;
}
I then filled the 2D Array with images in draw()
for(int i=0; i<2; i++){
for(int j=0; j<4; j++){
invArray[j][i].update();
if(invArray[j][i].y>=600){
invArray[j][i].y= 0;
invArray[j][i].render();
}
}
}

You're using arrays which are fixed size.
In theory you might be able to use array helper functions like shorten() and expand(), but you really got watch your counters and array structure.
In practice, for a beginner, I would say this is error prone.
It might be simpler(but hackier) to set the array element of the hit invader to null,
then simply check if the invader is not null before test collisions/rendering/etc.
e.g. in draw():
for(int i=0; i<2; i++){
for(int j=0; j<4; j++){
if(invArray[j][i] != null){
invArray[j][i].update();
if(invArray[j][i].y>=600){
invArray[j][i].y= 0;
invArray[j][i].render();
}
}
}
}
Another option is to use an ArrayList which has a dynamic size.
e.g.
ArrayList<Taxi> invaders = new ArrayList<Taxi>();
In setup you'd do something similar:
for(int i=0; i<2; i++){
for(int j=0; j<4; j++){
invaders.add(new Taxi(taxiX, taxiY));
taxiX= taxiX+ 100;
}
taxiX=20;
taxiY= taxiY+ 140;
}
then in draw():
for(int i = 0 ; i < invaders.size(); i++){
Taxi t = invaders.get(i);
t.update();
if(t.y>=600){
t.y= 0;
t.render();
}
/*
if(YOUR_HIT_CONDITION_HERE){
invaders.remove(t);
}
*/
}
It's a bit tricky to go back and forth between 1D and 2D arrays/indexing at the beginning, but it's not that bad once you get the hand of it.
To convert from 2D x,y to 1D index:
int index = x + y * width;
(where x,y are you counters and width is the width of your grid (number of columns)).
The other way around, 1D index to 2D x,y:
int x = index % width;
int y = index / width;

Try to decouple the hit detection from removing elements from the arraylist, maybe using a flag and removing at the end on the draw loop. Use arraylist.size() as limit of the loop in one part of the code. Maybe that can solve your problem with hit detection, maybe you need a counter.

Related

How to access intensity of all the pixels of Image in openCV C++

For accessing single point, I am using this line of code and it works
int intensity = gray_image.at<uchar>(Point(100, 100));
However when I use this code to access all the pixels in image, it gives memory error,
for (int i = 0; i < gray_image.rows;i++)
{
for (int j = 0; j < gray_image.cols; j++) {
intensity += gray_image.at<uchar>(Point(i, j));
}
}
When I run above code, it does not give compile time error but gives memory exception. Where am I going wrong?
You can just skip the use of Point and do the following.
for (int i = 0; i < gray_image.rows;i++)
{
for (int j = 0; j < gray_image.cols; j++) {
intensity += gray_image.at<uchar>(i, j);
}
}
You're requesting a pixel (j,i) that doesn't exist. This wouldn't have been an error in a square image (where the number of rows = number of columns), but you're using a rectangular image.
The Mat::at function has multiple prototypes, the two that you're concerned with are:
C++: template<typename T> T& Mat::at(int i, int j)
C++: template<typename T> T& Mat::at(Point pt)
The documentation for Mat::at states that Point pt is defined as the Element position specified as Point(j,i), so you've effectively swapped your rows and columns.
The reason this happens is because the image is stored in a 1D array of pixels, and to get a pixel Point (r,c) is translated to p = r * image.cols + c;

Looping through an arraylist of object variables and inputing them into an array in Processing

This is a section of my code, I have an ArrayList of 10 objects called "bob" and I want to loop through them so that each of their names (a local integer defined in the bob class) to be put in the array named "names" in order.
for (bob b : bob) {
for (int i = 0; i < 10; i++){
names[i] = b.name;
}
}
I tried this approach:
for (bob b : bob) {
for (int i = 0; i < 10; i++){
names[i] = b[i].name; //I added the "[i]" after b attempting to loop through
//the arraylist but it does not work
}
}
the syntax does not seem to allow me to loop through the arraylist of the objects like that. I am a beginning programmer so please excuse my lack of programming knowledge. It would be very helpful if someone could at least give me an idea of where to go from here. Thank you in advance!
When dealing with ArrayList you need to use the set() and get() methods to access the contents of it. Here's a somewhat hamfisted attempt at recreating the scenario you describe. Hope it helps.
class Bob {
int name;
Bob() {
this.name = floor(random(10000));
}
}
void setup(){
ArrayList<Bob> alb = new ArrayList<Bob>();
for(int i = 0; i < 50; i++){ //populate ArrayList
alb.add(new Bob());
}
int[] names = new int[10];
for(int i = 0; i < names.length; i++){
names[i] = alb.get(i).name; // use get() method
}
for(int i = 0; i < names.length; i++){
print(names[i]);
print('\n');
}
}
Your question highlights two techniques for iterating over a collection: with or without, an index. Each is best suited for different data structures and scenarios. It takes some experience to decide when to use one or the other, and is also a matter of personal style.
It is common to write code like for( int x: myInts ) and then realize you want the index of the current item, which isn't available. Or conversely, to write code like for( int i=first; i<last; i++) and then become irritated because determining first and last is tedious, or prone to bugs.
Notice your code is a double-nested loop. It says "iterate over each item in the collection Bob, and then for each one, iterate over each item in the collection of names". So if Bob had ten items, this would iterate one hundred total times, probably not what you want. You need to rewrite as a single, non-nested for loop ...
If you decide to iterate without an index, then names should be some type of list, where you can add items using append(). Consider the StringList available in Processing. Otherwise if you decide to iterate with an index, then names could be an array, although it could still be a list if it was already populated with old values which you wish to overwrite. The following shows both techniques:
void setup()
{
ArrayList<String> baseList = new ArrayList<String>(10);
for( int i=0; i<10; i++ )
baseList.add( i, Integer.toString( i + (i*10) ) );
// Approach 1: Iterate without an index,
// build a list with no initial allocation and using append()
StringList namesList = new StringList();
for( String s : baseList )
{
namesList.append( s );
println( namesList.get( namesList.size()-1 ) );
}
// Approach 2: Iterate with an index,
// build a list using preallocation and array access
String[] namesArray = new String[10];
for( int i=0; i<10; i++ )
{
namesArray[i] = baseList.get(i);
println( namesArray[i] );
}
}

Simple image processing algorithm causes Processing to freeze

I've written an algorithm in Processing to do the following:
1. Instantiate a 94 x 2 int array
2. Load a jpg image of dimensions 500 x 500 pixels
3. Iterate over every pixel in the image and determine whether it is black or white then change a variable related to the array
4. Print the contents of the array
For some reason this algorithm freezes immediately. I've put print statements in that show me that it freezes before even attempting to load the image. This is especially confusing to me in light of the fact that I have written another very similar algorithm that executes without complications. The other algorithm reads an image, averages the color of each tile of whatever size is specified, and then prints rectangles over the region that was averaged with the average color, effectively pixelating the image. Both algorithms load an image and examine each of its pixels. The one in question is mostly different in that it doesn't draw anything. I was going to say that it was different for having an array but the pixelation algorithm holds all of the colors in a color array which should take up far more space than the int array.
From looking in my mac's console.app I see that there was originally this error: "java.lang.OutOfMemoryError: GC overhead limit exceeded". From other suggestions/sources on the web I tried bumping the memory allocation from 256mb to 4000mb (doing this felt meaningless because my analysis of the algorithms showed they should be the same complexity but I tried anyways). This did not stop freezing but changed the error to a combination of "JavaNativeFoundation error occurred obtaining Java exception description" and "java.lang.OutOfMemoryError: Java heap space".
Then I tried pointing processing to my local jdk with the hope of utilizing the 64 bit jdk over processing's built in 32 bit jdk. From within Processing.app/Contents I executed the following commands:
mv Java java-old
ln -s /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk Java
Processing would not start after this attempt with the following error populating my console:
"com.apple.xpc.launchd[1]: (org.processing.app.160672[13559]) Service exited with abnormal code: 1"
Below is my code:
First the noncompliant algorithm
int squareSize=50;
int numRows = 10;
int numCols = 10;
PFont myFont;
PImage img;
//33-126
void setup(){
size(500,500);
count();
}
void count(){
ellipseMode(RADIUS);
int[][] asciiArea = new int[94][2];
println("hello?");
img=loadImage("countingPicture.jpg");
println("image loaded");
for(int i=0; i<(500/squareSize); i++){
for(int j=0; j<(500/squareSize); j++){
int currentValue=i+j*numCols;
if(currentValue+33>126){
break;
}
println(i+", "+j);
asciiArea[currentValue][0]=currentValue+33;
asciiArea[currentValue][1]=determineTextArea(i,j,squareSize);
//fill(color(255,0,0));
//ellipse(i*squareSize,j*squareSize,3,3);
}
}
println("done calculating");
displayArrayContents(asciiArea);
}
int determineTextArea(int i, int j, int squareSize){
int textArea = 0;
double n=0.0;
while(n < squareSize*squareSize){
n+=1.0;
int xOffset = (int)(n%((double)squareSize));
int yOffset = (int)(n/((double)squareSize));
color c = img.get(i*squareSize+xOffset, j*squareSize+yOffset);
if(red(c)!=255 || green(c)!=255 || blue(c)!=255){
println(red(c)+" "+green(c)+" "+blue(c));
textArea++;
}
}
return textArea;
}
void displayArrayContents(int[][] arr){
int i=0;
println("\n now arrays");
while(i<94){
println(arr[i][0]+" "+arr[i][1]);
}
}
The pixelation algorithm that works:
PImage img;
int direction = 1;
float signal;
int squareSize = 5;
int wideness = 500;
int highness = 420;
int xDimension = wideness/squareSize;
int yDimension= highness/squareSize;
void setup() {
size(1500, 420);
noFill();
stroke(255);
frameRate(30);
img = loadImage("imageIn.jpg");
color[][] colors = new color[xDimension][yDimension];
for(int drawingNo=0; drawingNo < 3; drawingNo++){
for(int i=0; i<xDimension; i++){
for(int j=0; j<yDimension; j++){
double average = 0;
double n=0.0;
while(n < squareSize*squareSize){
n+=1.0;
int xOffset = (int)(n%((double)squareSize));
int yOffset = (int)(n/((double)squareSize));
color c = img.get(i*squareSize+xOffset, j*squareSize+yOffset);
float cube = red(c)*red(c) + green(c)*green(c) + blue(c)*blue(c);
double grayValue = (int)(sqrt(cube)*(255.0/441.0));
double nAsDouble = (double)n;
average=(grayValue + (n-1.0)*average)/n;
average=(grayValue/n)+((n-1.0)/(n))*average;
}
//average=discretize(average);
println(i+" "+j+" "+average);
colors[i][j]=color((int)average);
fill(colors[i][j]);
if(drawingNo==0){ //stroke(colors[i][j]); }
stroke(210);}
if(drawingNo==1){ stroke(150); }
if(drawingNo==2){ stroke(90); }
//stroke(colors[i][j]);
rect(drawingNo*wideness+i*squareSize,j*squareSize,squareSize,squareSize);
}
}
}
save("imageOut.jpg");
}
You're entering an infinite loop, which makes the println() statements unreliable. Fix the infinite loop, and your print statements will work again.
Look at this while loop:
while(i<94){
println(arr[i][0]+" "+arr[i][1]);
}
When will i ever become >= 94?
You never increment i, so its value is always 0. You can prove this by adding a println() statement inside the while loop:
while(i<94){
println("i: " + i);
println(arr[i][0]+" "+arr[i][1]);
}
You probably wanted to increment i inside the while loop. Or just use a for loop instead.

Canvas multiple Text draw performance

Is there a way of drawing efficiently multiple characters individually at some reasonable FPS on Canvas in Dart?
I am rendering an array of characters with different colors, background rectangles, etc and it runs smoothly only if the "resolution of characters" is max 40x40.
This is the drawing method:
static draw(CanvasRenderingContext2D ctx, CanvasRenderingContext2D ctxUnvisible) {
for(int i = 0; i < chars.length; i++) {
for(int j = 0; j < chars[0].length; j++) {
ctxUnvisible.fillRect(i*offX, j*offY, (i+1)*offX, (j+1)*offY);
}
}
for(int i = 0; i < chars.length; i++) {
for(int j = 0; j < chars[0].length; j++) {
ctxUnvisible.fillStyle = charArray[i][j].color;
ctxUnvisible.fillText(charArray[i][j].char, i*offX, j*offY);
}
}
ctx.drawImage(ctxUnvisible.canvas, 0, 0);
}
The first double loop renders background rectangles as "text background" and the second draws the characters itself. This unfornately doesn't work for larger number of characters. Is there some more efficient way of drawing it? I am already drawing to unvisible canvas and then copying it to the visible one, but that's still not enough.
In system all single char is prerendered ( I've heard it, not confirmed. ). You can make lazy initialized Map of CanvasElements and draw every character like image.
Example:
CanvasElement precompiled_a = new CanvasElement(width:20, height:20);
CanvasRenderingContext2D ctx = precompiled_a.context2D;
ctx.fillStyle = "black";
ctx.fillText("a", 10, 10);
CanvasElement c = querySelector("canvas");
c.context2D.drawImage(precompiled_a, 2, 2);

Rearranging data for quadtree/octree

I am working on implementing a voxel octree raycaster, and the only thing left is rearranging the data to populate the leaf level of the octree, so that the data then can be averaged to build the lower levels of the tree.
I'm thinking in 2D (quadtree) initially for convenience. I have the data ordered like in the left in the drawing, and I am currently able to rearrange it like to the right. Example is 8x8.
However, I realized that I need to order the data in node order, like in the drawing below:
In other words, I want to go from an array where the data correspond to indices like this:
[0 1 2 3 4 5 6 7 8 9 ... 63]
to an array that would have the data in this order:
[0 1 4 5 16 17 20 21 2 3 ... 63]
for an 8x8 quadtree example.
I can't figure out how to do it. My main problem is dealing with an arbitrary tree size. I could probably hard-code a set of nested loops if I knew the size beforehand, but that it obviously not a great or elegant solution. I'm thinking there might be a recursive way achieve it.
This it what my quick and dirty sketch for sorting the data in the way described in picture one. It basically works by keeping track of four positions in the original data, and then stepping these forward as the new array gets filled. As far as I have been able to tell, this works fine but is not extendable to my needs:
int w = 8;
int[] before = new int[w*w*w];
int[] after = new int[w*w*w];
for (int i=0; i<w*w*w; i++) {
before[i] = i;
}
int toFill = 0;
int front = 0;
int back = w;
int frontZ = w*w;
int backZ = w*w + w;
do {
for (int i=0; i<w/2; i++) {
for (int j=0; j<w/2; j++) {
after[toFill++] = front++;
after[toFill++] = front++;
after[toFill++] = back++;
after[toFill++] = back++;
after[toFill++] = frontZ++;
after[toFill++] = frontZ++;
after[toFill++] = backZ++;
after[toFill++] = backZ++;
}
front += w;
back += w;
frontZ += w;
backZ += w;
}
front += w*w;
back += w*w;
frontZ += w*w;
backZ += w*w;
} while (toFill < w*w*w);
for (int i=0; i<w*w*w; i++) {
println("after " + i + " " + after[i]);
}
For the problem I stated, phs hinted me that it is called a Z-order curve. Thanks to that, I found this question: Z-order-curve coordinates where an algorithm for the 2D case is presented. I tried it, and it works.
Here are a few implementations of the 3D case as well: How to compute a 3D Morton number (interleave the bits of 3 ints)

Resources