I am coding a Java game that uses mouse actions. I have a point msc in my main class - it gets changed whenever I press the mouse and gets set to (0, 0) whenever I release the mouse. For the buttons, they check if msc is inside their rectangle, and if so, call click.
One of the buttons is supposed to toggle a boolean; when I click on it though, it switches true and false very fast because msc gets updated every time paintComponent is called.
Here is the code for the button click method:
if (button.contains(Screen.msc)) {
beenClicked = true;
this.width = this.width - 2;
this.height = this.height - 2;
this.x = this.x + 1;
this.y = this.y + 1;
g.setColor(currColor);
textColor = Color.YELLOW;
}
but that is not where the problem is I think. Here is the code that changes msc:
public void mouseReleased(MouseEvent e) {
Screen.msc = new Point(0, 0);
}
public void mousePressed(MouseEvent e) {
Screen.msc = new Point((e.getX()) - ((Frame.size.width - Screen.myWidth) / 2), e.getY() - ((Frame.size.height - (Screen.myHeight)) - (Frame.size.width - Screen.myWidth) / 2));
}
and the code for what happens when the specific toggle button is clicked:
if (toggleToolTips.clicked()) {
if (Screen.canDrawTooltip) {
Screen.canDrawTooltip = false;
} else if(!Screen.canDrawTooltip){
Screen.canDrawTooltip = true;
}
}
The problem is every time I go and click the button, the boolean switches back and forth real fast. When I hold it, it just rapidly and continually switches. I would like to make it so that I click once and it switches once.
Your setting the boolean beenClicked but are not checking it anywhere. I would suggest trying
if (!beenClicked && toggleToolTips.clicked())
{
Screen.canDrawTooltip = !Screen.canDrawTooltip);
}
And setting beenClicked back to false somewhere such as mouseReleased.
Related
I have a program that tracks the mouse with MouseEvent.MOVED in javafx and whenever i press and hold the mouse button the tracking stops.
I have tried to switch events from addEventFilter to addEventHandler. Adding another Event, MouseEvent.DRAGED. But it wont even register an event until i disable the code from MouseEvent.Moved. I have tried to combine these but nothing seems to work. Help is very much appreciated.
EventHandler<MouseEvent> tracking = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e){
double x = e.getSceneX();
double y = e.getSceneY();
if((x + size < 400) && (y - circle.getRadius() > 1)){
switch (value){
case 0 :
circle.setCenterX(x);
circle.setCenterY(y);
break;
case 1 :
rec.setLayoutX(x);
rec.setLayoutY(y);
break;
case 2 :
pol.getPoints().clear();
pol.getPoints().addAll(new Double[]{x - size, y, x + size, y, x, y + size});
break;
}
}
}
};
EventHandler<MouseEvent> test = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e){
System.out.print("test: ");
}
};
pane1.addEventHandler(MouseEvent.MOUSE_MOVED, tracking);
pane1.addEventFilter(MouseEvent.MOUSE_DRAGGED, test);
Okey i found why it diden´t work. The MouseEvent was actually being activated on the object that was tracking the mouse. So when i clicked the mouse it created a drag event on that object that woulden´t end until i released the mouse button, thanks for the help :)
edit: I still dont get why it dident work from the beginning. Shouldent the eventHandler method capture the event when it bubbles up?
I'm watching The Coding Train's Processing Tutorials. In 5.4, he makes this line of code that is supposed to have an ellipse then move when clicked, but stop when clicked again. But for me it just says Debugger Halted. Here is my code:
float x = 100;
boolean going = false;
void setup() {
size(400, 300);
}
void draw() {
background(0);
fill(255);
ellipse(x, 150, 24, 24);
if (going) {
x = x + 2;
}
}
void mousePressed() {
going = true;
}
My guess is you're running in debug mode with a break point set.
You probably want to disable debug mode by clicking the butterfly button in the upper-right corner, or you want to find the break point and remove it by clicking the line number with a diamond icon.
I am building a text editor and trying to add the ability to select lines using the line number margin. My current approach is to use mouseDragged to update the selected lines. This works fine when doing slow mouse movements, but when doing faster movements the selection isn't able to keep up and just stops updating.
I have tried using a new thread for the processing of the selected range but it still freezes.
Update: Changed to a mouse range of two values (min/max) rather than every line - this fixed the issue
The mouseDragged method
private void mouseDragged(MouseEvent event, Mouse mouse) {
int eventY = event.getY();
int currentLineNumber = this.getLineNumber(eventY);
mouse.endRange(currentLineNumber);
if(mouse.getRange()[0] != mouse.getRange()[1]) {
this.selectLineRange(mouse);
} else {
this.selectLineForOffset(eventY);
}
}
Mouse state
private class Mouse {
int mouseY = -1;
int[] range = new int[2];
private void resetMouse(boolean resetBeginLine) {
this.mouseY = -1;
this.range = new int[2];
}
void endRange(int lineNumber) {
range[1] = lineNumber;
}
void beginRange(int lineNumber) {
range[0] = lineNumber;
}
int[] getRange() {
return range;
}
boolean validRange() {
return ((range[0] | range[1]) > 0);
}
}
And finally the select line range method
private void selectLineRange(Mouse mouse) {
if (mouse.validRange()) {
int minLine = Math.min(mouse.getRange()[0], mouse.getRange()[1]);
int maxLine = Math.max(mouse.getRange()[0], mouse.getRange()[1]);;
Element root = editor.getDocument().getDefaultRootElement();
int startSelection = root.getElement(minLine).getStartOffset();
int endSelection = root.getElement(maxLine).getEndOffset();
//editor.setCaretPosition(mouse.mouseDirection == Direction.UP ? startSelection : endSelection - 1);
editor.select(startSelection, Math.max(endSelection - 1, 0));
}
}
Having code in the same function that knows both about the concept of a mouse and the concept of a document is a recipe for disaster. Split your code into multiple functions where each function works at a different level of abstraction.
All you need is to know at which Y the mouse went down, and at which Y the mouse currently is. From this, you can at any given moment re-calculate the range of selected lines. First you convert viewport-Y to workspace-Y, then you convert workspace-Y to line-number, and voila, you have each line number.
This: selectedLineNumbers.add(currentLineNumber); presumes that you will receive a mouse event on each line. If you don't, then your list will contain gaps. And you won't, because mouse events come few and far apart when you are moving the mouse too quickly. That's why your selectedLineNumbers should be a range, (startingLineNumber, endingLineNumber) not a list of distinct line numbers.
I'm currently trying to make a small Entity-Relationship-Modell creating tool for Databases.
To avoid errors I try to don't allow the rectangles to overlap with a other rectangle.
I got most of my code working and it detects almost every collusion but in one case I can still overlap them and I don't know how to fix this error.
The problem is that it will look on only on rectangle not on both. But I really don't know how to intercept that case.
The strange thing to me is that my Debug line
System.out.println("still intersects?");
never triggers. Can somebody help me out in this error?
Image to the error in my Colision
This Function gets triggered every time I move a Rectangle.
The attribute Selected is a Boolean which says me which Rectangle I'm moving.
Then I check on which side its overlapping and revert back to the old position.
boolean Move(Point point) {
boolean moved = false;
boolean foundone = false;
for (ERMRectangle rectangle : Rectangles) {
if (rectangle.selected) {
foundone = true;
moved = true;
//calculated new Rectangle after Move
Rectangle Temp = new Rectangle();
Temp.x = point.x + rectangle.click.x;
Temp.width = rectangle.position.width;
Temp.height = rectangle.position.height;
Temp.y = point.y + rectangle.click.y;
for (ERMRectangle rectangle2 : Rectangles) {
if (rectangle != rectangle2 && rectangle2.position.intersects(Temp))//prevent overlapping
{
Rectangle intersection = rectangle2.position.intersection(Temp);
if (intersection.height > intersection.width) {
Temp.x = rectangle2.position.x - rectangle2.position.width;
if (intersection.x != rectangle2.position.x) {
Temp.x = rectangle2.position.x + rectangle2.position.width;
}
} else {
Temp.y = rectangle2.position.y - rectangle2.position.height;
if (intersection.y != rectangle2.position.y) {
Temp.y = rectangle2.position.y + rectangle2.position.height;
}
}
}
if(rectangle != rectangle2 && rectangle2.position.intersects(Temp))
{
System.out.println("still intersects?");
}
}
rectangle.position = Temp;
}
}
return moved;
}
ERMRectangle class:
import java.awt.Rectangle;
public class ERMRectangle {
public Rectangle position;
public boolean selected;
public Point click;
}
Edit: i resolved it by adding one more for loop into my methode which checks if it still interselects the rectangle and reverts both x and y cordinnates.
If at any moment, there will only be one rectangle moving (dragged by the user) there is no need to use nested loops to check for collision n-square times.
All you need is a method like this in your ERMRectangle class:
These codes assume your ERMRectangle class extends Rectangle class from Java
public boolean isColliding(ArrayList<ERMRectangle> rects)
{
for(ERMRectangle r : rects)
if(this != r && this.intersects(r))
return true;
return false;
}
You can then invoke isColliding() in the mouseReleased(MouseEvent e) in the mouse listener for your rectangles, and trigger the necessary actions when collision is detected. So, upon every mouse release after dragging, it will check for collisions on the rectangle which you have just moved.
To check for collision as you drag, place the similar codes as you would in mouseReleased(MouseEvent e) into mouseDragged(MouseEvent e). This will do a real-time collision detection check as you drag the rectangle.
I'm having trouble with event driven input detection for moving my actors.
I'm currently using a GestureDetector and detecting a Tap (this all works)`
#Override
public void show() {
GestureDetector GD = new GestureDetector(this);
InputMultiplexer inputMulti = new InputMultiplexer();
inputMulti.addProcessor(hudStage);
inputMulti.addProcessor(GD);
Gdx.input.setInputProcessor(inputMulti);
}
#Override
public boolean tap(float x, float y, int count, int button) {
System.out.println("YOU HAVE PERFORMED A TAP");
this.playStage.act(Gdx.graphics.getDeltaTime());
return true;
}`
Currently tap just prints out something along the lines of you have performed a tap(see above) it also calls the stage act method which works partly (It moves the actor a frames worth of movement instead of the entire distance). I've used polling to get the actor to perform how I want as i can call the method in the render loop which then allows it to continue updating movements frame by frame. Using Event driven I've not currently found a of updating it frame by frame so instead it does as much as it can in one frame and then stops.
I've looked around, a lot, looked into threading but it seems libgdx is not thread safe. My main problem with going back to polling is that i need to separate out my stages and I'm not entirely sure how to do that.
For polling i didn't use an action but used this code
if(!fStarted){
if (Gdx.input.isTouched()) {
fStarted = true;
touchX = Gdx.input.getX();
spriteX = cSprite.x;
}
}
final float dv = delta * speed;
if (Math.abs(touchX - spriteX) > 45) {
playStage.getBatch().draw(flameImage, spriteX, fSprite.y);
if (spriteX < touchX) {
spriteX += dv;
//fSprite.x = spriteX;
}
if (spriteX > touchX) {
spriteX -= dv;
//fSprite.x = spriteX;
}
}
else{
spriteX = 9000;
fStarted=false;
}
fStarted just determines whether or not the actor is currently moving to a position. As the actor is a projectile I didn't want more than one at one point (game choices you know).
If there is any other information you need just comment and I'll provide it.
Clarity
How can I use event driven gesture detection to move an actor to a position that is tapped by the user?