Having problems implementing SAT polygon collision detection in Java - java

Im currently trying to implement SAT in java but for some reason it doesn't work. I have rewritten my code multiple times, looked over it even more and watched many tutorials but cant find my mistake. In some cases for some edges it works partly properly but otherwise it detects collision when not colliding.
Later i'll add AABB collision detection for better performance.
Here are the relevant parts of my code:
SAT class:
public class SAT {
public static boolean checkSAT(Polygon poly1, Polygon poly2) {
Vector[] axes = new Vector[poly1.p.length + poly2.p.length];
for (int i = 0; i < poly1.p.length + poly2.p.length; i++) {
int a = i; if(i == poly1.p.length) a -= poly1.p.length;
axes[i] = poly1.getEdge(a).getNormal().getNormalized();
}
double p1_min = Double.POSITIVE_INFINITY, p1_max = Double.NEGATIVE_INFINITY,
p2_min = Double.POSITIVE_INFINITY, p2_max = Double.NEGATIVE_INFINITY;
for (int i = 0; i < axes.length; i++) {
for (int j = 0; j < poly1.p.length; j++) {
double proj = axes[i].dotProduct(poly1.p[j]);
if(proj < p1_min) p1_min = proj;
if(proj > p1_max) p1_max = proj;
}
for (int j = 0; j < poly2.p.length; j++) {
double proj = axes[i].dotProduct(poly2.p[j]);
if(proj < p2_min) p2_min = proj;
if(proj > p2_max) p2_max = proj;
}
if (p1_max < p2_min || p2_max < p1_min)
return false;
}
return true;
}
}
vector class:
public class Vector {
public final double x;
public final double y;
public Vector(double x, double y) {
this.x = x;
this.y = y;
}
public Vector getNormal() {
return new Vector(-y, x);
}
public double getLength() {
return Math.sqrt(x*x + y*y);
}
public Vector getNormalized() {
double l = getLength();
return new Vector(x/l, y/l);
}
public double dotProduct(Vector vec) {
return x * vec.x + y * vec.y;
}
}
relevant parts of the polygon class:
public class Polygon {
public Vector[] m; //"model" of the polygon
public Vector[] p; //coordinates of the corners of the polygon in space
public double posX;
public double posY;
public Polygon(Vector[] m) {
this.m = m;
p = new Vector[m.length];
transform();
}
//later i'll add rotation
public void transform() {
for (int i = 0; i < m.length; i++) {
p[i] = new Vector(m[i].x + posX, m[i].y + posY);
}
}
public void setPosition(Vector pos) {
posX = pos.x;
posY = pos.y;
transform();
}
public Vector getEdge(int i) {
if(i >= p.length) i = 0;
int j = i+1; if(j >= p.length) j = 0;
return new Vector(p[j].x - p[i].x, p[j].y - p[i].y);
}
}

Update:
I found the mistake and it's just plain stupid!! And on top of that I spend more than 5 hours finding it!!!!!!
double p1_min = Double.POSITIVE_INFINITY, p1_max = Double.NEGATIVE_INFINITY,
p2_min = Double.POSITIVE_INFINITY, p2_max = Double.NEGATIVE_INFINITY;
//those doubles should be declared inside the for loop
for (int i = 0; i < axes.length; i++) {
//right here
for (int j = 0; j < poly1.p.length; j++) {
double proj = axes[i].dotProduct(poly1.p[j]);
if(proj < p1_min) p1_min = proj;
if(proj > p1_max) p1_max = proj;
}
for (int j = 0; j < poly2.p.length; j++) {
double proj = axes[i].dotProduct(poly2.p[j]);
if(proj < p2_min) p2_min = proj;
if(proj > p2_max) p2_max = proj;
}
if (p1_max < p2_min || p2_max < p1_min)
return false;
}

Related

Java invoking command line arguments from the main method to a separate method

How could I optimise this code to take the String[] games values from the main method and have a separate method: public static int points(String[] games). I am super new to Java and don't really understand how to invoke methods.
public class TotalPoints {
public static void main(String[] args) {
String[] games = {"1:0","2:0","3:0","4:0","2:1","3:1","4:1","3:2","4:2","4:3"};
int sum = 0;
int matches = 10;
int x = 0;
int y = 0;
for (int i = 0; i < games.length; i++) {
String[] pieces = games[i].split(":");
x = Integer.parseInt(pieces[0]);
y = Integer.parseInt(pieces[1]);
}
for (int j = 0; j < matches; j++) {
if (x > y) {
sum = sum + 3;
} else if (x == y) {
sum = sum + 1;
}
}
System.out.println(sum);
}
}
You can write something like
public class TotalPoints {
public static void main(String[] args) {
int sum = points(args);
System.out.println(sum);
}
public static int points(String[] games) {
int sum = 0;
int matches = 10;
int x = 0;
int y = 0;
for (int i = 0; i < games.length; i++) {
String[] pieces = games[i].split(":");
x = Integer.parseInt(pieces[0]);
y = Integer.parseInt(pieces[1]);
}
for (int j = 0; j < matches; j++) {
if (x > y) {
sum = sum + 3;
} else if (x == y) {
sum = sum + 1;
}
}
return sum;
}
}
And when you run this class, pass the arguments from command line like
java TotalPoints "1:0" "2:0" "3:0" "4:0" "2:1" "3:1" "4:1" "3:2" "4:2" "4:3"
very simple:
public class TotalPoints {
public static void main(String[] args) {
String[] games = {"1:0","2:0","3:0","4:0","2:1","3:1","4:1","3:2","4:2","4:3"};
int result = points(games);
}
public static int points(String[] games) {
//dowhat ever you want and return an int value
}
}
I suggest this to you
public class TotalPoints {
public static void main(String[] args) {
String[] games = {"1:0","2:0","3:0","4:0","2:1","3:1","4:1","3:2","4:2","4:3"};
int sum = points(games);
System.out.println(sum);
}
private static int points(String[] games) {
int sum = 0;
int matches = 10;
int x = 0;
int y = 0;
for (String game : games) {
String[] pieces = game.split(":");
x = Integer.parseInt(pieces[0]);
y = Integer.parseInt(pieces[1]);
}
for (int j = 0; j < matches; j++) {
if (x > y) {
sum = sum + 3;
}
else if (x == y) {
sum = sum + 1;
}
}
return sum;
}
}
I replace for (int i = 0; i < games.length; i++)
by
for (String game : games)
it's a simpler way to browse a list

Simple Neural Network using only one class

I have implemented a simple neural network in Java that is supposed to solve the XOR problem (http://www.mind.ilstu.edu/curriculum/artificial_neural_net/xor_problem_and_solution.php).
I was wondering what you need Neuron and a NeuronLayer etc. classes for, so I decided to try to make it work using only one class.
Unfortunately, after some epochs, it reaches a state where the error is one of two values: 0.5 or -0.5.
I have tried limiting the range that the starting weights are chosen from but that didn't change anything.
Maybe, some of you can help me spot a mistake or improve the network.
Thanks in advance!
Here is my code:
int inCount = 2;
int hidCount = 3;
int outCount = 1;
float learningRate = 0.01;
float[] inputs = new float[inCount];
float[] hidden = new float[hidCount];
float[] outputs = new float[outCount];
float[][] IHweights = new float[inCount][hidCount];
float[][] HOweights = new float[hidCount][outCount];
void setup ()
{
for (int i = 0; i < IHweights.length; i++)
{
for (int e = 0; e < IHweights[i].length; e++)
{
float newWeight = random(-1,1);
while(newWeight > -0.5 && newWeight < 0.5)
{
newWeight = random(-1,1);
}
IHweights[i][e] = newWeight;
println(IHweights[i][e]+"\n");
}
}
for (int i = 0; i < HOweights.length; i++)
{
for (int e = 0; e < HOweights[i].length; e++)
{
float newWeight = random(-1,1);
while(newWeight > -0.5 && newWeight < 0.5)
{
newWeight = random(-1,1);
}
HOweights[i][e] = newWeight;
}
}
}
void draw ()
{
float[] inData = {round(random(1)),round(random(1))};
println(inData[0]+" "+inData[1]);
float[] expResult = {(int) inData[0]^(int) inData[1]};
println(" -> "+expResult[0]);
feedForward(inData,expResult);
}
public float sigmoid (float x)
{
if (x>10)
{
return 1;
}
if (x<-10)
{
return 0;
}
return 1/(1+exp(-x));
}
public void feedForward (float[] input, float[] expOut)
{
inputs = input;
for (int i = 0; i < hidCount; i++)
{
float var = 0;
for (int e = 0; e < inCount; e++)
{
var += inputs[e] * IHweights[e][i];
}
hidden[i] = sigmoid(var);
}
for (int i = 0; i < outCount; i++)
{
float var = 0;
for (int e = 0; e < hidCount; e++)
{
var += hidden[e] * HOweights[e][i];
}
outputs[i] = sigmoid(var);
}
float[] error = new float[outCount];
float[] deltaOut = new float[outCount];
for (int i = 0; i < outCount; i++)
{
error[i] = expOut[i] - outputs[i];
deltaOut[i] = outputs[i] * (1-outputs[i]) * error[i];
}
float[] deltaHid = new float[hidCount];
for (int i = 0; i < hidCount; i++)
{
deltaHid[i] = hidden[i] * (1-hidden[i]);
for (int e = 0; e < outCount; e++)
{
deltaHid[i] += HOweights[i][e] * outputs[e];
}
}
for (int i = 0; i < inCount; i++)
{
for (int e = 0; e < hidCount; e++)
{
IHweights[i][e] += inputs[i] * deltaHid[e] * learningRate;
}
}
for (int i = 0; i < hidCount; i++)
{
for (int e = 0; e < outCount; e++)
{
HOweights[i][e] += hidden[i] * deltaOut[e] * learningRate;
}
}
println(error[0]);
}

How to implement Lazy Constraint Callbacks in CPLEX (java API)

currently I am trying to implement a CPLEX exact solution for the Asymmetric Capacitated Vehicle Routing Problem with the MTZ sub-tour elimination constraints.
My problems occurs when I try to implement Lazy Constraint Callbacks. More specifically I get a null pointer exception. There are almost no tutorials for implementing callbacks, so your help will be deeply appreciated.
This is my code:
CVRP class
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import ilog.concert.*;
import ilog.cplex.*;
public class ACVRP {
// euclidean distance method
public static double distance(int x1, int y1, int x2, int y2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
public static void solveModel() {
int n = 32; // number of customers
int k = 5; // number of vehicles
int c = 100; // capacity of vehicles
int datacoords[][] = new int[n][2];
double[][] node = new double[n][n]; // dissimilarity matrix
int[] demand = new int[n]; // demand of every customer
try {
// load matrixes
FileReader frd = new FileReader("demands.txt");
FileReader frcoords = new FileReader("coords.txt");
BufferedReader brd = new BufferedReader(frd);
BufferedReader brcoords = new BufferedReader(frcoords);
String str;
int counter = 0;
while ((str = brd.readLine()) != null) {
String[] splitStr = str.trim().split("\\s+");
demand[counter] = Integer.parseInt(splitStr[1]);
counter++;
}
counter = 0;
while ((str = brcoords.readLine()) != null) {
String[] splitStr = str.trim().split("\\s+");
datacoords[counter][0] = Integer.parseInt(splitStr[1]);
datacoords[counter][1] = Integer.parseInt(splitStr[2]);
counter++;
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
node[i][j] = distance(datacoords[i][0],datacoords[i][1],datacoords[j][0],datacoords[j][1]);
// if (i == j ){
// node[i][j] = 99999999;
// }
}
}
brd.close();
brcoords.close();
IloCplex cplex = new IloCplex();
// variables
IloIntVar[][] x = new IloIntVar[n][];
for (int i = 0; i < n; i++) {
x[i] = cplex.boolVarArray(n);
for (int j = 0; j < n; j++) {
x[i][j].setName("x." + i + "." + j );
}
}
// mtz variables
IloNumVar[] u = cplex.numVarArray(n, 0, Double.MAX_VALUE);
for (int j = 0; j < n; j++) {
u[j].setName("u." + j);
}
//objective
IloLinearNumExpr conObj = cplex.linearNumExpr();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if ( i != j ){
conObj.addTerm(node[i][j], x[i][j]) ;
}
}
}
cplex.addMinimize(conObj);
// constraints
for (int i = 1; i < n; i++) {
IloLinearNumExpr equation1 = cplex.linearNumExpr();
for (int j = 0; j < n; j++) {
if (i!=j) {
equation1.addTerm(1.0, x[i][j]);
}
}
cplex.addEq(equation1, 1.0);
}
for (int j = 1; j < n; j++) {
IloLinearNumExpr equation2 = cplex.linearNumExpr();
for (int i = 0; i < n; i++) {
if (i!=j) {
equation2.addTerm(1.0, x[i][j]);
}
}
cplex.addEq(equation2, 1.0);
}
IloLinearNumExpr equation3 = cplex.linearNumExpr();
for (int i = 1; i < n; i++) {
equation3.addTerm(1.0, x[i][0]);
}
cplex.addEq(equation3, k);
IloLinearNumExpr equation4 = cplex.linearNumExpr();
for (int j = 1; j < n; j++) {
equation4.addTerm(1.0, x[0][j]);
}
cplex.addEq(equation4, k);
cplex.use(new LazyContstraintMTZ(n, c, demand, x, u, cplex));
//parameters
//cplex.setParam(IloCplex.Param.TimeLimit,50);
//cplex.setParam(IloCplex.Param.Preprocessing.Reduce, 0);
// cplex.setParam(IloCplex.Param.RootAlgorithm, IloCplex.Algorithm.Primal);
// solve model
cplex.solve();
cplex.exportModel("model.lp");
System.out.println(cplex.getBestObjValue());
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i != j) {
if (cplex.getValue(x[i][j]) != 0) {
System.out.println("name: " + x[i][j].getName() + " value: " + cplex.getValue(x[i][j]));
}
}
}
}
// end
cplex.end();
} catch (IloException | NumberFormatException | IOException exc) {
exc.printStackTrace();
}
}
}
class for lazy constraint :
import ilog.concert.*;
import ilog.cplex.*;
public class LazyContstraintMTZ extends IloCplex.LazyConstraintCallback {
int n; // number of customers
int c; // capacity of vehicles
int[] demand; // demand of every customer
IloIntVar[][] x;
IloNumVar[] u;
IloCplex cplex;
IloRange[] rng;
//constructor
LazyContstraintMTZ(int n, int c, int[] demand, IloIntVar[][] x, IloNumVar[] u, IloCplex cplex){
this.n = n;
this.c = c;
this.demand = demand;
this.x = x;
this.u = u;
this.cplex = cplex;
}
protected void main() throws IloException {
// Get the current x solution
// double[][] sol = new double[n][n];
// for (int i = 0; i < n; i++) {
// for (int j = 0; j < n; j++) {
// sol[i][j] = cplex.getValue(x[i][j]);
// }
// }
for (int i = 1; i < n; i++) {
for (int j = 1; j < n; j++) {
if (i!=j && demand[i]+demand[j]<=c){
IloLinearNumExpr equation5 = cplex.linearNumExpr();
equation5.addTerm(1.0, u[i]);
equation5.addTerm(-1.0, u[j]);
equation5.addTerm(c, x[i][j]);
rng[i].setExpr(equation5);
rng[i].setBounds(Double.MIN_VALUE, c-demand[j]);
cplex.addLazyConstraint(rng[i]);
}
}
}
for (int i = 1; i < n; i++) {
IloLinearNumExpr equation6 = cplex.linearNumExpr();
equation6.addTerm(1.0, u[i]);
rng[i].setExpr(equation6);
rng[i].setBounds(demand[i], c);
cplex.addLazyConstraint(rng[i]);
}
}
}
As far as I can tell, rng is never initialized in your callback class. So it is always null and as soon as you attempt to set an element in it, you will get that NullPointerException.
Note that you don't even need that array. Instead of
rng[i].setExpr(equation5);
rng[i].setBounds(Double.MIN_VALUE, c-demand[j]);
cplex.addLazyConstraint(rng[i]);
you can just write
IloRange rng = cplex.range(Double.MIN_VALUE, equation5, c - demand[j]);
cplex.addLazyConstraint(rng);
(and similarly for equation6).
Also note that Double.MIN_VALUE is likely not what you want. This gives the smallest representable number larger than 0. I guess what you want is Double.NEGATIVE_INFINITY to specify a range without lower bound. In that case you could also just write
IloRange rng = cplex.le(equation5, c - demand[j]);

Printing A class with 3D Array field

I have a class which is :
public class CCTest {
public double f;
public double[][][] x;
public double counter;
};
and i have assigned random number to x,
CCTest[] cls = new CCTest[5];
for (int i = 0; i < cls.length; i++) {
cls[i] = new CCTest();
}
for (int i = 0; i < (Size = 5); i++) {
cls[i].x = new double[this.c][this.D][this.Size];
for (int j = 0; j < this.D; j++) {
cls[i].x = getRandomX(this.c, this.D, this.Size);
}
}
then I tried to display the result using :
public static void display(double[][][] array) {
int rows = array.length;
int columns = array[0].length;
int depth = array[0][0].length;
for (int d = 0; d < depth; d++) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
System.out.print(array[r][c][d] + " ");
}
System.out.println();
}
System.out.println();
}
}
The Random Generation method is :
public static double[][][] getRandomX(int x, int y, int z) {
double[][][] result = new double[x][y][z];
Random r = new Random();
for (int i = 0; i < z; i++) {
for (int j = 0; j < y; j++) {
for (int k = 0; k < x; k++) {
result[k][j][i] = r.nextDouble();
}
}
}
return result;
}
but the output is empty [] , any idea please
The inner loop : for (int j = 0; j < this.D; j++) {...} is useless so you can remove this.The display and getRandomX() functions are fine. Try this in main , works in my environment:
CCTest[] cls = new CCTest[5];
for (int i = 0; i < cls.length; i++) {
cls[i] = new CCTest();
}
for (int i = 0; i < (Size = 5); i++) {
cls[i].x = new double[c][D][S];
cls[i].x = getRandomX(c, D, S);
}
for (int i = 0; i < (Size = 5); i++) {
display(cls[0].x);
}
Your display method should rather look like:
public static void display(double[][][] array) {
for (int x = 0; x < array.length; x++) {
for (int y = 0; y < array[x].length; y++) {
for (int z = 0; z < array[x][y].length; z++) {
System.out.println(array[x][y][z]);
}
}
}
}
There is another question which comes to my mind. What is getRandomX? You haven't shown us. I'd use the following:
public static double[][][] getRandom3DArray(double[][][] array) {
Random r = new Random();
for (int x = 0; x < array.length; x++) {
for (int y = 0; y < array[x].length; y++) {
for (int z = 0; z < array[x][y].length; z++) {
array[x][y][z] = r.nextDouble();
}
}
}
return array;
}
You're mistaking rows with depth in your display.

Implementing pacman game issue when moving it up and down

I am trying to build a simple pacman game, and I just got started.
Currently my constructor looks like this:
static String[][] board;
static int pacmanBornHeight;
static int pacmanBornWidth;
public PacmanKata(int height, int width) {
board = new String[height][width];
pacmanBornHeight = (int) Math.floor(height / 2);
pacmanBornWidth = (int) Math.floor(width / 2);
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
board[i][j] = "*";
}
}
board[pacmanBornHeight][pacmanBornWidth] = "V";
}
This constructor set up the board and the pacman will be located at the middle, I used "V" as the symbol.
I try to create two methods currenlty, move up and down.
Here is the setup:
I first called the tickUp method:
public void tickUp(int steps) {
int counter = 1;
int timer = 0;
for (int loop = 0; loop < steps; loop++) {
board[pacmanBornHeight - counter][pacmanBornWidth] = "V";
for (int innerTimer = 0; innerTimer < counter; innerTimer++) {
board[pacmanBornHeight - innerTimer][pacmanBornWidth] = " ";
}
counter++;
timer++;
}
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
System.out.println("-------------------------");
} //end going UP
And I print out this to console(I initialized a 10 by 10 board):
Pacman moved up three steps, as expected, and eat three dots. I slightly modified and created a move down method:
public void tickDown(int steps) {
int counter = 1;
int timer = 0;
for (int loop = 0; loop < steps; loop++) {
board[pacmanBornHeight + counter][pacmanBornWidth] = "V";
for (int innerTimer = 0; innerTimer < counter; innerTimer++) {
board[pacmanBornHeight + innerTimer][pacmanBornWidth] = " ";
}
counter++;
timer++;
}
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
System.out.println("-------------------------");
}//end tickDown
Now I called tickDown and asked it to move down 3 steps, but I got this result:
The trouble I am having is, I do not know how to locate the Pacman last location. The move down method simply created a new Pacman and moved down 3 steps, that is not what I want. How can I fix this?
Change your tickUp and tickDown methods to save the new position of your Pacman:
public void tickDown(int steps) {
int counter = 1;
int timer = 0;
for (int loop = 0; loop < steps; loop++) {
for (int innerTimer = 0; innerTimer < counter; innerTimer++) {
board[pacmanBornHeight + innerTimer][pacmanBornWidth] = " ";
}
pacmanBornHeight += counter;
//Allow for wraparounds:
if (pacmanBornHeight > board.length) {
pacmanBornHeight = 0;
}
board[pacmanBornHeight][pacmanBornWidth] = "V";
timer++;
}
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
System.out.println("-------------------------");
}//end tickDown
I moved the loop to write spaces in the board to the beginning of the outer loop; that way you get the spaces based on the starting position of Pacman. Once you've written the spaces to the array, you update Pacman's position and write it in the array.
Edit:
Here's an example showing how you'd use a one-dimensional array as your board:
public class PacmanKata {
static String[] board;
static int pacmanPosition;
static int boardHeight;
static int boardWidth;
public static void main(String[] args) {
PacmanKata kata = new PacmanKata(10,10);
kata.tickUp(7);
kata.tickRight(9);
}
public PacmanKata(int height, int width) {
boardHeight = height;
boardWidth = width;
board = new String[height*width];
int offset = (width + 1) % 2;
pacmanPosition = (int) Math.floor((height + offset)*width/2);
for (int i = 0; i < board.length; i++) {
board[i] = "*";
}
board[pacmanPosition] = "V";
}
private void printBoard() {
for (int i = 0; i < board.length; i++) {
System.out.print(board[i]);
if ((i+1) % boardWidth == 0) {
System.out.println();
}
}
System.out.println("-------------------------");
}
public void tickUp(int steps) {
int counter = -1 * boardHeight;
for (int loop = 0; loop < steps; loop++) {
//Current position = ' '
board[pacmanPosition] = " ";
//Pacman's position changes:
pacmanPosition += counter;
//Allow for wraparounds:
if (pacmanPosition < 0) {
pacmanPosition += board.length;
}
//Update the board with Pacman's new position:
board[pacmanPosition] = "V";
}
printBoard();
}//end tickUp
public void tickRight(int steps) {
int counter = 1;
for (int loop = 0; loop < steps; loop++) {
//Current position = ' '
board[pacmanPosition] = " ";
//Pacman's position changes:
pacmanPosition += counter;
if (pacmanPosition % boardWidth == 0) {
pacmanPosition -= boardWidth;
}
//Update the board with Pacman's new position:
board[pacmanPosition] = "V";
}
printBoard();
}//end tickUp
}
Instead of having pacmanBornWidth and pacmanBornHeight fields, you should have a field with pacman current position (all fields shouldn't be static):
String[][] board;
java.awt.Point pacmenPos;
public PacmanKata(int height, int width) {
board = new String[height][width];
pacmanPos = new Point((int) width/2, (int) height/2);
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
board[i][j] = "*";
}
}
board[pacmanPos.x][pacmanPos.y] = "V";
}
Now replace all occurrences of pacmanBornWidth and pacmanBornHeight with pacmanPos.x and pacmanPos.y.
And in your tickUp and tickDown methods, just update pacman position:
public void tickUp(int steps) {
...
pacmanPos.translate(0, steps);
...
}
public void tickDown(int steps) {
...
pacmanPos.translate(0, -steps);
...
}
This will also work the same if you add tickLeft and tickRight methods:
public void tickLeft(int steps) {
...
pacmanPos.translate(-steps, 0);
...
}
public void tickRight(int steps) {
...
pacmanPos.translate(steps, 0);
...
}

Categories