2d Plateform Game Collision - java

Ok... So im creating my first 2d platform game... unfortunately everything is new but i have gotten everything else to work so far but I cant get collision to work. This is kinda long so i expect not to get an answer, but someone who can help... Thank you in advance.
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
public class Expordium {
private JFrame f = new JFrame("Expordium");
private boolean win;
private int level;
private Display display;
public boolean isR, isU, isL, isD;
public static void main(String[] args) {
Expordium game = new Expordium();
game.play(game);
}
Expordium(){
win=false;
level=1;
}
private void play(Expordium game){
display = new Display(game);
f.getContentPane().add(display);
f.addKeyListener(new MyKeyListener());
f.setSize(980 , 360);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
private void advanceLevel() {
level++;
}
public String getLevel() {
String strLevel;
strLevel=Integer.toString(level);
return strLevel;
}
public class MyKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch( keyCode ) {
case KeyEvent.VK_UP:
isU=true;
break;
case KeyEvent.VK_DOWN:
isD=true;
break;
case KeyEvent.VK_LEFT:
isL=true;
break;
case KeyEvent.VK_RIGHT:
isR=true;
break;
case KeyEvent.VK_SPACE :
display.shoot();
}
}
public void keyReleased( KeyEvent e ) {
int keyCode = e.getKeyCode();
switch( keyCode ) {
case KeyEvent.VK_UP:
isU=false;
break;
case KeyEvent.VK_DOWN:
isD=false;
break;
case KeyEvent.VK_LEFT:
isL=false;
break;
case KeyEvent.VK_RIGHT:
isR=false;
break;
}
}
}
}
Display Class
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.html.HTMLDocument.Iterator;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
public class Display extends JPanel implements Runnable{
private static final int FPS = 1000 / 36;
private JFrame f = new JFrame("Expordium");
private Collection<Block> elements = new ArrayList<Block>();
private Collection<Bullet> bullets = new ArrayList<Bullet>();
private BufferedImage Bg;
public Wall wall;
public Guy guy;
public End end;
public Bullet bullet;
private String file;
private Expordium game;
private String[][] strLevel = new String[30][10];
private String[][] strWall = new String[30][10];
Display(Expordium g){
game=g;
readFile();
for(int i=0; i<30; i++){
for(int j=0; j<10; j++){
if(strLevel[i][j].equals("W")){
elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-T.PNG"));
strWall[i][j]=strLevel[i][j];
}
if(strLevel[i][j].equals("A")){
elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-L.PNG"));
strWall[i][j]=strLevel[i][j];
}
if(strLevel[i][j].equals("S")){
elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-B.PNG"));
strWall[i][j]=strLevel[i][j];
}
if(strLevel[i][j].equals("D")){
elements.add(new Wall(i*32,j*32,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/Grass-R.PNG"));
strWall[i][j]=strLevel[i][j];
}
if(strLevel[i][j].equals("s")){
elements.add(guy=new Guy(i*32,j*32,false,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Guy/Guy-R.PNG"));
}
if(strLevel[i][j].equals("e")){
elements.add(end=new End(i*32,j*32,false,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Block/End.PNG"));
}
}
}
new Thread(this).start();
}
public void run(){
long tm = System.currentTimeMillis();
while(true){
update();
repaint();
try {
tm += FPS;
Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
}
catch(InterruptedException e)
{
System.out.println(e);
}
}
}
This is the collision detection part:
public boolean collision() {
java.util.Iterator<Block> iterator = elements.iterator();
while(iterator.hasNext()){
if(iterator.next().isSolid && guy.isColliding((Block)iterator.next())){
return true;
}
}
return false;
}
End
public void update() {
if(!guy.isJump && game.isU){
guy.Jump();
}
if(game.isR){
if(!collision()){
guy.Move(2);
}
}
if(game.isL){
if(!collision()){
guy.Move(1);
}
}
if(guy.isJump){
guy.Jump();
}
}
public void paint(Graphics g){
try {
Bg = ImageIO.read(new File("C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Object/BackGround.PNG"));
} catch (IOException e) {}
g.drawImage(Bg, 0,0,null);
java.util.Iterator<Block> iterator = elements.iterator();
while(iterator.hasNext())
((Block) iterator.next()).draw(g);
java.util.Iterator<Bullet> iterator1 = bullets.iterator();
while(iterator1.hasNext())
((Block) iterator1.next()).draw(g);
}
private void readFile() {
int num=0;
String noFile = "";
String loc ="C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Level/Level " + game.getLevel() + ".txt";
File Level = new File(loc);
file=TextFile.getContents(Level);
for(int i=0; i<file.length(); i++){
if(file.substring(num, num+1).equals("W") || file.substring(num, num+1).equals("A") || file.substring(num, num+1).equals("S") || file.substring(num, num+1).equals("D") || file.substring(num, num+1).equals("e") || file.substring(num, num+1).equals("s") || file.substring(num, num+1).equals(" ")){
noFile=noFile+file.substring(num, num+1);
}
num++;
}
num=0;
for(int j=0; j<10; j++){
for(int i=0; i<30; i++){
strLevel[i][j]=noFile.substring(num, num+1);
num++;
}
}
}
public void shoot() {
if(guy.dir==1){
bullets.add(new Bullet(guy.getX(),guy.getY(),1,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Object/Bullet.PNG"));
}
if(guy.dir==2){
bullets.add(new Bullet(guy.getX(),guy.getY(),2,true,"C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Object/Bullet.PNG"));
}
}
}
Guy Class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Guy extends Block{
private int x, y, groundY;
public boolean isSolid;
private BufferedImage guy;
public boolean isJump=false;
private int accM, accJ;
private String location;
public int dir=2;
public Guy(int startx, int starty, boolean solid, String loc) {
super(startx, starty, solid, loc);
try {
guy = ImageIO.read(new File(loc));
}catch (IOException ex) {}
x=startx;
y=starty;
isSolid=solid;
location=loc;
}
public boolean isColliding(Block e){
int leftSide = getX();
int rightSide = getX() + 31;
int top = getY();
int bottom = getY() + 31;
int eLeftSide = e.getX();
int eRightSide = e.getX() + 31;
int eTop = e.getY();
int eBottom = e.getY() + 31;
if(eLeftSide < rightSide)
if(eRightSide > leftSide)
if(eTop < bottom)
if(eBottom > top)
return true;
return false;
}
public void draw(Graphics g) {
try {
guy = ImageIO.read(new File(location));
} catch (IOException e) {}
g.drawImage(guy,x,y,null);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void setX(int x1){
x=x1;
}
public void setY(int y1){
y=y1;
}
public void Move(int i) {
if(i==2){
dir=2;
location="C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Guy/Guy-R.PNG";
x=x+2;
}
else{
dir=1;
location="C:/Program Files (x86)/Software/eclipse/Programs/Expordium/Picture/Guy/Guy-L.PNG";
x=x-2;
}
}
public void Jump() {
if(groundY==0){
isJump=true;
y=y+3;
groundY=groundY+3;
}
else if(groundY!=0 && groundY<=48 && groundY!=96){
y=y-3;
groundY=groundY+3;
}
else if(groundY!=0 && groundY>=48 && groundY!=96){
y=y+3;
groundY=groundY+3;
}
else{
isJump=false;
groundY=0;
}
}
}
Wall Class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Wall extends Block{
private int x, y;
public boolean isSolid;
private BufferedImage wall;
public Wall(int startx, int starty, boolean solid, String loc) {
super(startx, starty, solid, loc);
try {
wall = ImageIO.read(new File(loc));
}catch (IOException ex) {}
x=startx;
y=starty;
isSolid=solid;
}
public void draw(Graphics g) {
g.drawImage(wall,x,y,null);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
End Class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class End extends Block{
private int x, y;
public boolean isSolid;
private BufferedImage end;
public End(int startx, int starty, boolean solid, String loc) {
super(startx, starty, solid, loc);
try {
end = ImageIO.read(new File(loc));
}catch (IOException ex) {}
x=startx;
y=starty;
isSolid=solid;
}
public void draw(Graphics g) {
g.drawImage(end,x,y,null);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
Block Class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public abstract class Block {
private int x, y;
public boolean isSolid;
private BufferedImage block;
private String location;
public Block(int startx, int starty, boolean solid, String loc) {
x=startx;
y=starty;
isSolid=solid;
location=loc;
try {
block = ImageIO.read(new File(loc));
} catch (IOException e) {
}
}
public abstract void draw(Graphics g);
public int getX(){
return x;
}
public int getY(){
return y;
}
}
Bullet Class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Bullet extends Block{
private int x, y;
public boolean isSolid;
private BufferedImage bullet;
public int dir;
public Bullet(int startx, int starty, int dir1, boolean solid, String loc) {
super(startx, starty, solid, loc);
try {
bullet = ImageIO.read(new File(loc));
}catch (IOException ex) {}
x=startx;
y=starty;
dir=dir1;
isSolid=solid;
}
public void draw(Graphics g) {
if(dir==1){
x=x-5;
}
if(dir==2){
x=x+5;
}
g.drawImage(bullet,x,y,null);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}

This has nothing to do with your question, but what you are doing is so bad, especially my first remark.
Each time you render the game, you load the image for your "guy" from the file. You should load them all (player-left, player-right) and then render the correct image, depending on the direction of your "guy".
You are using absolute path to point to the images. Use relative paths.
Do not use 1 and 2 as directions, but something more logic, eg:
-2 means run to the left
-1 means no movement, but pointing to the left
(0 means no movement)
+1 means no movement, but pointing to the right
+2 means run to the right
Variable names do start with a lowercase character, eg: bg instead of Bg
Use in your next game project floats for the coordinates.
Here is some code:
private BufferedImage player_left;
private BufferedImage player_right;
public Guy() { // Your consturctor:
player_left = ImageIO.read(new File("resources/img/player-left.png"));
player_right = ImageIO.read(new Fiel("resources/img/player-right.png"));
}
public void draw(Graphics g)
{
if (direction == -1) { // left
g.draw(player_left, .......);
} else if (direction == 1) // right
{
g.draw(player_right, ......);
} else if (direction == ...)
{
.....
}
}

One thing I noticed is that you're calling the next() method twice in the iterator. Each time you call the next() method the iterator returns the next Block. If there are no Block objects left, you'll get an exception.
The code below fixes that, but I doubt if it's going to fix the problem itself...
public boolean collision() {
java.util.Iterator<Block> iterator = elements.iterator();
while(iterator.hasNext()){
Block item = iterator.next();
if(item.isSolid && guy.isColliding(item)){
return true;
}
}
return false;
}

Have you ever looked into an open source 2d game engine ? It will do all the heavy lifting for you e.g. Physics / Collision Detection / Controls.
Here is a usefull stackoverflow post:
https://stackoverflow.com/questions/293079/java-2d-game-frameworks

in the following part of the code:
if(eLeftSide < rightSide)
if(eRightSide > leftSide)
if(eTop < bottom)
if(eBottom > top)
return true;
return false;
you only check for one instance of collision (when the guy is inside the block). For simple bounding box collisions you'll need other type of checking. Try drawing two boxes on paper and check how they can be colliding and try to implement that

Related

Using Graphics2D, when I drag the shapes, I want to move the shapes

When I drag the shapes that I drew, I want to move.
but I do not know how to do it.
I have tried the make move method in GPanel but could not make it.
knowledge.
I have been working on this for almost 1 week and tried all the solutions that I could think of.
This is my first time posting a code question on stack overflow.
I do really want to learn.
. And love you all.
I hope one day I could be a savior for code newbies
Have to use affine transform
this is drawing page
package frame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.Vector;
import javax.swing.JPanel;
import main.GConstants.EAnchorLocation;
import main.GConstants.EDrawingStyle;
import shapeTool.GShapeTool;
public class GPanel extends JPanel {
private static final long serialVersionUID = 1L;
private GShapeTool shapeTool;
private GShapeTool selectedShape;
private Vector<GShapeTool> shapes;
public GPanel() {
this.setBackground(Color.WHITE);
this.shapes = new Vector<GShapeTool>();
MouseHandler mouseHandler = new MouseHandler();
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
this.addMouseWheelListener(mouseHandler);
}
public void initialize() {}
public Vector<GShapeTool> getShapes() {
return this.shapes;
}
public void setShapes(Vector<GShapeTool> shapes){
this.shapes = shapes;
this.updateUI();
}
public void paint(Graphics graphics) {
super.paint(graphics);
for(GShapeTool shape: this.shapes) {
shape.draw((Graphics2D)graphics);
}
}
public void setShapeTool(GShapeTool shapeTool) {
this.shapeTool = shapeTool;
}
private boolean onShape(int x, int y) {
boolean shapeCheck = false;
for(GShapeTool shapeTool: this.shapes) {
if(shapeTool.contains(x, y)) {
this.selectedShape = shapeTool;
shapeCheck = true;
} else {
shapeTool.setSelected(false, (Graphics2D)getGraphics());
}
}
if(shapeCheck) {
this.selectedShape.setSelected(true, (Graphics2D)getGraphics());
}
return shapeCheck;
}
private void setInitialPoint(int x, int y) {
this.selectedShape = this.shapeTool.clone();
this.selectedShape.setInitialPoint(x, y);
}
private void setFinalPoint(int x, int y) {
for(GShapeTool shapeTool: this.shapes) {
shapeTool.setSelected(false, (Graphics2D)getGraphics());
}
// Graphics2D graphics2D = (Graphics2D) this.getGraphics();
//set xor mode;
// graphics2D.setXORMode(getBackground());
this.selectedShape.setFinalPoint(x, y);
this.selectedShape.setSelected(true, (Graphics2D)getGraphics());
this.shapes.add(this.selectedShape);
}
private void setIntermediatePoint(int x, int y) {
this.selectedShape.setIntermediatePoint(x, y);
}
private void animate(int x, int y) {
Graphics2D graphics2D = (Graphics2D) this.getGraphics();
//set xor mode;
graphics2D.setXORMode(getBackground());
this.selectedShape.animate(graphics2D, x, y);
}
private class MouseHandler
implements MouseListener, MouseMotionListener, MouseWheelListener {
private boolean isDrawing;
MouseHandler() {
this.isDrawing = false;
}
#Override
public void mouseClicked(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) {
if(e.getClickCount() == 1) {
this.mouseLButton1Clicked(e);
} else if(e.getClickCount() == 2) {
this.mouseLButton2Clicked(e);
}
} else if(e.getButton() == MouseEvent.BUTTON2) {
if(e.getClickCount() == 1) {
this.mouseRButton1Clicked(e);
}
}
}
#Override
public void mouseMoved(MouseEvent e) {
if(isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.eNPointDrawing) {
animate(e.getX(), e.getY());
}
}
}
private void mouseLButton1Clicked(MouseEvent e) {
if(!this.isDrawing) {
if(!onShape(e.getX(), e.getY())) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.eNPointDrawing) {
setInitialPoint(e.getX(), e.getY());
this.isDrawing = true;
}
}
else if(onShape(e.getX(), e.getY())) {
onShape(e.getX(), e.getY());
}
} else {
if(shapeTool.getDrawingStyle() == EDrawingStyle.eNPointDrawing) {
setIntermediatePoint(e.getX(),e.getY());
}
}
}
private void mouseLButton2Clicked(MouseEvent e) {
if(this.isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.eNPointDrawing) {
setFinalPoint(e.getX(), e.getY());
this.isDrawing = false;
}
}
}
private void mouseRButton1Clicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) {
if(!this.isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.e2PointDrawing) {
setInitialPoint(e.getX(), e.getY());
this.isDrawing = true;
}
}
}
}
#Override
public void mouseDragged(MouseEvent e) {
if(this.isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.e2PointDrawing) {
animate(e.getX(), e.getY());
}
}
}
#Override
public void mouseReleased(MouseEvent e) {
if(this.isDrawing) {
if(shapeTool.getDrawingStyle() == EDrawingStyle.e2PointDrawing) {
setFinalPoint(e.getX(), e.getY());
this.isDrawing = false;
}
}
}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseWheelMoved(MouseWheelEvent e) {}
}
}
this is abstract class for shapes
package shapeTool;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Ellipse2D.Double;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.Vector;
import main.GConstants.EAnchorLocation;
import main.GConstants.EDrawingStyle;
public abstract class GShapeTool implements Serializable {
private static final long serialVersionUID = 1L;
public enum EAnchors {
x0y0,
x0y1,
x0y2,
x1y0,
x1y2,
x2y0,
x2y1,
x2y2,
RR;
}
public final static int wAnchor = 10;
public final static int hAnchor = 10;
private EDrawingStyle eDrawingStyle;
protected boolean isSelected;
protected Shape shape;
private Ellipse2D[] anchors;
public GShapeTool(EDrawingStyle eDrawingStyle) {
this.eDrawingStyle = eDrawingStyle;
this.isSelected = false;
this.anchors = new Ellipse2D.Double[EAnchors.values().length];
for(EAnchors eAnchor: EAnchors.values()) {
this.anchors[eAnchor.ordinal()] = new Ellipse2D.Double();
}
}
public EDrawingStyle getDrawingStyle() {
return this.eDrawingStyle;
}
public boolean contains(int x, int y) {
return this.shape.contains(x , y);
}
private void drawAnchors(Graphics2D graphics2D) {
// draw bounding rectangle
Rectangle rectangle = this.shape.getBounds();
int x0 = rectangle.x-wAnchor;
int x1 = rectangle.x + rectangle.width/2;
int x2 = rectangle.x + rectangle.width;
int y0 = rectangle.y-hAnchor;
int y1 = rectangle.y + rectangle.height/2;
int y2 = rectangle.y + rectangle.height;
this.anchors[EAnchors.x0y0.ordinal()].setFrame(x0,y0,wAnchor,hAnchor);
this.anchors[EAnchors.x0y1.ordinal()].setFrame(x0,y1,wAnchor,hAnchor);
this.anchors[EAnchors.x0y2.ordinal()].setFrame(x0,y2,wAnchor,hAnchor);
this.anchors[EAnchors.x1y0.ordinal()].setFrame(x1,y0,wAnchor,hAnchor);
this.anchors[EAnchors.x1y2.ordinal()].setFrame(x1,y2,wAnchor,hAnchor);
this.anchors[EAnchors.x2y0.ordinal()].setFrame(x2,y0,wAnchor,hAnchor);
this.anchors[EAnchors.x2y1.ordinal()].setFrame(x2,y1,wAnchor,hAnchor);
this.anchors[EAnchors.x2y2.ordinal()].setFrame(x2,y2,wAnchor,hAnchor);
this.anchors[EAnchors.RR.ordinal()].setFrame(x1,y0-50,wAnchor,hAnchor);
//draw anchors
graphics2D.setColor(Color.BLACK);
for(EAnchors eAnchor: EAnchors.values()) {
graphics2D.draw(this.anchors[eAnchor.ordinal()]);
}
}
private void eraseAnchors(Graphics2D graphics2D) {
graphics2D.setColor(Color.WHITE);
for(EAnchors eAnchor: EAnchors.values()) {
graphics2D.draw(this.anchors[eAnchor.ordinal()]);
}
}
public void setSelected(boolean isSelected, Graphics2D graphics2D) {
if(this.isSelected) {
if(!isSelected) {
//erase
this.eraseAnchors(graphics2D);
}
} else {
if(isSelected) {
//draw
this.drawAnchors(graphics2D);
}
}
this.isSelected = isSelected;
}
public void draw(Graphics2D graphics) {
graphics.draw(this.shape);
}
public void animate(Graphics2D graphics2d, int x, int y) {
//erase;
this.draw(graphics2d);
// //move point
this.movePoint(x,y);
// //draw;
this.draw(graphics2d);
}
//interface
public abstract GShapeTool clone();
public abstract void setInitialPoint(int x, int y);
public abstract void setFinalPoint(int x, int y);
public abstract void setIntermediatePoint(int x, int y);
public abstract void movePoint(int x, int y);
}
and this is shape class that extends GShapeTool
package shapeTool;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import main.GConstants.EDrawingStyle;
public class GRectangle extends GShapeTool {
//attributes
private static final long serialVersionUID = 1L;
//components
//constructor
public GRectangle() {
super(EDrawingStyle.e2PointDrawing);
this.shape = new Rectangle();
}
#Override
public GShapeTool clone() {
GShapeTool cloned = new GRectangle();
return cloned;
}
// methods
#Override
public void setInitialPoint(int x, int y) {
Rectangle rectangle = (Rectangle) this.shape;
rectangle.setLocation(x, y);
rectangle.setSize(0, 0);
}
#Override
public void setIntermediatePoint(int x, int y) {
// TODO Auto-generated method stub
}
#Override
public void setFinalPoint(int x, int y) {
}
#Override
public void movePoint(int x, int y) {
Rectangle rectangle = (Rectangle) this.shape;
rectangle.setSize(x-rectangle.x, y-rectangle.y);
}
}
You should get a dragstart event. That is when you save the mouse position and the selected object(s).
When you get a dragfinished event, again note the mouse positon and move the objects accordingly. The move might just happen on the screen, but e.g. in case the drop occurred on the trashcan you want to delete them.
Now while the drag is active you might get a number of more dragging events, which you should use to update the screen and give feedback to the user. This would most of the time just be to look at the mouse positon and the selected objects and draw them accordingly.

Player Character Movement Error LibGDX RPG

I am making an RPG game, however, I have an error at the moment. The player's character can move in all four cardinal directions, but the player becomes stuck if you move right, up or down.
Also, the error seems to have some logic to it:
if moving down, the character is stuck in a loop moving down
unless the up arrow is pressed, then the player will begin a new infinite loop for up
unless the right arrow is pressed, then the player will begin a new infinite loop for right
So right seems to take precedence over up which takes precedence over down.
Strangely, the leftward movement works perfectly. Even when the character is stuck in an infinite loop, the left arrow key will always cause the player to move left in the correct way.
I don't understand where the error is in my code. I don't know why the leftward movement works while the other three directions do not. I don't understand why there seems to be some sort of priority ordering between the other three directions as well.
I have looked through the program and I don't think I treat leftward movement differently to any other direction. However, I might be wrong, considering this error.
Due to the 30k word limit, I do not have enough space to include all the code here. Therefore, I have included a link to my github, so you can see the code there instead.
https://github.com/davey67/bludbourne
I think these classes are probably the most important classes though:
package com.bludbourne.game.desktop;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.bludbourne.game.BludBourne;
public class DesktopLauncher {
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.title="BludBourne";
config.useGL30=false;
config.width =480;
config.height=480;
Application app = new LwjglApplication(new BludBourne(),config);
Gdx.app=app;
Gdx.app.setLogLevel(Application.LOG_DEBUG);
}
}
/
package com.bludbourne.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.bludbourne.game.screens.MainGameScreen;
import com.badlogic.gdx.Game;
public class BludBourne extends Game {
public static final MainGameScreen _mainGameScreen = new MainGameScreen();
#Override
public void create () {
setScreen(_mainGameScreen);
}
#Override
public void dispose () {
_mainGameScreen.dispose();
}
}
/
package com.bludbourne.game;
import java.util.HashMap;
import java.util.Map;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.math.Vector3;
public class PlayerController implements InputProcessor
{
private final static String TAG = PlayerController.class.getSimpleName();
enum Keys{
LEFT,RIGHT,UP,DOWN,QUIT
}
enum Mouse{
SELECT,DOACTION
}
private static Map<Keys,Boolean> keys=new HashMap<PlayerController.Keys,Boolean>();
private static Map<Mouse,Boolean> mouseButtons = new HashMap<PlayerController.Mouse,Boolean>();
private Vector3 lastMouseCoordinates;
static {
keys.put(Keys.LEFT,false);
keys.put(Keys.RIGHT,false);
keys.put(Keys.UP,false);
keys.put(Keys.DOWN, false);
keys.put(Keys.QUIT, false);
}
static {
mouseButtons.put(Mouse.SELECT, false);
mouseButtons.put(Mouse.DOACTION, false);
}
private Entity _player;
public PlayerController(Entity player) {
this.lastMouseCoordinates=new Vector3();
this._player=player;
}
#Override
public boolean keyDown(int keycode)
{
if(keycode ==Input.Keys.LEFT||keycode==Input.Keys.A) {
this.leftPressed();
}
if(keycode ==Input.Keys.RIGHT||keycode==Input.Keys.D) {
this.rightPressed();
}
if(keycode ==Input.Keys.UP||keycode==Input.Keys.W) {
this.upPressed();
}
if(keycode ==Input.Keys.DOWN||keycode==Input.Keys.S) {
this.downPressed();
}
if(keycode==Input.Keys.Q) {
this.quitPressed();
}
return true;
}
#Override
public boolean keyUp(int keycode)
{
if(keycode ==Input.Keys.LEFT||keycode==Input.Keys.A) {
this.leftReleased();
}
if(keycode ==Input.Keys.RIGHT||keycode==Input.Keys.D) {
this.rightReleased();
}
if(keycode ==Input.Keys.UP||keycode==Input.Keys.W) {
this.upReleased();
}
if(keycode ==Input.Keys.DOWN||keycode==Input.Keys.S) {
this.downReleased();
}
if(keycode==Input.Keys.Q) {
this.quitReleased();
}
return true;
}
#Override
public boolean keyTyped(char character)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button)
{
if(button==Input.Buttons.LEFT||button==Input.Buttons.RIGHT) {
this.setClickedMouseCoordinates(screenX,screenY);
}
if(button==Input.Buttons.LEFT) {
this.selectMouseButtonPressed(screenX,screenY);
}
if(button==Input.Buttons.RIGHT) {
this.doActionMouseButtonPressed(screenX,screenY);
}
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button)
{
if(button==Input.Buttons.LEFT) {
this.selectMouseButtonReleased(screenX,screenY);
}
if(button==Input.Buttons.RIGHT) {
this.doActionMouseButtonReleased(screenX,screenY);
}
return true;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean scrolled(int amount)
{
// TODO Auto-generated method stub
return false;
}
public void dispose() {
}
public void leftPressed() {
keys.put(Keys.LEFT,true);
}
public void rightPressed() {
keys.put(Keys.RIGHT,true);
}
public void upPressed() {
keys.put(Keys.UP,true);
}
public void downPressed() {
keys.put(Keys.DOWN,true);
}
public void quitPressed() {
keys.put(Keys.QUIT, true);
}
public void setClickedMouseCoordinates(int x,int y) {
lastMouseCoordinates.set(x,y,0);
}
public void selectMouseButtonPressed(int x,int y) {
mouseButtons.put(Mouse.SELECT,true);
}
public void doActionMouseButtonPressed(int x,int y) {
mouseButtons.put(Mouse.DOACTION, true);
}
public void leftReleased() {
keys.put(Keys.LEFT,false);
}
public void rightReleased() {
keys.put(Keys.RIGHT,true);
}
public void upReleased() {
keys.put(Keys.UP,true);
}
public void downReleased() {
keys.put(Keys.DOWN,true);
}
public void quitReleased() {
keys.put(Keys.QUIT, true);
}
public void selectMouseButtonReleased(int x,int y) {
mouseButtons.put(Mouse.SELECT, false);
}
public void doActionMouseButtonReleased(int x ,int y) {
mouseButtons.put(Mouse.DOACTION, false);
}
public void update(float delta) {
processInput(delta);
}
public static void hide() {
keys.put(Keys.LEFT, false);
keys.put(Keys.RIGHT, false);
keys.put(Keys.UP, false);
keys.put(Keys.DOWN, false);
keys.put(Keys.QUIT, false);
}
private void processInput(float delta) {
if(keys.get(Keys.LEFT)) {
_player.calculateNextPosition(Entity.Direction.LEFT,delta);
_player.setState(Entity.State.WALKING);
_player.setDirection(Entity.Direction.LEFT,delta);
}
else if(keys.get(Keys.RIGHT)) {
_player.calculateNextPosition(Entity.Direction.RIGHT,delta);
_player.setState(Entity.State.WALKING);
_player.setDirection(Entity.Direction.RIGHT,delta);
}
else if(keys.get(Keys.UP)) {
_player.calculateNextPosition(Entity.Direction.UP,delta);
_player.setState(Entity.State.WALKING);
_player.setDirection(Entity.Direction.UP,delta);
}
else if(keys.get(Keys.DOWN)) {
_player.calculateNextPosition(Entity.Direction.DOWN,delta);
_player.setState(Entity.State.WALKING);
_player.setDirection(Entity.Direction.DOWN,delta);
}
else if(keys.get(Keys.QUIT)) {
Gdx.app.exit();
}
else {
_player.setState(Entity.State.IDLE);
}
if(mouseButtons.get(Mouse.SELECT)) {
mouseButtons.put(Mouse.SELECT, false);
}
}
}
/
package com.bludbourne.game;
import java.util.UUID;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
public class Entity
{
private static final String TAG = Entity.class.getSimpleName();
private static final String _defaultSpritePath = "sprites/characters/Warrior.png";
private Vector2 _velocity;
private String _entityID;
private Direction _currentDirection = Direction.LEFT;
private Direction _previousDirection = Direction.UP;
private Animation _walkLeftAnimation;
private Animation _walkRightAnimation;
private Animation _walkUpAnimation;
private Animation _walkDownAnimation;
private Array<TextureRegion> _walkLeftFrames;
private Array<TextureRegion> _walkRightFrames;
private Array<TextureRegion> _walkUpFrames;
private Array<TextureRegion> _walkDownFrames;
protected Vector2 _nextPlayerPosition;
protected Vector2 _currentPlayerPosition;
protected State _state = State.IDLE;
protected float _frameTime = 0f;
protected Sprite _frameSprite = null;
protected TextureRegion _currentFrame = null;
public final int FRAME_WIDTH = 16;
public final int FRAME_HEIGHT = 16;
public static Rectangle boundingBox;
public enum State
{
IDLE, WALKING
}
public enum Direction
{
UP, RIGHT, DOWN, LEFT
}
public Entity() {
initEntity();
}
public void initEntity()
{
this._entityID = UUID.randomUUID().toString();
this._nextPlayerPosition = new Vector2();
this._currentPlayerPosition = new Vector2();
this.boundingBox = new Rectangle();
this._velocity = new Vector2(2f, 2f);
Utility.loadTextureAsset(_defaultSpritePath);
loadDefaultSprite();
loadAllAnimations();
}
public void update(float delta)
{
_frameTime = (_frameTime + delta) % 5;
setBoundingBoxSize(0f, 0.5f);
}
public void init(float startX, float startY)
{
this._currentPlayerPosition.x = startX;
this._currentPlayerPosition.y = startY;
this._nextPlayerPosition.x = startX;
this._nextPlayerPosition.y = startY;
}
public void setBoundingBoxSize(float percentageWidthReduced, float percentageHeightReduced)
{
float width;
float height;
float widthReductionAmount = 1.0f - percentageWidthReduced;
float heightReductionAmount = 1.0f - percentageHeightReduced;
if (widthReductionAmount > 0 && widthReductionAmount < 1)
{
width = FRAME_WIDTH * widthReductionAmount;
}
else
{
width = FRAME_WIDTH;
}
if (heightReductionAmount > 0 && heightReductionAmount < 1)
{
height = FRAME_HEIGHT * heightReductionAmount;
}
else
{
height = FRAME_HEIGHT;
}
if (width == 0 || height == 0)
{
Gdx.app.debug(TAG, "Width and Height are 0!! " + width + ":" + height);
}
float minX;
float minY;
if (MapManager.UNIT_SCALE > 0)
{
minX = _nextPlayerPosition.x / MapManager.UNIT_SCALE;
minY = _nextPlayerPosition.y / MapManager.UNIT_SCALE;
}
else
{
minX = _nextPlayerPosition.x;
minY = _nextPlayerPosition.y;
}
boundingBox.set(minX, minY, width, height);
}
private void loadDefaultSprite()
{
Texture texture = Utility.getTextureAsset(_defaultSpritePath);
TextureRegion[][] textureFrames = TextureRegion.split(texture, FRAME_WIDTH, FRAME_HEIGHT);
_frameSprite = new Sprite(textureFrames[0][0].getTexture(), 0, 0, FRAME_WIDTH, FRAME_HEIGHT);
_currentFrame = textureFrames[0][0];
}
public void loadAllAnimations()
{
Texture texture = Utility.getTextureAsset(_defaultSpritePath);
TextureRegion[][] textureFrames = TextureRegion.split(texture, FRAME_WIDTH, FRAME_HEIGHT);
_walkDownFrames = new Array<TextureRegion>(4);
_walkLeftFrames = new Array<TextureRegion>(4);
_walkRightFrames = new Array<TextureRegion>(4);
_walkUpFrames = new Array<TextureRegion>(4);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
TextureRegion region=textureFrames[i][j];
if(region==null) {
Gdx.app.debug(TAG, "Got null animation frame "+i+","+j);
}
switch(i) {
case 0:
_walkDownFrames.insert(j,region);
break;
case 1:
_walkLeftFrames.insert(j,region);
break;
case 2:
_walkRightFrames.insert(j,region);
break;
case 3:
_walkUpFrames.insert(j,region);
break;
}
}
}
_walkDownAnimation = new Animation(0.25f,_walkDownFrames,Animation.PlayMode.LOOP);
_walkLeftAnimation = new Animation(0.25f,_walkLeftFrames,Animation.PlayMode.LOOP);
_walkRightAnimation = new Animation(0.25f,_walkRightFrames,Animation.PlayMode.LOOP);
_walkUpAnimation = new Animation(0.25f,_walkUpFrames,Animation.PlayMode.LOOP);
}
public void dispose() {
Utility.unloadAsset(_defaultSpritePath);
}
public void setState(State state) {
this._state = state;
}
public Sprite getFrameSprite() {
return _frameSprite;
}
public TextureRegion getFrame() {
return _currentFrame;
}
public Vector2 getCurrentPosition() {
return _currentPlayerPosition;
}
public void setCurrentPosition(float currentPositionX,float currentPositionY) {
_frameSprite.setX(currentPositionX);
_frameSprite.setY(currentPositionY);
this._currentPlayerPosition.x=currentPositionX;
this._currentPlayerPosition.y=currentPositionY;
}
public void setDirection(Direction direction,float deltaTime) {
this._previousDirection=this._currentDirection;
this._currentDirection=direction;
switch(_currentDirection) {
//not sure about this
case DOWN:
_currentFrame=(TextureRegion) _walkDownAnimation.getKeyFrame(_frameTime);
break;
case LEFT:
_currentFrame=(TextureRegion) _walkLeftAnimation.getKeyFrame(_frameTime);
break;
case RIGHT:
_currentFrame=(TextureRegion) _walkRightAnimation.getKeyFrame(_frameTime);
break;
case UP:
_currentFrame=(TextureRegion) _walkUpAnimation.getKeyFrame(_frameTime);
break;
default:
break;
}
}
public void setNextPositionToCurrent() {
setCurrentPosition(_nextPlayerPosition.x,_nextPlayerPosition.y);
}
public void calculateNextPosition(Direction currentDirection,float deltaTime) {
float testX=_currentPlayerPosition.x;
float testY=_currentPlayerPosition.y;
_velocity.scl(deltaTime);
switch(currentDirection) {
case LEFT:
testX-=_velocity.x;
break;
case RIGHT:
testX+=_velocity.x;
break;
case UP:
testY+=_velocity.y;
break;
case DOWN:
testY-=_velocity.y;
break;
default:
break;
}
_nextPlayerPosition.x=testX;
_nextPlayerPosition.y=testY;
_velocity.scl(1/deltaTime);
}
}
I feel that I am probably missing something obvious, however, I still cannot see the error. Help is much appreciated. Thank you.
My github also contains the sprite sheet and the three maps, all of which would be stored in the asset folder of my project.
May I draw your attention to these four methods in PlayerInput
public void leftReleased() {
keys.put(Keys.LEFT,false);
}
public void rightReleased() {
keys.put(Keys.RIGHT,true);
}
public void upReleased() {
keys.put(Keys.UP,true);
}
public void downReleased() {
keys.put(Keys.DOWN,true);
}
I believe it should be false, not true when the key is released. I've verified that this prevents the infinite loop.
The priority order of right, up, then down is due to the order in which the keys are checked in processInput.

Java 2d space gravity not working

I am trying to make a 2d game in java with realistic physics. The game is supposed to be set in space from a top down view. The best way I can explain the view is to use this link: 3d graph found one gooogle images with search "3d graph xyz". The view is supposed to be set so that you are looking from the top of the +y towards the -y.
In the game I currently only have it showing one sun and one planet to test the gravity. However, when I run the game the planet only moves away from the sun in a towards the bottom right. I believe this to be due to me misusing the equation when moving it to java. For reference the equations I used were Newton's Law of Universal Gravitation (F=(G*M1*M2)/D^2) and Newton's Second Law of Motion (F=MA, but used as A=F/M).
In short, My question is what did I do wrong with my equations? I will post all my code below, but fair warning it is designed to be expanded upon so there is a lot of excess currently.
Thanks for any help in advance.
Core class:
package src.main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import src.main.input.Input;
import src.main.input.InputHandler;
import src.main.map.Map;
public class Core extends JPanel
{
private static InputHandler iHandler = new InputHandler();
private static Input input = new Input(iHandler);
private long ticks;
private Map map;
public static Dimension SIZE;
public static Random rand = new Random();
public Core(Dimension d)
{
setPreferredSize(d);
SIZE = d;
ticks = 0;
map = new Map(SIZE.width, SIZE.height);
start();
}
public synchronized void update()
{
ticks++;
iHandler.update(ticks);
/*if (iHandler.getWheelRotation() != 0)
{
int i = iHandler.getWheelRotation();
map.changeMagnification(i > 0);
if (i > 0)
i--;
else
i++;
iHandler.setWheelRotation(i);
if (i < 0 && map.getMagnification() == 0)
iHandler.setWheelRotation(0);
if (i > 0 && map.getMagnification() == Map.MAX_MAGNIFY)
iHandler.setWheelRotation(0);
}*/
map.update(ticks);
}
public synchronized void paintComponent(Graphics g2)
{
Graphics2D g = (Graphics2D) g2;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, SIZE.width, SIZE.height);
map.draw(g);
}
public void start()
{
Thread thread = new Thread()
{
public void run()
{
while (true)
{
long time = System.currentTimeMillis();
update();
repaint();
time = (1000 / 128) - (System.currentTimeMillis() - time);
if (time > 0)
{
try
{
Thread.sleep(time);
} catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
};
thread.start();
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
Rectangle r = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDefaultConfiguration().getBounds();
public void run()
{
JFrame frame = new JFrame();
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new Core(new Dimension(r.width, r.height)));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addKeyListener(input);
frame.addMouseListener(input);
frame.addMouseMotionListener(input);
frame.addMouseWheelListener(input);
}
});
}
}
Map Class:
package src.main.map;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import src.main.Core;
import src.main.celestials.SolarSystem;
public class Map
{
private int magnification;
public static final int MAX_MAGNIFY = 15;
private ArrayList<SolarSystem> systems = new ArrayList<SolarSystem>();
public Map(int x, int y)
{
SolarSystem s=new SolarSystem(new Point(500,500), "sun", (int) (1.9891 * Math.pow(10, 30)));
s.addPlanet(new Point(550, 550), "planet");
systems.add(s);
}
public void update(long ticks)
{
for(int i = 0; i < systems.size(); i++)
systems.get(i).update(ticks);
}
public void draw(Graphics2D g)
{
g.setColor(Color.DARK_GRAY);
magnification= 1;
for(int i=0; i<systems.size(); i++)
{
systems.get(i).draw(g, magnification);
}
}
public int getMagnification()
{
return magnification;
}
public void changeMagnification(boolean bigger)
{
if (bigger)
magnification++;
else
magnification--;
if (magnification > MAX_MAGNIFY)
magnification = MAX_MAGNIFY;
if (magnification < 1)
magnification = 1;
}
}
Body Class:
package src.main.celestials;
import java.awt.Point;
import src.main.Core;
import src.main.map.Map;
public abstract class Body
{
protected String name;
protected double x, y, mass;
public Body(Point t, String s, int m)
{
x = t.x;
y = t.y;
name = s;
mass = m;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
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;
}
public double getMass() {
return mass;
}
public void setMass(double mass) {
this.mass = mass;
}
public abstract void update(long ticks);
}
SolarSystem Class:
package src.main.celestials;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import src.main.celestials.Planet;
public class SolarSystem extends Body {
private ArrayList<Planet> planets = new ArrayList<Planet>();
private BufferedImage[] images = new BufferedImage[7];
private BufferedImage sun;
public SolarSystem(Point t, String s, int m) {
super(t, s, m);
try
{
String loc = System.getProperty("user.home") + "\\Desktop\\Proof of Concept Game\\Proof of Concept Game\\Gravity Test\\Suns\\";
images[0] = ImageIO.read(new File(loc + "Sun_Blue.png"));
images[1] = ImageIO.read(new File(loc + "Sun_BlueWhite.png"));
images[2] = ImageIO.read(new File(loc + "Sun_Orange.png"));
images[3] = ImageIO.read(new File(loc + "Sun_Red.png"));
images[4] = ImageIO.read(new File(loc + "Sun_White.png"));
images[5] = ImageIO.read(new File(loc + "Sun_Yellow.png"));
images[6] = ImageIO.read(new File(loc + "Sun_YellowWhite.png"));
} catch (Exception e)
{
e.printStackTrace();
}
sun = images[(int) (Math.random() * images.length)];
}
//earth mass:5.97219 × 10^24KG
//sun mass: 1.9891 × 10^30KG
//sun/earth ratio: 333060.4016
#Override
public void update(long ticks) {
// run interactions between planets and solar systems
for(int i=0; i<planets.size(); i++)
{
planets.get(i).setxAccel(genAccelX(i));
planets.get(i).setyAccel(genAccelY(i));
}
// update using acceleration and velocity
for(int i=0; i<planets.size(); i++)
{
planets.get(i).update(ticks);
}
}
public void addPlanet(Point point, String name)
{
planets.add(new Planet(point, name, (int) (5.97219*Math.pow(10, 24))));
}
/*public double genAccel(int i)
{
double G=6.67*Math.pow(10, -11);
double Dx=Math.pow(planets.get(i).getX()-getX(), 2);
double Dy=Math.pow(planets.get(i).getY()-getY(), 2);
double D=Math.sqrt(Dx+Dy);
return G*planets.get(i).getMass()/Math.pow(D, 2);
}
public double genAccelX(int i)
{
double Dx=Math.pow(planets.get(i).getX()-getX(), 2);
double Dy=Math.pow(planets.get(i).getY()-getY(), 2);
double D=Math.sqrt(Dx+Dy);
double A=genAccel(i);
return Dx*A/D;
}
public double genAccelY(int i)
{
double Dx=Math.pow(planets.get(i).getX()-getX(), 2);
double Dy=Math.pow(planets.get(i).getY()-getY(), 2);
double D=Math.sqrt(Dx+Dy);
double A=genAccel(i);
return Dy*A/D;
}*/
public double genAccelX(int i)
{
double x1=0;
double x2=0;
/*if(getX()>planets.get(i).getX())
{*/
x1=getX();
x2=planets.get(i).getX();
/*}
else
{
x1=planets.get(i).getX();
x2=getX();
}*/
double G=6.67e-11;
double d=x1-x2;
d*=d;
planets.get(i).setxForce((G*getMass()*planets.get(i).getMass())/d);
return planets.get(i).getxForce()/planets.get(i).getMass();
}
public double genAccelY(int i)
{
double y1=0;
double y2=0;
/*if(getY()<planets.get(i).getY())
{*/
y1=getY();
y2=planets.get(i).getY();
/*}
else
{
y1=planets.get(i).getY();
y2=getY();
}*/
double G=6.67e-11;
double d=y1-y2;
d*=d;
planets.get(i).setyForce((G*getMass()*planets.get(i).getMass())/d);
return planets.get(i).getyForce()/planets.get(i).getMass();
}
public void draw(Graphics2D g, int magnification) {
g.drawImage(sun, (int)(x) * magnification + 2, (int)(y) * magnification + 2, 50, 50, null);
for(int i=0; i<planets.size(); i++)
{
g.setColor(Color.PINK);
g.fillOval((int)planets.get(i).getX(), (int)planets.get(i).getY(), 20, 20);
}
}
}
Planet Class:
package src.main.celestials;
import java.awt.Point;
public class Planet extends Body {
double xForce, yForce, xAccel, yAccel, xVel, yVel;
public Planet(Point t, String s, int m) {
super(t, s, m);
}
public double getxForce() {
return xForce;
}
public void setxForce(double xForce) {
this.xForce = xForce;
}
public double getyForce() {
return yForce;
}
public void setyForce(double yForce) {
this.yForce = yForce;
}
public double getxAccel() {
return xAccel;
}
public void setxAccel(double xAccel) {
this.xAccel = xAccel;
}
public double getyAccel() {
return yAccel;
}
public void setyAccel(double yAccel) {
this.yAccel = yAccel;
}
public double getxVel() {
return xVel;
}
public void setxVel(double xVel) {
this.xVel = xVel;
}
public double getyVel() {
return yVel;
}
public void setyVel(double yVel) {
this.yVel = yVel;
}
#Override
public void update(long ticks) {
xVel+=xAccel;
yVel+=yAccel;
x+=xVel;
y+=yVel;
System.out.println("X: "+(int)x+"\t\t"+"Y: "+(int)y);
System.out.println("XVel: "+xVel+"\t\t"+"YVel: "+yVel);
System.out.println("XAccel: "+xAccel+"\t"+"YAccel: "+yAccel);
}
}
First of all, concerning your comment
I thought I was in the java forum?
(also #PM77-1 :) StackOverflow is not a forum at all! Also see https://meta.stackexchange.com/a/92110 . It is a "Question And Answer" site, and this imposes some constraints on how you should ask, and what to expect as a response. (Actually, the fact that I'm writing this here is already a "violation" of these rules, and I'm risking downvotes for that). The question in its current form is hardly suitable for any site of the StackExchange network. If you write a question here, then you should ...
Include a clear and focussed question (namely, one that goes beyond "What is wrong with my code?")
Provide Minimal, Complete, and Verifiable example (preferably, if possible and appropriate, as a single code block, with no dependencies to other, unrelated classes, and no dependencies to external resources etc.)
That said, regarding your actual "question": The formula that you are using is correct. But it is not properly implemented. The formula is
(according to Wikipedia)
The "r" refers to the distance between the centers of mass of the objects.
In your code, you tried to implement this in the SolarSystem#genAccelX and SolarSystem#genAccelY methods:
...
double x1=0;
double x2=0;
x1=getX();
x2=planets.get(i).getX();
double G=6.67e-11;
double d=x1-x2;
d*=d;
planets.get(i).setxForce((G*getMass()*planets.get(i).getMass())/d);
return planets.get(i).getxForce()/planets.get(i).getMass();
But the problem is that you are computing this separately for x and for y. Thus, the resulting force is losing its actual direction (and is "wrong" anyhow).
To put it simply: The d that you are computing there is negative, because the planet should move to the left. But by taking d*=d, it becomes positive (and this, the planet is moving to the right)
The solution:
You should describe all positions, velocities and forces as vectors instead of computing everything separately for x and y. Basically, it will boil down to a class like
class Vector {
private double x, y;
// Setters, getters...
....
double distanceSquared(Vector other) {
double dx = x - other.x;
double dy = y - other.y;
return Math.sqrt(dx*dx+dy*dy);
}
double distance(Vector other) {
return Math.sqrt(distanceSquared(other));
}
// Some other useful methods:
double length() { ... }
void normalize(double factor) { ... }
void scale(double factor) { ... }
void add(Vector other) { ... }
void addScaled(double factor, Vector other) { ... }
void sub(Vector other) { ... }
Vector difference(Vector other) { ... }
}
Given such a class, the method for computing the force and acceleration could roughly look like this:
// The bodies here may be the sun and a planet:
public double computeForceStrength(Body body0, Body body1)
{
double G=6.67e-11;
Vector position0 = body0.getPosition();
Vector position1 = body1.getPosition();
double distanceSquared = position0.distanceSquared(position1);
// The formula from wikipedia:
double f = G * body0.getMass() * body1.getMass() / distanceSquared;
return f;
}
void performSomeTimeStep(Body body0, Body body1)
{
Vector direction = position1.difference(position0);
direction.normalize();
double f = computeForceStrength(body0, body1);
body0.getVelocity().addScaled(direction, f / body0.getMass());
body1.getVelocity().addScaled(direction, -f / body1.getMass());
}
(just to show the basic idea - again: There are many degrees of freedom)
There are several other (stylistic) issues with the code, but ... when it is working, you may want to submit it to https://codereview.stackexchange.com/ ....

my objects flash for a sec and then are gone

I have some code that makes 273 black squires on the screen but yet they only show up for a second. I know its something wrong with the repaint but i can't find it.
import java.applet.*;
import java.util.*;
import java.awt.*;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.*;
public class Start extends Applet implements Runnable, KeyListener
{
public boolean running = true;
int fall = 60;
int count = 0;
Thread thread;
private Image i;
private Graphics doubleG;
Brick b[] = new Brick[273];//abtsert class
public int[] x = {270,300,330,360,390,420,450,480,510,540,570,600,630};
public int[] y = {-10,20,50,80,110,140,170,200,230,260,290,320,350,380,410,440,470,500,530,560,590,620,650};
public boolean[] bl = {false,true};
public int[] color = {0,1,2,3,4};
public int xc = 0;//indx of x
public int yc = 0;//indx of y
public int indx = 0;//indx of b
public int start = 0;
public void init()
{
Arrays.fill(b,new Background());
addKeyListener(this);
setFocusable(true);
thread = new Thread(this);
thread.start();
}
public void run()
{
while(running)
{
try
{
thread.sleep(17);
}
catch(InterruptedException e)
{
}
repaint();
}
}
public void paint(Graphics g)
{
resize(700,700);
if(start == 0)
{
set(g);//sets fills b with objects
start = 1;
}
else//prints out the abjects stored in b[]
{
while(indx != 273)
{
b[indx].paint(g);
indx++;
}
indx=0;
}
g.drawRect(300,50,300,600);
}
public void update(Graphics g)
{
if(i == null)
{
i = createImage(this.getSize().width, this.getSize().height);
doubleG = i.getGraphics();
}
doubleG.setColor(getBackground());
doubleG.fillRect(0,0,700,700);
doubleG.setColor(getForeground());
paint(doubleG);
g.drawImage(i,0,0,this);
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == e.VK_LEFT)
{
}
if(e.getKeyCode() == e.VK_RIGHT)
{
}
repaint();
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
public void set(Graphics g)
{
while(yc <= 22)
{
b[indx].start(g,x[xc],y[yc]);
if(xc <= 12)
{
xc++;
}
if(xc == 12)
{
yc++;
xc=0;
}
indx++;
}
yc=0;
indx=0;
}
}
this is the abstract class
import java.applet.*;
import java.util.*;
import java.awt.*;
public abstract class Brick
{
public int px;
public int py;
public abstract void paint(Graphics g);
public abstract void start(Graphics g ,int x ,int y);
}
this is the class that uses the abstract class
import java.applet.*;
import java.util.*;
import java.awt.*;
public class Background extends Brick//thing thats being painted
{
public int px;//where the x,y are stored
public int py;
public void paint(Graphics g)//used to repaint it
{
g.setColor(Color.BLACK);
g.fillRect(px,py,29,29);
}
public void start(Graphics g,int x, int y)//used to set the object
{
g.setColor(Color.BLACK);
g.fillRect(x,y,29,29);
px = x;
py = y;
}
}

Rotating an image based on key presses

I was trying to modify an existing code to rotate an image based on key presses. so far i've managed to do the following and I'm stuck. i've made use of Affine transform for the first time. The image rotates only once when it's supposed to rotate as many times as the RIGHT key is pressed.
package aircraftPackage;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class RotateImage extends JFrame implements KeyListener {
private static final long serialVersionUID = 1L;
private Image TestImage;
private BufferedImage bf;
private int cordX = 100;
private int cordY = 100;
private double currentAngle;
public RotateImage(Image TestImage) {
this.TestImage = TestImage;
MediaTracker mt = new MediaTracker(this);
mt.addImage(TestImage, 0);
try {
mt.waitForID(0);
}
catch (Exception e) {
e.printStackTrace();
}
setTitle("Testing....");
setSize(500, 500);
imageLoader();
setVisible(true);
}
public void rotate() {
//rotate 5 degrees at a time
currentAngle+=5.0;
if (currentAngle >= 360.0) {
currentAngle = 0;
}
repaint();
}
public void imageLoader() {
try {
String testPath = "test.png";
TestImage = ImageIO.read(getClass().getResourceAsStream(testPath));
} catch (IOException ex) {
ex.printStackTrace();
}
addKeyListener(this);
}
public void update(Graphics g){
paint(g);
}
public void paint(Graphics g){
bf = new BufferedImage( this.getWidth(),this.getHeight(), BufferedImage.TYPE_INT_RGB);
try{
animation(bf.getGraphics());
g.drawImage(bf,0,0,null);
}catch(Exception ex){
}
}
public void animation(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
AffineTransform origXform = g2d.getTransform();
AffineTransform newXform = (AffineTransform)(origXform.clone());
//center of rotation is center of the panel
int xRot = this.getWidth()/2;
int yRot = this.getHeight()/2;
newXform.rotate(Math.toRadians(currentAngle), xRot, yRot);
g2d.setTransform(newXform);
//draw image centered in panel
int x = (getWidth() - TestImage.getWidth(this))/2;
int y = (getHeight() - TestImage.getHeight(this))/2;
g2d.drawImage(TestImage, x, y, this);
g2d.setTransform(origXform);
g.drawImage(TestImage, cordX, cordY, this);
}
public static void main(String[] args) {
new RotateImage(null);
}
public void keyPressed(KeyEvent ke) {
final RotateImage ri = new RotateImage(TestImage);
switch (ke.getKeyCode()) {
case KeyEvent.VK_RIGHT: {
cordX += 5;
ri.rotate();
}
break;
case KeyEvent.VK_LEFT: {
cordX -= 5;
}
break;
case KeyEvent.VK_DOWN: {
cordY += 5;
}
break;
case KeyEvent.VK_UP: {
cordY -= 3;
}
break;
}
repaint();
}
public void keyTyped(KeyEvent ke) {
}
public void keyReleased(KeyEvent ke) {
}
}
would be helpful if anyone could correct me on where im making the mistake.
Thanks
the problem you are creating new rotate image on each event key so it looks like not working
try to change the place of this line to be none modifiable on each key event
public static void main(String[] args) {
new RotateImage(null);
}
public void keyPressed(KeyEvent ke) {
final RotateImage ri = new RotateImage(TestImage);
UPDATE:
the reason is because the value of constructor is null you should pass image
new RotateImage(null);
modify this on your code
1)make it static
private static Image TestImage;
2)define
private static RotateImage ri;
3)call in main like this
public static void main(String[] args) {
ri = new RotateImage(TestImage);
}
step 4(removed)
UPDATE:
read these question on stack overflow
another question
UPDATE2:
here is the full code it works perfectly ( the right key ) dont foget to include you image in the same package and its the same type .png here is the code
package aircraftPackage;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class RotateImage extends JFrame implements KeyListener {
private static final long serialVersionUID = 1L;
private static Image TestImage;
private static RotateImage ri;
private BufferedImage bf;
private int cordX = 100;
private int cordY = 100;
private double currentAngle;
public RotateImage(Image TestImage) {
this.TestImage = TestImage;
MediaTracker mt = new MediaTracker(this);
mt.addImage(TestImage, 0);
try {
mt.waitForID(0);
}
catch (Exception e) {
e.printStackTrace();
}
setTitle("Testing....");
setSize(500, 500);
imageLoader();
setVisible(true);
}
public void rotate() {
//rotate 5 degrees at a time
currentAngle+=5.0;
if (currentAngle >= 360.0) {
currentAngle = 0;
}
repaint();
}
public void imageLoader() {
try {
String testPath = "test.png";
TestImage = ImageIO.read(getClass().getResourceAsStream(testPath));
} catch (IOException ex) {
ex.printStackTrace();
}
addKeyListener(this);
}
public void update(Graphics g){
paint(g);
}
public void paint(Graphics g){
bf = new BufferedImage( this.getWidth(),this.getHeight(), BufferedImage.TYPE_INT_RGB);
try{
animation(bf.getGraphics());
g.drawImage(bf,0,0,null);
}catch(Exception ex){
}
}
public void animation(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
AffineTransform origXform = g2d.getTransform();
AffineTransform newXform = (AffineTransform)(origXform.clone());
//center of rotation is center of the panel
int xRot = this.getWidth()/2;
int yRot = this.getHeight()/2;
newXform.rotate(Math.toRadians(currentAngle), xRot, yRot);
g2d.setTransform(newXform);
//draw image centered in panel
int x = (getWidth() - TestImage.getWidth(this))/2;
int y = (getHeight() - TestImage.getHeight(this))/2;
g2d.drawImage(TestImage, x, y, this);
g2d.setTransform(origXform);
g.drawImage(TestImage, cordX, cordY, this);
}
public static void main(String[] args) {
ri = new RotateImage(TestImage);
}
public void keyPressed(KeyEvent ke) {
switch (ke.getKeyCode()) {
case KeyEvent.VK_RIGHT: {
cordX += 5;
ri.rotate();
}
break;
case KeyEvent.VK_LEFT: {
cordX -= 5;
ri.rotate();
}
break;
case KeyEvent.VK_DOWN: {
cordY += 5;
ri.rotate();
}
break;
case KeyEvent.VK_UP: {
cordY -= 3;
ri.rotate();
}
break;
}
repaint();
}
public void keyTyped(KeyEvent ke) {
}
public void keyReleased(KeyEvent ke) {
}
}
public void keyPressed(KeyEvent ke) {
final RotateImage ri = new RotateImage(TestImage);
switch (ke.getKeyCode()) {
case KeyEvent.VK_RIGHT: {
cordX += 5;
ri.rotate();
}
It seems that you are rotating the same image every time so it will always rotate for only 5 deg.
edit : hum too late . . see shareef post.

Categories