I was working on an animation on processing. Then, I have a question about the lights. Normally, my code is more long. However, I made a simple code which can usefull also for the beginners.
void setup()
{
size(400, 400, P3D);
noStroke();
}
void draw()
{
background(0);
if (mousePressed) { // lights should work if the mouse pressed on the sphere
lights(); // It should continue till press again on the sphere
} // If the mouse pressed again on the sphere, lights should close
translate(200,200,0); // translate the sphere to the middle of window
sphere(100); // making a sphere for see ligts
}
So, as you can see on the comments. If the mouse pressed on the sphere the lights should work and it should keep working till the mousepressed again on the sphere. Then, if mouse pressed on the sphere it should close the lights.It should keep working again and again. If you know how to make it. You are welcome. Thanks.
You need to have a variable that keeps the state of the light and switch it on if it's off or switch it off if it's on.
After doing that, using mousePressed in the if statement might create some problems since if the click is not quick enough (maybe you press for a bit too long) it will turn on and then off the light so it will look like it was never turned on.
To avoid that I suggest using mouseReleased() function.
Heres the final code:
boolean isOn = false; // variable keeping the state of the light
void setup()
{
size(400, 400, P3D);
noStroke();
}
void draw()
{
background(0);
if (isOn) // checks the state in which the light should be
lights();
translate(200,200,0); // translate the sphere to the middle of window
sphere(100); // making a sphere for see ligts
}
void mouseReleased() { // this function is automatically called in draw method
if (isOn) //after a click the state of the light is inverted
isOn = false;
else isOn = true;
}
Anyway if for some reason you needed to use specifically mousePressed function her's some code also working:
void draw()
{
background(0);
if (mousePressed) { // lights should work if the mouse pressed on the sphere
if (isOn)
isOn = false;
else isOn = true;
delay(200); // delay added to minimize the problem explained above
} // If the mouse pressed again on the sphere, lights should close
if (isOn)
lights();
translate(200,200,0); // translate the sphere to the middle of window
sphere(100); // making a sphere for see ligts
}
Related
i have created a rectangle
public Rectangle rectangle_hitbox;
It has the coordinates and dimensions of the enemies. In the render method, I want that when this rectangle is pressed, the string "Done" is printed. I tried with:
if(Gdx.input.isTouched()){
System.out.println("Done");
} else {
System.out.println("Missed");
}
But it works anywhere on the map and not only in rectangles
The Gdx.input.isTouched() method doesn't know about the position of your rectagle. It just check whether the screen is touched or not.
Try using Gdx.input.getX() and Gdx.input.getY() to get the coordinates of the click or touch event when the screen is touched and check these coordinates against the coordinates of your rectangle.
Also don't forget to unproject the coordinates if you are using a camera. See this answer for more information.
if(Gdx.input.isTouched()){
Vector3 touchPosition = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0f);
// TODO maybe unproject the position using camera.unproject(touchPosition);
if (isTouchInsideRectangle(touchPosition)) {
System.out.println("Done");
}
else {
System.out.println("Missed");
}
}
When I click screen, the Stop screen flashes on and then it goes back to the Walk screen. How do I get it to stay on the Stop screen until I click my mouse again?
boolean walk;
String textStop;
String textWalk;
float x; //positions
float y; //positions
void setup() {
size (400,500);
stop = false;
textStop = "STOP!";
textWalk = "WALK!";
}
void draw() {
background(0,255,0);
text(textWalk, x , y);
x = 150;
y = 250;
textSize(40);
}
void mousePressed() {
if (stop);{
background(255,0,0);
text(textStop, x , y);
}
} ```
Whenever you call background() you're clearing the screen.
Because this happens in draw() every frame is cleared and redrawn with textWalk (and textStop) only gets displayed when you click (for the short duration of the mousePressed() event).
You could use the walk variable for that. I see you use stop though it's not declared. They seem to be the opposite of each other in context so why not simpify and use just one. Sure you can code this if/else to toggle the value or you can simply use the !(logical not) operator:
void mousePressed() {
walk = !walk;
}
when walk is true render textWalk
otherwise (else) render textStop
something like:
if(walk){
text(textWalk, x , y);
}else{
text(textStop, x , y);
}
Here's a modified version of your code using the notes above:
boolean walk = true;
String textStop = "STOP!";
String textWalk = "WALK!";
float x = 150; //positions
float y = 250; //positions
void setup() {
size (400,500);
textSize(40);
}
void draw() {
if(walk){
background(0,255,0);
text(textWalk, x , y);
}else{
background(255,0,0);
text(textStop, x , y);
}
}
void mousePressed() {
walk = !walk;
}
(Notice I've moved a few lines: in general it's a good idea to initialise values that don't change once at the start of your program rather than continuously. In this basic example it doesn't really affect performance, but for more complex programs it's a good idea to keep track of what changes and what doesn't.
Also, it might help with other programs in the future to have a bit of separation between data that changes on events (e.g. walk on mouse pressed) and how that data gets rendered (e.g. using walk to render in draw())
I am making a simple game with JavaFX, where a ball bounces around the screen after being released from the bottom (via a button). When the ball is bouncing around the pane, if it hits a Rectangle it changes its color to blue.
I am attempting to add a method called checkBounds to keep track of when the ball (a Circle) hits the Rectangle. As soon as the ball comes into contact with the rectangle, the score should increase by 10. The scoring mechanism works, but it continues to increment with each frame that the ball takes through the Rectangle, instead of only incrementing once when it enters. (eg. It should only go up by 10 one time, not continue going up by 10 the whole time the ball passes through). I callcheckBounds() 3 times in my timeline loop to check each rectangle on each loop iteration.
checkBounds(ball, gameSquare);
checkBounds(ball, gameSquare2);
checkBounds(ball, gameSquare3);
How would I fix this logic error? I've attempted several different options, but none seem to work.
private void checkBounds(Shape block, Rectangle rect) {
boolean collisionDetected = false;
Shape intersect = Shape.intersect(block, rect);
if (intersect.getBoundsInLocal().getWidth() != -1) {
collisionDetected = true;
}
if (collisionDetected) {
score.setText(Integer.toString(currentScore.getCurrentValue()));
currentScore.incrementBy(10);
rect.setFill(Color.BLUE);
}
}
I believe what you want to detect is the state change of your collisionDetected from false to true. One way to do this is to keep the state of the previous value as a member variable for each collision object. To do this, we need some identifying id for the rectangle, so you may want to pass in the id into the checkBounds method:
private void checkBounds(Shape block, Rectangle rect, int id) {
we also need to create a member variable to store the states:
private HashMap<Integer,Boolean> previousCollisionStateMap = new HashMap<>();
and then inside your checkBounds code, you can modify the condition to check for changes
Boolean prevState = previousCollisionStateMap.get(id);
if (prevState == null) { // this is just to initialize value
prevState = false;
previousCollisionStateMap.put(id,false);
}
if (!prevState && collisionDetected) {
score.setText(Integer.toString(currentScore.getCurrentValue()));
currentScore.incrementBy(10);
rect.setFill(Color.BLUE);
}
and don't forget to update the state at the end
previousCollisionStateMap.put(id,collisionDetected);
Right now I'm trying to code a simple abacus with JavaFX. There are balls on horizontal rails arranged in a gridpane, and I'm using a translateTransition to move them to the right on click. The following is the code I have right now, which works fine on any of the balls in the grid except it only animates the movement to the right. On the second click, the ball jumps back to the left to its original position without the animation and I can't figure out why it's not animating. Any help or ideas would be greatly appreciated!
private void onClick(final Circle circle) {
circle.setOnMouseClicked(new EventHandler<MouseEvent>() {
public void handle(MouseEvent mouseEvent) {
//set movement direction, check if circle has been moved
int targetX = 200;
if (circle.getTranslateX() > 1) {
targetX = 0;
}
//animation trigger and details
TranslateTransition push = new TranslateTransition(Duration.millis(500));
push.setNode(circle);
push.setFromX(circle.getCenterX());
push.setToX(targetX);
push.play();
}
});
}
I'm writing a tank game . I want to have a method called shoot that when I press Space the tank have to shoot . my problem is that when the program calls this method it goes through the while loop and after that it prints the end location of the ball . I need to implement something in the while loop that every time it calculates dx and dy it goes to the paint method and paint the new location of the ball. I tried adding paintImmediately() but it throws stackoverflow error. thanks for helping me.
actually I'm changing dx and dy and I want the paint method to draw the ball at that place...
public void shoot(Image img, double fromx, double fromy, double ydestination, int speed) {
int time = 0;
double speedy, speedx;
while (dy!=ydestination) {
time++;
speedy = speed * Math.sin(Math.toRadians(angle));
speedx = speed * Math.cos(Math.toRadians(angle));
dy = (int) ((-5) * time * time + speedy * time + fromy);
dx = (int) (speedx * time + fromx);
// paintImmediately((int)dx,(int) dy, 10, 10);
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
and here is my overrided paint method the last line is for the bullet that is my question :
#Override
public void paint(Graphics g) {
System.out.println("paint");
super.paint(g);
render(bufferedGraphics);
g.drawImage(bufferedScreen, 0, 0, null);
// System.out.println(x1);
BufferedImage buff = rotateImage(mile1, angle);
BufferedImage buf = rotateImage(mile2, angle);
g.drawImage(buff, mx1 - 40, my1, null);
g.drawImage(buf, mx2 , my2, null);
g.drawImage(bullet, (int) dx, (int) dy, null);
//setVisible(true);
}
You are using the wrong approach. You are tying 3 events together: user input (click to shoot), game state update (bullet moves) and draw refresh rate (paint).
In general trying to make these work at the same speed is a nightmare and you'll never achieve it. The most common, easy and robust approach is to have an event loop. User input events trigger changes to the game state, the game state is updated periodically either by turns or by some elapsed time (and state update will depend on how much time has elapsed), the state is drawn every time it is needed, which is periodically but also for some other events like minimizing the windows, etc etc...
For Java, you can find a good library for this here. With a sample hello world that shows the different parts here.
P.S: Also, be very careful when manually sending threads to sleep. That might make your entire program unresponsive.
If your drawing code has sleep() in it to introduce waits, you are doing things very wrong indeed. You are trying to sleep there because you want the screen to keep on updating with new positions... but you are actually making the screen freeze completely, because there is only 1 thread drawing things in Java Swing; and if you sleep that thread, nothing gets drawn (and you can't even press keys or use the mouse).
What you should do instead is to update the position of your bullet over several calls to your paint() method. In pseudocode:
paint(Graphics g) {
// calls paint() on all objects in the game world
}
// you should call this once per frame
update(World w) {
// call update() on each game-world object
}
// in Tank
fire(Tank t, Point target) {
// creates a bullet at the tanks' position, and adds it to the World
}
// within Bullet
update() {
// moves this bullet along its path to its target;
// if target reached, add an explosion there and destroy the bullet
}
// within Explosion
update() {
// advance to next explosion frame;
// or if finished, destroy the explosion object
}
You can read more on game event loops here and here.