Processing: How to make Sphere that rotates when mouseClicked? - java

In my program, I want a sphere to represent a globe. I want the user to press down the mouse1 button and rotate the sphere. When the user is not pressing the mouse1 down, the sphere should just be staying still regardless of how the mouse is moving. In simple terms, I want a sphere to rotate only when the mouse is pressed. Here is my code for the sphere rotating.
float lockXRotation;
float lockYRotation;
void setup() {
size(1000,700,P3D); //reference
}
void draw() {
mouseAction();
fill(200, 0, 160);
if(mousePressed == false){
rotateX(lockXRotation);
rotateY(lockYRotation);
}
sphere(100);
}
void mouseAction () {
translate(500, 350, 0); //reference starts here'
if(mousePressed){
rotateX(mouseY * -0.01);
rotateY(mouseX * -0.01); //ends here
lockXRotation = 0;//what should i put so it will stay still?
lockYRotation = 0;
}
}
I have tried mouseX * -0.01 for lockXRotation but it offsets by the distance of the x to the origin. Is there a function to find the rotation an object is in?

Okay, so you want the sphere's location to lock when the user presses the mouse.
I took a look at your code and ran it on Processing, I believe that your lockXRotation is not doing what it is suppose to.
If you look at lines 12 - 15, where it says if (mousePressed == false), then it should rotateX(lockXRotation), those lines don't belong in the draw function, but if you put them in the mouseAction function, that might solve the problem.

Related

How to zoom into mouse position with correct translation

I'm trying to zoom a grid in Processing and I am having trouble with applying the correct translation such that zooming is centered around the mouse position. I have searched the web for a while but nothing I try seems to work.
The screen size is width and height and the mouse position is mouseX and mouseY.
The code I have at the moment is below, but it zooms the grid (controlled by player.zoom) from the top left corner which is not what I want. To update the translation of the grid, player has the 2d vector player.translate.
void mouseWheel(MouseEvent event) {
float zoomFactor = 200.0f;
float scroll = event.getCount();
player.zoom -= scroll * player.zoom / zoomFactor;
// player.translate.x += something;
// player.translate.y += something;
}
If you need more details to answer I can link the repo with the source code.
I have created a very simple mock-up for you which will hopefully point you in the right direction into applying this to your player.
So this little demo shows the zooming in to the centre of an ellipse whilst keeping it as the central focus.
float scale = 1;
// displacement left/right
float xPan = 720;
// displacement up/down
float yPan = 450;
boolean zoomIn = true;
void setup() {
size(1440, 900);
}
void draw() {
// allows us to zoom into the center of the screen rather than the corner
translate(width/2, height/2);
scale(scale);
translate(-xPan, -yPan);
background(200);
// draws the ellipse in the center
ellipse(width/2, height/2, 100, 100);
// does the zooming
if (zoomIn) {
scale *= 1.01;
}
}
I suggest you to copy this into a new project and then comment out specific lines to try to understand what's going on and how you can transfer this over to your own project.
The same principles still apply, I didn't do this with mouse input in the effort of making the program as simple as possible.

(Processing)How to move a 3D object according to the screen's XY axis, instead of the world's X,Y,Z(PeasyCam)

Im writing a 3D sketch in which the user rotates the camera with peasyCam while left clicking and moving the mouse. The thing is that I want to move the objects while right click is pressed so that the user can drag the object across the screen's X and Y axis. Of course I know how to use mouseX and mouseY inputs to modify the translation but only across the 3D space coordinates as it shows on the GIF below:
example code of whats happening in the image:
import peasy.*;
import peasy.org.apache.commons.math.*;
import peasy.org.apache.commons.math.geometry.*;
PeasyCam cam;
float x=15;float y=15; float z=15;
float e;
void setup(){
size (700,700,P3D);
cam = new PeasyCam(this, 200);
cam.setRightDragHandler(null);
}
void draw(){
background(0);
pushMatrix();
translate(5, 5, 0);
fill(255);
stroke(255);
sphere(5);
popMatrix();
pushMatrix();
fill(255,0,0);
stroke(255,0,0);
translate(x, y, z);
sphere(5);
popMatrix();
stroke(0,0,255);
line(5,5,0,x,y,z);
//obvoiusly not working method
if(mousePressed && (mouseButton == RIGHT)){
x= x+(mouseX-pmouseX);
y= y+(mouseY-pmouseY);
}
}
void mouseWheel(MouseEvent event) {
e = event.getCount();
z=z+e;
println(e);
}
void mousePressed(){
if (mouseButton==RIGHT){
cam.setActive(false);
}
}
void mouseReleased(){
cam.setActive(true);
}
What I would need is to be able to drag the sphere only on the screens X/Y axis, at a fixed Z just like image below shows(simple simulation I made of the behaviour im looking for).
PeasyCam is for exploring the 3D space. The question might be difficult to undesrtand. The problem is about moving the object on the 3D world, using the screen/canvas 2D coordinates to make the object follow the cursor's movement. If the mouse goes to the left (x axis decreases), the object should move to the left on the screen, and not just on the worlds X axis. This is how the second example image behaves, but achieved by just simulating the 3D space with no actual rotations to the x,y,z axis.
I've been scratching my head with this thing and I cant seem to figure it out. I wouldn't have asked here otherwise. Thanks in advance guys.
PeasyCam is a library that gives you a camera that by default is controlled by the mouse. This allows you to render 3D scenes and not worry about the camera, since the library handles it for you.
But it sounds like that's not what you want. You want to render a 3D scene and use the mouse to control the position of the shapes in that scene. Basically, your controls are fighting with the default controls provided by the PeasyCam library.
I see that you've already tried disabling the right-click controls here:
cam.setRightDragHandler(null);
So at the very least you probably want to do the same thing with the left drag handler.
But at that point, why are you using the PeasyCam library at all?
And even if you disable the default left controls, you'll notice that the dragging of shapes is "exaggerated" because the camera is closer to the red shape, so moving it a little bit looks like it's moving more. Just like an object right in front of your face looks like it's moving a lot more than an object that's far away.
It sounds like what you really want to do is get rid of the PeasyCam library, and then use standard Processing functions to calculate the position of the spheres based on the user input. Check out the modelX(), modelY(), and modelZ() function in the reference.
Edit: Here is a simple example that shows the model functions in action:
float x;
float y;
void setup() {
size (700, 700, P3D);
}
void draw() {
background(0);
pushMatrix();
translate(width/2, height/2, 0);
fill(255);
stroke(255);
sphere(5);
popMatrix();
fill(255, 0, 0);
stroke(255, 0, 0);
if (mousePressed) {
x= modelX(mouseX, mouseY, 0);
y= modelY(mouseX, mouseY, 0);
}
translate(x, y, 15);
sphere(5);
}
May be you should be looking in beginHUD() and endHUD();
Here is the example code:
(Code from https://forum.processing.org/one/topic/2-questions-on-camera-view.html)
import peasy.*;
PeasyCam cam;
void setup() {
size(300,200,P3D);
// either put it here like this:
// cam = new PeasyCam(this, 50, 0, 0, 100);
cam = new PeasyCam(this, 0, 0, 0, 100);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);
// or separate like this:
cam.lookAt(50,0,0);
}
void draw() {
background(0);
//3D object
pushMatrix();
fill(255,0,0);
translate(50,0,0);
rotateX(-.5);
rotateY(-.5);
box(30);
popMatrix();
//2D object that is not affected by the camera
cam.beginHUD();
fill(0,0,255);
rect(200, height/2 -25 , 50, 50);
cam.endHUD();
}

scrolling never-ending background in Game not working as expected

I am working on my first side-scroller game and am trying to achieve a neverending background effect and it's nearly working as i would expect but there are little glitches.
I have 2 instances of the background (each fills the screen width), with one placed at the bottom left corner of the screen and one off the screen to the right. I am then moving my camera each frame to the right and when the first background instance is completely offscreen to the left i reset its X to the right of the camera so that it is now (relative to the camera) off the right of the screen. this is working a lot of the time, but every now and again it seems the method to reset its x position is getting called a few frames late and results in a gap in the background.
the update code i am using in the main game is -
private void update(float delta){
//update camera and world
camera.position.set(camera.position.x+scrollSpeed, camera.position.y, 0);
camera.update();
world.step(step, velocityIterations, positionIterations);
if(gameInProgress){
//backgrounds (array holds the 2 instances of the background)
for(int i=0; i< bgFillArray.size; i++){
bgFillArray.get(i).update();
}
}
stage.act(delta);
tweenManager.update(delta);
}
the update method in the BgFill class -
public void update(){
float currentXPos = getX();
float leftBoundary = camera.position.x-1200;
float rightOfScreen = camera.position.x+400;
if(active){
//check to see if the camera has gone past this instance. if so then move to right
if(currentXPos <= leftBoundary){
setX(rightOfScreen);
}
}
}
Firstly, is this the usual way (or even close) to do a continuous scrolling background?
if it is, what am I doing wrong?

Java Brickbreaker paddle collision detection

I am trying to make a brickbreaker game and I have run into some issues when it comes to collision detection. If you have ever played brick breaker you know that on the paddle, if the ball is moving to the left and you hit the left side of the top, then it continues moving right. Although, if you hit it on the right side in this case, then the ball changes directions. And also if you hit it on the sides of the paddle, it bounces off on the Y axis. Since I have no idea how to do the top part of the paddle, I can't show you the code because I don't have any :) This is the code that I am using for the sides:
Rectangle rect1 = new Rectangle((int) paddleDir, 570, imsLoader.getImage("paddle1").getWidth(), imsLoader.getImage("paddle1").getHeight());
Rectangle rect2 = new Rectangle((int) ballX, (int) ballY, imsLoader.getImage("ball").getWidth(), imsLoader.getImage("ball").getHeight());
if (rect1.intersects(rect2))
{
if (rect1.x == rect2.getMaxX() || rect1.getMaxX() == rect2.x)
{
ballVX = -ballVX;
clipsLoader.play("pattleHit", false);
}
else
{
ballVY = -ballVY;
ballY += 0.05;
clipsLoader.play("pattleHit", false);
}
}
What happens is that the ball when gets hit on the side, just goes right through the paddle going all over the place and when it reaches the other end either goes up or down!
You have to make the ball bounce, right?
Let's look at an example. Think the top square as the ball (I can't draw that nice). When the ball collides from left, it should move right and if it's from right, then go left.
You can achieve this with a simple thing. Don't change the horizontal velocity but instead reverse the vertical one.
if (ball.getBounds().intersects(paddle.getBounds()))
{
ball.setVy(-ball.getVy());
}
Easy right!
Now let's figure out how to do bounce effect on bricks.
This is a scenario when ball hits the brick. The red area is the intersection. Now notice it carefully.
If the intersection width is greater than the intersection height, the ball has hit in the bottom or vertical sides of the brick.
If the intersection height is greater that the intersection width, then it is a horizontal collision.
So we have to first calculate the intersection rectangle. It's so easy with java.
Rectangle intersection = ball.getBounds().intersection(brick.getBounds());
Now let's implement the bouncing.
if (intersection.width >= intersection.height)
{
ball.setVy(-ball.getVy());
}
if (intersection.height >= intersection.width)
{
ball.setVx(-ball.getVx());
}
That's it and you should have it fully functional.

Creating "stick controls" for android game?

I'm trying to create a simple Android game, a 2D action shooter which has 2 control sticks (circles) on the screen, the left one is movement control and the right one weapon control. Direction is being controlled by the position of your thumb relative to the circle’s center.
I've been following a tutorial on this site: http://www.kilobolt.com/day-7-creating-an-android-game-from-start-to-finish.html but it only gave me the base to work on. I have no programming experience so I'm quite lost now.
I got the movement working only on TOUCH_DOWN event, the hero moves to about where it should but to change direction I have to lift my thumb and touch the circle again. TOUCH_DRAGGED (or ACTION_MOVE) is broken because if I drag my finger across the circle the character moves really fast. I guess the problem is too many touch events are being handled, but I have no idea how to fix it.
How can I change this so that I can drag my thumb around the circle and the hero will change its direction instantly, and keep its speed constant all the time? Also the speed should be the same no matter how close or far from the center of the circle you touch.
private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_DOWN || event.type == TouchEvent.TOUCH_DRAGGED) {
if (inBounds(event, 50, 300, 150, 150, 'c')) {
ctrl.setX(event.x);
ctrl.setY(event.y);
ctrl.direction();
hero.move(ctrl.getDirX(), ctrl.getDirY());
}
}
if (event.type == TouchEvent.TOUCH_UP) {
if (inBounds(event, 0, 0, 35, 35,'r')) {
pause();
}
hero.stopMove();
}
}
hero.update();
The movement: hero's speedX and speedY are added to hero's centerX and centerY on every hero.update() call.
public void move(float x, float y) {
speedX += x * MOVESPEED;
speedY += y * MOVESPEED;
}
This method that handles the x & y speed. Found it here at stackoverflow, and because touch_down event is working ok, I guess it's doing it's job. Although I feel it's not exactly how it's supposed to be. L_STICK_C is a constant with values of 100 and 350 (center of the circle).
public void direction() {
dir.x = x - L_STICK_C.x;
dir.y = y - L_STICK_C.y;
double hyp = Math.sqrt(dir.x * dir.x + dir.y * dir.y);
dir.x = (float) (dir.x / hyp);
dir.y = (float) (dir.y / hyp);
}
I suggest you look into some game programming tutorials. You usually would not move the character directly from the touch input. You'd set a game state variable once a game loop which would correspond to the position of your thumb inputs. Then you'd only update the hero once per game loop based on those inputs. This lets allows you to keep the game input control code, and hero code separate, and makes it re-usable for other parts of your game.
EDIT:
Based on your code, every time you drag your finger, you generate a bunch of dragged events. So you are adding onto your characters speed for each event. You should probably just be looking at the distance to center and x / y of the input on the last touch event, not all of them.

Categories