How to test if cursor in on circle? (Processor) - mouseevent

I want to implement on my project this sketch about dragging a box.
Instead of one box, I have several circles each drawn with different coordinates in the form
ellipse(lemma23.x, lemma23.y, diameterLemma23, diameterLemma23);
ellipse(law3.x, law3.y, diameterLaw3, diameterLaw3);
ellipse(law2.x, law2.y, diameterLaw2, diameterLaw2);
How do I test if the cursor is on one of the circles?
Here's a screen shot of my project:
I want to test when cursor is on (or near) a circle so that I can change its position by dragging.
The entire sketch is in pastebin.

I started with the example in your question. There are a few main differences for drawing multiple shapes:
You have to check whether the cursor is within each shape.
You have to draw each shape.
You may want to worry about overlapping, but I did not.
In the following code, I build upon the example directly although I removed the few lines which change the color of the box when clicked and I reorganized the code into the MovingEllipse class so that multiple ellipses can be drawn easily. (This code draws two ellipses.)
Note that the code in draw() checks the position of the mouse for each ellipse, however, I suppose this could be improved upon (i.e. perhaps by creating an array of ellipse positions and looping over the array). Also, for this code to work properly, mousePressed and mouseReleased methods need to be copied like the mouseDragged method. (I was trying to make my example brief.)
Anyway, this is one way to draw multiple ellipses and detect which one should be moved. Hope it helps!
int esize = 75;
MovingEllipse e1 = new MovingEllipse(0.0, 0.0, esize, 0.0, 0.0);
MovingEllipse e2 = new MovingEllipse(0.0, 0.0, esize, 0.0, 0.0);
void setup()
{
size(640, 360);
e1.eX = width/2.0; // Center of ellipse 1.
e1.eY = height/2.0;
e2.eX = width/4.0; // Center of ellipse 2.
e2.eY = height/4.0;
}
void draw()
{
background(0);
// Test if the cursor is over the ellipse.
if (mouseX > e1.eX-esize && mouseX < e1.eX+esize &&
mouseY > e1.eY-esize && mouseY < e1.eY+esize) {
e1.overBox = true;
e2.overBox = false;
} else if (mouseX > e2.eX-esize && mouseX < e2.eX+esize &&
mouseY > e2.eY-esize && mouseY < e2.eY+esize) {
e2.overBox = true;
e1.overBox = false;
} else {
e1.overBox = false;
e2.overBox = false;
}
// Draw the ellipse(s).
e1.update(e1.eX, e1.eY, e1.overBox);
e2.update(e2.eX, e2.eY, e2.overBox);
}
void mouseDragged() {
e1.mouseDragged();
e2.mouseDragged();
}
// Don't forget to repeat this for mousePressed and mouseReleased!
// ...
class MovingEllipse {
float eX, eY; // Position of ellipse.
int eSize; // Radius. For a circle use eSize for both x and y radii.
float xOffset, yOffset; // Where user clicked minus center of ellipse.
boolean locked, overBox; // Flags used for determining if the ellipse should move.
MovingEllipse (float ex, float ey, int esize, float xoff, float yoff) {
eX = ex;
eY = ey;
eSize = esize;
xOffset = xoff;
yOffset = yoff;
}
void update(float ex, float ey, boolean over) {
eX = ex;
eY = ey;
overBox = over;
// Draw the ellipse. By default, (eX, eY) represents the center of the ellipse.
ellipse(eX, eY, eSize, eSize);
}
void mousePressed() {
if(overBox) {
locked = true;
} else {
locked = false;
}
xOffset = mouseX-eX;
yOffset = mouseY-eY;
}
void mouseDragged() {
if(locked) {
eX = mouseX-xOffset;
eY = mouseY-yOffset;
}
}
void mouseReleased(){
locked = false;
}
}

Just check if the distance between the cursor and the centre of the circle is within the hit radius. The hit radius could be made larger than the radius of the circle to catch near hits.

Related

XNA 4.0 Camera and object handling on screen

For developing a side-scrolling platform 2D game I want to implement a moving camera class, the reason of using the class instead of moving the whole map is that I'll have to use too many objects at once witch will cause a lag. I cannot let that happen.
There's a nice algorithm for handling the camera, when player is moving further than the width of the screen then camera moves on players direction until he is once again in the middle of the screen, I've been working several days for making this algorithm work however there's been no success.
// Main
public class Camera
{
protected float _zoom;
protected Matrix _transform;
protected Matrix _inverseTransform;
//The zoom scalar (1.0f = 100% zoom level)
public float Zoom
{
get { return _zoom; }
set { _zoom = value; }
}
// Camera View Matrix Property
public Matrix Transform
{
get { return _transform; }
set { _transform = value; }
}
// Inverse of the view matrix,
// can be used to get
// objects screen coordinates
// from its object coordinates
public Matrix InverseTransform
{
get { return _inverseTransform; }
}
public Vector2 Pos;
// Constructor
public Camera()
{
_zoom = 2.4f;
Pos = new Vector2(0, 0);
}
// Update
public void Update(GameTime gameTime)
{
//Clamp zoom value
_zoom = MathHelper.Clamp(_zoom, 0.0f, 10.0f);
//Create view matrix
_transform = Matrix.CreateScale(new Vector3(_zoom, _zoom, 1)) *
Matrix.CreateTranslation(Pos.X, Pos.Y, 0);
//Update inverse matrix
_inverseTransform = Matrix.Invert(_transform);
}
}
This is the camera class I made for handling the screen, it's main purpose is to resize the screen, more precisely to zoom in and out whenever I want to change my screen, (Title screen, Playing screen, Game over, and like that.)
Moving the camera is quite simple with keys, like this.
if (keyState.IsKeyDown(Keys.D))
Cam.Pos.X -= 20;
if (keyState.IsKeyDown(Keys.A))
Cam.Pos.X += 20;
if (keyState.IsKeyDown(Keys.S))
Cam.Pos.Y -= 20;
if (keyState.IsKeyDown(Keys.W))
Cam.Pos.Y += 20;
And ofc. the drawing method witch apply the camera.
spriteBatch.Begin(SpriteSortMode.Texture, BlendState.AlphaBlend, null, null, null, null, Cam.Transform);
Here comes the part when I stop, so what I want to do is make something like 2 2D rooms. By Room I mean the place where I usually place objects. like this "Vector2(74, 63)" So I want to create a place where I could draw items that would stick to the screen and wouldn't move, and make the screen bounds that would make my algorithm to work, witch will be always on screen and as an addition it will check if one of the borders of the screen "room" reaches the certain coordinates of the map "room".
I think that the reason for that would be obvious because I don't want player to move camera outside the map when he reaches the wall, otherwise the player would already see a part of the next map where he will be transformed.
The reason of drawing both maps next to each other is again to reduce the loading time so player wouldn't have to wait for playing the next map.
Alright, so I've run into more troubles than I expected so I'll add extra information and will start with the player class:
// Main
public class Player
{
public Texture2D AureliusTexture;
public Vector2 position;
public Vector2 velocity;
public Vector2 PosForTheCam; // Variable that holds value for moving the camera
protected Vector2 dimensions;
protected CollisionPath attachedPath;
const float GRAVITY = 18.0f;
const float WALK_VELOCITY = 120f;
const float JUMP_VELOCITY = -425.0f;
// Constructor
public Player()
{
dimensions = new Vector2(23, 46);
position = new Vector2(50, 770);
}
public void Update(float deltaSeconds, List<CollisionPath> collisionPaths)
{
#region Input handling
KeyboardState keyState = Keyboard.GetState();
if (keyState.IsKeyDown(Keys.Left))
{
velocity.X = -WALK_VELOCITY;
}
else if (keyState.IsKeyDown(Keys.Right))
{
velocity.X = WALK_VELOCITY;
}
else
{
velocity.X = 0;
}
if (attachedPath != null && keyState.IsKeyDown(Keys.Space))
{
velocity.Y = JUMP_VELOCITY;
attachedPath = null;
}
velocity.Y += GRAVITY;
#endregion
#region Region of handling the camera based on Player
PosForTheCam.X = velocity.X;
#endregion
#region Collision checking
if (velocity.Y >= 0)
{
if (attachedPath != null)
{
position.X += velocity.X * deltaSeconds;
position.Y = attachedPath.InterpolateY(position.X) - dimensions.Y / 2;
velocity.Y = 0;
if (position.X < attachedPath.MinimumX || position.X > attachedPath.MaximumX)
{
attachedPath = null;
}
}
else
{
Vector2 footPosition = position + new Vector2(0, dimensions.Y / 2);
Vector2 expectedFootPosition = footPosition + velocity * deltaSeconds;
CollisionPath landablePath = null;
float landablePosition = float.MaxValue;
foreach (CollisionPath path in collisionPaths)
{
if (expectedFootPosition.X >= path.MinimumX && expectedFootPosition.X <= path.MaximumX)
{
float pathOldY = path.InterpolateY(footPosition.X);
float pathNewY = path.InterpolateY(expectedFootPosition.X);
if (footPosition.Y <= pathOldY && expectedFootPosition.Y >= pathNewY && pathNewY < landablePosition)
{
landablePath = path;
landablePosition = pathNewY;
}
}
}
if (landablePath != null)
{
velocity.Y = 0;
footPosition.Y = landablePosition;
attachedPath = landablePath;
position.X += velocity.X * deltaSeconds;
position.Y = footPosition.Y - dimensions.Y / 2;
}
else
{
position = position + velocity * deltaSeconds;
}
}
}
else
{
position += velocity * deltaSeconds;
attachedPath = null;
}
#endregion
}
}
So I state it clear that I asked my friend to do most of it because I wanted to handle the gravity and the slopes so we made it work similar like in Unity. And he happened to know how to do that.
And so I'll add the Update method that handles the camera from the Main Class.
MM.Update(gameTime); // Map Managher update function for map handling
Cam.Update(gameTime); // Camera update
Cam.Zoom = 2.4f; // Sets the zoom level for the title screen
// Takes the start position for camera in map and then turns off the update
// so the camera position can be changed. Else it would just keep an infinite
// loop and we couldn't change the camera.
if (StartInNewRoom)
{
Cam.Pos = MM.CameraPosition; // Applys the camera position value from the map manager class
StartInNewRoom = false;
}
I am unsure how to handle the camera, like I used your method and the result often ended up that camera moves by itself or it doesn't move at all.
If you don't want objects to move with the camera like a HUD you need a second spriteBatch.Begin() without your camera matrix which you draw after your actual scene.
To make the camera not move out of the map you could use some kind of collision detection. Just calculate the right border of your camera. It depends where the origin of your camera is.
Is your camera matrix working like this? Because the position should be negative or it will move in the wrong direction.
This is how mine looks like.
return Matrix.CreateTranslation(new Vector3(-camera.position.X, -camera.position.Y, 0)) *
Matrix.CreateRotationZ(Rotation) * Matrix.CreateScale(Zoom) *
Matrix.CreateTranslation(new Vector3(Viewport.Width * 0.5f, Viewport.Height * 0.5f, 0));
Viewport.Width/Height * 0.5 centers you camera.
You can also apply this behind your Pos.X/Y
To Camera follows player
public void Update(Player player)
{
//Clamp zoom value
_zoom = MathHelper.Clamp(_zoom, 0.0f, 10.0f);
//Create view matrix
_transform = Matrix.CreateScale(new Vector3(_zoom, _zoom, 1)) *
Matrix.CreateTranslation(player.Pos.X, player.Pos.Y, 0);
//Update inverse matrix
_inverseTransform = Matrix.Invert(_transform);
}

While Loop and rotations. Is there a way to keep it within in the boundaries?

I am using a while loop, rotate and translate in order to get the effect I want for my program. I want to be able to contain the loop within the boundaries of the sketch. Can anyone explain to me how that can be done, please?
Here is the code:
float x, y, r, g, b, radius;
void setup()
{
size(800, 700);
smooth();
frameRate(15);
}
void draw()
{
handleRedBox();
}
void handleRedBox() {
background(255);
stroke(255, 0, 0);
color from = color(100, random(255), 2);
color to = color(0, 200, 0);
color interA = lerpColor (to, from, .44);
int x = 100;
while (x < width/2 || x> width/2 ) {
int y = 100;
while (y <height/2 || y > height/2) {
blendMode(DIFFERENCE);
noStroke();
fill(interA);
quadstuff();
strokeWeight(5);
stroke(0, random(255), 0);
line(width/2, height/2, mouseY, mouseX);
translate(width, height);
rotate(radians(frameCount));
y = y + 50;
}
x = x + 50;
}
ghostcirc();
ghostcirc2();
}
void ghostcirc() {
int w = 0;
while (w < width) {
int q = 0;
while (q <height) {
blendMode(ADD);
fill(random(61), random(90), random(250));
ellipse(255, 255, 100, 100);
;
noStroke();
translate(width, height);
rotate(radians(frameCount));
q = q + 100;
}
w = w + 50;
}
}
void ghostcirc2() {
for (int w= 0; w < width; w+=10) {
blendMode(ADD);
fill(random(61), random(90), random(250));
ellipse(50, 50, 75, 75);
;
noStroke();
translate(width, height);
rotate(radians(frameCount));
//if (keyPressed == true){
// fill(random(100), random(90), random(250));
}
}
void quadstuff() {
int rad = 60; // Width of the shape
float xpos, ypos; // Starting position of shape
float xspeed = 2.8; // Speed of the shape
float yspeed = 2.2; // Speed of the shape
xpos = width/2;
ypos = height/2;
//ellipse(mouseX+x, mouseY+y, 100,100);
quad(xpos, ypos, rad, rad, mouseX+rad, mouseY+rad, xspeed, yspeed);
stroke(0);
strokeWeight(5);
}
Your question is still pretty broad, and that's still a lot of code to try to debug. But I appreciate that you went through the trouble of narrowing it down, so I'm going to try to help in general terms.
Your code involves a lot of stuff that I don't really understand, so I'm going to start with a simpler example. Honestly you might be better off doing the same- start over with something more basic, and add the bounding logic from the beginning. That's going to be much easier than trying to add it in after you've already written everything.
So, there are two main ways to do this type of animation in Processing. I'll cover both.
Option 1: Rely on translate() and rotate() to position stuff for you.
This is what your code does. Here is a simpler example that shows an ellipse rotating around the mouse position:
float angle = 0;
void setup() {
size(500, 500);
}
void draw() {
angle+=.1;
background(0);
translate(mouseX, mouseY);
rotate(angle);
translate(100, 0);
ellipse(0, 0, 50, 50);
}
Now, if you want to bound the ellipse to stay inside the window, first you need to determine where the ellipse will be on the screen. This could be complicated since we're using the translate() and rotate() functions, which are a little like moving the camera instead of moving the ellipse- the ellipse "thinks" it's still at position 0,0. So we need to get the position of the ellipse after we move the camera. Luckily Processing gives us the screenX() and screenY() functions:
float screenX = screenX(0, 0);
float screenY = screenY(0, 0);
This will tell us where on the screen the ellipse will be drawn (or more accurately, where position 0,0 will be after the transforms are applied). We can use this to check whether these go outside the bounds of the window, and then do whatever bounding you want.
Exactly what type of bounding you do depends on what you want to happen. You could wrap the animation around the screen so that when it goes off the right side it reappears on the left side. You could limit the positions so they only go to the border of the window instead of moving past it. Here is that:
float angle = 0;
void setup() {
size(500, 500);
}
void draw() {
angle+=.1;
background(0);
translate(mouseX, mouseY);
rotate(angle);
translate(100, 0);
float screenX = screenX(0, 0);
float screenY = screenY(0, 0);
if (screenX < 25) {
rotate(-angle);
translate(25-screenX, 0);
rotate(angle);
} else if (screenX > 475) {
rotate(-angle);
translate(475-screenX, 0);
rotate(angle);
}
if (screenY < 25) {
rotate(-angle);
translate(0, 25-screenY);
rotate(angle);
} else if (screenY > 475) {
rotate(-angle);
translate(0, 475-screenY);
rotate(angle);
}
ellipse(0, 0, 50, 50);
}
This code is the same as above, except now it uses screenX() and screenY() to determine when the ellipse will be off the screen, and then uses translate() to move it back inside the bounds of the screen.
Option 2: Keep track of the position yourself.
Instead of relying on translate() and rotate() to do the positioning for you, you could also just use some basic algebra and trig to do the positioning yourself.
Here is the simple program, without bounding yet:
float angle = 0;
void setup() {
size(500, 500);
}
void draw() {
angle+=.1;
background(0);
float circleX = mouseX + cos(angle)*100;
float circleY = mouseY + sin(angle)*100;
ellipse(circleX, circleY, 50, 50);
}
Notice that I'm calculating the position of the ellipse myself instead of relying on translate() and rotate(). Now it might be easier to think about exactly where the circle will be, so I can do the bounding:
float angle = 0;
void setup() {
size(500, 500);
}
void draw() {
angle+=.1;
background(0);
float circleX = mouseX + cos(angle)*100;
float circleY = mouseY + sin(angle)*100;
if (circleX < 25) {
circleX = 25;
} else if (circleX > 475) {
circleX = 475;
}
if (circleY < 25) {
circleY = 25;
} else if (circleY > 475) {
circleY = 475;
}
ellipse(circleX, circleY, 50, 50);
}
This might be a little easier to think about, since you can work with the screen coordinates directly. Both options do the same thing, they're just different ways of thinking about it.
From here it's just a matter of defining exactly how your bounding should work. I've given you one example, but you could do anything you want.
You might also want to restrict your input variables (in my case, mouseX and mouseY) so the animation never leaves the window. Adding this at the top of the draw() function of either one of the above options will prevent the animation from leaving the screen:
if (mouseX < 150) {
mouseX = 150;
} else if (mouseX > 350) {
mouseX = 350;
}
if (mouseY < 150) {
mouseY = 150;
} else if (mouseY > 350) {
mouseY = 350;
}
Again, how you do this is really up to you and what you want to happen. It will probably be easier if you start over with a basic program like mine and then add one small thing at a time instead of trying to add it to your existing huge sketch. Good luck.

Bézier curve for smooth sketch on monogame

I am a MonoGame developer,and I would like to draw a curve on the phone screen but, the curve isn't regular rather jerky and composed by several lines.
I used some codes like this:
First method draws the sprites evently spaced apart like this:
// increment is how far apart each sprite is drawn
private void DrawEvenlySpacedSprites(Texture2D texture, Vector2 point1, Vector2 point2, float increment)
{
var distance = Vector2.Distance(point1, point2); // the distance between two points
var iterations = (int)(distance / increment); // how many sprites with be drawn
var normalizedIncrement = 1.0f / iterations; // the Lerp method needs values between 0.0 and 1.0
var amount = 0.0f;
if(iterations == 0)
iterations = 1;
for (int i = 0; i < iterations; i++)
{
var drawPoint = Vector2.Lerp(point1, point2, amount);
_spriteBatch.Draw(texture, drawPoint, Color.White);
amount += normalizedIncrement;
}
}
The Update method:
private Vector2? _previousPoint;
protected override void Update(GameTime gameTime)
{
TouchCollection touches = TouchPanel.GetState();
foreach (TouchLocation touch in touches)
{
if (touch.State == TouchLocationState.Moved)
{
GraphicsDevice.SetRenderTarget(renderTarget);
_spriteBatch.Begin();
if (_previousPoint.HasValue)
DrawEvenlySpacedSprites(texture, _previousPoint.Value, touch.Position, 0.5f);
_spriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
}
}
if (touches.Any())
_previousPoint = touches.Last().Position;
else
_previousPoint = null;
base.Update(gameTime);
}
I have this result:
To remedy it, I tried to use the Bezier curves,but I couldn't implement this solution.
Please, could you help me.
Waiting for your valuable comments and suggestions.

How to find the Joint coordinates(X,Y,Z) ,also how to draw a locus of the tracked joint?

I am trying to develop a logic to recognize a circle which is made by users right hand, I got the code to draw the skeleton and track from the sample code,
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
}
}
using (DrawingContext dc = this.drawingGroup.Open())
{
// Draw a transparent background to set the render size
dc.DrawRectangle(Brushes.Black, null, new Rect(0.0, 0.0, RenderWidth, RenderHeight));
if (skeletons.Length != 0)
{
foreach (Skeleton skel in skeletons)
{
RenderClippedEdges(skel, dc);
if (skel.TrackingState == SkeletonTrackingState.Tracked)
{
this.DrawBonesAndJoints(skel, dc);
}
else if (skel.TrackingState == SkeletonTrackingState.PositionOnly)
{
dc.DrawEllipse(
this.centerPointBrush,
null,
this.SkeletonPointToScreen(skel.Position),
BodyCenterThickness,
BodyCenterThickness);
}
}
}
// prevent drawing outside of our render area
this.drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, RenderWidth, RenderHeight));
}
}
What I want to do now is to track the coordinates of users right hand for gesture recognition,
Here is how I am planning to get the job done:
Start the gesture
Draw the circled gesture, Make sure to store the coordinates for start and then keep noting the coordinates for every 45 degree shift of the Joint from the start, for 8 octants we will get 8 samples.
For making a decision that a circle was drawn we can just check the relation ship between the eight samples.
Also, in the depthimage I want to show the locus of the drawn gesture, so as the handpoint moves it leaves a trace behind so at the end we will get a figure which was drawn by an user. I have no idea how to achieve this.
Coordinates for each joint are available for each tracked skeleton during each SkeletonFrameReady event. Inside your foreach loop...
foreach (Skeleton skeleton in skeletons) {
// get the joint
Joint rightHand = skeleton.Joints[JointType.HandRight];
// get the individual points of the right hand
double rightX = rightHand.Position.X;
double rightY = rightHand.Position.Y;
double rightZ = rightHand.Position.Z;
}
You can look at the JointType enum to pull out any of the joints and work with the individual coordinates.
To draw your gesture trail you can use the DrawContext you have in your example or use another way to draw a Path onto the visual layer. With your x/y/z values, you would need to scale them to the window coordinates. The "Coding4Fun" library offers a pre-built function to do it; alternatively you can write your own, for example:
private static double ScaleY(Joint joint)
{
double y = ((SystemParameters.PrimaryScreenHeight / 0.4) * -joint.Position.Y) + (SystemParameters.PrimaryScreenHeight / 2);
return y;
}
private static void ScaleXY(Joint shoulderCenter, bool rightHand, Joint joint, out int scaledX, out int scaledY)
{
double screenWidth = SystemParameters.PrimaryScreenWidth;
double x = 0;
double y = ScaleY(joint);
// if rightHand then place shouldCenter on left of screen
// else place shouldCenter on right of screen
if (rightHand)
{
x = (joint.Position.X - shoulderCenter.Position.X) * screenWidth * 2;
}
else
{
x = screenWidth - ((shoulderCenter.Position.X - joint.Position.X) * (screenWidth * 2));
}
if (x < 0)
{
x = 0;
}
else if (x > screenWidth - 5)
{
x = screenWidth - 5;
}
if (y < 0)
{
y = 0;
}
scaledX = (int)x;
scaledY = (int)y;
}

Change text fill colour when rect is overlayed - Processing

I have this little animation here that animates in a repeated seamless pattern.
I have text, colored white, in the middle of the canvas that the looped shapes pass over. What I am trying to work out is when the white bars pass over the text it turns black. So as half the white bar goes over the T of "Text", half the T would be black and the half not covered would be still white on a diagonal.
Would this be done with splitting up the letters? By doing masking, or using vector images?
Here is a graphic example of what I'm trying to achieve.
http://imm.io/2Qsb
drawLine wob1;
drawLine wob2;
drawLine wob3;
drawLine wob4;
drawLine wob5;
PFont helv;
drawText title;
void setup() {
//frame.setResizable(true);
size(320, 480);
smooth();
frameRate(50);
wob1 = new drawLine(0);
wob2 = new drawLine(200);
wob3 = new drawLine(400);
wob4 = new drawLine(600);
wob5 = new drawLine(800);
title = new drawText();
}
void draw() {
background(#000000);
wob1.increment();
wob1.display(#ffffff);
wob1.pos();
wob1.boundary();
wob2.increment();
wob2.display(#ffffff);
wob2.boundary();
wob3.increment();
wob3.display(#ffffff);
wob3.boundary();
wob4.increment();
wob4.display(#ffffff);
wob4.boundary();
wob5.increment();
wob5.display(#ffffff);
wob5.boundary();
title.rendertitle(#ffffff;
}
class drawLine {
int x = -480;
int y = 0;
int count;
drawLine(int offset) {
this.x = this.x + offset;
}
void increment() {
this.x += 3;
this.y += 4;
}
void display(int col) {
//noStroke();
fill(col);
//translate(0,0);
rectMode(CENTER);
rotate(-PI/3.0);
rect(x,y,100,3000);
rotate(PI/3.0);
}
void pos() {
println(this.x);
//if(this.x >= -218 && this.x <= 207){ colr = #000000; } else { colr = #ffffff; }
}
void boundary() {
if(this.x > 520) {
this.x = -480; this.y = 0;
}
}
}
class drawText {
drawText() {
helv = loadFont("Helvetica-Bold.vlw");
}
void rendertitle(int colr) {
fill(colr);
textFont(helv, 30);
text("Text goes here", width/2, height/2, 240, 50);
}
}
I worked out a solution using two generated images. The first one imgText contains only text (white) in front of black background. The second one imgMaskfunctions as mask and therefore contains the screen line pattern. It's fine to generate the first (text image) only once within the setup() part; because your type doesn't change/move or transform. The mask image has to be updated every frame if you want to achieve the effect of "scanning" lines. This happens every draw() loop through the shift of the offset parameter.
The rest is pretty basic; clear the background every frame and draw the inverted version of imgText before you display the actual masked image.
PImage imgText;
PImage imgMask;
PFont font;
int barHeight = 20;
float offset = 0;
float offsetTick = 0.3;
void setup () {
size (320, 240);
noStroke ();
smooth ();
font = createFont ("Helvetica-Bold.vlw", 18);
// Create new image containing only
// the white text infront of an empty
// black sketch background
background (0);
fill (255);
textFont (font);
textAlign (CENTER);
text ("Text goes here", width/2, height/2);
imgText = createImage (width, height, ARGB);
copySketchIntoImage (imgText);
// Create empty mask image
imgMask = createImage (width, height, ARGB);
}
void draw () {
// Move the scan lines further down
// by increasing offset
offset += offsetTick;
if (offset > barHeight * 2) {
offset = 0;
}
// Update the text mask image
updateMask (offset);
imgText.mask (imgMask);
// Draw the inverted background+text
background (255);
fill (0);
text ("Text goes here", width/2, height/2);
// Display the masked version of the
// text image above the inverted background
image (imgText, 0, 0);
}
void updateMask (float theOffset) {
background (0);
fill (255);
for (float i=theOffset - barHeight; i < height; i += barHeight * 2) {
rect (0, i, width, barHeight);
}
copySketchIntoImage (imgMask);
}
// Method to copy all sketch pixels
// into an existing PImage.
void copySketchIntoImage (PImage theDestImage) {
loadPixels ();
theDestImage.loadPixels ();
for (int i=0; i < pixels.length; i++) {
theDestImage.pixels[i] = pixels[i];
}
theDestImage.updatePixels ();
}