We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › pan camera() in X and Y (like mario brothers)
Page Index Toggle Pages: 1
pan camera() in X and Y (like mario brothers) (Read 1099 times)
pan camera() in X and Y (like mario brothers)
Aug 11th, 2007, 12:35am
 
I simply want to pan the camera in the X and Y dimensions.

Beginning with the most basic, I am simply drawing a 2D line and then trying to get it to render the same in 3D.

Here's the 2D code:

Code:

size(500, 500);
background(0);
stroke(255);
strokeWeight(50);
line(0, 250, width, 250);


I've played around with the camera() function a bunch, but no matter what paramaters I use, it always collapses the line down to one pixel thick.

Code:

size(500, 500, P3D);
camera(width/2.0, height/2.0, (height/2.0) / tan(PI*60.0 / 360.0), width/2.0, height/2.0, 0, 0, 1, 0);
background(0);
stroke(255);
strokeWeight(50);
// ONLY SHOWN AS 1 PIXEL THICK, EVEN THOUGH STROKEWEIGHT IS SET TO 50
line(0, 250, 0, width, 250, 0);


How would the P3D code need to be modified to render the same thing as the 2D code?

And once I have the initial screen looking the same in 3D, what paramaters of camera() do I need to increment/decrement to make the camera pan to the right and left and up and down?
Re: pan camera() in X and Y (like mario brothers)
Reply #1 - Aug 11th, 2007, 2:26am
 
See http://dev.processing.org/bugs/show_bug.cgi?id=123 - strokeWeight() doesn't do anything in P3D right now (unclear whether it will in the future, either - a 3d stroke is a strange and somewhat undefined thing, some 3d graphics cards don't even handle this completely consistently).  My suggestion would be to create a function that actually draws geometrical strokes (with thickness) if you need them to transform properly in 3d; for 2d, you might look up fat line rasterization methods and do things pixel by pixel (I assume strokeWeight will work in P2D once that's back, so some of the relevant algorithms might already be in PGraphics2d.java or PPolygon.java in the source for Processing if you dare to poke around).
Re: pan camera() in X and Y (like mario brothers)
Reply #2 - Aug 11th, 2007, 5:06am
 
Eric Jordan wrote on Aug 11th, 2007, 2:26am:
strokeWeight() doesn't do anything in P3D right now...


I must be lucky becuase I discovered that it does work in OPENGL on my MacBook. But now I've hit another major snag: Anytime I update the position of the camera, the canvas gets wiped. This is really bad because I don't want to have to redraw the entire contents of the screen on every frame, just the new stuff that comes in to view by the sidescrolling.

Is there any way to keep 2D shapes around when changing the position of the camera

Here is the function that I'm using to update the camera (in 2D):

Code:

void camera2D (float x1, float y1) {
camera(x1, // eyeX
y1, // eyeY
(height/2.0) / tan(PI*60.0 / 360.0), // eyeZ
x1, // centerX
y1, // centerY
0, // centerZ
0, // upX
1, // upY
0); // upZ
}
Re: pan camera() in X and Y (like mario brothers)
Reply #3 - Aug 11th, 2007, 8:50am
 
Hmm, I don't think a camera() call clears the canvas by itself - are you sure you're not calling background() somewhere?  If you mean, rather, that the geometry is not stored between frame draws, that is correct - if you move the camera and want geometry to appear in the new position relative to the camera, you have to explicitly redraw it.  camera() and all the other transformation functions basically just set up a framework that decides where to draw a triangle on the screen when you call a triangle drawing function.  You still have to call that drawing function every time you want the triangle to appear.  Put another way, the only remnant of a drawing call that you've made after it returns is the set of pixels that it changed on the screen (or in the pixels[] array).

For a side scroller, you actually need to change all the pixels on the screen every time the camera moves, so you'll at least have to redraw everything that is visible.  A fairly fast way to do this is to chunk up your levels along the x axis in blocks the size of the screen width, and then draw the geometry in (and only in) the two chunks that should be visible wrt the current camera positioning.  That way if have a ridiculous level with 20,000 objects that extends to a thousand times the screen width you never have to draw more than about 40 objects at once, which should not be too much strain on a processor.  You could also sort all your geometry along the x axis and just pick out what you need to draw from the sorted list.  Either way is a bit of bookkeeping for a lot of performance gain.

That said, if you would prefer to preserve _exactly_ what was drawn, and there's no nice/efficient way of redrawing it, you could always shift it over by a pixel (sort of - I'll explain) using the following draw loop (only works fast and correctly in P3D, though), obviously with your own drawRightEdgePixels(int) function that does exactly what it says (the int is a marker to tell it where the camera is):

Code:

int position = 0; //position of camera along x axis
void draw(){
loadPixels();
for (int i=0; i<pixelShiftPerFrame; i++){
System.arraycopy(pixels, 1, pixels, 0, pixels.length-1);
drawRightEdgePixels(position++);
//Note: w/o this function actually drawing
//the right edge pixels, pixels will wrap
//around from the left edge shifted up by
//one pixel.
}
updatePixels();
}

Honestly, though, unless your drawing functions are so detailed that you alter every pixel individually as they enter the screen, this is going to likely be slower than simply redrawing all the visible geometry, and the bookkeeping becomes enormously difficult.  OpenGL has very little overhead for drawing sprites, so I think a platformer is probably best done with a redraw every frame.
Page Index Toggle Pages: 1