I'm having trouble with the MouseEvent getPoint() method, the Math.asin() method, and just in general with coordinates. I am trying to create multiple objects called "Laser" to get fired from the "playerRobot". A rectangle is created around the playerRobot and the tempR.getCenterX and tempR.getCenterY are used to construct the point at the center of the playerRobot's location. The MouseEvent getPoint() is used to get the location of the mouse relative to the focused component. In the Laser class, two methods called getPointX(int y) and getPointY(int x) return a point with the respective x and y values corresponding to the given y or x value. I.e., getPointX(int y) returns a point with y and its corresponding x value. These methods do this by finding the linear equation between the given point of the playerRobot and the mouse. Then, the Laser is supposed to be drawn at the playerRobot point and redrawn to follow its linear equation to the mouse's point and continue on the linear equation until it reaches the borders of the component. However, depending on the angle at which the Laser is fired, it does not seem to always do this. Also, sometimes the Laser does not fire at all, sometimes it fires in the wrong direction or at the wrong angle, and sometimes it is longer than 50 pixels, which is always supposed to be the length of the Laser.
TL;DR: The Laser does not always fire from the playerRobot and does not always follow the linear line to the mouse's point, sometimes fires in the wrong direction or at the wrong angle, and sometimes is longer than 50 pixels.
Here is the code in the GameCanvas class that creates a new Laser object, followed by the code in the Laser class:
GameCanvas:
package application;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.scene.shape.Line;
import javax.swing.*;
public class GameCanvas extends JPanel implements ActionListener, KeyListener, MouseListener {
Timer t = new Timer(5, this);
double x = 0, y = 0, velX = 0, velY = 0;
boolean keyPress = false;
int code = 0;
long time = 1;
int currAIDelete = -1;
int currPlayerDelete = -1;
Graphics gr;
Point mousePoint = new Point();
AffineTransform oldTransform = new AffineTransform();
public GameCanvas() {
t.start();
addKeyListener(this);
addMouseListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
if(GameGUI.startScreen != null) {x = GameGUI.startScreen.imageLocationList.get(4).x; y = GameGUI.startScreen.imageLocationList.get(4).y; velX = 0; velY = 0;}
}
public void paintComponent(Graphics g) {
gr = g;
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if(!GameGUI.getGameOver()) {
if(g2 != null) {
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(7))).getImage(), (int) (x + 0.5), (int) (y + 0.5 + 64), GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(7).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(7).height, this);
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(6))).getImage(), (int) (x + 0.5), (int) (y + 0.5 + 16), GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(6).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(6).height, this);
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(5))).getImage(), (int) (x + 0.5), (int) (y + 0.5 + 16), GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(5).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(5).height, this);
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(4))).getImage(), (int) (x + 0.5), (int) (y + 0.5), GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(4).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(4).height, this);
for(int i = 3; i >= 0; i--)
g2.drawImage(new javax.swing.ImageIcon(getClass().getResource(GameGUI.startScreen.imageList.get(i))).getImage(), GameGUI.startScreen.imageLocationList.get(i).x, GameGUI.startScreen.imageLocationList.get(i).y, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(i).width, GameGUI.startScreen.DEFAULT_SCALED_IMAGE_SIZE_LIST.get(i).height, this);
Color tempColor = g2.getColor();
g2.setColor(tempColor);
GameGUI.startScreen.healthBar();
tempColor = g2.getColor();
GameGUI.startScreen.healthBarGlyphVector = new Font("Tahoma", 0, 11).createGlyphVector(new FontRenderContext(null, true, false), String.valueOf(GameGUI.startScreen.playerHealth));
g2.setColor(GameGUI.startScreen.playerHealthBarColor);
g2.drawGlyphVector(GameGUI.startScreen.healthBarGlyphVector, (int) (x + 40 - GameGUI.startScreen.healthBarGlyphVector.getNumGlyphs() * (double) GameGUI.startScreen.healthBarGlyphVector.getFont().getSize() / 2 + 0.5), (long) (y + 0.5) - 20);
GameGUI.startScreen.playerHealthBar.setLocation((int) (x + 0.5), (int) (y + 0.5) - 10);
g2.draw(GameGUI.startScreen.playerHealthBar);
g2.fill(GameGUI.startScreen.playerHealthBar);
GameGUI.startScreen.healthBarGlyphVector = new Font("Tahoma", 0, 11).createGlyphVector(new FontRenderContext(null, true, false), String.valueOf(GameGUI.startScreen.aiHealth));
g2.setColor(GameGUI.startScreen.aiHealthBarColor);
g2.drawGlyphVector(GameGUI.startScreen.healthBarGlyphVector, (int) (GameGUI.gameResources.getAIRobot().getLocation().get(0).x + 40 - GameGUI.startScreen.healthBarGlyphVector.getNumGlyphs() * (double) GameGUI.startScreen.healthBarGlyphVector.getFont().getSize() / 2 + 0.5), GameGUI.gameResources.getAIRobot().getLocation().get(0).y - 20);
GameGUI.startScreen.aiHealthBar.setLocation(GameGUI.gameResources.getAIRobot().getLocation().get(0).x, GameGUI.gameResources.getAIRobot().getLocation().get(0).y - 10);
g2.draw(GameGUI.startScreen.aiHealthBar);
g2.fill(GameGUI.startScreen.aiHealthBar);
g2.setColor(tempColor);
if(GameGUI.gameResources.playerLaserList != null) {
for(int i = GameGUI.gameResources.playerLaserList.size() - 1; i >= 0; i--) {
tempColor = g2.getColor();
oldTransform = g2.getTransform();
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(10));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawLine((int) (GameGUI.gameResources.playerLaserList.get(i).getCurrentLine().getStartX() + 0.5), (int) (GameGUI.gameResources.playerLaserList.get(i).getCurrentLine().getStartY() + 0.5), (int) (GameGUI.gameResources.playerLaserList.get(i).getCurrentLine().getEndX() + 0.5), (int) (GameGUI.gameResources.playerLaserList.get(i).getCurrentLine().getEndY() + 0.5));
g2.setTransform(oldTransform);
g2.setColor(tempColor);
}
}
if(GameGUI.gameResources.aiLaserList != null) {
for(int i = GameGUI.gameResources.aiLaserList.size() - 1; i >= 0; i--) {
tempColor = g2.getColor();
oldTransform = g2.getTransform();
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(10));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawLine((int) (GameGUI.gameResources.aiLaserList.get(i).getCurrentLine().getStartX() + 0.5), (int) (GameGUI.gameResources.aiLaserList.get(i).getCurrentLine().getStartY() + 0.5), (int) (GameGUI.gameResources.aiLaserList.get(i).getCurrentLine().getEndX() + 0.5), (int) (GameGUI.gameResources.aiLaserList.get(i).getCurrentLine().getEndY() + 0.5));
g2.setTransform(oldTransform);
g2.setColor(tempColor);
}
}
}
}
else try {
if(GameGUI.startScreen.checkGameOver() && GameGUI.startScreen.getGameOverVector() != null) {
g2.drawGlyphVector(GameGUI.startScreen.getGameOverVector(), (int) (380 - GameGUI.startScreen.getGameOverVector().getNumGlyphs() * (double) GameGUI.startScreen.healthBarGlyphVector.getFont().getSize() / 2 + 0.5), 250 - 29);
GameGUI.startScreen.imageList = new ArrayList <String> (Arrays.asList());
}
} catch (GameResourceException ex) {
Logger.getLogger(GameCanvas.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void actionPerformed(ActionEvent e) {
if((code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN || code == KeyEvent.VK_LEFT || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_W || code == KeyEvent.VK_S || code == KeyEvent.VK_A || code == KeyEvent.VK_D) && keyPress && x >= 0 && x <= 680 && y >= 0 && y <= 400) {
x += velX;
y += velY;
GameGUI.gameResources.getPlayerRobot().setLocation(new Point((int) (x + 0.5), (int) (y + 0.5)), new Point((int) (x + 0.5 + 37), (int) (y + 0.5 + 99)));
}
else {
if(x < 0) x++;
if(x > 680) x--;
if(y < 0) y++;
if(y > 400) y--;
}
if(GameGUI.gameResources.playerLaserList != null) {
for(int i = GameGUI.gameResources.playerLaserList.size() - 1; i >= 0; i--) {
Rectangle tempRectAI = new Rectangle(GameGUI.gameResources.getAIRobot().getLocation().get(0).getLocation().x, GameGUI.gameResources.getAIRobot().getLocation().get(0).getLocation().y, GameGUI.gameResources.getAIRobot().getLocation().get(1).getLocation().x, GameGUI.gameResources.getAIRobot().getLocation().get(1).getLocation().y);
Line line = GameGUI.gameResources.playerLaserList.get(i).getCurrentLine();
if(GameGUI.gameResources.playerLaserList.get(i).getLocation().x + 50 < 0 || GameGUI.gameResources.playerLaserList.get(i).getLocation().x > 762 || GameGUI.gameResources.playerLaserList.get(i).getLocation().y + 50 < 0 || GameGUI.gameResources.playerLaserList.get(i).getLocation().y > 500 || tempRectAI.intersectsLine(line.getStartX(), line.getStartY(), line.getEndX(), line.getEndY()))
GameGUI.gameResources.playerLaserList.remove(i);
else {
GameGUI.gameResources.playerLaserList.get(i).move(time);
}
}
}
if(GameGUI.gameResources.aiLaserList != null) {
for(int i = GameGUI.gameResources.aiLaserList.size() - 1; i >= 0; i--) {
Rectangle tempRectPlayer = new Rectangle(GameGUI.gameResources.getPlayerRobot().getLocation().get(0).getLocation().x, GameGUI.gameResources.getPlayerRobot().getLocation().get(0).getLocation().y, GameGUI.gameResources.getPlayerRobot().getLocation().get(1).getLocation().x, GameGUI.gameResources.getPlayerRobot().getLocation().get(1).getLocation().y);
Line line = GameGUI.gameResources.aiLaserList.get(i).getCurrentLine();
if(GameGUI.gameResources.aiLaserList.get(i).getLocation().x + 50 < 0 || GameGUI.gameResources.aiLaserList.get(i).getLocation().x > 762 || GameGUI.gameResources.aiLaserList.get(i).getLocation().y + 50 < 0 || GameGUI.gameResources.aiLaserList.get(i).getLocation().y > 500 || tempRectPlayer.intersectsLine(line.getStartX(), line.getStartY(), line.getEndX(), line.getEndY()))
GameGUI.gameResources.aiLaserList.remove(i);
else {
GameGUI.gameResources.aiLaserList.get(i).move(time);
}
}
}
repaint();
}
public void up() {
velY = -1.5;
velX = 0;
}
public void down() {
velY = 1.5;
velX = 0;
}
public void left() {
velX = -1.5;
velY = 0;
}
public void right() {
velX = 1.5;
velY = 0;
}
public void keyPressed(KeyEvent e) {
keyPress = true;
code = e.getKeyCode();
if(code == KeyEvent.VK_UP || code == KeyEvent.VK_W) {
up();
}
if(code == KeyEvent.VK_DOWN || code == KeyEvent.VK_S) {
down();
}
if(code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_D) {
right();
}
if(code == KeyEvent.VK_LEFT || code == KeyEvent.VK_A) {
left();
}
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {
keyPress = false;
}
public void mouseExited(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseClicked(MouseEvent evt) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent evt) {
mousePoint = evt.getPoint();
if(GameGUI.getGameOver()) GameGUI.gameResources.resetForNextLevel();
else {
GameGUI.gameResources.getPlayerRobot().setLocation(new Point((int) (x + 0.5), (int) (y + 0.5)), new Point((int) (x + 0.5 + 37), (int) (y + 0.5 + 99)));
Rectangle tempR = new Rectangle(GameGUI.gameResources.getPlayerRobot().getLocation().get(0).x, GameGUI.gameResources.getPlayerRobot().getLocation().get(0).y, GameGUI.gameResources.getPlayerRobot().getLocation().get(1).x, GameGUI.gameResources.getPlayerRobot().getLocation().get(1).y);
GameGUI.gameResources.playerLaserList.add(new Laser(new Point((int) (tempR.getCenterX() + 0.5), (int) (tempR.getCenterY() + 0.5)), evt.getPoint(), GameGUI.gameResources));
}
}
}
Laser:
package application;
import java.awt.Point;
import javafx.scene.shape.Line;
public class Laser {
private Point point1;
private Point point2;
private Point currentPoint;
private double angle;
private Line laserLine;
private Point farEnd;
private Point farStart;
private double x1, x2, y1, y2, m, y3, x3;
private GameResources gameResources;
public Laser(Point tempPoint1, Point tempPoint2, GameResources tempGR) {
gameResources = tempGR;
currentPoint = point1 = tempPoint1;
point2 = tempPoint2;
double leg1 = point2.x - point1.x;
double leg2 = point2.y - point1.y;
double hyp = Math.sqrt(Math.pow(leg1, 2) + Math.pow(leg2, 2));
angle = Math.asin(leg2 / hyp);
if(angle < 0) angle = 2 * Math.abs(angle);
farEnd = getPointX(460);
farStart = getPointX(0);
laserLine = new Line(farStart.x, farStart.y, farEnd.x, farStart.y);
x1 = tempPoint1.x;
y1 = tempPoint1.y;
x2 = tempPoint2.x;
y2 = tempPoint2.y;
m = (y2 - y1) / (x2 - x1);
x3 = 0;
y3 = 0;
}
public Point getInitialLocation() {
return point1;
}
public Point getLocation() {
return currentPoint;
}
public double getAngle() {
return angle;
}
public Line getLine() {
return laserLine;
}
public Line getCurrentLine() {
Line currentLine = new Line();
if(getAngle() < Math.PI && getAngle() > 0)
currentLine = new Line((int) (currentPoint.x + 0.5), (int) (currentPoint.y + 0.5), (int) (getPointX((int) (currentPoint.y + 0.5) + (int) (Math.sin(angle) * 50 + 0.5)).x + 0.5), (int) (currentPoint.y + 0.5) + (int) (Math.sin(angle) * 50 + 0.5));
else if(getAngle() > Math.PI && getAngle() < 2 * Math.PI)
currentLine = new Line((int) (currentPoint.x + 0.5), (int) (currentPoint.y + 0.5), (int) (getPointX((int) (currentPoint.y + 0.5) - (int) (Math.sin(angle) * 50 + 0.5)).x + 0.5), (int) (currentPoint.y + 0.5) - (int) (Math.sin(angle) * 50 + 0.5));
System.out.println(currentLine.getStartX() + " " + currentLine.getStartY() + " " + point1);
return currentLine;
}
public void setLocation(Point tempLocation) {
currentPoint = tempLocation;
}
public Point getPointY(int x) {
if(x1 == x2 && y1 != y2) return null;
else if(m < 0) y3 = ((y2 - y1) / (x2 - x1)) * (double) x - (x2 * ((y2 - y1) / (x2 - x1)) - y2);
else if(m > 0) y3 = ((y2 - y1) / (x2 - x1)) * (double) x + (x2 * ((y2 - y1) / (x2 - x1)) - y2);
else if(m == 0) y3 = ((y2 - y1) / (x2 - x1)) * (double) x;
return new Point(x, (int) (y3 + 0.5));
}
public Point getPointX(int y) {
if(x1 == x2 && y1 != y2) return new Point((int) (x1 + 0.5), y);
else if(m < 0) x3 = ((double) y + (x2 * ((y2 - y1) / (x2 - x1)) - y2)) / ((y2 - y1) / (x2 - x1));
else if(m > 0) x3 = ((double) y - (x2 * ((y2 - y1) / (x2 - x1)) - y2)) / ((y2 - y1) / (x2 - x1));
else if(m == 0) x3 = (double) y / (((y2 - y1) / (x2 - x1)));
return new Point((int) (x3 + 0.5), (int) (y + 0.5));
}
public Line move(double time) {
//old algorithm
/*double x = 0, y = 0;
if(y2 > y1) {
y = currentPoint.y + gameResources.getLaserSpeed() * time;
currentPoint = getPointX((int) y);
}
else if(y2 < y1) {
y = currentPoint.y - gameResources.getLaserSpeed() * time;
currentPoint = getPointX((int) y);
}
else if(y2 == y1 && x2 > x1) {
x = currentPoint.x + gameResources.getLaserSpeed() * time;
currentPoint = getPointY((int) x);
}
else if(y2 == y1 && x2 < x1) {
x = currentPoint.x - gameResources.getLaserSpeed() * time;
currentPoint = getPointY((int) x);
}*/
//new algorithm
if(getAngle() < Math.PI / 2 && getAngle() > 0) {
System.out.println("(1) First quad");
setLocation(getPointY((int) (getLocation().x + 1 + 0.5)));
}
else if(getAngle() < Math.PI && getAngle() > Math.PI / 2) {
System.out.println("(2) Second quad");
setLocation(getPointY((int) (getLocation().x - 1 - 0.5)));
}
else if(getAngle() > Math.PI && getAngle() < 3 * Math.PI / 2) {
System.out.println("(3) Third quad");
setLocation(getPointY((int) (getLocation().x - 1 - 0.5)));
}
else if(getAngle() > 3 * Math.PI / 2 && getAngle() < 2 * Math.PI) {
System.out.println("(4) Fourth quad");
setLocation(getPointY((int) (getLocation().x + 1 + 0.5)));
}
else if(getAngle() == 2 * Math.PI || getAngle() == 0)
setLocation(new Point((int) (getLocation().x + 1 + 0.5), (int) (getLocation().y + 0.5)));
else if(getAngle() == Math.PI)
setLocation(new Point((int) (getLocation().x - 1 - 0.5), (int) (getLocation().y + 0.5)));
else if(getAngle() == Math.PI / 2)
setLocation(new Point((int) (getLocation().x + 0.5), (int) (getLocation().y + 1 + 0.5)));
else if(getAngle() == 3 * Math.PI / 2)
setLocation(new Point((int) (getLocation().x + 0.5), (int) (getLocation().y - 1 - 0.5)));
return getCurrentLine();
}
public void setGameResources(GameResources tempGR) {
gameResources = tempGR;
}
}
I am making a game in java and I have most of it done. However, one of the last bugs i need to fix is that enemy sprites can overlap each other and spawn on top of one another off screen. I want to make it so if enemy sprites collide they can only touch but not overlap. here is the code for the enemy class.
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Enemy extends Base {
int x;
int y;
int velx = -2;
int vely = 0;
public Enemy(int x, int y) {
super(x,y);
this.x = x;
this.y = y;
}
public void update() {
movement();
x += velx;
y += vely;
if (x < - 15) {
x = -15;
movement();
}
if (x > 1100) {
x = 1100;
movement();
}
if (y > 660) {
y = 660;
movement();
}
if (y < 10) {
y = 10;
movement();
}
}
public void draw(Graphics g) {
g.drawImage(getEnemyImage(), x, y, null);
}
public static Image getEnemyImage(){
ImageIcon ic = new ImageIcon("enemy.gif");
return ic.getImage();
}
public Rectangle getBounds(){
return new Rectangle(x, y, getEnemyImage().getWidth(null), getEnemyImage().getHeight(null));
}
public void checkColision(){
ArrayList<Base> enemies = GamePanel.getEnemyList();
if (x <= 0) {
velx = 2;
}
if (x >= 1096) {
velx = -2;
}
for (int a = 0; a < enemies.size(); a++) {
Base temp = GamePanel.enemy.get(a);
if (getBounds().intersects(temp.getBounds())) {
// where the collision check should happen.
}
}
}
public void movement(){
if (y > 16) {
if (x > GamePanel.p.getX()) {
velx = - 2;
}
if (x < GamePanel.p.getX()) {
velx = 2;
}
if (y > GamePanel.p.getY()) {
vely = -2;
}
if (y < GamePanel.p.getY()) {
vely = 2;
}
}
}
}
and this is where the enemies are spawned.
for (int a = 0; a < enemy_amount; a++) {
space += 50;
int rand = (int)(Math.random() * 2) + 1;
if (rand == 1) {
int randp = (int)(Math.random() * 2) + 1;
int x = 0;
int y = 0;
if (randp == 1) {
x = 1250 + space;
y = 500;
}
if (randp == 2) {
x = 1250 + space;
y = 100;
}
enemy.add(new Enemy(x,y));
}
if (rand == 2) {
int randp = (int)(Math.random() * 2) + 1;
int x = 0;
int y = 0;
if (randp == 1) {
x = 250;
y = -100 - space;
}
if (randp == 2) {
x = 850;
y = -100 - space;
}
enemy.add(new Enemy2(x,y));
}
}
any help would be great because i am really stuck.
I have a Custom View which draws lines an saves them to an ArrayList. What I want to be able to do is check if a specified point is on a line inside the Arraylist and return the line. I have been able to do this when the line is straight by using if (l.startX == l.stopX && l.startY < l.stopY but this doesn't work if the line is on an angle. I would also like to do this with drawText and drawCircle. Is there some simple way of doing this that I have missed?
DrawView.java
class Line {
float startX, startY, stopX, stopY;
public Line(float startX, float startY, float stopX, float stopY) {
this.startX = startX;
this.startY = startY;
this.stopX = stopX;
this.stopY = stopY;
}
public Line(float startX, float startY) { // for convenience
this(startX, startY, startX, startY);
}
}
public class DrawView extends View {
Paint paint = new Paint();
ArrayList<Line> lines = new ArrayList<Line>();
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(6f);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
}
#Override
protected void onDraw(Canvas canvas) {
for (Line l : lines) {
canvas.drawLine(l.startX, l.startY, l.stopX, l.stopY, paint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
lines.add(new Line(event.getX(), event.getY()));
return true;
}
else if ((event.getAction() == MotionEvent.ACTION_MOVE ||
event.getAction() == MotionEvent.ACTION_UP) &&
lines.size() > 0) {
Line current = lines.get(lines.size() - 1);
current.stopX = event.getX();
current.stopY = event.getY();
Invalidate();
return true;
}
else {
return false;
}
}
}
I don't know if there is a canvas library for this but manually you can:
go through your list of lines
form equations for each line in let's say slope-intercept form y = mx + b
plugin in the event.X() and event.Y() into the above equation as x and y for each line
if the 2 sides are equal then your touch event is on that line
After many hours of trying I managed to come up with a an algorithm to check if a point is on a given line using a mixture of slope-intersect formula and if (x = startX && y > startY && y < stopY) Below is the code, it returns true if point is on line otherwise false, hopefully this can save someone time!
public boolean checkPosition(float x, float y, float sx, float sy, float ex, float ey) {
float mX = ex - sx;
float mY = ey - sy;
float smX = sx - ex;
float smY = sy - ey;
float pmX = mX;
float pmY = mY;
float psmX = smX;
float psmY = smY;
float yY = ey - y;
float xX = ex - x;
float sX = sx - x;
float sY = sy - y;
float m = mY / mX;
float b = sy - (m * sx);
if (mX < 0) {
pmX = mX * - 1;
}
if (mY < 0) {
pmY = mY * - 1;
}
if (smX < 0) {
psmX = smX * - 1;
}
if (smY < 0) {
psmY = smY * - 1;
}
if (yY < 0) {
yY = yY * - 1;
}
if (xX < 0) {
xX = xX * - 1;
}
if (sX < 0) {
sX = sX * - 1;
}
if (sY < 0) {
sY = sY * - 1;
}
if (sy == ey && y == sy) {
if (sx >= ex) {
if (x <= sx && x >= ex) return true;
else return false;
}
else if (ex >= sx) {
if (x <= ex && x >= sx) return true;
else return false;
}
else return false;
}
else if (sx == ex && x == sx) {
if (sy >= ey) {
if (y <= sy && y >= ey) return true;
else return false;
}
else if (ey >= sy) {
if (y <= ey && y >= sy) return true;
else return false;
}
else return false;
}
else if (xX <= pmX && sX <= psmX && yY <= pmY && sY <= psmY) {
if (y == (m * x) + b) return true;
else return false;
}
else return false;
}
I am trying to make a processing program, but if I use P2D, P3D, or OPENGL mode I get an error:
com.sun.jdi.VMDisconnectedException
at com.sun.tools.jdi.TargetVM.waitForReply(TargetVM.java:285)
at com.sun.tools.jdi.VirtualMachineImpl.waitForTargetReply(VirtualMachineImpl.java:1015)
at com.sun.tools.jdi.PacketStream.waitForReply(PacketStream.java:51)
at com.sun.tools.jdi.JDWP$ObjectReference$InvokeMethod.waitForReply(JDWP.java:4589)
at com.sun.tools.jdi.ObjectReferenceImpl.invokeMethod(ObjectReferenceImpl.java:374)
at processing.mode.java.runner.Runner.findException(Runner.java:701)
at processing.mode.java.runner.Runner.reportException(Runner.java:652)
at processing.mode.java.runner.Runner.exception(Runner.java:595)
at processing.mode.java.runner.EventThread.exceptionEvent(EventThread.java:367)
at processing.mode.java.runner.EventThread.handleEvent(EventThread.java:255)
at processing.mode.java.runner.EventThread.run(EventThread.java:89)
the error message itself varies between P2D and P3D, but they both get a no framebuffer objects available error. I am using processing 2.0b7, please help and let me know if you need more info.
Note: I don't know if this is a separate issue or not, but I am also getting GLSL shader errors to.
Now, here is my code:
Cell[][] Cells = new Cell[50][50];
byte Direction = 1;
byte Times = 1;
int oldwidth = 500;
int oldheight = 500;
void setup() {
size(oldwidth, oldheight, OPENGL);
background(255);
colorMode(HSB,250);
for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) {
Cells[x][y] = new Cell(x * 5, y * 5, 255, x * (width / 50), y * (height / 50), width / 50, height / 50);
}
}
}
void draw() {
for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) {
if (width == oldwidth) Cells[x][y].Width = width / 50;
if (height == oldheight) Cells[x][y].Height = height / 50;
if (Direction == 1){
Cells[x][y].Hue += 5;
if (Cells[x][y].Hue > 250) Cells[x][y].Hue -= 250;
}
if (Direction == 2){
Cells[x][y].Saturation -= 5;
if (Cells[x][y].Saturation < 0) Cells[x][y].Saturation += 500;
}
if (Direction == 3){
Cells[x][y].Hue -= 5;
if (Cells[x][y].Hue < 0) Cells[x][y].Hue += 250;
}
if (Direction == 4){
Cells[x][y].Saturation += 5;
if (Cells[x][y].Saturation > 500) Cells[x][y].Saturation -= 500;
}
Cells[x][y].Draw();
}
}
if (Times == 50){
Times = 1;
if (Direction == 4) Direction = 1; else Direction += 1;
} else Times += 1;
delay(10);
}
class Cell {
int X;
int Y;
int Width;
int Height;
float Hue;
float Saturation;
float Brightness;
Cell(color parC, int parX, int parY, int parWidth, int parHeight) {
Hue = hue(parC);
Saturation = saturation(parC);
Brightness = brightness(parC);
X = parX;
Y = parY;
Width = parWidth;
Height = parHeight;
}
Cell(float parHue, float parSaturation, float parBrightness, int parX, int parY, int parWidth, int parHeight) {
Hue = parHue;
Saturation = parSaturation;
Brightness = parBrightness;
X = parX;
Y = parY;
Width = parWidth;
Height = parHeight;
}
void Draw() {
if (Saturation > 250) if (Saturation > 500) stroke(color(Hue,0,Brightness)); else stroke(color(Hue,Saturation - (Saturation - 250) * 2,Brightness)); else stroke(color(Hue,Saturation,Brightness));
if (Saturation > 250) if (Saturation > 500) fill(color(Hue,0,Brightness)); else fill(color(Hue,Saturation - (Saturation - 250) * 2,Brightness)); else fill(color(Hue,Saturation,Brightness));
rect(X, Y, Width, Height);
}
}
I just realized that it is just that my graphics card does not support OPENGL 2.0
Here is a program that has a ball drop and bounce from wherever the mouse is clicked. Would anyone know how to change the rate that the ball drops to the force of gravity?
Im trying to figure out the proper solution to this... but i am having a little trouble. All help and or input would be much appreciated.
float x;
float y;
float yspeed = 0;
float xspeed = 0;
float balldiameter = 10;
float ballradius = balldiameter/2;
void setup() {
size (400,400);
background (255);
fill (0);
ellipseMode(CENTER);
smooth();
noStroke();
x = width/2;
y = height/2;
}
void draw() {
mouseChecks();
boundaryChecks();
ballFunctions();
keyFunctions();
}
void mouseChecks() {
if (mousePressed == true) {
x = mouseX;
y = mouseY;
yspeed = mouseY - pmouseY;
xspeed = mouseX - pmouseX;
}
}
void boundaryChecks() {
if (y >= height - ballradius) {
y = height - ballradius;
yspeed = -yspeed/1.15;
}
if (y <= ballradius) {
y = ballradius;
yspeed = -yspeed/1.35;
}
if (x >= width -ballradius) {
x = width -ballradius;
xspeed = -xspeed/1.10;
}
if (x <= ballradius) {
x = ballradius;
xspeed = -xspeed/1.10;
}
}
void ballFunctions() {
if (balldiameter < 2) {
balldiameter = 2;
}
if (balldiameter > 400) {
balldiameter = 400;
}
ballradius = balldiameter/2;
background(255); //should this be in here?
ellipse (x,y,balldiameter,balldiameter);
yspeed = yspeed += 0.2;
xspeed = xspeed/1.005;
y = y + yspeed;
x = x + xspeed;
}
void keyFunctions() {
if (keyPressed) {
if(keyCode == UP) {
balldiameter +=1;
}
if (keyCode == DOWN) {
balldiameter -=1;
}
}
}
The acceleration of gravity on earth is 9.81 m/s^2. So, if your ball's velocity is 0 at the point the mouse is clicked, the final velocity will be the acceleration integrated in relation to time. This would be (9.81 * t) / 2. Where t is in seconds. The resulting units would be m/sec. You would have to convert meters to some screen space unit for drawing.