I'm trying to code a GUI that allows the user to move a box around. There is also another box on the screen, called "block" that the box isn't allowed to intersect. I have box moving fine, but I don't know how to stop the two from intersecting and keep the drawing of the box on the screen. Right now, the box disappear when it hits the block (I know why it's doing this, I just don't know how to fix it).
X and Y are the movement detected by the left and right mouse keys.
box = new Rectangle2D.Double(0 + X, 0 + Y, 200, 50);
block = new Rectangle2D.Double(300, 300, 50, 50);
if (box.intersects(block)) {
hit = true;
} else {
hit = false;
}
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.red);
g2.draw(block);
if (model.hit()) {
g2.setPaint(Color.black);
g2.drawString("WHOA THERE", 20, 50);
} else {
g2.setPaint(Color.blue);
g2.fill(box);
I'm a little unclear on what you're asking. If you're asking how to draw the box when it hits the block, the problem is your if/else statement. In the if case, it skips the drawing block. Remove the else to draw the box even if it hits.
If you're asking how to prevent the two boxes from intersecting, that's easy. If you detect they intersect, move the moving box so it's just outside the block. So if the block is at x = 10, set the moving box (model?) so it's at x = 11. HTH
Related
Hi I am currently making a program that will show a spring that moves with the values that I enter and uses the formulas of physics. The problem is that, when I create a spring and make the animation start, the old image stays there and overrides without deleting the one before here's the code of the problem :
bouton3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
/*anime.animer();
anime.repaint();*/
for (int t = 0; t < 500; t += 5) {
for (int i = 105; i < 175; i += 5) {
Ellipse2D elp1 = new Ellipse2D.Double(i, 100, 15, 30);
((Graphics2D) dessinPanel.getGraphics()).draw(elp1);
}
for (int i = 105; i < 175; i += 5) {
Ellipse2D elp1 = new Ellipse2D.Double(i, 100, 15 + osi.simuler(t), 30);
((Graphics2D) dessinPanel.getGraphics()).draw(elp1);
dessinPanel.repaint();
Rectangle2D rect = new Rectangle2D.Double(186 + osi.simuler(t), 90, 50, 50);
((Graphics2D) dessinPanel.getGraphics()).draw(rect);
dessinPanel.repaint();
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Here`s also some pictures to show the problem:
before
after
You need to decouple your painting from your value adjustments.
Your painting operation should start by clearing the background, then paint the spring and box using the current input values.
When an input value changes, simply update the variable and invalidate() the display area.
For better performance, clearing the background can also be done by drawing the spring and box at their current positions in the background color. This also makes the updating of the input values more difficult.
One more technique you might use would be to widen the brush and draw first in the background color, then shrink the brush and draw the actual spring and rectangle in their correct form. This would be equivalent to erasing the background as long as you control the amount either can move in a single frame.
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.
I am trying to draw increasing circles in a TextureView. The centre of all circles is the same. I then try to increase the drawn Circle until a specific limit is reached. Then I want to clear the canvas and start over again. However using my code (see below), the canvas seems to never be cleared. Actually it flashes white shortly when it should be cleared, but then when the first circle in the next cycle is drawn (after attempting to clear canvas), all previous circles reappear and the whole animation seems to go crazy. After letting it run for several seconds I am left with dozens of circles (some overlapping) instead of only approximately 4 per cycle. Furthermore they do not have the radius I gave them (basically my code ends up drawing numerous circles of random sizes). Spent several days trying different things, but nothing seems to help.
Here's my code:
paint.setColor(Color.argb(opac, 177, 177, 177));
stroke = 5;
paint.setStrokeWidth(stroke);
radius = 10;
Canvas canvas = new Canvas();
Boolean clear = false;
//Added these two lines following advice from a previous answer:
Paint clearPaint = new Paint();
clearPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
while (mRunning && !Thread.interrupted()) {
canvas = mSurface.lockCanvas(null);
try {
if(clear){
canvas.drawPaint(clearPaint); //This line should clear the canvas.
clear = false;
}else{
canvas.drawCircle(circleX, circleY, radius, paint);
}
} finally {
mSurface.unlockCanvasAndPost(canvas);
}
if(radius+15 <= circleY-stroke/2){
radius+=15;
}else{
radius = 10;
clear = true;
}
try {
Thread.sleep(360);
} catch (InterruptedException e) {
// Interrupted
}
Would really appreciate it if someone could help me out here. I wasn't able to proceed with my project for several weeks now due to this problem.
Create a new Paint Instance for just clearing the canvas
Paint clearPaint = new Paint();
clearPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
In your if() block for clearing the canvas, paint it with the above instance of Paint
if(clear){
canvas.drawPaint(clearPaint);
clear = false;
}
I have a Game Tutorial that I followed, that paints String's on the Screen using Graphics2D. It works like a star, but the only problem is that I don't undertstand why.
I call draw(graphics) in a game loop and it works fine. I use an int, named currentChoice to keep track of which letter should be Red and which should be Black.
Well, I call the method Draw in a loop. I just don't understand how does the graphics clear the previous string it drew. I mean, I call the method constantly, and it keeps on Drawing string's on the window, and its 'clearing' the other ones (if you get what i'm saying).
Basicly, I just don't undertstant how it's clearing the screen (NOTE: I am super new to this sort of thing)
CODE (I call this in a loop and it works):
public void draw(Graphics2D graphics) {
bg.draw(graphics);
graphics.setColor(titleColor);
graphics.setFont(titleFont);
graphics.drawString("Peache's Revenge", 50, 70);
graphics.setFont(font);
for (int i = 0; i < options.length; i++) {
if (i == currentChoice) {
graphics.setColor(Color.RED);
} else {
graphics.setColor(Color.BLACK);
}
graphics.drawString(options[i], 145, 140 + i * 15);
}
}
Assuming the Graphics context does not change (ie is the same for each call), then, unless the background is cleared, content will continue to be painted ontop of it.
From you comments, bg.draw is drawing the background, over the top of whatever was previously painted, meaning that anything that was previously painted will now be covered by the background, thus requiring the text to be re-generated.
I'm having a problem with checking the colision of objects painted on the screen. For example: I'm currently making a snake game and I have to make it check whether the snake is hitting a certain block object ( which makes the snake increase and increases the score when the snake hits/'eats' the block ). So I made a function to check the collision between the snake and the block object but it doesn't work correctly ( when moving over the object with the snake from right above, it does work, but otherwise it does not ):
public boolean checkColision() {
if(SnakeObjs.get(0).x >= obj.x && SnakeObjs.get(0).x
<= obj.x+10 && SnakeObjs.get(0).y
>= obj.y && SnakeObjs.get(0).y <= obj.y+10) {
return true;
}else{
return false;
}
}
This function checks the collision. Where SnakeObjs.get(0) contains the x and y choords of the snake object that needs to hit the block object and the obj contains the x and y coordinates of the block object to check the collision with.
The paint method, painting both the block object and the snake object, looks like this:
public void paint(Graphics g) {
for(int i=0;i<SnakeObjs.size();i++) {
g.setColor(new Color(
(int)((double)Math.random()*200.0),
(int)((double)Math.random()*200.0),
(int)((double)Math.random()*200.0)));
g.fillRect(SnakeObjs.get(i).x, SnakeObjs.get(i).y, 10, 10);
g.setColor(Color.WHITE);
g.drawRect(SnakeObjs.get(i).x-1, SnakeObjs.get(i).y-1, 12, 12);
}
g.setColor(new Color(
(int)((double)Math.random()*200.0),
(int)((double)Math.random()*200.0),
(int)((double)Math.random()*200.0)));
g.fillRect(obj.x, obj.y, 10, 10);
g.setColor(Color.BLACK);
g.drawString("Score: "+score, 10, 10);
}
If anyone can help me out on this collision problem it would be great.
Thanks in advance,
Best Regards,
Skyfe.
The mistake is that you interpret one object as rectangle and the other as point. You check if the point is in the rectangle and not if the both rectangle intersect. That it work from right and from top.
I recommended to save an rectangle for the snake and the object. Ad a method getBounds(). then you can use the method intersect() from Rectangle. You can also use this bounds for your draw operation.