I didn't exactly know how to word the title, but here is my problem:
I'm making the Conway's Game of Life in JavaFX, and I have two 2D arrays in different sizes. One array works as the game-board/grid, and the other works as the pattern I want to insert onto the board. Say the first array is 60x60, and the second is 3x3.
To make the board and the pattern, I use something like this:
//Board
for (int x = 0; x < 60; x++) {
for (int y = 0; y < 60; y++)
board[x][y].setNextState(false);
gc.setFill(Color.LIGHTGRAY);
gc.fillRect(x * 10, y * 10, 9, 9);
}
}
//Pattern
for (int x = 0; x < pattern.length; x++)
for (int y = 0; y < pattern[x].length; y++)
if (pattern[x][y] == 1) {
board[x][y].setNextState(true);
} else {
board[x][y].setNextState(false);
}
gc.setFill(board[x][y].getState() ? Color.rgb(244, 92, 66) : Color.LIGHTGRAY);
gc.fillRect(x * 10, y * 10, 9, 9);
}
}
When done as above, the pattern gets placed top left on the board. But say I want it placed in the middle, I would have to use something like x = 30 and y = 30 in the pattern loop, but that wouldn't work in the if (pattern[x][y] == 1) line. How can I make this work?
I'm terrible at explaining, but I hope I made my question clear!
Apply an offset to the xy position when refering to the board and keep unchanged when refering to the pattern. Be aware that offsetX cannot be > of board width - pattern width, same for Y :
int offsetX = 30;
int offsetY = 30;
for (int x = 0; x < pattern.length; x++)
for (int y = 0; y < pattern[x].length; y++)
if (pattern[x][y] == 1) {
board[x + offsetX][y + offsetY].setNextState(true);
} else {
board[x + offsetX][y + offsetY].setNextState(false);
}
gc.setFill(board[x + offsetX][y + offsetY].getState() ? Color.rgb(244, 92, 66) : Color.LIGHTGRAY);
gc.fillRect((x + offsetX) * 10, (y + offsetY) * 10, 9, 9);
}
}
You can achieve it like this:
for (int x = 0; x < pattern.length; x++) {
for (int y = 0; y < pattern[x].length; y++) {
int bx = x + 30,
by = y + 30;
if (pattern[x][y] == 1) {
board[bx][by].setNextState(true);
} else {
board[bx][by].setNextState(false);
}
...
and so on.
Related
I was beginning with coding in Processing when I encountered an error which I can't find a solution for.
**DISCLAIMER: I'm new to coding, so I'm having trouble understanding how it works lol
I was attempting to use processing to write a code for a kinect program that would create a ripple effect, but I can't figure out how to define two variables.
Code:
// A simple ripple effect. Click on the image to produce a ripple
// Author: radio79
// Code adapted from http://www.neilwallis.com/java/water.html
// Code adapted from https://forum.processing.org/two/discussion/25348/can-i-apply-ripple-effect-to-kinect
import org.openkinect.processing.*;
Kinect kinect;
PImage img;
Ripple ripple;
void setup() {
size(1920, 1080);
kinect = new Kinect(this);
kinect.initVideo();
img = new PImage(kinect.colorWidth, kinect.colorHeight);
ripple = new Ripple();
//frameRate(60);
}
void draw() {
image(kinect.getVideoImage(), 0, 0);
img.loadPixels();
for (int loc = 0; loc < Kinect.colorWidth * Kinect.colorHeight; loc++) {
img.pixels[loc] = ripple.col[loc];
}
img.updatePixels();
ripple.newframe();
}
class Ripple {
int i, a, b;
int oldind, newind, mapind;
short ripplemap[]; // the height map
int col[]; // the actual pixels
int riprad;
int rwidth, rheight;
int ttexture[];
int ssize;
Ripple() {
// constructor
riprad = 3;
rwidth = width >> 1;
rheight = height >> 1;
ssize = width * (height + 2) * 2;
ripplemap = new short[ssize];
col = new int[width * height];
ttexture = new int[width * height];
oldind = width;
newind = width * (height + 3);
}
void newframe() {
// update the height map and the image
i = oldind;
oldind = newind;
newind = i;
i = 0;
mapind = oldind;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
short data = (short)((ripplemap[mapind - width] + ripplemap[mapind + width] +
ripplemap[mapind - 1] + ripplemap[mapind + 1]) >> 1);
data -= ripplemap[newind + i];
data -= data >> 5;
if (x == 0 || y == 0) // avoid the wraparound effect
ripplemap[newind + i] = 0;
else
ripplemap[newind + i] = data;
// where data = 0 then still, where data > 0 then wave
data = (short)(1024 - data);
// offsets
a = ((x - rwidth) * data / 1024) + rwidth;
b = ((y - rheight) * data / 1024) + rheight;
//bounds check
if (a >= width)
a = width - 1;
if (a < 0)
a = 0;
if (b >= height)
b = height-1;
if (b < 0)
b=0;
col[i] = img.pixels[a + (b * width)];
mapind++;
i++;
}
}
}
}
void mouseDragged() {
for (int j = mouseY - ripple.riprad; j < mouseY + ripple.riprad; j++) {
for (int k = mouseX - ripple.riprad; k < mouseX + ripple.riprad; k++) {
if (j >= 0 && j < height && k>= 0 && k < width) {
ripple.ripplemap[ripple.oldind + (j * width) + k] += 512;
}
}
}
}
The error is: 'The global variable "x" does not exist', 'The global variable "y" does not exist' and so forth. Please help.
The variables I need help defining appear on line 18 for the first time, they are colorWidth and colorHeight
The line reads:
img = new PImage(kinect.colorWidth, kinect.colorHeight);
The colorWidth and colorHeight are underlined in red.
I have tried using this method:
public
float colorWidth;
float colorHeight;
But, only the second line appears to be defined properly. The first line emits the message "colorWidth cannot be resolved or is not a field" when the program runs, or "illegal modifier for parameter colorWidth; only final is permitted" when the underline is clicked.
Picture of what the program shows after the public code
PLEASE HELP!!! Thank you!
The keyword public here just means nothing, it must be said of a function or variable. And you just don't need it. So removing it should fix the problem!
Suppose I have a two-dimensional grid of pixels (4 by 4 pixels) - and I have an image the size of my sketch that has been cut into 16 parts.
Now I load all 16 parts into an array. I want to map this array onto the 2D grid in turn, so that my overall image is put together again correctly. That is, top left image 0.png and bottom right image 16.png.
I just can't find the formula that allows me to do this. For example, I know that with x+y*width you can run trough all pixels – from top left to bottom right - so I tried that. Without *width it doesn't sit together properly - with x+y*width- ArrayIndexOutOfBoundsException (for sure).
So I thought I needed a 2D array - but with images[x][y] i get a NullPointerException. I attached you an image of what I am trying to create:
This is my code so far – without the 2D Array…
float pixelamount = 4;
float pixelsize;
PImage[] images = new PImage [16];
void setup() {
size(1080, 1080);
pixelsize = width/pixelamount;
for (int i = 0; i < images.length; i++) {
images[i] = loadImage(i + ".png");
}
imageMode(CENTER);
}
void draw() {
background(0);
pushMatrix();
translate(pixelsize/2, pixelsize/2);
for (int x = 0; x < pixelamount; x++) {
for (int y = 0; y < pixelamount; y++) {
pushMatrix();
translate(pixelsize*x, pixelsize*y);
image(images[x+y], 0, 0, pixelsize, pixelsize);
popMatrix();
}
}
popMatrix();
}
As I said – in the line image(images[x+y], 0, 0, pixelsize, pixelsize); I just do not get the math right. Do I need a 2D Array to solve this? Or something totally different?
This should be resolved without 2D array.
If the dimensions of the field are known 4x4, then possibly the loop should run from 0 to 4 something like this:
void draw() {
background(0);
pushMatrix();
translate(pixelsize/2, pixelsize/2);
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
pushMatrix();
translate(pixelsize * x, pixelsize * y);
image(images[4 * x + y], 0, 0, pixelsize, pixelsize);
popMatrix();
}
}
popMatrix();
}
Alex is correct.
Cyrill, you're on the right track but seem to get confused between 3 ways at looking at your data:
The images array is a 1D array (indices 0 to 15)
The for loop is nested therefore you need to convert 2D indices to 1D. You are right: x+y*width would give you the correct array index, but in this case width is not the full width of your sketch in pixels but the width of the grid (i.e. the number of columns in the 4x4 grid: 4)
You are getting a null pointer pointer because you're trying to access elements in a 1D array as if it's 2D.
Something like this should work:
float pixelamount = 4;
float pixelsize;
PImage[] images = new PImage [16];
void setup() {
size(1080, 1080);
pixelsize = width/pixelamount;
for (int i = 0; i < images.length; i++) {
images[i] = loadImage(i + ".png");
}
//imageMode(CENTER);
}
void draw() {
background(0);
pushMatrix();
translate(pixelsize/2, pixelsize/2);
for (int x = 0; x < pixelamount; x++) {
for (int y = 0; y < pixelamount; y++) {
pushMatrix();
translate(pixelsize*x, pixelsize*y);
image(images[x + y * pixelamount], 0, 0, pixelsize, pixelsize);
popMatrix();
}
}
popMatrix();
}
If you want to loop with a single for loop (instead of a nested for loop) which would match how you store your data you can use this formula to go from 1D index to 2D indices:
x = index % gridColumns
y = index / gridColumns
(Bare in mind these are integers (so in other languages (like Python/JS/etc.) you'd pay attention to the division operation))
Here's a basic example to illustrate this:
size(1080, 1080);
textAlign(CENTER, CENTER);
textFont(createFont("Courier New Bold", 12));
int pixelAmount = 4;
int pixelSize = width/pixelAmount;
int gridColumns = 4;
// iterate once
for(int i = 0; i < 16; i++){
// calculate 2D grid indices
int xIndex = i % gridColumns;
int yIndex = i / gridColumns;
// convert from index to pixel size
int x = xIndex * pixelSize;
int y = yIndex * pixelSize;
// render debug data
String debugText = "1D index:" + i +
"\n2D indices:[" + xIndex + "][" + yIndex + "]" +
"\nx, y pixels::" + x + "," + y;
fill(255);
rect(x, y, pixelSize, pixelSize);
fill(0);
text(debugText, x + pixelSize / 2, y + pixelSize / 2);
}
Here's the same example as the above using a 2D array and nested loops:
size(1080, 1080);
textAlign(CENTER, CENTER);
textFont(createFont("Courier New Bold", 12));
int pixelAmount = 4;
int pixelSize = width/pixelAmount;
int[][] grid = new int[pixelAmount][pixelAmount];
// mimick image loading (storing 1D index)
int index = 0;
for(int y = 0; y < pixelAmount; y++)
for(int x = 0; x < pixelAmount; x++)
grid[x][y] = index++;
// mimick reading 2D array data
for(int y = 0; y < pixelAmount; y++){
for(int x = 0; x < pixelAmount; x++){
int xPixels = x * pixelSize;
int yPixels = y * pixelSize;
// manually copute index
// index = x + y * pixelAmount;
// or retrieve stored index
index = grid[x][y];
String debugText = "1D index:" + index + ".png" +
"\n2D indices:[" + x + "][" + y + "]" +
"\nx, y pixels::" + xPixels + "," + yPixels;
fill(255);
rect(xPixels, yPixels, pixelSize, pixelSize);
fill(0);
text(debugText, xPixels + pixelSize / 2, yPixels + pixelSize / 2);
}
}
My answer is more for the sake of completeness: displaying both 1D/2D ways at looking at the data.
Based on the latest answer – this is my code – working perfectly!
float pixelamount = 4;
float pixelsize;
PImage[] images = new PImage [16];
void setup() {
size(1080, 1080);
pixelsize = width/pixelamount;
for (int i = 0; i < images.length; i++) {
images[i] = loadImage(i + ".png");
}
imageMode(CENTER);
}
void draw() {
background(0);
pushMatrix();
translate(pixelsize/2, pixelsize/2);
for (int x = 0; x < pixelamount; x++) {
for (int y = 0; y < pixelamount; y++) {
pushMatrix();
translate(pixelsize * x, pixelsize * y);
image(images[x + y * int(pixelamount)], 0, 0, pixelsize, pixelsize);
popMatrix();
}
}
popMatrix();
}
What I want the program to do is when I am pressing on any square it runs the setColor function for that particular square
The image of the grid
Here is the code
public void mousePressed(MouseEvent e) {
mX = e.getX();
mY = e.getY();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (mX >= x + 75 && mX <= x && mY >= y + 75 && mY <= y) {
grid[i][j].setColor(r, g, b);
x += 75;
}
x = 0;
y += 75;
}
}
repaint();
}
The grid is 8 by 8 meaning there are 64 squares. I am kind of stuck on this one and would appreciate some help :)
I am trying to make Space Invaders in Processing. I am currently working on getting the enemy to move correctly. I have got them to be drawn in the right spot but I haven't gotten them to be moved correctly. Here is my code:
PImage mainPlayer;
PImage enemyPlayer;
float Xspeed = 60;
float Yspeed = 60;
float X;
float Y;
Enemy EnemyPlayer = new Enemy("EnemyPlayerSpaceInvaders.png", 10, 10, 6);
void setup() {
size(1400, 800);
//enemyPlayer = loadImage("EnemyPlayerSpaceInvaders.png");
mainPlayer = loadImage("MainPlayerSpaceInvaders.png");
}
void draw() {
background(0);
Enemy[] enemyPlayer = new Enemy[60];
for (int i = 0; i < 5; i += 1) {
for (int j = 0; j < 11; j += 1) {
enemyPlayer[j *i] = new Enemy("EnemyPlayerSpaceInvaders.png", 50 + j * 100, 5 + 75 * i, 6);
}
}
for (int i = 0; i < 5; i += 1) {
for (int j = 0; j < 11; j += 1) {
if(enemyPlayer[j * i].alive){
enemyPlayer[j * i].Draw();
}
enemyPlayer[j *i].moveAndDraw(6);
}
}
}
class Enemy {
boolean alive = true;
float x;
float y;
float speed;
String playerTexFile;
PImage playerTex;
Enemy(String PlayerTexFile, float X, float Y, float Speed){
x = X;
y = Y;
speed = Speed;
playerTexFile = PlayerTexFile;
}
void Draw(){
playerTex = loadImage(playerTexFile);
image(playerTex, x, y);
}
void moveAndDraw(float Speed){
playerTex = loadImage(playerTexFile);
if(alive){
x += Speed;
if (x >= 1300) {
x = 100;
y += 50;
}
}
}
}
Here is my result:
The Draw function works but what you're seeing that is messing it up is the moveAndDraw() function.
And the enemy drawings aren't moving. I have made this before with c++ SFML but in that there is a very basic getPosition function. The reason I want to get position is that right now I'm having to use inaccurate numbers as the X and Y position and for the enemy to move correctly I need to know exactly what it's position is. I have checked multiple pages on processing.org but none of them helped. I haven't found any getPosition void and all the ones I've seen other people using a void to do this I just haven't been able to get it to work. If there is some code that could get me this to work or just some function I've looked over and even a website page I could look at I'd be open to it. Please tell me anything I can do to get this working.
The issue is that you recreate the enemies in every frame at it's initial position:
void draw() {
background(0);
Enemy[] enemyPlayer = new Enemy[60];
for (int i = 0; i < 5; i += 1) {
for (int j = 0; j < 11; j += 1) {
enemyPlayer[j *i] = new Enemy("EnemyPlayerSpaceInvaders.png", 50 + j * 100, 5 + 75 * i, 6);
}
}
// [...]
}
You've to:
Create a global array of enemies Enemy[] enemyPlayer (and delete PImage enemyPlayer).
Create and initialize the enemies in setup.
Use and move the existing enemies in draw:
Further note, that your loops doesn't do what you expect it to do. Create the enemies in 2 nested loops. If i runs from o to 6 and j from 0 to 10, the the index of an enemy is i*10 + j.
The enemies can be moved in a single loop from 0 to enemyPlayer.length.
//PImage enemyPlayer; <--- DELETE
// global array of enemies
Enemy[] enemyPlayer = new Enemy[60];
// [...]
void setup() {
size(1400, 800);
mainPlayer = loadImage("MainPlayerSpaceInvaders.png");
// create enemies
for (int i = 0; i < 6; i += 1) {
for (int j = 0; j < 10; j += 1) {
enemyPlayer[i*10 + j] = new Enemy("rocket64.png", 50 + j * 100, 5 + 75 * i, 6);
}
}
}
void draw() {
background(0);
// move enemies
for(int i = 0; i < enemyPlayer.length; ++i ) {
if(enemyPlayer[i].alive){
enemyPlayer[i].Draw();
}
enemyPlayer[i].moveAndDraw(6);
}
}
I have a matrix double[][] with arbitrary dimensions but bigger than 300 (maybe in one or maybe on both dimensions). I want to scale it to double[300][300].
My main approach is to interpolate the matrix and bring it up to double[600][600] and then take four elements and find their average, i.e. the elements 0,0, 0,1, 1,0 and 1,1 will be the 0,0 of the final 300x300 matrix.
I have found the interpolation library in JAVA but I cannot figure out how to use it. Can anyone provide some examples or info?
The library is: http://docs.oracle.com/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/Interpolation.html
Thnx.
What about writing a simple method that maps source cells to destination, then averages out?
public static boolean matrixReduce(double[][] dst, double[][] src) {
double dstMaxX = dst.length - 1, dstMaxY = dst[0].length - 1;
double srcMaxX = src.length - 1, srcMaxY = src[0].length - 1;
int count[][] = new int[dst.length][dst[0].length];
for (int x = 0; x < src.length; x++) {
for (int y = 0; y < src[0].length; y++) {
int xx = (int) Math.round((double) x * dstMaxX / srcMaxX);
int yy = (int) Math.round((double) y * dstMaxY / srcMaxY);
dst[xx][yy] += src[x][y];
count[xx][yy]++;
}
}
for (int x = 0; x < dst.length; x++) {
for (int y = 0; y < dst[0].length; y++) {
dst[x][y] /= count[x][y];
}
}
return true;
}