I am a newbie and trying to move a ball at a slope. Here is the code where I am giving coordinates (100,300,300,600) to move the ball in a slope but it's getting away from the the slope line. Here's the code: -
import javax.swing.*;
import java.awt.*;
public class AgentMotion extends JPanel implements Runnable
{
Color color = Color.red;
int dia = 0;
long delay = 40;
private double x;
private double y;
private double x1;
private double y1;
private int dx = 1;
private int dy = 1;
private int dv = 1;
private double direction;
double a;
double b;
double a1;
double b1;
public void abc(double x, double y, double x2, double y2) {
this.x = x;
this.y = y;
this.x1 = x2;
this.y1 = y2;
this.direction=Math.toRadians(Math.atan2(x1-x,y1-y));
System.out.println("segfewg"+direction);
this.a = x;
this.b = y;
this.a1 = x1;
this.b1 = y1;
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(color);
//int x=100;
//int y=200;
int x3=(int)this.x;
int y3=(int)this.y;
g.fillOval(x3,y3,5,5); // adds color to circle
g.setColor(Color.black);
g2.drawOval(x3,y3,5,5); // draws circle
g2.drawLine(100, 300, 300, 600);
}
public void run() {
if(direction<0)
{
System.out.println("refregreg");
while(dy!=0) {
try {
Thread.sleep(delay);
} catch(InterruptedException e) {
System.out.println("interrupted");
}
move2();
repaint();
move();
repaint();
}
}
else
{
while(dx!=0) {
try {
Thread.sleep(delay);
} catch(InterruptedException e) {
System.out.println("interrupted");
}
move2();
repaint();
move();
repaint();
}
}
}
public void move() {
if(direction>0)
{
if(x + dv*Math.cos(direction) <a ||x + dia + dv * Math.cos(direction) >b) {
dx *= 0;
color = getColor();
}
x += dx;
}
else
{
System.out.println(x + dia + dv * Math.cos(direction));
if(x + dia + dv * Math.cos(direction) >b) {
dx *= 0;
color = getColor();
}
x -= dx;
}
}
public void move2() {
if(direction>0)
{
if(dv * Math.sin(direction) + y <a1 || dv * Math.sin(direction) + dia + y > b1) {
dy *= 0;
color = getColor();
}
y += dy;
}
else
{
System.out.println(dv * Math.sin(direction) + dia + y);
if(dv * Math.sin(direction) + y <a1 || dv * Math.sin(direction) + dia + y < b1) {
dy *= 0;
color = getColor();
}
y -= dy;
}
}
public Color getColor() {
int rval = (int)Math.floor(Math.random() * 256);
int gval = (int)Math.floor(Math.random() * 256);
int bval = (int)Math.floor(Math.random() * 256);
return new Color(rval, gval, bval);
}
public void start() {
while(dx==0) {
try {
System.out.println("jiuj");
Thread.sleep(25);
} catch(InterruptedException e) {
System.out.println("dwdwdwd");
}
}
Thread thread = new Thread(this);
thread.setPriority(Thread.NORM_PRIORITY);
thread.start();
}
}
A few suggestions
dx and dy should be double
atan is overkill as #Spektre says. What you want is much more simple to calculate direction.
this.direction = (y2 - y) / (x2 - x)
If we give (100,300,300,600) as the arguments to abc (which would presumably be a constructor for this class), the slope is 1.5. Therefore we could say:
dx = 1.0
dy = 1.5
and this would keep on the line perfectly. For the general case where you want to change the begin and the end point, you have to calculate the ratio. So you could set either dx or dy to 1.0 and then set the other one so that the ratio is maintained. Something like the following mathematical pseudocode:
dx = (x2 - x) / minimum(x2-x, y2-y)
dy = (y2 - y) / minimum(x2-x, y2-y)
Related
I am trying to code a paint like program (for fun), but to challenge myself I tried to do it using setRGB method, but I see that when I move the mouse fast the behavior of the stroke gets erratic, do you know how to "soft" the data get from methods getX and getY? or why I am getting random points colored
Thank you in advance and sorry for my english. :)
public class Canvas extends JPanel implements ActionListener, MouseMotionListener, MouseListener {
int canvasW;
int canvasH;
BufferedImage imgCanvas;
int X1;
int Y1;
int X0;
int Y0;
int sizeCanvas = 10;
int expCanvas = 2 * sizeCanvas - 1;
public Canvas(int width, int height) {
canvasH = height;
canvasW = width;
setPreferredSize(new Dimension(width, height));
setBorder(BorderFactory.createLineBorder(Color.black));
setBackground(Color.white);
CanvasImage(width, height);
addMouseListener(this);
addMouseMotionListener(this);
}
public BufferedImage CanvasImage(int width, int height) {
imgCanvas = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
return imgCanvas;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(imgCanvas, null, null);
}
#Override
public void actionPerformed(ActionEvent e) {
}
public void drawer() {
int deltaX = abs(X1 - X0);
int deltaY = abs(Y1 - Y0);
double m;
double b;
if (deltaX >= deltaY) {
if (deltaY == 0) {
m = 0;
} else {
m = (X0 - X1) / (Y0 - Y1);
}
b = Y0 - m * X0;
if (X1 > X0) {
for (int i = X0; i <= X1; i++) {
imgCanvas.setRGB(i, (int) (m * i + b), Color.BLACK.getRGB());
System.out.println(i + " ; " + (int) (m * i + b));
}
} else {
for (int i = X0; i >= X1; i--) {
imgCanvas.setRGB(i, (int) (m * i + b), Color.BLACK.getRGB());
System.out.println(i + " ; " + (int) (m * i + b));
}
}
} else {
if (deltaX == 0) {
m = 0;
} else {
m = (Y0 - Y1) / (X0 - X1);
}
b = X0 - m * Y0;
if (Y1 > Y0) {
for (int i = Y0; i <= Y1; i++) {
imgCanvas.setRGB((int) (m * i + b), i, Color.BLACK.getRGB());
}
} else {
for (int i = Y0; i >= Y1; i--) {
imgCanvas.setRGB((int) (m * i + b), i, Color.BLACK.getRGB());
}
}
}
}
#Override
public void mouseDragged(MouseEvent e) {
X1 = e.getX();
Y1 = e.getY();
drawer();
repaint();
X0 = X1;
Y0 = Y1;
}
#Override
public void mousePressed(MouseEvent e) {
X0 = e.getX();
Y0 = e.getY();
}
So I am doing circle to circle collision in java. I am aware that there are many similiar questions like mine on this website but my problem is unique from all of them. When I run my code, the circle's collide with each other once every 4 times. Meaning: 3 times they will go through without colliding with one another but one time they will collide. Any help is greatly appreciated.
public class Ball {
float x, y; // coordinates of ball rectangle
float xo, yo;
float vx = 2, vy = 2; // coordinates of velocity vector
Color colour; // ball colour
float d; // diameter of the ball or sizes of ball rectangle
Ellipse2D.Float circle;
// overloaded constructor
Ball(int x, int y, int vx, int vy, int d, Color colour) {
this.x = x;
this.y = y;
this.d = d;
xo = x;
yo = y;
this.setColour(colour);
this.setVelocity(vx, vy);
circle = new Ellipse2D.Float(x, y, d, d);
}
public void setColour(Color colour) {
this.colour = colour;
}
public void setVelocity(int vx, int vy) {
this.vx = vx;
this.vy = vy;
}
public void show(Graphics g) {
((Graphics2D) g).setPaint(colour);
circle.setFrame(x, y, d, d);
((Graphics2D) g).fill(circle);
xo = x;
yo = y;
}
public void hide(Graphics g) {
Color c = ((Graphics2D) g).getBackground();
((Graphics2D) g).setPaint(c);
circle.setFrame(xo, yo, d, d);
((Graphics2D) g).fill(circle);
}
public void setPosition(float x, float y) {
this.x = x;
this.y = y;
}
public void move(int a, int b, int xh, int yh) {
if (vy > 0) {
if (y + d + vy - yh - b > 0) {
y = yh + b - d;
vy = -vy;
} else
y += vy;
} else {
if (y + vy <= b) {
y = b;
vy = -vy;
} else
y += vy;
}
if (vx > 0) {
if (x + d + vx - xh - a > 0) {
x = xh + a - d;
vx = -vx;
} else
x += vx;
} else {
if (x + vx <= a) {
x = a;
vx = -vx;
} else
x += vx;
}
}
The Collision Detector is in the class below
public class Game extends JFrame {
int ah, bh, xh, yh; // parameters of the rectangle frame
Color[] ColorAr = { Color.red, Color.blue, Color.pink, Color.green,
Color.yellow, Color.magenta, Color.black, Color.orange, Color.gray,
Color.cyan };
Ball b[];
int quantity = 4;
public void paint(Graphics g) {
int i;
((Graphics2D) g).setPaint(Color.black);
((Graphics2D) g).drawRect(ah, bh, xh, yh);
for (i = quantity - 1; i >= 0; i--) {
b[i].hide(g);
}
for (i = 0; i < quantity; i++) {
b[i].show(g);
}
}
public void prepare() {
int i;
ah = 20;
bh = 40;
xh = 400;
yh = 400;
b = new Ball[quantity];
for (i = 0; i < quantity; i++) {
b[i] = new Ball((int) (Math.random() * (300 - 1 + 1)) + 1, 100, 1,
1, 26, ColorAr[(int) (Math.random() * 9)]);
}
}
public void collision() {
int radius = 13;
int distance = 2 * radius;
if (b[1].x + distance == b[0].x && b[1].y == b[0].y
|| b[1].x - distance == b[0].x && b[1].y == b[0].y) {
b[1].vx = -b[1].vx;
b[0].vx = -b[0].vx;
}
}
public void run() {
int i;
while (true) {
for (i = 0; i < quantity; i++)
b[i].move(ah, bh, xh, yh);// move balls
collision();
for (int j = 0; j < 10000000; j++)
; // delay;
// collision();
repaint();
}
}
public static void main(String args[]) {
Game frame = new Game();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setBackground(Color.white);
frame.setSize(450, 470);
frame.prepare();
frame.setVisible(true);
frame.run();
}
}
For two circles:
First calculate the sum of lengths: radius_1 + radius_2 (the first and the second circle).
Collision of two circles can be detected if you calculate the length of (imaginary) line between centers. If THAT length <= radius_1 + radius_2, two circles are colliding.
I am making Pong in Java right now using Eclipse. I am trying to get the balls to bounce off the padels proportionally to where they hit the padel. If they hit at the top or bottom, I would like them to bounce off at 75 degrees up at the top or 75 degrees down at the bottom. If they hit near the center, then I would like them to bounce off closer to horizontal.
I am calculating the angle in the ball class with this math:
double speed = getSpeed() + ballIncrease;
yPos = Math.abs(yPos);
double angle = multiplier * yPos;
double ratio = Math.tan(angle);
xSpeed = ratio * (speed/(ratio + 1));
ySpeed = Math.sqrt((speed * speed) - (xSpeed * xSpeed));
I think that it should be correct, but the balls don't behave like I expect them to. I was wondering if anyone can help me solve this problem.
package Pong;
/*Place cursor here to start
*
*/
//Import Libraries
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
#SuppressWarnings("serial")
public class Pong extends JPanel implements KeyListener{
//Create random instances
Random r2 =new Random();
public final static int padelStart = 150;
public final static int padelSpace = 10;
final static int BOX_WIDTH = 1200;
public final static int BOX_HEIGHT = 800;
double ballX = BOX_WIDTH/2;
double ballY = BOX_HEIGHT/2;
public static Padel padel1 = new Padel(padelSpace,padelStart,true);
public static Padel padel2 = new Padel(BOX_WIDTH-padelSpace-padel1.getWidth(),padelStart,false);
Ball ball1 = new Ball(ballX,ballY);
Ball ball2 = new Ball(300,300);
public static int padel1y1;
public static int padel1y2;
public static int padel2y1;
public static int padel2y2;
//Constants
public final static int UPDATE_RATE = 200;
//Main game class
public Pong () {
//Set window size
setPreferredSize(new Dimension(BOX_WIDTH,BOX_HEIGHT));
//Start game thread
Thread gameThread = new Thread() {
public void run(){
while(true){
//Draw objects
padel1y1 = padel1.getY();
padel1y2 = padel1.getY() + Padel.padelLength;
padel2y1 = padel2.getY();
padel2y2 = padel2.getY() + Padel.padelLength;
padel1.update();
padel2.update();
ball1.update();
ball2.update();
repaint();
//Wait
try {Thread.sleep(1000 / UPDATE_RATE);}
catch (InterruptedException ex) {}
}
}
};
gameThread.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(0,0,BOX_WIDTH,BOX_HEIGHT);
padel1.draw(g);
padel2.draw(g);
ball1.draw(g);
ball2.draw(g);
}
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_UP){padel2.setSpeed(-Padel.padelSpeed);}
if(e.getKeyCode() == KeyEvent.VK_DOWN){padel2.setSpeed(Padel.padelSpeed);}
if(e.getKeyCode() == KeyEvent.VK_W){padel1.setSpeed(-Padel.padelSpeed);}
if(e.getKeyCode() == KeyEvent.VK_S){padel1.setSpeed(Padel.padelSpeed);}
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){padel2.setSpeed(0);}
if(e.getKeyCode() == KeyEvent.VK_DOWN){padel2.setSpeed(0);}
if(e.getKeyCode() == KeyEvent.VK_W){padel1.setSpeed(0);}
if(e.getKeyCode() == KeyEvent.VK_S){padel1.setSpeed(0);}
}
public void keyTyped(KeyEvent e) {}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Create Frame
JFrame frame = new JFrame("PONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONGPONG");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Pong pong = new Pong();
frame.setContentPane(pong);
frame.setSize(BOX_WIDTH,BOX_HEIGHT);
frame.pack();
frame.addKeyListener(pong);
frame.setVisible(true);
}
});
}
}
Padel Class:
package Pong;
import java.awt.*;
import java.util.Random;
public class Padel {
public int y;
public int x;
public boolean ws;
public int speed = 0;
public final static int padelSpeed = 3;
public final static int padelWidth = 30;
public final static int padelLength = 200;
Random rng = new Random();
int r = rng.nextInt(256);
int g = rng.nextInt(256);
int b = rng.nextInt(256);
Color color = new Color(r,g,b);
public Padel(int xPos, int yPos, boolean wands){
y = yPos;
x = xPos;
ws = wands;
}
public void update(){
if(speed > 0 && y + padelLength < Pong.BOX_HEIGHT){
y = y + speed;
}
if(speed < 0 && y > 0){
y = y + speed;
}
}
public void draw(Graphics g) {
g.setColor(color);
g.fillRoundRect(x, y, padelWidth, padelLength, 25, 25);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getWidth(){
return padelWidth;
}
public int getLength(){
return padelLength;
}
public int getSpeed(){
return speed;
}
public void setSpeed(int speed1){
speed = speed1;
}
public int getPadelSpeed(){
return padelSpeed;
}
}
Ball Class:
package Pong;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
public class Ball {
Random rng = new Random();
int r = rng.nextInt(256);
int g = rng.nextInt(256);
int b = rng.nextInt(256);
Color color = new Color(r,g,b);
public final static double ballSpeedMin = -2.0;
public final static double ballSpeedMax = 2.0;
public final static double middleSpeedCutoff = 1.0;
public final static double ballIncrease = .2;
public final int ballRadiusMin = 10;
public final int ballRadiusMax = 40;
double x;
double y;
double xSpeed;
double ySpeed;
int ballRadius;
public Ball(double xPos,double yPos){
x = xPos;
y = yPos;
xSpeed = getRandomSpeed();
ySpeed = getRandomSpeed();
ballRadius = getRandomRadius();
}
public double getRandomSpeed(){
Random r =new Random();
return ballSpeedMin + (ballSpeedMax - ballSpeedMin) * r.nextDouble();
}
public int getRandomRadius(){
Random r = new Random();
return r.nextInt((ballRadiusMax - ballRadiusMin) + 1) + ballRadiusMin;
}
public void update(){
x = x + xSpeed;
y = y + ySpeed;
ySpeed = verticalBounce();
double multiplier = .75;
if(getLowX() < Pong.padelSpace + Padel.padelWidth){
if(y>=Pong.padel1y1 && y<=Pong.padel1y2){
double yPos = y - Pong.padel1y1 - (Padel.padelLength/2);
if(yPos<0){
double speed = getSpeed() + ballIncrease;
yPos = Math.abs(yPos);
double angle = multiplier * yPos;
double ratio = Math.tan(angle);
xSpeed = ratio * (speed/(ratio + 1));
ySpeed = -Math.sqrt((speed * speed) - (xSpeed * xSpeed));
}
else if(yPos>0){
double speed = getSpeed() + ballIncrease;
yPos = Math.abs(yPos);
double angle = multiplier * yPos;
double ratio = Math.tan(angle);
xSpeed = ratio * (speed/(ratio + 1));
ySpeed = Math.sqrt((speed * speed) - (xSpeed * xSpeed));
}
else{
double speed = getSpeed();
xSpeed = speed;
ySpeed = 0;
}
}
else{
System.exit(0);
}
}
if(getHighX() > Pong.BOX_WIDTH - Pong.padelSpace - Padel.padelWidth){
if(y>Pong.padel2y1 && y<Pong.padel2y2){
double yPos = y - Pong.padel2y1 - (Padel.padelLength/2);
if(yPos<0){
double speed = getSpeed() + ballIncrease;
yPos = Math.abs(yPos);
double angle = multiplier * yPos;
double ratio = Math.tan(angle);
xSpeed = - ratio * (speed/(ratio + 1));
ySpeed = -Math.sqrt((speed * speed) - (xSpeed * xSpeed));
}
else if(yPos>0){
double speed = getSpeed() + ballIncrease;
yPos = Math.abs(yPos);
double angle = multiplier * yPos;
double ratio = Math.tan(angle);
xSpeed = - ratio * (speed/(ratio + 1));
ySpeed = Math.sqrt((speed * speed) - (xSpeed * xSpeed));
}
else{
double speed = getSpeed();
xSpeed = -speed;
ySpeed = 0;
}
}
else{
System.exit(0);
}
}
}
public void draw(Graphics g) {
g.setColor(color);
int xPos = (int) Math.round(x) - ballRadius;
int yPos = (int) Math.round(y) - ballRadius;
g.fillOval(xPos,yPos,ballRadius*2,ballRadius*2);
}
public double verticalBounce(){
if(y - ballRadius<0 || y + ballRadius > Pong.BOX_HEIGHT){
return -ySpeed;
}
else{
return ySpeed;
}
}
public double getY(){
return y;
}
public double getX(){
return x;
}
public double getYSpeed(){
return ySpeed;
}
public double getXSpeed(){
return xSpeed;
}
public void setYSpeed(double y){
ySpeed = y;
}
public void setXSpeed(double x){
xSpeed = x;
}
public double getLowX(){
return x - ballRadius;
}
public double getLowY(){
return y - ballRadius;
}
public double getHighX(){
return x + ballRadius;
}
public double getHighY(){
return y + ballRadius;
}
public double getSpeed(){
return Math.sqrt((xSpeed*xSpeed)+(ySpeed*ySpeed));
}
}
double multiplier = .75;
//...
double yPos = y - Pong.padel1y1 - (Padel.padelLength/2);
//...
double angle = multiplier * yPos;
Are you aware that the angles you pass in trigonometric functions are expressed in radians?Assuming your paddle length is 20, with yPos varying between [-10, 10] your angle will vary between [-7.5, 7.5]. Translate this in radians and you'll see your angle rotates around the circle a bit more than 2 times. Is really this what you want?
I am a self taught programmer and I am coding Screen Snake for fun. I am using not using integers to store the position of the snake or apples, I am using doubles. I am having an issue when the snake goes through the apple. When the collide, the code does not register that it collided. I am assuming that this is because their X and Y values might be like .1 off. I have been trying to fix this for 2 weeks but have not been able to. Sorry if my code is a bit messy. I don't know exactly what you guys need from the code so I posted all of it. Also I really appreciate the help! Thanks!!
Main class:
Random random = new Random();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double ScreenW = screenSize.getWidth();
double ScreenH = screenSize.getHeight();
int ScreenX = (int)Math.round(ScreenW);
int ScreenY = (int)Math.round(ScreenH);
JFrame frame = new JFrame();
double x = 1, y = 1;
int size = 5;
int ticks;
private int columnCount = 25;
private int rowCount = 15;
double a = (ScreenW / columnCount) - 1;
double b = (ScreenH / rowCount) - 1;
private Key key;
private List<Rectangle2D> cells;
private Point selectedCell;
boolean up = false;
boolean down = false;
boolean right = true;
boolean left = false;
boolean running = true;
private Thread thread;
private BodyP p;
private ArrayList<BodyP> snake;
private Apple apple;
private ArrayList<Apple> apples;
double width = screenSize.width;
double height = screenSize.height;
double cellWidth = width / columnCount;
double cellHeight = height / rowCount;
double xOffset = (width - (columnCount * cellWidth)) / 2;
double yOffset = (height - (rowCount * cellHeight)) / 2;
public Max_SnakeGame() throws IOException {
System.out.println(screenSize);
System.out.println(a + "," + b);
System.out.println(ScreenH + b);
System.out.println(ScreenW + a);
frame.getContentPane().add(new Screen());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setLocationRelativeTo(null);
frame.setMaximumSize(screenSize);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
Image img = Toolkit
.getDefaultToolkit()
.getImage(
"C:/Users/Max/My Documents/High School/Sophomore year/Graphic Disign/People art/The Mods Who Tell Pointless Stories.jpg");
frame.setIconImage(img);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new Max_SnakeGame();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public class Screen extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
public Screen() {
key = new Key();
addKeyListener(key);
setMaximumSize(screenSize);
setOpaque(false);
setBackground(new Color(0, 0, 0, 0));
setFocusable(true);
snake = new ArrayList<BodyP>();
apples = new ArrayList<>();
start();
}
public void start() {
running = true;
thread = new Thread(this);
thread.start();
}
public void run() {
while (running) {
MoveUpdate();
repaint();
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
repaint();
Graphics2D g2d = (Graphics2D) g.create();
cells = new ArrayList<>(columnCount * rowCount);
if (cells.isEmpty()) {
for (int row = 0; row < rowCount; row++) {
for (int col = 0; col < columnCount; col++) {
Rectangle2D cell = new Rectangle2D.Double(xOffset
+ (col * cellWidth), yOffset
+ (row * cellHeight), cellWidth, cellHeight);
cells.add(cell);
}
}
}
g2d.setColor(Color.GRAY);
for (Rectangle2D cell : cells) {
g2d.draw(cell);
}
for (int i = 0; i < snake.size(); i++) {
snake.get(i).draw(g);
}
for (int i = 0; i < apples.size(); i++) {
apples.get(i).draw(g);
}
}
}
private class Key implements KeyListener {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_RIGHT && !left) {
up = false;
down = false;
right = true;
}
if (keyCode == KeyEvent.VK_LEFT && !right) {
up = false;
down = false;
left = true;
}
if (keyCode == KeyEvent.VK_UP && !down) {
left = false;
right = false;
up = true;
}
if (keyCode == KeyEvent.VK_DOWN && !up) {
left = false;
right = false;
down = true;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
public void MoveUpdate() {
if (snake.size() == 0) {
p = new BodyP(x, y, a, b);
snake.add(p);
}
if (apples.size() == 0){
double x1 = random.nextInt(25);
double Ax = ((x1*a+x1+1)*10)/10;
double y1 = random.nextInt(15);
double Ay = ((y1*b+y1+1)*10)/10;
double Afx = Math.round(Ax);
double Afy = Math.round(Ay);
System.out.println("Ax:"+Afx);
System.out.println("Ay:"+Afy);
apple = new Apple(Ax, Ay, a, b);
apples.add(apple);
}
for(int i = 0; i < apples.size(); i++) {
if(Math.round(x)-1 == apples.get(i).getx() || Math.round(x) == apples.get(i).getx() && Math.round(y)== apples.get(i).gety() || Math.round(y)-1 == apples.get(i).gety()) {
size++;
apples.remove(i);
i--;
}
}
ticks++;
if (ticks > 2500000) {
if (up == true) {
if (y <= 2) {
y = ScreenH - b;
System.out.println("Y:" + y);
} else {
y -= b + 1;
System.out.println("Y:" + y);
}
}
// down loop
else if (down == true) {
if (y >= ScreenH - b) {
y = 1;
System.out.println("Y:" + y);
}
else {
y += b + 1;
System.out.println("Y:" + y);
}
}
// left loop
else if (left == true) {
if (x <= 1) {
x = ScreenW - a;
System.out.println("X:" + x);
}
else {
x -= a + 1;
System.out.println("X:" + x);
}
}
// right loop
else if (right == true) {
if (x >= ScreenW - a) {
x = 1;
System.out.println("X:" + x);
}
else {
x += a + 1;
System.out.println("X:" + x);
}
}
ticks = 0;
p = new BodyP(x, y, a, b);
snake.add(p);
// rect.setFrame(x, y, a, b);
if (snake.size() > size) {
snake.remove(0);
}
}
}
}
Snake class:
public class BodyP {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double ScreenW = screenSize.getWidth();
double ScreenH = screen`enter code here`Size.getHeight();
double x = 1, y = 1;
private int columnCount = 25;
private int rowCount = 15;
double a = (ScreenW / columnCount) - 1;
double b = (ScreenH / rowCount) - 1;
public BodyP(double x, double y, double a, double b) {
this.x = x;
this.y = y;
this.a = a;
this.b = b;
}
public void MoveUpdate(){
}
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Rectangle2D rect = new Rectangle2D.Double(x, y, a, b);
g.setColor(Color.BLACK);
g2.fill(rect);
}
public double getx() {
return x;
}
public void setx(double x) {
this.x = x;
}
public double gety() {
return y;
}
public void sety(double y) {
this.y = y;
}
}
Apple class:
public class Apple {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double ScreenW = screenSize.getWidth();
double ScreenH = screenSize.getHeight();
double x = 1, y = 1;
private int columnCount = 25;
private int rowCount = 15;
double a = (ScreenW / columnCount) - 1;
double b = (ScreenH / rowCount) - 1;
public Apple(double x, double y, double a, double b) {
this.x = x;
this.y = y;
this.a = a;
this.b = b;
}
public void MoveUpdate(){
}
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Rectangle2D rect = new Rectangle2D.Double(x, y, a, b);
g.setColor(Color.RED);
g2.fill(rect);
}
public double getx() {
return x;
}
public void setx(double x) {
this.x = x;
}
public double gety() {
return y;
}
public void sety(double y) {
this.y = y;
}
}
If you think this is due rounding errors, use Euclidean distance and compare with the desired tolerance:
final double tolerance = 1.0; // or whatsoever
double dx = snake.x - apple.x;
double dy = snake.y - apple.y;
if ( dx*dx + dy*dy < tolearance * tolerance ) ...
I suggest to implement something like Point.distanceTo(Point) method to make this convenient.
I am trying to get the x and y value of a point after increasing the distance r. Perhaps there is a better way of calculate the angle phi too, so that I don't need to check in which quadrant the point is. The 0-point is at the half of the width and height of the window. Here is my attempt:
package test;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
public final class Laser extends java.applet.Applet implements Runnable{
private static final long serialVersionUID = -7566644836595581327L;
Thread runner;
int width = 800;
int height = 600;
Point point = new Point(405,100);
Point point1 = new Point(405,100);
public void calc(){
int x = getWidth()/2;
int y = getHeight()/2;
int px = point.x;
int py = point.y;
int px1 = point1.x;
int py1 = point1.y;
double r = 0;
double phi = 0;
// Point is in:
// Quadrant 1
if(px > x && py < y){
r = Math.hypot(px1-x, y-py1);
phi = Math.acos((px1-x)/r)*(180/Math.PI);
}/*
// Quadrant 2
else if(px < x && py < y){
r = Math.hypot(x-px, y-py);
phi = Math.acos((px-x)/r)*(180/Math.PI);
}
// Quadrant 3
else if(px < x && py > y){
r = Math.hypot(x-px, py-y);
phi = Math.acos((px-x)/r)*(180/Math.PI)+180;
}
// Quadrant 4
else if(px > x && py > y){
r = Math.hypot(px-x, py-y);
phi = Math.acos((px-x)/r)*(180/Math.PI)+180;
}*/
r += 1;
point1.x = (int) (r*Math.cos(phi));
point1.y = (int) (r*Math.sin(phi));
System.out.println(r+";"+point1.x+";"+point1.y);
}
public void paint(Graphics g) {
g.setColor(Color.ORANGE);
calc();
g.drawLine(point.x, point.y, point1.x, point1.y);
int h = getHeight();
int w = getWidth();
g.setColor(Color.GREEN);
g.drawLine(0, h/2, w, h/2);
g.drawLine(w/2, 0, w/2, h);
}
/*
public void initPoints(){
for(int i = 0; i < pointsStart.length; i++){
int x = (int)(Math.random()*getWidth());
int y = (int)(Math.random()*getHeight());
pointsStart[i] = pointsEnd[i] = new Point(x,y);
}
}
*/
public void start() {
if (runner == null) {
runner = new Thread(this);
setBackground(Color.black);
setSize(width, height);
//initPoints();
runner.start();
}
}
#SuppressWarnings("deprecation")
public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}
public void run() {
while (true) {
repaint();
try { Thread.sleep(700); }
catch (InterruptedException e) { }
}
}
public void update(Graphics g) {
paint(g);
}
}
You are changing (x,y) to be r from some other point, when it had previously been some distance r' from that point, correct? So why not avoid the trigonometry, and just scale each of the components from that point by r/r'?
Edit: ok, iterate over the pixels along whichever component (x or y) is longer (let's assume it's y); for each xi in (0..x), yi = xi*(y/x), and you plot (xi,yi).
Keep it simple! And use double variables for such computations, I changed it for you.
package test;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.Point2D;
public final class Laser extends java.applet.Applet implements Runnable {
private static final long serialVersionUID = -7566644836595581327L;
Thread runner;
int width = 800;
int height = 600;
Point2D.Double point = new Point2D.Double(400, 100);
Point2D.Double point1 = new Point2D.Double(405, 102);
public void calc() {
double px = point.x;
double py = point.y;
double px1 = point1.x;
double py1 = point1.y;
double dx = px1 - px;
double dy = py1 - py;
double len = Math.hypot(dx, dy);
double newlen = len+2;
double coeff = Math.abs((newlen-len)/len);
point1.x += dx * coeff;
point1.y += dy * coeff;
System.out.println(len+";"+point1.x+";"+point1.y);
}
public void paint(Graphics g) {
g.setColor(Color.ORANGE);
calc();
g.drawLine((int)point.x, (int)point.y, (int)point1.x, (int)point1.y);
int h = getHeight();
int w = getWidth();
g.setColor(Color.GREEN);
g.drawLine(0, h / 2, w, h / 2);
g.drawLine(w / 2, 0, w / 2, h);
}
/*
* public void initPoints(){
*
* for(double i = 0; i < pointsStart.length; i++){ double x =
* (double)(Math.random()*getWidth()); double y =
* (double)(Math.random()*getHeight()); pointsStart[i] = pointsEnd[i] = new
* Point(x,y); }
*
* }
*/
public void start() {
if (runner == null) {
runner = new Thread(this);
setBackground(Color.black);
setSize(width, height);
// initPoints();
runner.start();
}
}
#SuppressWarnings("deprecation")
public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}
public void run() {
while (true) {
repaint();
try {
Thread.sleep(700);
}
catch (InterruptedException e) {
}
}
}
public void update(Graphics g) {
paint(g);
}
}