I am fast approaching several deadlines for my highschool graduation project so any advice you can give would be great. My project is to code a movie. The idea is to use processing to move the characters like tokens and also use code to animate things like rain and fire. Right now I am finding it very difficult to move images and/or rotate them. This is a big hurtle for my project. The current code I have for this is butchered and complicated but here it is.
Image of leading lady, Radial: https://www.dropbox.com/s/x3gvendnaeftapj/radialoutlinel.png
/*
Radialrolling
*/
PImage img; // Declare variable "a" of type PImage
float ballX = 10;
float ballY = 200;
float h = 300;
//create a variable for speed
float speedY = 2; // spped set to 0 in order to test rotating. Necessary for rolling motion
float speedX = 0.;
void setup() {
size(800,800);
smooth();
noStroke();
background(0, 0, 0);// Load the image into the program
// change the mode we draw circles so they are
// aligned in the top left
ellipseMode(CORNER);
img = loadImage("radialoutlinel.png");
}
void RadialRoll(){
rotate(0);//if this is anything but 0 ball will appear of screen
image(img, ballX, ballY, h, h); //create a continuos rotation using the new fun
//nctions in the draw things
}
void draw() {
//clear the background and set the fill colour
background(0);
fill(255);
//draw the circle in it's current position
// ellipse(ballX, ballY, h,h);
//add a little gravity to the speed
speedY = speedY + 0;
speedX = speedX + .02;
ballX = ballX + speedX;
RadialRoll();
if (ballX > width - h) {
// set the position to be on the floor
ballX = width - h;
// and make the y speed 90% of what it was,
// but in the opposite direction
speedX = speedX * -1;
//switch the direction
//speedY = speedY;
}
if (ballX > width - h) {
// set the position to be on the floor
ballX = width - h;
// and make the y speed 90% of what it was,
// but in the opposite direction
speedX = speedX * -1;
//switch the direction
//speedY = speedY;
}
else if (ballX <= 0) {
// if the ball hits the top,
// make it bounce off
speedX = -speedX;
}
if (ballY > height - h) {
// set the position to be on the floor
ballY = height - h;
// and make the y speed 90% of what it was,
// but in the opposite direction
speedY = speedY * -1;
//switch the direction
//speedY = speedY;
}
else if (ballY <= 0) {
// if the ball hits the top,
// make it bounce off
speedY = -speedY;
}
}
How can I move images on screen and rotate them with little hassle?
Thank you very much.
-TheIronHobo
First when you look at rotate() function it take radians (values from 0 to TWO_PI) as argument so when you want fluent rotation use something like this
rotate(counter*TWO_PI/360);
Where counter could be integer value increased in every draw() loop. But if you just add this to you code image will be rotating around point [0,0] (upper left corner) and you will not see image for 1/4 of the rotation. To better understanding this you should read this TUTORIAL then you could start with basic rotation:
PImage img;
int counter = 1;
void setup() {
size(800, 800);
smooth();
background(0, 0, 0);
img = loadImage("radialoutlinel.png");
imageMode(CENTER); //you can change mode to CORNER to see the difference.
}
void draw() {
background(0);
fill(255);
counter++;
translate(width/2, height/2);
rotate(counter*TWO_PI/360);
image(img, 0, 0, 300, 300);
}
Then if you want also move image from left to right side you will just adjust translate() first parameter.
Related
I've recently built a game of pong for a UNI assignment in Processing, but whenever the ball hits the top, bottom, side of the screen or the 'paddle' it only bounces back once half the ball is off the screen. I just want the edge of the ball to hit first rather than the centre, but am unsure where my code is going wrong. I hope this makes sense, I'm a definite beginner.
Here is my code for reference
//underwater pong
float x, y, speedX, speedY;
float diam = 10;
float rectSize = 200;
float diamHit;
PImage bg;
PImage img;
int z;
void setup() {
size(920, 500);
smooth();
fill(255);
stroke(255);
imageMode(CENTER);
bg = loadImage("underthesea.jpg");
img = loadImage("plastic.png");
reset();
}
void reset() {
x = width/2;
y = height/2;
//allows plastic to bounce
speedX = random(5, 5);
speedY = random(5, 5);
}
void draw() {
background(bg);
image(img, x/2, y);
rect(0, 0, 20, height);
rect(width/2, mouseY-rectSize/2, 50, rectSize);
//allows plastic to bounce
x += speedX;
y += speedY;
// if plastic hits movable bar, invert X direction
if ( x > width-30 && x < width -20 && y > mouseY-rectSize/2 && y < mouseY+rectSize/2 ) {
speedX = speedX * -1;
}
// if plastic hits wall, change direction of X
if (x < 25) {
speedX *= -1.1;
speedY *= 1.1;
x += speedX;
}
// if plastic hits up or down, change direction of Y
if ( y > height || y < 0 ) {
speedY *= -1;
}
}
void mousePressed() {
reset();
}
I wasn't able to run your code because I am missing the background and plastic images, but here's what's probably going wrong. I'm not 100% since I do not know the dimensions of your images either.
You are using imageMode(CENTER). See the documentation for details.
From the docs:
imageMode(CENTER) interprets the second and third parameters of image() as the image's center point. If two additional parameters are specified, they are used to set the image's width and height.
This treats the coordinates you input into the image function as the center of the image.
Your first issue is that you are placing your image at x/2 but doing all your collision checks with x in mind. x does not represent the middle of your image, because you're drawing it at x/2.
Then I'm not sure if you are doing your horizontal collision checks right, as you are checking against hardcoded values. I do know you are doing your vertical collision checks wrong. You are checking if the center of the image is at the top of the canvas, 0, or the bottom of the canvas, height. This means that your image will already have moved out of the screen halfway.
If you want to treat the image coordinates as the center of your image, you need to check the left edge of the image at x - imageWidth / 2, the right edge at X+ imageWidth / 2, the top edge at y - imageWidth / 2 (remember the y coordinates are 0 at the top of the canvas and increase towards the bottom) and the bottom at y - imageWidth / 2. Here's a great website which goes into more detail on 2d collision detection, i'd highly recommend you give it a read. It's an awesome website.
I started programming this pong game for CS class. I want to have the ball starting off in the center of the field so I used:
ellipse (width/2, height/2, 15, 15);
I want to make the game start once I press the space key. In order to do that I used:
if (keyPressed == true) {ellipse (ballX, ballY, 15, 15); fill (0, 255, 0);}
However it does not work. Can someone please help me figure out what is wrong with my code? Please consider that this is not a JavaScript but a Processing question.
Here is my entire code so far:
float ballX = 15, ballY = 15, dX = 15, dY = 15; // variables for the ball
float paddleX; // variables for the paddles
int mouseY; // variable to make the pong move with the mouse movement
boolean key, keyPressed;
void setup() {
size (1500,1100); // the field is going to be 1500x110px big
paddleX = width - 40;
ballX = 15; ballY = 15;
}
void draw() {
background(0); // black background
ellipse (width/2, height/2, 15, 15); // this is the starting point of the ball
if (keyPressed == true) { ellipse (ballX, ballY, 15, 15); fill (0, 255, 0); } // the game will only start when a key is pressed
if (ballX > width || ballX < 0) { dX = -dX; } // if the ball reaches the right or left wall it will switch directions
if (ballY > height || ballY < 0) { dY = -dY; }// if the ball reaches the upper or lower wall it will switch directions
ballX = ballX + dX; ballY = ballY + dY; // the ball with move with the speed set as dX and dY
rect(paddleX/58, mouseY, 20, 100); fill (255,10,20); // green pong
rect(paddleX, mouseY, 20, 100); fill (60,255,0); // red pong
}
The answer to this question is the same as the answer to your other question: you need to store the state of your sketch in variables, then you need to draw each frame based on that state, and finally you need to change those variables to change the state of your game.
Here's a simple example that only draws an ellipse after you press a key:
boolean playing = false;
void keyPressed() {
playing = true;
}
void draw() {
background(0);
if (playing) {
ellipse(width/2, height/2, 50, 50);
}
}
In this example, the playing variable is my state. I then update that state in the keyPressed() function, and I use that state to determine what I draw in my draw() function. You'll have to extrapolate a bit, but this process of breaking your problem down into a state, changing that state, and drawing that state is the answer to all of your questions.
I want to achieve a slow fade in size on every collapse into itself. In other words, when the circle is at its biggest, the ellipses will be at the largest in size and conversely the opposite for the retraction. So far I am trying to achieve this affect by remapping the cSize from the distance of the center point, but somewhere along the way something is going wrong. At the moment I am getting a slow transition from small to large in ellipse size, but the inner ellipses are noticeably larger. I want an equal distribution of size amongst all ellipses in relation to center point distance.
I've simplified the code down to 4 ellipses rather than an array of rows of ellipses in order to hopefully simplify this example. This is done in the for (int x = -50; x <= 50; x+=100).
I've seen one or two examples that slightly does what I want, but is more or less static. This example is kind of similar because the ellipse size gets smaller or larger in relation to the mouse position
Distance2D
Here is an additional diagram of the grid of ellipses I am trying to create, In addition, I am trying to scale that "square grid" of ellipses by a center point.
Multiple ellipses + Scale by center
Any pointers?
float cSize;
float shrinkOrGrow;
void setup() {
size(640, 640);
noStroke();
smooth();
fill(255);
}
void draw() {
background(#202020);
translate(width/2, height/2);
if (cSize > 10) {
shrinkOrGrow = 0;
} else if (cSize < 1 ) {
shrinkOrGrow = 1;
}
if (shrinkOrGrow == 1) {
cSize += .1;
} else if (shrinkOrGrow == 0) {
cSize -= .1;
}
for (int x = -50; x <= 50; x+=100) {
for (int y = -50; y <= 50; y+=100) {
float d = dist(x, y, 0, 0);
float fromCenter = map(cSize, 0, d, 1, 10);
pushMatrix();
translate(x, y);
rotate(radians(d + frameCount));
ellipse(x, y, fromCenter, fromCenter);
popMatrix();
}
}
}
The values you're passing into the map() function don't make a lot of sense to me:
float fromCenter = map(cSize, 0, d, 1, 100);
The cSize variable bounces from 1 to 10 independent of anything else. The d variable is the distance of each ellipse to the center of the circle, but that's going to be static for each one since you're using the rotate() function to "move" the circle, which never actually moves. That's based only on the frameCount variable, which you never use to calculate the size of your ellipses.
In other words, the position of the ellipses and their size are completely unrelated in your code.
You need to refactor your code so that the size is based on the distance. I see two main options for doing this:
Option 1: Right now you're moving the circles on screen using the translate() and rotate() functions. You could think of this as the camera moving, not the ellipses moving. So if you want to base the size of the ellipse on its distance from some point, you have to get the distance of the transformed point, not the original point.
Luckily, Processing gives you the screenX() and screenY() functions for figuring out where a point will be after you transform it.
Here's an example of how you might use it:
for (int x = -50; x <= 50; x+=100) {
for (int y = -50; y <= 50; y+=100) {
pushMatrix();
//transform the point
//in other words, move the camera
translate(x, y);
rotate(radians(frameCount));
//get the position of the transformed point on the screen
float screenX = screenX(x, y);
float screenY = screenY(x, y);
//get the distance of that position from the center
float distanceFromCenter = dist(screenX, screenY, width/2, height/2);
//use that distance to create a diameter
float diameter = 141 - distanceFromCenter;
//draw the ellipse using that diameter
ellipse(x, y, diameter, diameter);
popMatrix();
}
}
Option 2: Stop using translate() and rotate(), and use the positions of the ellipses directly.
You might create a class that encapsulates everything you need to move and draw an ellipse. Then just create instances of that class and iterate over them. You'd need some basic trig to figure out the positions, but you could then use them directly.
Here's a little example of doing it that way:
ArrayList<RotatingEllipse> ellipses = new ArrayList<RotatingEllipse>();
void setup() {
size(500, 500);
ellipses.add(new RotatingEllipse(width*.25, height*.25));
ellipses.add(new RotatingEllipse(width*.75, height*.25));
ellipses.add(new RotatingEllipse(width*.75, height*.75));
ellipses.add(new RotatingEllipse(width*.25, height*.75));
}
void draw() {
background(0);
for (RotatingEllipse e : ellipses) {
e.stepAndDraw();
}
}
void mouseClicked() {
ellipses.add(new RotatingEllipse(mouseX, mouseY));
}
void mouseDragged() {
ellipses.add(new RotatingEllipse(mouseX, mouseY));
}
class RotatingEllipse {
float rotateAroundX;
float rotateAroundY;
float distanceFromRotatingPoint;
float angle;
public RotatingEllipse(float startX, float startY) {
rotateAroundX = (width/2 + startX)/2;
rotateAroundY = (height/2 + startY)/2;
distanceFromRotatingPoint = dist(startX, startY, rotateAroundX, rotateAroundY);
angle = atan2(startY-height/2, startX-width/2);
}
public void stepAndDraw() {
angle += PI/64;
float x = rotateAroundX + cos(angle)*distanceFromRotatingPoint;
float y = rotateAroundY + sin(angle)*distanceFromRotatingPoint;
float distance = dist(x, y, width/2, height/2);
float diameter = 50*(500-distance)/500;
ellipse(x, y, diameter, diameter);
}
}
Try clicking or dragging in this example. User interaction makes more sense to me using this approach, but which option you choose really depends on what fits inside your head the best.
How can I make the mouse move like a joystick. Here is a example of what I mean except this only moves to the right and when the mouse is all the way to the right it stops. I want the circle to stop if the mouse is at the center and move where ever the mouse is.
float ballX = 0; // need to keep track of the ball's current position
float ballY = 150;
void setup() {
size(300,300); // standard size
}
void draw() {
background(200); // dull background
float speed = 2.0 * ( mouseX / (width*1.0) );
println("speed is " + speed); // print just to check
ballX = ballX + speed; // adjust position for current movement
fill(255,0,0);
ellipse(ballX, ballY, 20,20);
}
You want to check the mouseX position against the center of the window, which is width/2.
To find the relative position of the mouse, simply subtract that center position from your mouse position. That way when the mouse is to the left of the center, that value is negative, and your ball will move to the left.
You might also want to keep your ball on the screen.
float ballX = 0; // need to keep track of the ball's current position
float ballY = 150;
void setup() {
size(300,300); // standard size
}
void draw() {
float centerX = width/2;
float maxDeltaMouseX = width/2;
float deltaMouseX = mouseX-centerX;
float speedX = deltaMouseX/maxDeltaMouseX;
background(200); // dull background
println("speed is " + speedX); // print just to check
ballX = ballX + speedX; // adjust position for current movement
//keep ball on screen
if(ballX < 0){
ballX = 0;
}
else if(ballX > width){
ballX = width;
}
fill(255,0,0);
ellipse(ballX, ballY, 20,20);
}
So, I am creating the game breakout in processing (programming language) but can't quite figure out a function to check for collision against the bat.
So far the section I have written for collision against the bat only collides the ball against the base and returns it in the opposite direction. For now, the game is a never ending phenomenon where the ball just collides with the walls. What I am trying to do is, collide the ball against the bat.
Oh this is my homework, so just please point me in the right direction instead of doing it for me.
Here's the code:
// Basic Breakout game
// Code from Matthre Yee-King
// brick position
float brickX;
float brickY;
// brick width and height
float brickH;
float brickW;
// ball position
float ballX;
float ballY;
// ball diameter
float ballD;
// ball direction
float ballDx;
float ballDy;
// bat position
float batX;
//bat width
float batW;
float batH;
//bat colour
float batB;
void setup() {
size (500, 500, P2D);
// set sizes of game items
brickW = 100;
brickH = 50;
batW = 100;
batH = 25;
ballD = 25;
batB = 255;
// random brick position
brickX = random(0, width - brickW);
brickY = random (0, height / 2);
// bat in the centre
batX = (width/2) - (batW/2);
// ball atop bat
ballX = batX + (batW/2);
ballY = height - batH - (ballD/2);
// ball movement
ballDx = random(-5, 5);
ballDy = -5;
rectMode(CORNER);
ellipseMode(CENTER);
}
void draw() {
// check for ball collision
// with top or sides of bat
checkBallAgainstBat();
// check for ball collision with
// left right and top walls
// and bounce
checkBallAgainstWalls();
// check ball against brick
checkBallAgainstBrick();
// move the ball
ballX += ballDx;
ballY += ballDy;
background(0);
// draw the bat
fill(0, 255, 0);
rect(batX, height - batH, batW, batH);
// draw the brick
fill(0, 0, batB);
batB = (batB + 10) % 255;
rect(brickX, brickY, brickW, brickH);
// draw the ball
fill(255, 0, 0);
ellipse(ballX, ballY, ballD, ballD);
if (keyCode == 37) { // left cursor key
batX -= 10;
// keep it on the screen
if (batX < 0) {
batX = 0;
}
}
if (keyCode == 39) {
batX += 10;
if (batX > (width - batW)) {
batX = width - batW;
}
}
}
// when they let go of the key, reset the keyCode
void keyReleased() {
keyCode = -1;
}
// this function checks if the ball has hit the top or sides of the bat and
// updates its direction as appropriate so the ball bouncs off the bat
void checkBallAgainstBat() {
if (ballY + ballD > height - batH) {
ballDy *= -1;
}
}
// this function checks if the ball has hit the brick. It should bounce off
// the brick and return true if so
boolean checkBallAgainstBrick() {
return false;
}
// this function checks if the ball has hit the top, left or right
// walls and update its
// direction as appropriate so the ball bounces off the walls
void checkBallAgainstWalls() {
if (ballX + ballD > width) {
ballDx *= -1;
}
if (ballX - ballD < 0) {
ballDx *= -1;
}
if (ballY - ballD < 0) {
ballDy *= -1;
}
}
Since the bat in breakout is a fixed width, your collision detection can be quite simple (in pseudo-code):
if (lower_edge(ball) > top_edge(bat)) {
// the ball has entered territory where it might have collided
if ((left_edge(ball) <= right_edge(bat)) && (right_edge(ball) >= left_edge(bat))) {
// the ball's within the horizontal bounds of the bat, so it's a "hit"
... calculate deflection ...
} else {
// oops, ball's gone past the bat and wasn't hit
strike_out();
} else {
// ball's still above the bat somewhere. do nothing
}
In english: If the ball's lower edge has gone past where the top edge of the bat is, we've POSSIBLY got a collision. This is only checking the vertical axis of the play field. You then check if the left or right edges of the ball fall within the horizontal location of the bat. If neither side of the ball overlaps the bat, then you've lost. Otherwise you've collided and you do the collision detection.