I'm trying to make a ball switch it's Y-Direction when it collides with the restrictions of the paddle. It is most likely a simple answer. Help would be appreciated. Thank you.
I labeled a couple of things to help.
public class GamePanel extends JPanel implements MouseMotionListener {
int Playerx;
int width;
int height;
// Ball Size
float radius = 20;
float diameter = radius * 2;
// Center of Call
float X = radius + 25;
float Y = radius + 10;
// Direction
float dx = 12;
float dy = 12;
GamePanel(){
setPreferredSize(new Dimension(1440, 900));
setFocusable(true);
setBackground(Color.BLACK);
addMouseMotionListener(this);
Thread thread = new Thread() {
public void run() {
while (true) {
width = getWidth();
height = getHeight();
X = X + dx ;
Y = Y + dy;
if (X - radius < 0) {
dx = -dx;
X = radius;
} else if (X + radius > width) {
dx = -dx;
X = width - radius;
}
if (Y - radius < 0) {
dy = -dy;
Y = radius;
}else if (Y + radius > height) {
dy = -dy;
Y = height - radius;
}
if(X-radius>=Playerx && X-radius <- Playerx + 100 && Y+radius>=800 && Y+radius<=810){
dy = -dy;
Y = height - radius;
}//Statement Above is the issue area
repaint();
try {
Thread.sleep(25);
} catch (InterruptedException ex) {
}
}
}
};
thread.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
if(Playerx<=50 && Playerx>= 0){g.fillOval(10,800,100,10);}
if(Playerx>50 && Playerx<1390){g.fillOval(Playerx-50,800,100,10);}
if(Playerx>=1390 && Playerx<1440){g.fillOval(1340,800,100,10);}
g.setColor(Color.BLUE);
g.fillOval((int)(X-radius), (int)(Y-radius), (int)diameter, (int)diameter);
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
Playerx = e.getX();
repaint();
}
}
I've tried setting different restrictions and different Y-Directions but it doesn't seem to work. The Ball goes straight through the paddle as if it's not there.
I managed to fix it.
I realized that my Playerx was in the middle of the paddle making everything offset 50.
float X = radius;
float Y = radius;
and
public void run() {
while (true) {
counter++;
width = getWidth();
height = getHeight();
X = X + dx ;
Y = Y + dy;
if (X - radius < 0) {
dx = -dx;
X = radius;
} else if (X + radius > width) {
dx = -dx;
X = width - radius;
}
if (Y - radius < 0) {
dy = -dy;
Y = radius;
}else if (Y + radius > height) {
dy = -dy;
Y = height - radius;
}if(X > Playerx-50 && X < Playerx+50 && Y+radius > paddleHeight && Y < 715){
dy = -dy;
Y = paddleHeight - radius;
}
Related
I made a bouncing ball code, and so far as the bouncing itself the code works perfectly. I then created a second ball, and it also does what it's supposed to do. However, when I try to use an if condition to make the two balls bounce off one another as well as the edges, it doesn't work. Either they don't move or they just don't collide, and go through each other. This code was made in processing. Can anyone help me make ball1 and ball2 collide?
Moving ball1;
Moving ball2;
void setup(){
size(600,600);
ball1 = new Moving();
ball2 = new Moving();
}
void draw(){
background(255);
ball1.move();
ball1.display();
ball1.bounce();
ball2.move();
ball2.display();
ball2.bounce();
ball1.clash();
ball2.clash();
}
class Moving {
float speed = 7;
float x = random(0, width);
float y= random(0, height);
float xdirection = 1;
float ydirection = 1;
float ball_size = 50;
float radius = ball_size/2;
Moving() {
}
void move() {
x = x + (xdirection * speed);
y = y + (ydirection* speed);
}
void display() {
noStroke();
fill(50, 0, 50);
circle(x, y, ball_size);
}
void bounce() {
if ((x >= width - radius) || (x <= radius)) {
xdirection = xdirection * -1;
}
if ((y >= height - radius)|| (y<=radius)) {
ydirection = ydirection * -1;
}
}
void clash() {
if ((ball1.y+radius == ball2.y+radius) && (ball1.x+radius == ball2.x+radius)) {
ball1.ydirection = ball1.ydirection * -1;
ball2.ydirection = ball2.ydirection * -1;
ball1.xdirection = ball1.xdirection * -1;
ball2.xdirection = ball2.xdirection * -1;
x = x + (xdirection * speed);
y = y + (ydirection* speed);
if (ball1.x+radius == ball2.x+radius) {
xdirection = xdirection * -1;
}
}
}
}
I need to make a circle look like it is bouncing but the output I get is many circles instead of only one moving. How can I make paint component only draw one circle during the animation instead of showing me several balls as it moves?
class thePanel extends JPanel {
int radius;
int diameter;
int x;
int y;
int dx;
int dy;
int timerInterval = 10;
Timer timer;
thePanel() {
x = 0;
y = 0;
dx = 3;
dy = 3;
radius = 20;
diameter = radius * 2;
timer = new Timer(timerInterval, new TimerListener());
timer.start();
repaint();
}
protected void paintComponent(Graphics g) {
super.paintComponents(g);
g.drawRect(getWidth() / 2, 0, getWidth() / 2, getHeight());
g.drawOval(this.x - radius, this.y - radius, diameter, diameter);
}
public void fixPosition() {
x += dx;
y += dy;
if (x < radius)
dx = Math.abs(dx);
if (x > getWidth() - radius)
dx = -Math.abs(dx);
if (y < radius)
dy = Math.abs(dy);
if (y > getHeight() - radius)
dy = -Math.abs(dy);
}
class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
fixPosition();
repaint();
}
}
}
I created a tilemap and a player (Which is just a squiggle right now). I put the tilemap and the player on the screen, but the player is in the upper left corner, and is always stuck in the tile. I can't figure out how to:
Get it out of the corner and
stop the collision from happening because it's a non-blocked block.
A few things you need to know before the code:
The tilesheet is the sheet with the different tiles on it and it goes
[non-blocked, nonblocked]
[blocked, blocked]
Here's the collision part of my object superclass (I know it looks like a lot but after the beginning you can get the drift):
public void calculateCorners(double x, double y) {
int leftTile = (int)(x - cwidth / 2) / tileSize;
int rightTile = (int)(x + cwidth / 2 - 1) / tileSize;
int topTile = (int)(y - cheight / 2) / tileSize;
int bottomTile = (int)(y + cheight / 2) / tileSize;
int tl = tileMap.getType(topTile, leftTile);
int tr = tileMap.getType(topTile, rightTile);
int bl = tileMap.getType(bottomTile, leftTile);
int br = tileMap.getType(bottomTile, rightTile);
topLeft = tl == Tile.BLOCKED;
topRight = tr == Tile.BLOCKED;
bottomLeft = bl == Tile.BLOCKED;
bottomRight = br == Tile.BLOCKED;
}
public void checkTileMapCollision() {
currCol = (int) x / tileSize;
currRow = (int) y / tileSize;
x += velX;
y += velY;
calculateCorners(x, ydest);
if (velY < 0) {
if (topLeft || topRight) {
velY = 0;
y = currRow * tileSize + cheight / 2;
System.out.println("Collision");
} else {
y += velY;
}
}
if (velY > 0) {
if (bottomLeft || bottomRight) {
velY = 0;
falling = false;
y = (currRow + 1) * tileSize - cheight / 2;
System.out.println("Collision");
} else {
y += velY;
}
}
calculateCorners(xdest, y);
if (velX < 0) {
if (topLeft || bottomLeft) {
velX = 0;
System.out.println("Collision");
x = currCol * tileSize + cwidth / 2;
} else {
x += velX;
}
}
if (velX > 0) {
if (topRight || bottomRight) {
velX = 0;
System.out.println("Collision");
x = (currCol + 1) * tileSize - cwidth / 2;
System.out.println("Collision");
} else {
x += velX;
}
}
}
And here's the most important stuff in my Player class:
public void update() {
System.out.println("update");
getNextPosition();
checkTileMapCollision();
setPosition((int) xtemp, (int) ytemp);
}
public void setLeft(boolean b) {
left = b;
}
public void setRight(boolean b) {
right = b;
}
public void getNextPosition() {
if (left) {
velX = -2;
System.out.println("Left");
} else if (right) {
velX = 2;
System.out.println("Right");
}
}
public void draw(Graphics2D g) {
x += velX;
y += velY;
g.drawImage(spriteSheet, (int) x, (int) y, null);
}
public void setPosition(int x, int y) {
this.x = x;
this.y = y;
}
public void setVel(int velX, int velY) {
this.velX = velX;
this.velY = velY;
}
If you need anything else, just tell me and I'll give it to you.
I am trying to write a program to allow a user to draw an ellipse by using clicks. The user left-clicks at first to select the radius, then right-clicks to select the horizontal radius, then right-clicks again to select the vertical radius. Nothing is drawn after clicking. I don't understand where the error is.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Ellipse extends JPanel implements MouseListener{
Graphics P;
public Ellipse()
{
addMouseListener(this);
}
static int Radius = 0;
int CenterX, CenterY, RadiusX, RadiusY;
public void paintComponent(Graphics g)
{
P=g;
EllipseMidpoint(CenterX, CenterY, RadiusX, RadiusY);
}
public void EllipseMidpoint(int Cx, int Cy, int Rx, int Ry)
{
int Rx2 = Rx * Rx;
int Ry2 = Ry * Ry;
int twoRx2 = 2 * Rx2;
int twoRy2 = 2 * Ry2;
int x = 0;
int y = Ry;
int p;
int px= 0;
int py = twoRx2 * y;
PlotEllipsePoint(Cx, Cy, x, y);
//Region 1
p = (int)(Ry2 - (Rx2 * Ry) + (0.25 + Rx2));
while (px < py)
{
x = x + 1;
px = twoRy2 + px;
if (p < 0)
{
p = Ry2 + px + p;
}
else
{
y = y - 1;
py = twoRx2 - py;
p = Ry2 + px - py + p;
}
PlotEllipsePoint(Cx, Cy, x, y);
}
//Region2
p = (int)(Ry2 * (x + 0.5) * (x + 0.5) + Rx2 * (y - 1) * (y - 1) - Rx2 * Ry2);
while (y > 0)
{
y = y - 1;
py = twoRx2 - py;
if (p > 0)
{
p = Rx2 - py + p;
}
else
{
x = x + 1;
px = twoRy2 + px;
p = Rx2 + px - py + p;
}
PlotEllipsePoint(Cx, Cy, x, y);
}
}
public void PlotEllipsePoint(int CX, int CY, int X, int Y)
{
drawPixel(CX + X, CY + Y);
drawPixel(CX - X, CY + Y);
drawPixel(CX + X, CY - Y);
drawPixel(CX - X, CY - Y);
}
public void drawPixel(int x, int y)
{
P.fillOval(x, y, 5, 5);
}
public void mousePressed(MouseEvent e)
{
if (e.getButton() == MouseEvent.BUTTON1)
{
CenterX = e.getX();
CenterY = e.getY();
}
else if (e.getButton() == MouseEvent.BUTTON3)
{
Radius = Radius + 1;
if (Radius == 1)
{
RadiusX = (int) Math.pow((Math.pow((e.getX() - CenterX), 2) + Math.pow((e.getY() - CenterY), 2)), 0.5);
}
else if (Radius == 2)
{
RadiusY = (int) Math.pow((Math.pow((e.getX() - CenterX), 2) + Math.pow((e.getY() - CenterY), 2)), 0.5);
}
PlotEllipsePoint(CenterX, CenterY, RadiusX, RadiusY);
}
}
public static void main(String[] args)
{
JFrame JF = new JFrame("Ellipse");
JF.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JF.setSize(500,500);
Ellipse E = new Ellipse();
JF.getContentPane().add(E);
JF.setVisible(true);
}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
Three things immediately jump out...
You should be calling super.paintComponent before doing any custom painting (and there is no need for paintComponent to be public), see Performing Custom Painting and Painting in AWT and Swing for more details
NEVER, EVER maintain a reference to the graphics context, you want something painted, you make a request to the repaint manager and you wait until one of your paint methods is called. Painting is controlled by the repaint manager an repaints may occur at any time, most of the time without yout knowledge or interaction.
You never call repaint to ask the repaint manager to repaint your component...At the end of your mousePressed method, call repaint()...
I have a question.
I'm not getting make the balls escape from the mouse pointer.
All balls go to the left corner when the mouse pointer enters the screen.
What am I doing wrong? Any tips??
My full code:
Java BounceBall mouse event
Or
http://ideone.com/vTGzb7
Method with problem:
public void move(Ball ball, Point mouse) {
try {
Point p = ball.getLocation();
Point speed = ball.getSpeed();
Dimension size = ball.getSize();
int vx = speed.x;
int vy = speed.y;
int x = p.x;
int y = p.y;
// ----------------------
if (mouse != null) {
int xDistance = Math.abs(x + size.width - mouse.x);
int yDistance = Math.abs(y + size.height - mouse.y);
if (xDistance < yDistance) {
if (x + size.width < mouse.x) {
if (vx > 0) {
vx *= -1;
}
} else {
if (vx > 0) {
vx *= -1;
}
}
} else {
if (y + size.height < mouse.y) {
if (vy > 0) {
vy *= -1;
}
} else {
if (vy > 0) {
vy *= -1;
}
}
}
}
// ----------------------
if (x + vx < 0 || x + size.width + vx > getParent().getWidth()) {
vx *= -1;
}
if (y + vy < 0
|| y + size.height + vy > getParent().getHeight()) {
vy *= -1;
}
x += vx;
y += vy;
ball.setSpeed(new Point(vx, vy));
ball.setLocation(new Point(x, y));
} catch (Exception e) {
e.printStackTrace();
}
}
For some balls it works fine.
They hit in the mouse pointer and change your direction.
But the majority goes to the corner of the screen.
Thank You.
Problem Solved...
Problem: The bubbles were locked in the upper corner of the screen. And do not hit the mouse pointer.
Solution: I calculated the distance from the X and Y position relative to the bubble diameter and the mouse pointer. For collision.
int xDistance = Math.abs((x + (diameter / 2)) - mouse.x);
int yDistance = Math.abs((y + (diameter / 2)) - mouse.y);
Then calculated the X and Y radius of the bubbles.
int radiusX = (size.width / 2);
int radiusY = (size.height / 2);
Finally, I changed the IF to check the relationship between the distance of the bubble radius. Changing your direction.
if (xDistance <= radiusX && yDistance <= radiusY) {
if (xDistance < yDistance) {
vx *= -1;
} else {
vy *= -1;
}
System.out.println("Hit!");
}
New Move Method:
public void move(Ball ball, Point mouse) {
try {
Point p = ball.getLocation();
Point speed = ball.getSpeed();
Dimension size = ball.getSize();
int diameter = ball.dimeter;
int vx = speed.x;
int vy = speed.y;
int x = p.x;
int y = p.y;
int radiusX = (size.width / 2);
int radiusY = (size.height / 2);
// ----------------------
if (mouse != null) {
int xDistance = Math.abs((x + (diameter / 2)) - mouse.x);
int yDistance = Math.abs((y + (diameter / 2)) - mouse.y);
System.out.printf("b(%d, %d) m(%d, %d) dx(%d, %d)\n", x, y,
mouse.x, mouse.y, (x + vx) - mouse.x, (y + vy)
- mouse.y);
if (xDistance <= radiusX && yDistance <= radiusY) {
if (xDistance < yDistance) {
vx *= -1;
} else {
vy *= -1;
}
System.out.println("Hit");
}
}
if (x + vx < 0 || x + size.width + vx > getParent().getWidth()) {
vx *= -1;
}
if (y + vy < 0
|| y + size.height + vy > getParent().getHeight()) {
vy *= -1;
}
x += vx;
y += vy;
ball.setSpeed(new Point(vx, vy));
ball.setLocation(new Point(x, y));
} catch (Exception e) {
e.printStackTrace();
}
}