How to export from Eclipse as runnable JAR - java

EDIT: updated code and question
I added main() method as stated in aswers but I still can't export it.
I am running my program as Java Applet, and apparently I need to use Java Application to run it standalone, but when I change run configuration to Application i get these errors:
Exception in thread "main" java.lang.NullPointerException
at acm.graphics.GImage.determineSize(GImage.java:564)
at acm.graphics.GImage.setImage(GImage.java:173)
at acm.graphics.GImage.<init>(GImage.java:115)
at acm.graphics.GImage.<init>(GImage.java:54)
at Pong.createTexture(Pong.java:160)
at Pong.run(Pong.java:81)
at Pong.main(Pong.java:55)
I need to export my project from Eclipse as a standalone runnable JAR, but when i go to export -> java -> JAR file i dont see any classes to select and im getting stuck at this (screen) window. I only have one class in my project.
This is not relevant anymore but I'll leave it here to keep edit history
import java.awt.Color;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.util.Random;
import acm.graphics.GImage;
import acm.graphics.GLabel;
import acm.graphics.GObject;
import acm.graphics.GOval;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
/* TO DO LIST
* ------------------
* Corner Bounce
*
*
*
*/
#SuppressWarnings("serial")
public class Pong extends GraphicsProgram {
public double mouseY;
private static final double PAUSE = 1000 / 96.0;
private Random rand = new Random();
private boolean AI_GODMODE = false;
// ball
public double startX;
public double startY;
private static final double BALL_SIZE = 20;
private static final double SPEED = 5;
private double ballHorizontalSpeed = SPEED * 1.5;
private double ballVerticalSpeed = SPEED;
// paddle
private static int HEIGHT = 150;
private static int WIDTH = 15;
private static int COUNTER = 0;
private static int AI_SPEED = 10; // AI difficulty 1-20
// label
public int AI_SCORE = 0;
public int PLAYER_SCORE = 0;
public int TOTAL_GAMES = 0;
private float TRANSPARENCY = 0.0f;
// counters
private static final int PADDING = 10;
private static final int MODIFIER = 3;
public static void main(String[] args) {
Pong p = new Pong();
p.run();
}
public void run() {
addMouseListeners();
// counters setup
GLabel counter = new GLabel(String.valueOf(COUNTER));
GLabel aiScore = new GLabel(String.valueOf(AI_SCORE));
GLabel average = new GLabel(String.valueOf("Avg: 0"));
GLabel playerScore = new GLabel(String.valueOf(COUNTER));
Color labelC = new Color(0, 0.0f, 0.0f, TRANSPARENCY);
Color scoreC = new Color(0, 0.0f, 0.0f, 0.1f);
counter.setFont("Impact-600");
aiScore.setFont("Impact-100");
average.setFont("Impact-50");
playerScore.setFont("Impact-100");
counter.setColor(labelC);
aiScore.setColor(scoreC);
playerScore.setColor(scoreC);
average.setColor(scoreC);
counter.setLocation(getWidth() / 2 - counter.getWidth() / 2,
getHeight() / 2 + counter.getHeight() / 3.2);
counter.sendToFront();
// make objects
GImage paddleLeftTexture = createTexture("texture.png", WIDTH + 1,
HEIGHT + 1);
GImage paddleRightTexture = createTexture("texture2.png", WIDTH + 1,
HEIGHT + 1);
GImage ballTexture = createTexture("ballTexture.png", (int) BALL_SIZE,
(int) BALL_SIZE);
GImage greenFlash = createTexture("greenFlash.png", 100, 300);
GImage blueFlash = createTexture("blueFlash.png", 100, 300);
GOval ball = makeBall();
GRect paddleLeft = makePaddle();
GRect paddleRight = makePaddle();
greenFlash.setLocation(-200, 0);
blueFlash.setLocation(-200, 0);
// generate GUI
drawGraphics(ball, paddleLeftTexture, paddleRightTexture, ballTexture,
greenFlash, blueFlash, counter, paddleLeft, paddleRight,
aiScore, playerScore, average);
// game start
bounce(labelC, aiScore, playerScore, counter, ball, paddleLeft,
paddleRight, paddleLeftTexture, paddleRightTexture,
ballTexture, greenFlash, blueFlash, average);
}
public void bounce(Color labelC, GLabel aiScore, GLabel playerScore,
GLabel counter, GOval ball, GRect paddleLeft, GRect paddleRight,
GImage paddleLeftTexture, GImage paddleRightTexture,
GImage ballTexture, GImage greenFlash, GImage blueFlash,
GLabel average) {
preGameSetup(ball, paddleRight, paddleRightTexture, counter);
updateAiScore(aiScore);
updatePlayerScore(playerScore);
updateAverage(average);
while (true) {
moveBall(ballHorizontalSpeed, ballVerticalSpeed, ball, ballTexture);
movePlayerPaddle(paddleLeft, paddleLeftTexture);
moveAiPaddle(ball, paddleRight, paddleRightTexture);
detectHit(ball, paddleRight, paddleLeft, counter, labelC);
if (TRANSPARENCY >= 0.0f) {
TRANSPARENCY -= TRANSPARENCY / 100f;
}
labelC = new Color(0, 0.0f, 0.0f, TRANSPARENCY);
counter.setColor(labelC);
if (detectBallOffScreen(ball)) {
ballOffScreen(ball, ballTexture, aiScore, playerScore,
greenFlash, blueFlash, average);
COUNTER = 0;
bounce(labelC, aiScore, playerScore, counter, ball, paddleLeft,
paddleRight, paddleLeftTexture, paddleRightTexture,
ballTexture, greenFlash, blueFlash, average);
}
pause(PAUSE);
}
}
public static GRect makePaddle() {
GRect result = new GRect(0, 0, WIDTH, HEIGHT);
result.setFilled(true);
result.setColor(Color.BLACK);
return result;
}
public static GOval makeBall() {
GOval result = new GOval(150, 100, BALL_SIZE, BALL_SIZE);
result.setFilled(true);
result.setColor(Color.WHITE);
return result;
}
private GImage createTexture(String importedImage, int width, int height) {
Image importResult = getImage(getCodeBase(), importedImage);
GImage textureResult = new GImage(importResult);
textureResult.setSize(width, height);
return textureResult;
}
public void mouseMoved(MouseEvent e) {
mouseY = e.getY();
}
private boolean ballHitBottom(GOval ball) {
double bottomY = ball.getY() + ball.getHeight();
return bottomY >= getHeight();
}
private boolean ballHitTop(GOval ball) {
double topY = ball.getY();
return topY <= 0;
}
private boolean ballHitPaddleRight(GOval ball, GRect paddle) {
double rightX = ball.getX() + ball.getWidth();
double rightY = ball.getY() + ball.getHeight() / 2;
double paddlePosX = paddle.getX();
double paddlePosY = paddle.getY();
if (rightX >= paddlePosX && rightY >= paddlePosY
&& rightY <= paddlePosY + paddle.getHeight())
return true;
else
return false;
}
private boolean detectBallOffScreen(GOval ball) {
if (ball.getX() < 2 * WIDTH - BALL_SIZE
|| ball.getX() > getWidth() - 2 * WIDTH)
return true;
else
return false;
}
private boolean ballHitPaddleLeft(GOval ball, GRect paddle) {
double leftX = ball.getX();
double leftY = ball.getY();
double paddlePosX = paddle.getX() + WIDTH;
double paddlePosY = paddle.getY();
if (leftX <= paddlePosX && leftY >= paddlePosY
&& leftY <= paddlePosY + paddle.getHeight())
return true;
else
return false;
}
/*
* private boolean ballHitPaddleBorder(GOval ball, GRect paddle) { ; if
* (ball.getX() > paddle.getX() - BALL_SIZE && ball.getX() < paddle.getX() +
* WIDTH && ball.getY() > paddle.getY() && ball.getY() < paddle.getY() +
* ballVerticalSpeed) return true; else if (ball.getX() > paddle.getX() -
* BALL_SIZE && ball.getX() < paddle.getX() + WIDTH && ball.getY() >
* paddle.getY() + HEIGHT && ball.getY() < paddle.getY() + HEIGHT -
* ballVerticalSpeed) return true; else return false; }
*/
private void preGameSetup(GObject ball, GObject paddleRight,
GObject paddleRightTexture, GLabel counter) {
startX = rand.nextInt((int) (getWidth() * 0.8))
+ (int) (0.1 * getWidth()); // zapobiega pojawieniu się piłki po
// lewej stronie lewej paletki
startY = rand.nextInt(getHeight());
ball.setLocation(startX, startY);
paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH, startY
- HEIGHT / 2);
paddleRight.setLocation(getWidth() - MODIFIER * WIDTH, startY - HEIGHT
/ 2);
paddleRightTexture.sendToFront();
counter.setLabel(String.valueOf(COUNTER));
counter.setLocation(getWidth() / 2 - counter.getWidth() / 2,
getHeight() / 2 + counter.getHeight() / 3.2);
ballHorizontalSpeed = SPEED * 1.5;
ballVerticalSpeed = SPEED;
}
private void updateAiScore(GLabel aiScore) {
aiScore.setLabel(String.valueOf(AI_SCORE));
aiScore.setLocation(getWidth() - aiScore.getWidth() - MODIFIER * WIDTH
- PADDING, getHeight() - PADDING);
}
private void updatePlayerScore(GLabel playerScore) {
playerScore.setLabel(String.valueOf(PLAYER_SCORE));
playerScore.setLocation(MODIFIER * WIDTH + PADDING, getHeight()
- PADDING);
}
private void updateScore(GLabel counter, Color labelC) {
counter.setLabel(String.valueOf(COUNTER));
counter.setLocation(getWidth() / 2 - counter.getWidth() / 2,
getHeight() / 2 + counter.getHeight() / 3.2);
TRANSPARENCY = 0.1f;
labelC = new Color(0, 0.0f, 0.0f, TRANSPARENCY);
counter.setColor(labelC);
}
private void updateAverage(GLabel average) {
if (TOTAL_GAMES == 0) {
average.setLabel("Round: 1 Avg: 0");
} else {
average.setLabel("Round: " + String.valueOf(TOTAL_GAMES + 1) + " Avg: "
+ String.valueOf((int) ((AI_SCORE + PLAYER_SCORE) / TOTAL_GAMES)));}
average.setLocation(getWidth() / 2 - average.getWidth() / 2,
getHeight() - PADDING);
}
private void drawGraphics(GObject ball, GObject paddleLeftTexture,
GObject paddleRightTexture, GObject ballTexture,
GObject greenFlash, GObject blueFlash, GObject counter,
GObject paddleLeft, GObject paddleRight, GObject aiScore,
GObject playerScore, GLabel average) {
add(ball);
add(paddleLeftTexture);
add(paddleRightTexture);
add(ballTexture);
add(greenFlash);
add(blueFlash);
add(counter);
add(paddleLeft);
add(paddleRight);
add(aiScore);
add(playerScore);
add(average);
}
private void detectHit(GOval ball, GRect paddleRight, GRect paddleLeft,
GLabel counter, Color labelC) {
if (ballHitBottom(ball) && ballVerticalSpeed >= 0) {
ballVerticalSpeed *= -1;
}
if (ballHitTop(ball) && ballVerticalSpeed <= 0) {
ballVerticalSpeed *= -1;
}
if (ballHitPaddleRight(ball, paddleRight)) {
ballHorizontalSpeed *= -1;
}
if (ballHitPaddleLeft(ball, paddleLeft)) {
ballHorizontalSpeed *= -1;
COUNTER++;
updateScore(counter, labelC);
boolean bool = rand.nextBoolean();
if (bool)
if (ballHorizontalSpeed > 0)
ballHorizontalSpeed += 1;
else
ballHorizontalSpeed -= 1;
else if (ballVerticalSpeed > 0)
ballVerticalSpeed += 0.5;
else
ballVerticalSpeed -= 0.5;
}
/*
* if(ballHitPaddleBorder(ball, paddleLeft)){ ballVerticalSpeed *= -1; }
*
* if(ballHitPaddleBorder(ball, paddleRight)){ ballVerticalSpeed *= -1;
* }
*/
}
private void ballOffScreen(GOval ball, GObject ballTexture, GLabel aiScore,
GLabel playerScore, GObject greenFlash, GObject blueFlash,
GLabel average) {
if (ball.getX() < 2 * WIDTH - BALL_SIZE) { // left
double pos = ball.getY() - greenFlash.getHeight() / 2;
ballTexture.move(-ballTexture.getWidth() * 2, 0);
AI_SCORE += COUNTER;
TOTAL_GAMES++;
updateAiScore(aiScore);
updateAverage(average);
for (int i = 20; i < 100; i += 5) {
greenFlash.setLocation(-i, pos);
pause(25);
}
} else { // right
double pos = ball.getY() - blueFlash.getHeight() / 2;
ballTexture.move(ballTexture.getWidth() * 2, 0);
PLAYER_SCORE += COUNTER;
TOTAL_GAMES++;
updatePlayerScore(playerScore);
updateAverage(average);
for (int i = 20; i < 100; i += 5) {
blueFlash.setLocation(getWidth() - blueFlash.getWidth() + i,
pos);
pause(25);
}
}
}
private void moveBall(double ballHorizontalSpeed, double ballVerticalSpeed,
GObject ball, GObject ballTexture) {
ball.move(ballHorizontalSpeed, ballVerticalSpeed);
ballTexture.setLocation(ball.getX(), ball.getY());
ballTexture.sendToFront();
}
private void movePlayerPaddle(GObject paddleLeft, GObject paddleLeftTexture) {
if (mouseY < getHeight() - HEIGHT) { // Player
paddleLeft.setLocation(2 * WIDTH, mouseY);
paddleLeftTexture.setLocation(2 * WIDTH, mouseY);
paddleLeftTexture.sendToFront();
} else {
paddleLeft.setLocation(2 * WIDTH, getHeight() - HEIGHT);
paddleLeftTexture.setLocation(2 * WIDTH, getHeight() - HEIGHT);
paddleLeftTexture.sendToFront();
}
}
private void moveAiPaddle(GOval ball, GRect paddleRight,
GImage paddleRightTexture) {
if (AI_GODMODE == true) { // modeSelector
if (ball.getY() < getHeight() - HEIGHT / 2
&& ball.getY() > HEIGHT / 2) {
paddleRight.setLocation(getWidth() - MODIFIER * WIDTH,
ball.getY() - HEIGHT / 2);
paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH,
ball.getY() - HEIGHT / 2);
paddleRightTexture.sendToFront();
} else if (ball.getY() <= HEIGHT / 2) {
paddleRight.setLocation(getWidth() - MODIFIER * WIDTH, 0);
paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH,
-0);
paddleRightTexture.sendToFront();
} else {
paddleRight.setLocation(getWidth() - MODIFIER * WIDTH,
getHeight() - HEIGHT);
paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH,
getHeight() - HEIGHT);
paddleRightTexture.sendToFront();
}
} else { // end godMode if
double targetY = ball.getY() + BALL_SIZE / 2;
if (targetY < getHeight() - HEIGHT / 2 && targetY > HEIGHT / 2) {
if (targetY < paddleRight.getY() + HEIGHT / 2) {
paddleRight.move(0, -AI_SPEED);
paddleRightTexture.move(0, -AI_SPEED);
} else if (targetY > paddleRight.getY() + HEIGHT / 2) {
paddleRight.move(0, AI_SPEED);
paddleRightTexture.move(0, AI_SPEED);
}
} // end normalMode if
} // end modeSelector if
} // end moveAiPaddle void
} // end class

Judging from the linked image, your class Pong does not have a main method. It simply cant be exported as a runnable jar file, because you could never run it. Add a main method, or export to a standard java jar file (File -> Export -> Java -> JAR file). The jar file it produces using the latter method will NOT be runnable if there is no main method, period. You have to have a main method in order to run this code stand alone, because that is the entry point for the application.
Per your comment, You will need to create an instance of the Pong class inside of the main method and invoke its run() method:
public static void main(String[] args) {
Pong p = new Pong();
p.run();
}
If the run method of the Pong class is static, you wont need an instance, and you could do this:
public static void main(String[] args) {
Pong.run();
}

You should be exporting it as a "Runnable JAR file" instead of a "JAR file". Once you choose this you should be able to use a drop down menu called "Launch configuration:", and then you can choose your export destination.
I am using Eclipse Kepler. It may not be the same for different versions.

Your project should contain class with main method so that you can see your project in Launch Configuration drop down list. (Eclipse Kepler)

Related

I am trying to find a path through a randomly generated maze

This is a maze solver and I am trying to find a path through the maze. The Map is generated using Prim's algorithm and the position class which is added at the end.
I am trying to find an optimal path through the randomly generated maze using BFS, A*, or DFS but I seem to be doing something wrong.
//impoted by wildcard
import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
public class MazeGenerator extends Canvas {
private final Random rand = new Random(); //random variable
private static int WIDTH;
private static int HEIGHT;
private int TILE_WIDTH = 15;
private int TILE_HEIGHT = 15;
private static LinkedList <position> maze = new LinkedList<>(); // maze
private static Map<position, Color> colors = new HashMap<>();
// paint class to draw out the maze
public void paint(Graphics g) {
super.paint(g);
g.translate(5, 5);
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, WIDTH * TILE_WIDTH, HEIGHT * TILE_HEIGHT);
g.setColor(Color.LIGHT_GRAY);
g.drawLine(0, 0, 0, HEIGHT * TILE_HEIGHT);
g.drawLine(0, 0, WIDTH * TILE_WIDTH, 0);
g.drawLine(WIDTH * TILE_WIDTH, 0, WIDTH * TILE_WIDTH, HEIGHT * TILE_HEIGHT);
g.drawLine(0, HEIGHT * TILE_HEIGHT, WIDTH * TILE_WIDTH, HEIGHT * TILE_HEIGHT);
LinkedList <position> mazeSteped = maze;
for(int y = 0; y < HEIGHT; y++)
{
for(int x = 0; x < WIDTH; x++)
{
int current = (y * WIDTH) + x;
int lower = ((y + 1) * WIDTH) + x;
if(!mazeSteped.contains(new position(current, lower)))
g.drawLine(x * TILE_WIDTH, (y + 1) * TILE_HEIGHT, (x + 1) * TILE_WIDTH, (y + 1) * TILE_HEIGHT);
if(!mazeSteped.contains(new position(current, current + 1)))
g.drawLine((x + 1) * TILE_WIDTH, y * TILE_HEIGHT, (x + 1) * TILE_WIDTH, (y + 1) * TILE_HEIGHT);
if(colors.containsKey(new position(x, y)))
{
g.setColor(colors.get(new position(x, y)));
g.fillRect(x * TILE_WIDTH, y * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
g.setColor(Color.LIGHT_GRAY);
}
}
}
}
// Prim's algorithm
public void generate(int Width, int Height)
{
LinkedList<Integer> visited = new LinkedList<>();
LinkedList<position> toVisit = new LinkedList<>();
visited.add(0);
toVisit.add(new position(0, 1));
toVisit.add(new position(0, Width));
while(toVisit.size() > 0)
{
int randomIndex = rand.nextInt(toVisit.size());
position nextPath = toVisit.remove(randomIndex);
if(visited.contains(nextPath.end))
continue;
if(nextPath.start > nextPath.end)
maze.add(new position(nextPath.end, nextPath.start));
else
maze.add(nextPath);
visited.add(nextPath.end);
//this is showing all four directions that the random variable can generate towards.
int above = nextPath.end - Width;
if(above > 0 && !visited.contains(above))
toVisit.add(new position(nextPath.end, above));
int left = nextPath.end - 1;
if(left % Width != Width - 1 && !visited.contains(left))
toVisit.add(new position(nextPath.end, left));
int right = nextPath.end + 1;
if(right % Width != 0 && !visited.contains(right))
toVisit.add(new position(nextPath.end, right));
int below = nextPath.end + Width;
if(below < Width * Height && !visited.contains(below))
toVisit.add(new position(nextPath.end, below));
}
}
public static void main(String[] args)
{
MazeGenerator mazeGen = new MazeGenerator();
int Height = 30;
HEIGHT = Height;
int Width = 30;
WIDTH = Width;
mazeGen.generate(Width, Height);
mazeGen.setSize(16*Width, 17*Height);
JFrame frame = new JFrame("Maze Generator");
frame.add(mazeGen);
frame.setSize(16*Width, 17*Height);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
//position or vector class that keeps track of position.
public class position{
public int start;
public int end;
public position(int start, int end){
this.start = start;
this.end = end;
}
public String toString(){
return "(" + start + ", " + end + ")";
}
public boolean equals(Object obj){
if(!(obj instanceof position))
return false;
position pos = (position) obj;
return pos.start == start && pos.end == end;
}
public int hashCode(){
return this.toString().hashCode();
}
public static void main(String [] args) {
position my = new position(1,1);
System.out.println(new position(1,1));
}
}
https://github.com/yuchinchenTW/MazeGenerate/tree/master
try this maze generator
using depth-first search and Recursive division method
The recursive division method can prevent stackoverflow on recursion
https://en.wikipedia.org/wiki/Maze_generation_algorithm

LibGdx Mouse Position relative to Orthographic Camera instead of Screen

Basically I wrote a "Dota like Style" based on the OrthographicCamera from libgdx.
You can test it out for youself here is the class.
I am using this to draw a TiledMap, and I have and array of tiles corresponding with the graphical tiles, however if I move the mouse, and with that the camera.
The coordinates off the mouse and the tiles are completely different.
Gdx.input x and y get their coordinates relative to the screen and not where the mouse is in the world relative to the camera.
I can't figure out a way to get the mouse position relative to the camera, so that if I move the camera I won't just get the regular mouse coordinates, but the actual world coordinates that the camera is showing, and where my mouse is located within the confines of the view of the camera relative to the world.
public class DotaCamera extends OrthographicCamera {
private float xmin;
private float xmax;
private float ymin;
private float ymax;
private float x;
private float y;
private int Width = Gdx.graphics.getWidth();;
private int Height = Gdx.graphics.getHeight();
private int camSpeedMax = 16;
private float camAcceleration = 0.3f;
private int camSpeedSmoother = 3;
private float camVelocityX = 0;
private float camVelocityY = 0;
private float fZoomMax = 1f;
private float fZoomMin = 0.5f;
private float fZoomSpeed = 0.03f;
public DotaCamera() {
this(0, 0, 0, 0);
}
public DotaCamera(float xmin, float xmax, float ymin, float ymax) {
super();
setBounds(xmin, xmax, ymin, ymax);
}
public void setBounds(float xmin, float xmax, float ymin, float ymax) {
this.xmin = xmin;
this.xmax = xmax;
this.ymin = ymin;
this.ymax = ymax;
}
public void setPosition(float x, float y) {
setPosition(x, y, 0);
}
public void setPosition(float x, float y, float z) {
position.set(x, y, z);
this.x = x;
this.y = y;
fixBounds();
}
private void fixBounds() {
if (position.x < xmin + viewportWidth / 2) {
position.x = xmin + viewportWidth / 2;
}
if (position.x > xmax - viewportWidth / 2) {
position.x = xmax - viewportWidth / 2;
}
if (position.y < ymin + viewportHeight / 2) {
position.y = ymin + viewportHeight / 2;
}
if (position.y > ymax - viewportHeight / 2) {
position.y = ymax - viewportHeight / 2;
}
}
/**
* Controls the zoom of the of the camera.
*/
public void updateZoom() {
int mouseWheelMovement = Mouse.getDWheel();
if (mouseWheelMovement > 0) {
if (this.zoom > fZoomMin) {
this.zoom -= fZoomSpeed;
} else {
this.zoom = fZoomMin;
}
}else if(mouseWheelMovement < 0){
if (this.zoom < fZoomMax) {
this.zoom += fZoomSpeed;
} else {
this.zoom = fZoomMax;
}
}
}
/**
* Update And move the Camera DOTA Stylized movement.
*/
public void updateAndMove() {
float dt = Gdx.graphics.getDeltaTime();
int MouseX = Mouse.getX(); // Get MouseX
int MouseY = Height - Mouse.getY(); // Get MouseY
int camSpeedX = 0;
int camSpeedY = 0;
String horizontalDirection = getMoveLeftRight(MouseX); // Get
// horizontalDirection
String verticalDirection = getMoveUpDown(MouseY); // Get
// verticalDirection
/* * * * * * * *
* Decide what to do with the horizontalDirection.
*/
switch (horizontalDirection) {
case "left":
camSpeedX = ((Width / 2) - (MouseX + (Width / 4)))
/ camSpeedSmoother; // Create Speed -X
camSpeedX = ((camSpeedX > camSpeedMax) ? camSpeedMax : camSpeedX); // Limit
// the
// speed.
if (camVelocityX < camSpeedX)
camVelocityX += camAcceleration;
break;
case "right":
camSpeedX = (((MouseX + (Width / 4)) - ((Width / 4) * 3)) - (Width / 4))
/ camSpeedSmoother; // Create speed +X.
camSpeedX = ((camSpeedX > camSpeedMax) ? camSpeedMax : camSpeedX); // Limit
// the
// speed.
if (camVelocityX < camSpeedX)
camVelocityX += camAcceleration; // Accelerate
camSpeedX *= -1; // To negate the speed.
break;
case "":
camVelocityX = 0;
break;
}
/* * * * * * * *
* Decide what to do with the verticalDirection.
*/
switch (verticalDirection) {
case "up":
camSpeedY = (Height / 4) - MouseY; // Create speed -Y
camSpeedY = ((camSpeedY > camSpeedMax) ? camSpeedMax : camSpeedY); // Limit
// the
// speed.
if (camVelocityY < camSpeedY)
camVelocityY += camAcceleration;
camSpeedY *= -1;
break;
case "down":
camSpeedY = (((MouseY + (Height / 4)) - ((Height / 4) * 3)) - (Height / 4))
/ camSpeedSmoother; // Create speed +Y.
camSpeedY = ((camSpeedY > camSpeedMax) ? camSpeedMax : camSpeedY); // Limit
// the
// speed.
if (camVelocityY < camSpeedY)
camVelocityY += camAcceleration;
break;
case "":
camVelocityY = 0;
break;
}
// System.out.println("vX:" +camVelocityX+ "vY: " +camVelocityY+ "sX: "
// +camSpeedX+ "sY: " +camSpeedY);
this.position.x -= (camVelocityX * camSpeedX) * dt;
this.position.y -= (camVelocityY * camSpeedY) * dt;
this.update();
}
/**
* Get the X-Axial Direction.
*
* #param MouseX
* #return Direction
*/
private String getMoveLeftRight(int MouseX) {
if (MouseX + (Width / 4) < Width / 2) {// Needs to move left?
return "left";
} else if (MouseX > (Width / 4) * 3) {// Needs to move right?
return "right";
}
return "";
}
/**
* Get the Y-Axial Direction.
*
* #param MouseY
* #return Direction
*/
private String getMoveUpDown(int MouseY) {
if (MouseY < Height / 4) {// Needs to move up?
return "up";
} else if (MouseY > (Height / 4) * 3) {// Needs to move down?
return "down";
}
return "";
}
Came across this problem and discovered the answer here:
https://gamedev.stackexchange.com/questions/27786/camera-coordinate-to-screen-coordinate
Supposedly, using Camera.unproject(Vector3 screenCoords) is the correct way of doing this.
My solution looks like this:
Vector3 getMousePosInGameWorld() {
return camera.unproject(new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0));
}
I hope you found the solution to what you need here
https://gamedev.stackexchange.com/questions/60703/libgdx-how-to-get-mouse-position-relative-to-a-tiled-map
maybe here
Get cursor position in LIBGDX
or here
http://www.netthreads.co.uk/2012/01/31/libgdx-example-of-using-scene2d-actions-and-event-handling/

Java Applet: Cant figure out how to display rectangle on keypressed

I am basically coding this basic arcade game and i need the circle to shoot out small rectangles that looks like bullets or missiles to hit the bad guys whenever the space bar is hit but i cant figure out how.
Heres my code so far:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class main extends Applet implements Runnable, KeyListener {
private Image i;
private Graphics doubleG;
// x and y are used to set (x,y) positions
// dx and dy are the changes in position
private int x = 850;
private int y = 850;
private int x2 = 100;
private int y2 = 100;
private int dx = 50;
private int radius = 30;
private int dx2 = 4;
private int dy2 = 4;
private int x3 = 100;
private int y3 = 200;
private int dx3 = 5;
private int dy3 = 5;
private int x4 = 100;
private int y4 = 300;
private int dx4 = 3;
private int dy4 = 3;
public void init(){
setSize(1920,1080);
setBackground(Color.black);
addKeyListener(this);
}
public void start(){
Thread thread = new Thread(this);
thread.start();
}
public void run() {
while(true){
//Enemy
if(x2 + dx2 > this.getWidth() - radius - 1){
x2 = this.getWidth() - radius - 1;
dx2 = -dx2;
}
if(x2 + dx2 < 0 + radius){
x2 = 0 + radius;
dx2 = -dx2;
}
x2 += dx2;
// Enemy
if(x3 + dx3 > this.getWidth() - radius - 1){
x3 = this.getWidth() - radius -1;
dx3 = -dx3;
}
if(x3 + dx3 < 0 + radius){
x = 0 + radius;
dx3 = -dx3;
}
x3 += dx3;
// Enemy
if(x4 + dx4 > this.getWidth() - radius - 1){
x4= this.getWidth() - radius -1;
dx4 = -dx4;
}
if(x4 + dx4 < 0 + radius){
x4 = 0 + radius;
dx4 = -dx4;
}
x4 += dx4;
// EVERYTHING ABOVE KEEPS ASTEROIDS IN THE SCREEN ALLOWING IT TO BOUNCE OFF WALLS
repaint();
try{
Thread.sleep(17);
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
public void stop(){
}
public void update(Graphics g){
// this function stops the flickering problem every time the ball moves by copying the image instead of repainting it
if(i == null){
i = createImage(this.getSize().width, this.getSize().height);
doubleG = i.getGraphics();
}
doubleG.setColor(getBackground());
doubleG.fillRect(0,0,this.getSize().width, this.getSize().height);
doubleG.setColor(getForeground());
paint(doubleG);
g.drawImage(i,0,0,this);
}
public void paint(Graphics g){
g.setColor(Color.BLUE);
g.fillOval(x, y, radius*2, radius*2);
g.setColor(Color.RED);
g.fillOval(x2, y2, radius + 10, radius + 10);
g.setColor(Color.RED);
g.fillOval(x3,y3, radius + 10, radius + 10);
g.setColor(Color.RED);
g.fillOval(x4, y4, radius + 10, radius + 10);
}
public void moveRight(){
if (dx-1 > -20){
dx += 1;
}
if(x + dx > this.getWidth() - radius - 1){
x = this.getWidth() - radius - 1;
dx = -dx;
}
x += dx;
}
public void moveLeft(){
if(dx - 1 > -20){
dx -= 1;
}
if(x + dx < 0 + radius){
x = 0 + radius;
dx = -dx;
}
x -= dx;
}
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch(e.getKeyCode()){
case KeyEvent.VK_LEFT:
moveLeft();
break;
case KeyEvent.VK_RIGHT:
moveRight();
break;
}
}
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
KeyListener will only raise KeyEvents if the component it is registered to is focusable AND has foucs.
You never call super.paint, expect some serious paint artifacts
Avoid overriding paint of top level containers (like Applet)
Consider using Swing based components over AWT, apart from been more update to date and more widely used, Swing components are also double buffered by default. Use a combination of JApplet and JPanel as the main drawing surface, overriding it's paintComponent method. In this case, also consider using a javax.swing.Timer over Thread, unless you want to try and maintain a variable delay between updates. This would also allow you to use the key bindings API overcoming the focus issues related to KeyListener

Only one brick disappears in breakout game

I am new to Java and am learning from Stanford lectures from YouTube.
So I was trying out their assignment to make a breakout game and so far so good until now. I have all my bricks, ball and paddle including the mechanics of the game but when i run the game only one brick can be removed when hit by the ball. see this. That brick happens to be the last brick added to the canvas.
The ball just flies past all other bricks with no effect. The relevant code is below.
Am I lacking some important knowledge about getElementAt here? I have a feeling that getCollidingObject is not assigned to collider, which is making the collision detection faulty. I hope someone can enlighten me on this!
private void addBallMotion(){
// y component of starting velocity; pixels per second
vy = 3.0;
/* x component of starting velocity; pixels per second
* which ranges according to the random generator
* can be negative or positive, ball can go left or right with equal chances
*/
vx = rgen.nextDouble(1.0, 3.0);
if (rgen.nextBoolean(0.5)){
vx = -vx;
}
while (true){
ball.move(vx, vy);
checkCollision();
pause(FPS);
}
}
private void checkCollision(){
checkWallCollision();
checkBrickAndPaddleCollision();
}
private void checkWallCollision(){
//checks for left or right collision
if ( (ball.getX() < leftBounds.getX() ) || (ball.getX() + BALL_RADIUS * 2 > rightBounds.getX()) ){
vx = -vx;
}
//checks for top or bottom collision
if ( (ball.getY() < topBounds.getY() ) || (ball.getY() + BALL_RADIUS * 2 > bottomBounds.getY()) ){
vy = -vy;
}
}
private void checkBrickAndPaddleCollision(){
GObject collider = getCollidingObject();
if (collider == brick){
remove(collider);
vy = -vy;
}
if (collider == paddle){
vy = -vy;
}
}
//check for collision at the 4 edges of the ball
//starting with the left and going clockwise
private GObject getCollidingObject(){
GObject ballLeft= getElementAt (ball.getX() - 1, ball.getY() + BALL_RADIUS);
GObject ballRight= getElementAt (ball.getX() + BALL_RADIUS * 2 + 1, ball.getY() + BALL_RADIUS);
GObject ballTop = getElementAt (ball.getX() + BALL_RADIUS * 2, ball.getY() - 1);
GObject ballBottom= getElementAt (ball.getX() + BALL_RADIUS, ball.getY() + BALL_RADIUS * 2 + 1);
if (ballLeft != null){
return (ballLeft);
}
else if (ballTop != null){
return (ballTop);
}
else if (ballRight != null){
return (ballRight);
}
else if (ballBottom != null){
return (ballBottom);
}
return (null);
}
private GRect paddle; // creates a paddle that only moves linearly according to mouses' x coordinate
private GRect brick;
private GOval ball;
private double vx, vy; // x and y components of the ball's velocity
//private GObject collider;
Here's the whole program:
import acm.graphics.*;
import acm.program.*;
import acm.util.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Breakout extends GraphicsProgram {
/** Width and height of application window in pixels */
public static final int APPLICATION_WIDTH = 400;
public static final int APPLICATION_HEIGHT = 600;
/** Dimensions of game board (usually the same) */
private static final int WIDTH = APPLICATION_WIDTH;
private static final int HEIGHT = APPLICATION_HEIGHT;
/** Dimensions of the paddle */
private static final int PADDLE_WIDTH = 60;
private static final int PADDLE_HEIGHT = 10;
/** Offset of the paddle up from the bottom */
private static final int PADDLE_Y_OFFSET = 30;
/** Number of bricks per row */
private static final int NBRICKS_PER_ROW = 10;
/** Number of rows of bricks */
private static final int NBRICK_ROWS = 10;
/** Separation between bricks */
private static final int BRICK_SEP = 4;
/** Width of a brick */
private static final int BRICK_WIDTH =
(WIDTH - (NBRICKS_PER_ROW - 1) * BRICK_SEP) / NBRICKS_PER_ROW;
/** Height of a brick */
private static final int BRICK_HEIGHT = 8;
/** Radius of the ball in pixels */
private static final int BALL_RADIUS = 10;
/** Offset of the top brick row from the top */
private static final int BRICK_Y_OFFSET = 70;
/** Offset of the side bricks from the sides of game window */
private static final int BRICK_X_OFFSET = ((WIDTH - NBRICKS_PER_ROW * (BRICK_WIDTH + BRICK_SEP) + BRICK_SEP) / 2);
/** Number of turns */
private static final int NTURNS = 3;
/** Number of frames per second */
private static final int FPS = 1;
/* Method: run() */
/** Runs the Breakout program. */
public void run() {
addMouseListeners();
addWorld();
// runGame();
}
private void addWorld(){
setSize (APPLICATION_WIDTH, APPLICATION_HEIGHT);
addPlayingBox();
addBricks();
addPaddle();
addBall();
// addCounter();
}
//adds the bound area onto screen
private void addPlayingBox(){
topBounds = new GLine (0, 0, WIDTH, 0);
bottomBounds = new GLine (0, HEIGHT, WIDTH, HEIGHT);
leftBounds = new GLine (0, 0, 0, HEIGHT);
rightBounds = new GLine (WIDTH, 0, WIDTH, HEIGHT);
add (topBounds);
add (bottomBounds);
add (leftBounds);
add (rightBounds);
}
private void addBricks(){
for (int i = 0; i < NBRICK_ROWS; i++){
int y = BRICK_Y_OFFSET + (i * (BRICK_HEIGHT + BRICK_SEP));
for (int j = 0; j < NBRICKS_PER_ROW; j++){
int x = (BRICK_X_OFFSET) + (j * (BRICK_WIDTH + BRICK_SEP));
brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT );
colorBrick(brick, i);
add (brick);
}
}
}
// every consecutive 2 rows are colored the same
private void colorBrick(GRect brick, int rowNumber){
brick.setFilled (true);
switch (rowNumber + 1) {
case 1: case 2: brick.setColor(Color.red);
break;
case 3: case 4: brick.setColor(Color.orange);
break;
case 5: case 6: brick.setColor(Color.yellow);
break;
case 7: case 8: brick.setColor(Color.green);
break;
case 9: case 10:brick.setColor(Color.cyan);
break;
}
}
//adds paddle to screen
private void addPaddle(){
paddle = new GRect (PADDLE_WIDTH, PADDLE_HEIGHT);
paddle.setFilled(true);
paddle.setColor (Color.BLACK);
add (paddle);
}
//creates motion for the paddle according to mouse movement
public void mouseMoved(MouseEvent e){
paddle.setLocation ((e.getX() - PADDLE_WIDTH / 2), (double) (HEIGHT - PADDLE_Y_OFFSET));
/* checks if the paddle within the playing area
* if not the paddles will stay at the extremities*/
if ( paddle.getX() > (WIDTH - PADDLE_WIDTH)){
paddle.setLocation((double) (WIDTH - PADDLE_WIDTH), (double) (HEIGHT - PADDLE_Y_OFFSET));
}
if ( paddle.getX() < 0){
paddle.setLocation((double) 0, (double) (APPLICATION_HEIGHT - PADDLE_Y_OFFSET));
}
}
private void addBall(){
ball = new GOval (((WIDTH - BALL_RADIUS * 2) / 2), ((HEIGHT - BALL_RADIUS * 2) / 2),
BALL_RADIUS * 2, BALL_RADIUS * 2);
ball.setFilled(true);
ball.setColor(Color.BLACK);
add (ball);
addBallMotion();
}
private void addBallMotion(){
// y component of starting velocity; pixels per second
vy = 3.0;
/* x component of starting velocity; pixels per second
* which ranges according to the random generator
* can be negative or positive, ball can go left or right with equal chances
*/
vx = rgen.nextDouble(1.0, 3.0);
if (rgen.nextBoolean(0.5)){
vx = -vx;
}
while (true){
ball.move(vx, vy);
checkCollision();
pause(FPS);
}
}
private void checkCollision(){
checkWallCollision();
checkBrickAndPaddleCollision();
}
private void checkWallCollision(){
//checks for left or right collision
if ( (ball.getX() < leftBounds.getX() ) || (ball.getX() + BALL_RADIUS * 2 > rightBounds.getX()) ){
vx = -vx;
}
//checks for top or bottom collision
if ( (ball.getY() < topBounds.getY() ) || (ball.getY() + BALL_RADIUS * 2 > bottomBounds.getY()) ){
vy = -vy;
}
}
private void checkBrickAndPaddleCollision(){
GObject collider = getCollidingObject();
if (collider == brick){
remove(collider);
vy = -vy;
}
if (collider == paddle){
vy = -vy;
}
}
//check for collision at the 4 edges of the ball
//starting with the left and going clockwise
private GObject getCollidingObject(){
GObject ballLeft= getElementAt (ball.getX() - 1, ball.getY() + BALL_RADIUS);
GObject ballRight= getElementAt (ball.getX() + BALL_RADIUS * 2 + 1, ball.getY() + BALL_RADIUS);
GObject ballTop = getElementAt (ball.getX() + BALL_RADIUS * 2, ball.getY() - 1);
GObject ballBottom= getElementAt (ball.getX() + BALL_RADIUS, ball.getY() + BALL_RADIUS * 2 + 1);
if (ballLeft != null){
return (ballLeft);
}
else if (ballTop != null){
return (ballTop);
}
else if (ballRight != null){
return (ballRight);
}
else if (ballBottom != null){
return (ballBottom);
}
return (null);
}
private GRect paddle; // creates a paddle that only moves linearly according to mouses' x coordinate
private GRect brick;
private GOval ball;
private double vx, vy; // x and y components of the ball's velocity
private RandomGenerator rgen = RandomGenerator.getInstance();
//private GObject collider;
private GLine topBounds; // creates a bounding box that is the playing area
private GLine bottomBounds;
private GLine leftBounds;
private GLine rightBounds;
}
Exactly as I thought.
Look - You have a field in your class called brick. It's of GRect type. At the beginning you're calling addWorld() method, which calls addBricks(). Now check what you wrote:
private void addBricks(){
for (int i = 0; i < NBRICK_ROWS; i++){
int y = BRICK_Y_OFFSET + (i * (BRICK_HEIGHT + BRICK_SEP));
for (int j = 0; j < NBRICKS_PER_ROW; j++){
int x = (BRICK_X_OFFSET) + (j * (BRICK_WIDTH + BRICK_SEP));
brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT );
colorBrick(brick, i);
add (brick);
}
}
}
What happens in there? You're having a loop in which brick is overriden NBRICK_ROWS * NBRICKS_PER_ROW times, which causes brick field to be the last created brick on your screen.
Basically, you're doing something similar to this:
int x;
x = 5;
x = 6;
x = 8;
// x is 8 now
And in checkBrickAndPaddleCollision() you're checking only if collider is brick. Which in other words means, you're checking if it's the last brick - if it is, then you remove it.
First of all you should create an array of bricks, not just one field.
ArrayList<GRect> bricks;
instead of:
GRect brick;
And then in addBricks() method, you should have:
bricks.add(new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT));
instead of:
brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT );
After this, in checkBrickAndPaddleCollision(), you should not check:
if (collider == brick) {
remove(collider);
vy = -vy;
}
but rather all bricks:
for(GRect brick : bricks) {
if (collider.equals(brick)) { // Note that you should rather use .equals, instead of == as Aurand stated in his comment
remove(collider);
vy = -vy;
}
}

Stanford cs106a - Breakout exersize

I'm trying to learn java by following the cs106a course online.
Currently I've arrived at the breakout exersize and I'm having some trouble with bugs
I haven't finished it completely but I want to solves these issues first before I go further.
Problem 1:
when the ball collides with the bricks they don't always seem to be removed from the canvas.
sometimes the brick will be removed on a second time it collides. But there is one row (of yellow bricks) that doesn't respond at all to the ball collisions.
Problem 2:
my paddle can be moved by dragging the mouse. the only problem is. the bricks can also be moved like the paddle.
I know it has something to do with this piece of code
gobj = getElementAt(lastX, lastY);
If I remove it altogether the bricks aren't moveable anymore. which is good. but I'm still
able to move the paddle no matter where I click and drag.
can anyone give me a hint so I can correct the mistakes?
Here's my code below.
Thanks
/*
* File: Breakout.java
* -------------------
* This file will eventually implement the game of Breakout.
*/
import acm.graphics.*;
import acm.program.*;
import acm.util.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import org.omg.CORBA.PUBLIC_MEMBER;
public class breakout extends GraphicsProgram {
/** Width and height of application window in pixels */
public static final int APPLICATION_WIDTH = 400;
public static final int APPLICATION_HEIGHT = 600;
/** Dimensions of game board (usually the same) */
private static final int WIDTH = APPLICATION_WIDTH;
private static final int HEIGHT = APPLICATION_HEIGHT;
/** Dimensions of the paddle */
private static final int PADDLE_WIDTH = 60;
private static final int PADDLE_HEIGHT = 10;
/** Offset of the paddle up from the bottom */
private static final int PADDLE_Y_OFFSET = 30;
/** Number of bricks per row */
private static final int NBRICKS_PER_ROW = 10;
/** Number of rows of bricks */
private static final int NBRICK_ROWS = 8;
/** Separation between bricks */
private static final int BRICK_SEP = 4;
/** Width of a brick */
private static final int BRICK_WIDTH = (WIDTH - (NBRICKS_PER_ROW - 1)* BRICK_SEP)/ NBRICKS_PER_ROW;
/** Height of a brick */
private static final int BRICK_HEIGHT = 8;
/** Radius of the ball in pixels */
private static final int BALL_RADIUS = 10;
/** Offset of the top brick row from the top */
private static final int BRICK_Y_OFFSET = 70;
/** Number of turns */
private static final int NTURNS = 3;
private static final int DELAY = 50;
private static final double X_START = WIDTH / 2;
private static final double Y_START = 450;
public void run() {
world();
play();
}
private void ball() {
ball = new GOval(X_START, Y_START, BALL_RADIUS, BALL_RADIUS);
ball.setFillColor(Color.BLACK);
ball.setFilled(true);
add(ball);
}
private void paddle() {
paddle = new GRect(100, 500, PADDLE_WIDTH, PADDLE_HEIGHT);
paddle.setColor(Color.BLACK);
paddle.setFilled(true);
add(paddle);
}
private void brick(int x, int y, Color c) {
GRect brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
brick.setColor(getBackground());
brick.setFillColor(c);
brick.setFilled(true);
add(brick);
}
private void brickRow(int x, int y, Color c) {
x = BRICK_SEP / 2;
y += BRICK_Y_OFFSET;
for (int i = 0; i < NBRICKS_PER_ROW; i++) {
brick(x, y, c);
x += BRICK_WIDTH + BRICK_SEP;
}
}
private void world() {
//initialize x and y position for the rows of bricks
int x = 0;
int y = 0;
// set starting color for first row
Color c = Color.red;
paddle();
//create 2 rows of bricks and switch colors
for (int i = 0; i < NBRICK_ROWS; i++) {
if (i <= 1) {
c = Color.ORANGE;
} else if (i > 1 && i <= 3) {
c = Color.YELLOW;
} else if (i > 3 && i <= 5) {
c = Color.GREEN;
} else if (i > 5 && i <= 7) {
c = Color.CYAN;
}
brickRow(x, y, c);
y += BRICK_HEIGHT + BRICK_SEP;
}
}
private void moveBall() {
ball.move(xVel, yVel);
}
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
gobj = getElementAt(lastX, lastY);
}
public void mouseDragged(MouseEvent e) {
if (paddle != null) {
paddle.move(e.getX() - lastX, getY());
lastX = e.getX();
lastY = e.getY();
}
//constrain paddle movement
if (paddle.getX() < 0){
paddle.setLocation(0, 500);
}else if (paddle.getX()+BRICK_WIDTH > WIDTH ){
paddle.setLocation(WIDTH-BRICK_WIDTH, 500);
}
}
private void checkForCollision() {
// ball collission with walls
if (ball.getY() > getHeight() - BALL_RADIUS
|| ball.getY() < 0 + BALL_RADIUS) {
yVel = -yVel;
} else if (ball.getX() > getWidth() - BALL_RADIUS
|| ball.getX() < 1 + BALL_RADIUS) {
xVel = -xVel;
// ball collission with paddle
} else if (getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) == paddle) {
yVel = -yVel;
// check for collision with bricks to remove them but ignore collision with paddle
} else if (getElementAt(ball.getX(), ball.getY()) != null
&& getElementAt(ball.getX(), ball.getY()) != paddle) {
remove(getCollidingObject(ball.getX(), ball.getY()));
yVel = -yVel;
} else if (getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) != null
&& getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) != paddle) {
remove(getCollidingObject(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS));
yVel = -yVel;
} else if (getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) != null
&& getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) != paddle) {
remove(getCollidingObject(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS));
yVel = -yVel;
} else if (getElementAt(ball.getX(), ball.getY() + BALL_RADIUS) != null
&& getElementAt(ball.getX(), ball.getY() + BALL_RADIUS) != paddle) {
remove(getCollidingObject(ball.getX(), ball.getY() + BALL_RADIUS));
yVel = -yVel;
}
}
private void play() {
addMouseListeners();
ball();
while (true) {
checkForCollision();
moveBall();
pause(DELAY);
}
}
private GObject getCollidingObject(double x, double y) {
return getElementAt(x, y);
}
private double lastX;
private double lastY;
private double xVel = 5;
private double yVel = 15;
private GOval ball;
private GRect paddle;
private GObject gobj;
}
Why don't you use suggested method in handout 19:
private GObject getCollidingObject()
use also collider:
GObject collider = getCollidingObject();
First of all separate your conditions with walls collisions and (paddle with bricks) game elements collisions into two separate methods cause to simplify else if cascading (decomposition I think you know what it means). You have only two objects what you should worry about paddle and bricks, so you need to compare only on (collider == paddle) and collider != null. Also you use only radius in comparisons but should use diameter (2 * radius). Have fun :)
You're y step for each movement of the ball is too large at 15. Since each brick is only 8 in height, at times you're bypassing the brick before evaluating whether that location contained an object or not. E.g. Lets assume you're last evaluation left you're ball with a Y location of 20 and the closest brick is only length of 2 away. You're next evaluation will not include this brick since you move 15 and the height of the brick is 8, meaning range of y values 22 to 30. You'll be out by 5 away from this brick in you're next evaluation. I know the values should be inverted considering the location of the bricks, but you get the point...
With smaller steps in y values collisions will be checked more regularly and provided you make the step small enough, remove this problem.

Categories