// this method will be called once per frame
(plane as any).tick = (delta: number) => {
let pos = geometry.getAttribute("position");
let pa = pos.array as Float32Array;
let vectorArr : THREE.Vector3[] = [];
for (let i = 0; i < pa.length; i += 3) {
vectorArr.push(new THREE.Vector3(pa[i], pa[i + 1], pa[i + 2]));
}
for (let vect of vectorArr) {
vect.x -= 5 * delta;
if (vect.x < - 40) {
vect.x = 40;
removeArr.push(vect);
}
}
vectorArr.map((vect, i) => {
pa[3 * i] = vect.x;
pa[3 * i + 1] = vect.y;
pa[3 * i + 2] = vect.z;
});
pos.needsUpdate = true;
}
The above code is used for modifying the plane, I'm basically just trying to reset the vectors that are past x=-40, but that's leaving behind some sort of 'connecting plane' between the plane. Image below an example, the material is double sided(but changing it still leaves behind the weird connecting plane).
What it looks like normally, without the vector.x -= 5 * delta below.
I'm basically just trying to create an infinite scrolling landscape, so if you have a good way to do this in ThreeJS apart from my code, please let me know!
I am fairly new to p5.js, however I am trying to read a .txt file which contains the below text, and draw a picture depending on the value within the .txt file.
00000
20022
00222
22020
11111
I am currently stumped as to how to draw an image depending on the number in the array, as an example '1' would be grass. I have loaded the file in as a string using the following code: track = loadStrings("track1.txt");
I am trying to load it as a 5x5 'tile' if you will. Any help would be appreciated :)
I've used p5.Image to create a picture based on the pixels in the file.
This is a way of writing the code:
let track;
let colors;
let img;
function setup() {
createCanvas(100, 100);
track=loadStrings("track1.txt")
colors = [color(255,0,0),color(0,255,0),color(0,0,255)]
}
function draw() {
background(220);
img = createImage(track.length, track[0].length)
img.loadPixels();
for (let i = 0 ; i < track.length ; i++){
for (let j = 0 ; j < track.length ; j++){
img.set(i, j, colors[int(track[i][j])]);
}
}
img.updatePixels();
image(img, 50, 50);
}
Well you could probs split it up into arrays and also if you'd have some sort of seperator for colors, like: track1.txt: 10, 30, 255\n ... r, g, b\n .... Right now you would have to use the rgb rrrgggbbb
let colors = track.split("\n") // makes every new line into an array
for(let x = 0; x <= width; x ++) // "\n" = new line
for(let y = 0; y <= height; y ++){
let currentCol = []
for(let i = 0; i < 9; i += 3)
currentCol.push(
colors[x + y][0 + i] + // I'm really not sure about the: colors[x + y]...
colors[x + y][1 + i] +
colors[x + y][2 + i]
)
set(x, y, color(currentCol[0], currentCol[1], currentCol[2]))
}
I also made a function with a slightly different formula, which might work better, i am not sure though, but this is the actual formula to get from pixel array
function getColor(x, y, allColorsArr){
let _col = [] // current color, underscore not to accidentally clear your variable
for(let i = 0; i < 3; i ++)
_col.push(
allColorsArr[x + y * width][0 + i * 3] +
allColorsArr[x + y * width][1 + i * 3] +
allColorsArr[x + y * width][2 + i * 3]
)
return {
r: parseInt(_col[0], 10),
g: parseInt(_col[1], 10),
b: parseInt(_col[2], 10)
} // returning an object here just for the `.r`; `.g`; `.b`
} // you could do something like: let Colors = {red: 0, green: 1, blue: 2}
// col[Colors.red], col[Colors.green], col[Colors.blue] if you want
// example: let col = getColor(1, 0, track.split("\n"))
// example: stroke(col.r, col.g, col.b)
THERE IS MOST LIKELY IS A BETTER WAY TO DO THIS, but at least this works...
I have been stuck doing this for if loop for the last few days.
Basically, it's a loop that starts at the height of 6 and decreases within the FOR loop, when the height (y) hits 1 I want it to start increasing by 1.
At the moment the loop hits 1, the height increases by 1 but then because it loops back around it does not increase the next shape by another 1.
I know its a bit confusing but I hope I can grab some help!
Thanks!
int $f = 6;
for ($e = 24 ; $e <= 31; $e++)
{
if ($f <= 1) {
string $currentObject = $objects[$e];
select -r $currentObject ;
setAttr ($currentObject+".sy") ($f++);
}
else {
string $currentObject = $objects[$e];
select -r $currentObject ;
setAttr ($currentObject+".sy") ($f--);
}
}
If I understand your problem correctly, you only want to switch the direction of increment or decrement at the extremes, not between, i. e. you need another variable that codes the direction (incrementing or decrementing). I called that $diff in this code:
int $f = 6;
int $diff = -1;
for ($e = 24 ; $e <= 31; $e++)
{
if ($f <= 1) {
$diff = 1;
} else if ($f >= 6) {
$diff = -1;
}
string $currentObject = $objects[$e];
select -r $currentObject ;
setAttr ($currentObject+".sy") ($f);
$f = $f + $diff;
}
All this rectangles are added in grid and I want after click each of them to change the color to white, but program throwing and exception.
Can i do this with this way or I need to get the position of rectangle a make on his place a new one ?
Rectangle[] rec = new Rectangle[22 * 12];
for( int i = 0; i < 22 * 12; i++){
rec[i] = new Rectangle(32, 32);
rec[i].setStroke(Color.BLACK);
rec[i].setFill( Color.valueOf("#202020") );
rec[i].setStrokeWidth(1);
rec[i].setOnMouseClicked(e -> {
Rectangle r = new Rectangle(32, 32, Color.WHITE);
rec[i].setFill( Color.WHITE); // exception at this line -> i must be final or ...
});
}
As your compile error says, you can't access non-final variables in a lambda expression. You can get around this by putting your rectangle in a different (effectively-final) variable:
Rectangle[] rec = new Rectangle[22 * 12];
for( int i = 0; i < 22 * 12; i++){
Rectangle r = new Rectangle(32, 32);
r.setStroke(Color.BLACK);
r.setFill( Color.valueOf("#202020") );
r.setStrokeWidth(1);
r.setOnMouseClicked(e -> {
r.setFill( Color.WHITE);
});
rec[i] = r ;
}
}
I have a code block in cocos2d that creates a background by cycling through a set of 10 images like so:
- (void)addBackground{
CGSize winSize = [CCDirector sharedDirector].winSize;
//Add images to batchNode
float maxReach = 0;
for (int imageNumber=1; imageNumber < 13; imageNumber++) {
CCLOG(#"Adding image intro%d.png to the introAnimation.",imageNumber);
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
CCSprite *background = [CCSprite spriteWithFile:[NSString stringWithFormat:#"national_scenery_part%d-iPad.png",imageNumber]];
background.position = ccp((winSize.width/2)+maxReach, winSize.height/2);
[self addChild:background z:0];
maxReach = maxReach + background.contentSize.width;
} else {
CCSprite *background = [CCSprite spriteWithFile:[NSString stringWithFormat:#"national_scenery_part%d.png",imageNumber]];
background.position = ccp((winSize.width/2)+maxReach, winSize.height/2);
[self addChild:background z:0];
maxReach = maxReach + background.contentSize.width;
}
}
}
But of course it only loops once. I'd like it to loop 3 times. I was thinking of setting an integer to 0 and add 1 at the end of each loop and then run it again until it reaches 3. Does that sound like the best way to do this?
You can use nested FOR/WHILE loop for repeating it 3 times.
It should work well. I don't see any issue using this.