// playerBall extends Animate class
//Even after entity becomes invisible,collision is detected
Collision occurs at the point where entity was before getting detached.
private void ballsR(){
registerUpdateHandler(new FPSLogger());
Random r = new Random();
int i= r.nextInt(7)+1;
if(count<1){
ballForColl[0] = ball;
count++;
System.out.println(count);
}
registerUpdateHandler(this.ballsDet = new TimerHandler(5.0f,true, new ITimerCallback() {
#Override
public void onTimePassed(TimerHandler pTimerHandler) {
// TODO Auto-generated method stub
/* ball.setVisible(false);
ball.setIgnoreUpdate(true);
ball.detachSelf();
ball.clearUpdateHandlers();
#override*/
resourcesManager.engine.runOnUpdateThread(new Runnable() {
#Override
public void run() {
/* Now it is save to remove the entity! */
//pScene.detachChild(SpriteRemoveExample.this.mFaceToRemove);
detachChild((ball));
ball.setIgnoreUpdate(true);
}
});
// detachChild(ball);
// unregisterUpdateHandler(ball) ;
}
}));
/************************************************************/
//my player ball class
public playerBall(final float pX, final float pY, final TiledTextureRegion pTextureRegion,VertexBufferObjectManager vbom) {
super(pX, pY, pTextureRegion,vbom);
this.mPhysicsHandler= new PhysicsHandler(this);
this.registerUpdateHandler(this.mPhysicsHandler);
this.mPhysicsHandler.setVelocity(DEMO_VELOCITY, DEMO_VELOCITY);
// System.out.println("this is srs1");
}
#Override
protected void onManagedUpdate(final float pSecondsElapsed) {
if(this.mX < 0) {
// System.out.println("this is srs");
this.mPhysicsHandler.setVelocityX(DEMO_VELOCITY);
} else if(this.mX + this.getWidth() > 800) {
this.mPhysicsHandler.setVelocityX(-DEMO_VELOCITY);
}
if(this.mY < 0) {
this.mPhysicsHandler.setVelocityY(DEMO_VELOCITY);
} else if(this.mY + this.getHeight() > 480) {
this.mPhysicsHandler.setVelocityY(-DEMO_VELOCITY);
}
super.onManagedUpdate(pSecondsElapsed);
}
}
What is "ball"? is it an Sprite, AnimatedSprite, Circle...
Does it contain a Body?
If the latter is true, you're probably forgetting to remove it from the physics world...
Try this:
final PhysicsConnector physicsConnector =
physicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(shape);
mEngine.runOnUpdateThread(new Runnable()
{
#Override
public void run()
{
if (physicsConnector != null)
{
physicsWorld.unregisterPhysicsConnector(physicsConnector);
body.setActive(false);
physicsWorld.destroyBody(bbody);
scene.detachChild(shape);
}
}
});
Related
Another question about inheritance in java: I was wondering about two things:
1) how can I set my program to switch between using an inherited class or not?
2) I'm not sure why my extended class glidingObject.java is not responding to my key presses
Here's my Game.java (which runs the game; I should be passing in some parameter that allows the user to choose which class to use right - either flying object or gliding object? I've also included my two classes for flying object and gliding object)
public class Game extends JPanel {
private static final long serialVersionUID = 1L;
public static int WIDTH = 800, HEIGHT = 750;
public static ArrayList<Rectangle> columns;
public static Random rand;
public static double score;
public static boolean gameOver, started; //two modes, started and gameover
public static String username;
public static String currTime;
public static Timer timer;
public static flyingObject obj;
private PropertyChangeSupport mPcs = new PropertyChangeSupport(this);
public Game(flyingObject object){
obj = object;
timer = new Timer(20, new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
tick();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
columns = new ArrayList<Rectangle>();
rand = new Random();
Background bk = new Background();
addColumn(true);
addColumn(true);
addColumn(true);
addColumn(true);
addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
started = true;
}
});
PropertyChangeListener listener = new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
try {
scoreBoard.record();
} catch (IOException e) {
e.printStackTrace();
}
}
};
this.addPropertyChangeListener(listener);
getDate(); //get the date of the game played
mPcs.firePropertyChange("gameOver",false, true); //alert record() method when the game is over
timer.start();
}
//adding the column
public static void addColumn(boolean start) {
int space = 300;
int width = 100;
int height = 50 + rand.nextInt(300);
if (start) {
//add top and bottom
columns.add(new Rectangle(WIDTH + width + columns.size() * 300, HEIGHT - height - 120, width, height + 100));
columns.add(new Rectangle(WIDTH + width + (columns.size() - 1) * 300, 0, width, HEIGHT - height - space));
}
else
{
columns.add(new Rectangle(columns.get(columns.size() - 1).x + 600, HEIGHT - height - 120, width, height + 100));
columns.add(new Rectangle(columns.get(columns.size() - 1).x, 0, width, HEIGHT - height - space));
}
}
//paint the columns
public void paintColumn(Graphics g, Rectangle column) {
g.setColor(Color.white);
g.fillRect(column.x, column.y, column.width, column.height);
}
public static void reset() {
obj = new glidingObject(WIDTH / 2 - 10, HEIGHT / 2 - 10);
columns.clear();
score = 0.0;
addColumn(true);
addColumn(true);
addColumn(true);
addColumn(true);
gameOver = false;
}
public void tick() throws IOException {
if (started) {
int speed = 10;
glidingObject.move();
for (int i = 0; i < columns.size(); i ++) {
Rectangle column = columns.get(i);
column.x -= speed;
if (column.x + column.width < 0) {
columns.remove(column);
if (column.y == 0) {
addColumn(false);
}
}
}
for (Rectangle column: columns) {
if (column.x == glidingObject.X) {
score += 0.5;
}
if (column.intersects(glidingObject.getBounds())) {
gameOver = true;
//when the object crashes, it does not go through the column
if (glidingObject.X <= column.x) {
glidingObject.X = column.x - glidingObject.DIAMETER;
}
else if (glidingObject.Y < column.height) {
glidingObject.Y = column.height;
}
Main.gameOver();
}
}
if (glidingObject.Y > HEIGHT || glidingObject.Y < 0) {
gameOver = true;
//timer.stop();
Main.gameOver();
}
if (glidingObject.Y + glidingObject.YMotion >= HEIGHT) {
gameOver = true;
//timer.stop();
Main.gameOver();
}
}
//update the display
repaint();
}
public void getDate() {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
currTime = dateFormat.format(date);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Background.paint(g);
glidingObject.paint(g);
for (Rectangle column: columns) {
paintColumn(g, column);
}
g.setColor(Color.white);
g.setFont(new Font("Manaspace", 1, 60));
if (!started) {
g.drawString("Click to start!", 75, HEIGHT / 2 - 50);
}
if (gameOver) {
g.drawString("Game Over!", 200, HEIGHT / 2 - 50);
}
if (!gameOver && started) {
g.drawString(String.valueOf(score), WIDTH / 2 - 25, 100);
}
}
}
class flyingobject.java
public class flyingObject implements ActionListener, MouseListener, KeyListener {
static int DIAMETER = 25;
static int Y; // Y position of the unicorn
static int X; // X position of the unicorn
static int YMotion; // Y movement of the unicorn
//parameters are the initial positions
public flyingObject(int xpos, int ypos) {
X = xpos;
Y = ypos; // this changes
}
//getters
public int getX() {
return X;
}
public int getY() {
return Y;
}
//setters
public void setX(int newX) {
X = newX;
}
public void setY(int newY) {
Y = newY;
}
//the bounds of the object (rectangle)
public static Rectangle getBounds() {
return new Rectangle(X, Y, DIAMETER, DIAMETER);
}
//the visible component of the object - this can get overriden by subclasses
public static void paint(Graphics g){
g.setColor(Color.white);
g.fillRect(X, Y, DIAMETER, DIAMETER);
}
//the movement component of the object
public static void jump() {
if (Game.gameOver) {
Game.reset();
Game.gameOver = false;
}
if (!Game.started) {
Game.started = true;
}
else if (!Game.gameOver) {
if (YMotion > 0) {
YMotion = 0;
}
YMotion -= 14;
}
}
public static void move() {
if ((Y > 0) && (Y < Game.HEIGHT)) {
YMotion += 1.5; // gravity
Y += YMotion;
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE)
{
jump();
}
}
#Override
public void mouseClicked(MouseEvent e) {
jump();
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
Class glidingobject.java (the game.java should allow the user to choose between just using flying object, or the extended class gliding object)
public class glidingObject extends flyingObject{
//velocity of the object
private static int vx;
private static int vy;
private static int lives;
public glidingObject(int xpos, int ypos) {
super(xpos, ypos);
vx = 0;
vy = 0;
lives = 3;
}
//getter methods
public int getVx() {
return vx;
}
public int getVy() {
return vy;
}
//setter methods
public void setVx(int newVx) {
vx = newVx;
}
public void setVy(int newVy) {
vy = newVy;
}
//moves the object
public static void jump() {
X += vx;
Y += vy;
}
public static void paint(Graphics g) {
g.setColor(Color.CYAN);
g.fillOval(X, Y, DIAMETER, DIAMETER);
}
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT){
vx = 10;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT){
vx = -10;
}
if (e.getKeyCode() == KeyEvent.VK_UP){
vy = 10;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN){
vy = -10;
}
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
I should be passing in some parameter that allows the user to choose which class to use right - either flying object or gliding object?
This is where interfaces become so powerful. Both the "flying" and "gliding" objects are going to share some common properties/functionality, these should be described by the interface. You Game should then only accept instances of this interface, it shouldn't care what the implementation, only that they adhere to the agreed interface.
This is principle of "code to interface, not implementation"
How complicated this gets is up to you, for example, you could have abstract implementations which describe "air" based entities and "ground" based entities, from which you could have "powered" and "unpowered" implementations of the abstract "air" class, all of which would be tied back to the "game entity" interface
I'm not sure why my extended class glidingObject.java is not responding to my key presses
This is because you're using KeyListener, this well known for it's focus related issues. See How to Use Key Bindings for the recommended solution
I seem to have a problem switching screens in libGDX. It switches to GameScreen, but it doesn't switch back to main screen nor to game over screen.
My game class:
#Override
public void create() {
menu();
}
public void play(){
this.setScreen(new GameSc(this));
play = true;
}
public void menu(){
this.setScreen(new GameMenu(this));
menu = true;
}
public void gameOver(){
this.setScreen(new GameOver(this));
}
My GameScreen class (which implements screen):
public GameSc(GameRunner runner) {
this.runner = runner;
background = new Texture(Gdx.files.internal("Textures/background.png"));
batch = new SpriteBatch();
box = new Box(this);
txt = new Texture(Gdx.files.internal("Textures/Enemies/Boxers/Enemy.png"));
snakes = new ArrayList<Snake>();
enemies = new ArrayList<Enemy>();
shape = new ShapeRenderer();
Gdx.gl.glClearColor(1f, 1f, 1f, 1f);
new Thread(new Runnable() {
#Override
public void run() {
while(true){
update();
}
}
}).start();
snakeThread();
enemyThread();
}
#Override
public void show() {
//initialize
}
#Override
public void resize(int width, int height) {
}
#Override
public void render(float dt) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//Drawing an image.
batch.begin();
batch.draw(background, 0,0 , Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.end();
box.render(batch);
for (int i = 0; i < snakes.size(); i++) {
snakes.get(i).render(shape);
}
for (int i = 0; i < enemies.size(); i++) {
enemies.get(i).render(batch);
}
}
public void update(){
box.update();
for (int i = 0; i < snakes.size(); i++) {
snakes.get(i).update();
}
for (int i = 0; i < snakes.size(); i++) {
if(!(snakes.get(i).isAlive)){
snakes.remove(i);
System.out.println(snakes.size());
}
}
}
private void snakeThread(){
new Thread(new Runnable() {
Random r = new Random();
//float[]anglem = {30,40,50,60,70,80,90,100};
#Override
public void run() {
while(true){
int x = r.nextInt(Gdx.graphics.getWidth()-50);
int y = r.nextInt(Gdx.graphics.getHeight()-50);
int delay = r.nextInt((6000-2000)+1)+2000;
int speed = MathUtils.random(50, 150);
float angle = (float) r.nextInt((110-30)+1)+30;
int length = MathUtils.random(15, 25);
try {
spawnSnake(x, y, angle, length, speed);
//System.out.println(delay);
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
box.update();
}
private void enemyThread(){
new Thread(new Runnable() {
#Override
public void run() {
while(true){
int x = MathUtils.random(Enemy.UNIFORM_WIDTH, Gdx.graphics.getWidth()-Enemy.UNIFORM_WIDTH);
int y = 0;
int speed = 15;
int delay = MathUtils.random(400, 600);
try {
spawnEnemy(x, y, speed, txt);
for (int i = 0; i < enemies.size(); i++) {
if(enemies.get(i).getY()<0){
enemies.remove(i);
}
}
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
box.update();
}
public void spawnSnake(int x, int y, float angle, int length, int speed){
Snake snake = new Snake(angle,new Vector2(x,y),speed,length);
snakes.add(snake);
}
public void spawnEnemy(int x, int y, int speed, Texture currentTexture){
Enemy enemy = new Enemy(x , y , speed, Enemy.UNIFORM_WIDTH, Enemy.UNIFORM_HEIGHT, txt);
enemies.add(enemy);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
if(runner.menu==false){
runner.getScreen().dispose();
shape.dispose();
batch.dispose();
}
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
This is how i change a screen (doesn't work):
if (bounds.contains(g.snakes.get(i).snake.get(y).x, g.snakes.get(i).snake.get(y).y) && isAlreadyTouched) {
isAlreadyTouched = false;
g.runner.play=false;
g.runner.gameOver();
}
You can find the whole source here.
Managed to solve this issue by moving g.runner.setScreen(new GameOver(this)) to another thread.
There are many ways to tackle a problem and I don't want to read through the source you posted but the line you posted does certainly not change the screen.
if (bounds.contains(g.snakes.get(i).snake.get(y).x, g.snakes.get(i).snake.get(y).y) && isAlreadyTouched) {
isAlreadyTouched = false;
g.runner.play=false;
g.runner.gameOver();
}
I'm not sure about the architecture of your source, there might be listener events that get triggered by g.runner.gameOver(); or g.runner.play = false` and then the following solution would create a mess for you eventually.
if (bounds.contains(g.snakes.get(i).snake.get(y).x, g.snakes.get(i).snake.get(y).y) && isAlreadyTouched) {
isAlreadyTouched = false;
g.runner.play=false;
g.runner.gameOver();
//Now set a screen
((Game)Gdx.app.getApplicationListener).setScreen(new GameOver(this);
}
I personally like to work with screens like I did above. Whenever I need to change a screen I cast the ApplicationListener to Game so I can set a new (or push a existing) screen.
But like I said, you might have deleted or not yet implemented code that should call the methods in your Game class to change the screen.
I'm trying to make a small app that bounces balls around the frame of the window. When I add more than 1 ball to the list; it doesn't loop through them as expected.
Here's my code:
The Main Class:
public class Main extends JFrame {
private static final long serialVersionUID = 1L;
private List<Ball> balls = new ArrayList<Ball>();
private List<Ball> tempballs = new ArrayList<Ball>();
private static Timer t;
public void addBall(Ball b) {
tempballs.add(b);
}
public void initUI() {
this.setSize(500, 500);
this.setDefaultCloseOperation(3);
this.setVisible(true);
}
private BufferStrategy bs;
private Random r = new Random();
public void paint() {
if (!tempballs.isEmpty()) {
balls.addAll(tempballs);
tempballs = new ArrayList<Ball>();
}
int i = 0;
System.out.println(balls.size());
for (Ball b : new ArrayList<Ball>(balls)) {
i++;
System.out.println(i);
if ((bs = this.getBufferStrategy()) == null) {
this.createBufferStrategy(2);
return;
}
if (bs.contentsLost() || bs.contentsRestored()) {
return;
}
if (b.y >= this.getHeight() - 100) {
b.ydirection = -r.nextDouble() * 5;
}
if (b.y < 20) {
b.ydirection = r.nextDouble() * 5;
}
if (b.x >= this.getWidth() - 100) {
b.xdirection = -r.nextDouble() * 5;
}
if (b.x < 0) {
b.xdirection = r.nextDouble() * 5;
}
b.x += b.xdirection;
b.y += b.ydirection;
if (b.xdirection > 0)
b.xdirection += 0.1;
else
b.xdirection += -0.1;
if (b.ydirection > 0)
b.ydirection += 0.1;
else
b.ydirection += -0.1;
Graphics g = bs.getDrawGraphics();
g.fillOval((int) b.x, (int) b.y, 100, 100);
bs.show();
g.dispose();
bs.dispose();
}
i = 0;
}
public static void main(String[] args) {
try {
final Main m = new Main();
m.addMouseListener(new Mouse(m));
m.initUI();
t = new Timer();
TimerTask tt = new TimerTask() {
#Override
public void run() {
m.paint();
}
};
t.schedule(tt, Calendar.getInstance().getTime(), 20);
} catch (ConcurrentModificationException e) {
e.printStackTrace();
}
}
}
Here's the Ball class:
public class Ball {
private Random r = new Random();
public double y, x, ydirection, xdirection;
public Ball(int x, int y) {
this.y = y;
this.x = x;
ydirection = r.nextGaussian() * 5;
xdirection = r.nextGaussian() * 5;
}
}
and the mouse listener:
public class Mouse implements MouseListener {
Main m;
public Mouse(Main m) {
this.m = m;
}
#Override
public void mouseClicked(MouseEvent e) {
m.addBall(new Ball(e.getX(), e.getY()));
System.out.println("cl");
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
Additional details:
It only loops through the first item in the list, but the list size grows.
I'm using java 6, but I will change versions if needed.
If your loop does not behave as intended, try to find out why it is cancelled. You have two return statements in your loop which could cause this behavior. Make sysouts before those returns to figure out which one is the cause. Then find out why your if around the return is true. To digg deeper you can use your IDE's debugging mode and place breakpoints at interesting lines or use the step mode to run one line of code at a time.
Besides this you can place both if before the loop, the values they are checking should not change while you are in the paint() function (you are using the UI thread which might change them).
You have below return statements inside the loop. If the execution reaches any of the return statements, the loop ends.
Figure out, if you are entering these conditions and returning for the first value in the list.
if ((bs = this.getBufferStrategy()) == null) {
this.createBufferStrategy(2);
return;
}
if (bs.contentsLost() || bs.contentsRestored()) {
return;
}
I'm trying to make a 2D game that should draw a character to the screen. But when I run it, I just get a black screen.
The important bits:
public class StartingClass extends Applet implements Runnable, KeyListener {
private static final long serialVersionUID = 1L;
private Walrus walrus;
private Image image, character;
private Graphics second;
private URL base;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Applet");
try {
base = getDocumentBase();
} catch (Exception e) {
// TODO: handle exception
}
// Image Setups
character = getImage(base, "src/data/walrus_right.png");
}
#Override
public void start() {
walrus = new Walrus();
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
while (true) {
walrus.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(character, walrus.getCenterX() - 61, walrus.getCenterY() - 63, this);
}
}
Also, here's my other class:
public class Walrus {
private int centerX = 100;
private int centerY = 382;
private boolean jumped = false;
private int speedX = 0;
private int speedY = 1;
public void update() {
// Moves Character or Scrolls Background accordingly.
if (speedX < 0) {
centerX += speedX;
} else if (speedX == 0) {
System.out.println("Do not scroll the background.");
} else {
if (centerX <= 150) {
centerX += speedX;
} else {
System.out.println("Scroll Background Here");
}
}
// Updates Y Position
if (centerY + speedY >= 382) {
centerY = 382;
}else{
centerY += speedY;
}
// Handles Jumping
if (jumped == true) {
speedY += 1;
if (centerY + speedY >= 382) {
centerY = 382;
speedY = 0;
jumped = false;
}
}
// Prevents going beyond X coordinate of 0
if (centerX + speedX <= 60) {
centerX = 61;
}
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void stop() {
speedX = 0;
}
public void jump() {
if (jumped == false) {
speedY = -15;
jumped = true;
}
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public boolean isJumped() {
return jumped;
}
public int getSpeedX() {
return speedX;
}
public int getSpeedY() {
return speedY;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setJumped(boolean jumped) {
this.jumped = jumped;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
}
I haven't gotten any errors at this point, but it's not working right.
The problem is that your image is not loaded. The line
getImage(base, "src/data/walrus_right.png");
tries to read the image for a deployed applet and will fail quietly (not throw errors), which is what caused the confusion. Try to replace it with
ImageIO.read(new File(getClass().getResource("relative/path.png").getPath()));
where you should replace the path as specified under getResource API.
Edit:
Break the call into several calls:
Class<? extends StartingClass> clas = getClass();
URL url = clas.getResource("relative/path.png");
String path = url.getPath();
File file = new File(path);
try {
Image image = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
and move with the debugger step by step to see which line throws the error. My guess is that the file is not located in the right place, which causes getResource to return null, which causes new File(path) to throw NullPointerException.
I'm completely new to Android game development and trying to develop a game using AndEngine.
The first steps went fine I think, but now I'm a little bit stuck.
The final game should be something like Air Control (https://play.google.com/store/apps/details?id=dk.logisoft.aircontrol) (Except I'm not using aircrafts but my nephews in space ;))
What the createPlayer() method should do: It should create a player at a random offscreen position, get a random offscreen target position and draw a path between the two points. Now the player should fly using a PathModifier. Before the player is visible on the screen there should be a little arrow as indicator that shows where the next player is coming from. When the player appears on the screen this little indicator should disappear.
I'm spawning the players currently using a simple timer. And everything works as I want when I set the interval of the timer to like 10 secs.
When I set the timer to something smaller, like 1 sec the problem is, that the indicator does not get removed. It just stays at its last position.
I think it is because there is already a new player spawned and that player or the playerIndicator are pointing to the newly created ones. And I dont know how to change that.
Where is my mistake?
Here is my createPlayer method and the player class:
createPlayer() Method
private void createPlayer() {
float[] startPos = getPlayerRandomStartPosition();
float[] targetPos = getPlayerRandomTargetPosition(startPos);
int playerNr = 0 + (int)(Math.random() * ((2 - 0) + 1));
int[] playerSpeed = { 25, 35, 45 };
float[] playerScale = { 0.3f, 0.25f, 0.2f };
String[] playerName = { "marvin", "noah", "liam" };
ITiledTextureRegion[] tex = { resourcesManager.p1_region, resourcesManager.p2_region, resourcesManager.p3_region };
float pointsListX[] = { startPos[0], targetPos[0] };
float pointsListY[] = { startPos[1], targetPos[1] };
Path path = new Path(pointsListX.length);
for (int j = 0; j < pointsListX.length; j++) {
path.to(pointsListX[j], pointsListY[j]);
}
player = new Player(startPos[0], startPos[1], tex[playerNr], vbom) {};
player.registerUpdateHandler(new IUpdateHandler() {
#Override
public void reset() {}
#Override
public void onUpdate(float pSecondsElapsed) {
if (player.getPlayerIndicator() != null) {
if (player.getStartPos()[1] <= 0) {
player.getPlayerIndicator().setPosition(player.getX(), 0 + (resourcesManager.indicator_region.getHeight() / 2));
} else if (player.getStartPos()[1] >= 800) {
player.getPlayerIndicator().setPosition(player.getX(), 800 - (resourcesManager.indicator_region.getHeight() / 2));
} else if (player.getStartPos()[0] <= 0) {
player.getPlayerIndicator().setPosition(0 + (resourcesManager.indicator_region.getHeight() / 2), player.getY());
} else {
player.getPlayerIndicator().setPosition(480 - (resourcesManager.indicator_region.getHeight() / 2), player.getY());
}
}
if (camera.isEntityVisible(player)) {
if (player.getPlayerIndicator() != null) {
engine.runOnUpdateThread(new Runnable() {
#Override
public void run() {
final EngineLock engineLock = engine.getEngineLock();
engineLock.lock();
player.getPlayerIndicator().detachSelf();
player.getPlayerIndicator().dispose();
player.setPlayerIndicator(null);
engineLock.unlock();
}
});
}
}
}
});
player.registerEntityModifier(new PathModifier(playerSpeed[playerNr], path) {
#Override
protected void onModifierFinished(final IEntity pItem) {
engine.runOnUpdateThread(new Runnable() {
#Override
public void run() {
final EngineLock engineLock = engine.getEngineLock();
engineLock.lock();
pItem.detachSelf();
pItem.dispose();
engineLock.unlock();
addToScore();
}
});
super.onModifierFinished(pItem);
}
});
player.setHasBeenOnScreen(false);
player.setTargetPos(targetPos);
player.setStartPos(startPos);
player.setScale(playerScale[playerNr]);
player.setSpeed(playerSpeed[playerNr]);
player.setUserData(playerName[playerNr]);
player.setRotation(getTargetAngle(targetPos[0], targetPos[1], player.getX(), player.getY()));
PlayerIndicator playerIndicator;
if (startPos[1] <= 0) {
playerIndicator = new PlayerIndicator(startPos[0], 0 + (resourcesManager.indicator_region.getHeight() / 2), resourcesManager.indicator_region, vbom);
playerIndicator.setRotation(180);
} else if (startPos[1] >= 800) {
playerIndicator = new PlayerIndicator(startPos[0], 800 - (resourcesManager.indicator_region.getHeight() / 2), resourcesManager.indicator_region, vbom);
} else if (startPos[0] <= 0) {
playerIndicator = new PlayerIndicator(0 + (resourcesManager.indicator_region.getHeight() / 2), startPos[1], resourcesManager.indicator_region, vbom);
playerIndicator.setRotation(270);
} else {
playerIndicator = new PlayerIndicator(480 - (resourcesManager.indicator_region.getHeight() / 2), startPos[1], resourcesManager.indicator_region, vbom);
playerIndicator.setRotation(90);
}
playerIndicator.setAlpha(0.5f);
player.setPlayerIndicator(playerIndicator);
attachChild(playerIndicator);
attachChild(player);
}
Player class
public class Player extends AnimatedSprite {
public Player(float pX, float pY, ITiledTextureRegion pTiledTextureRegion, VertexBufferObjectManager pVertexBufferObjectManager) {
super(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager);
long[] frameDurration = {300, 300, 300};
animate(frameDurration);
hasBeenOnScreen = false;
}
float[] startPos = { -100, -100 };
float[] targetPos;
int speed = 10;
PlayerIndicator playerIndicator;
boolean hasBeenOnScreen = false;
public PlayerIndicator getPlayerIndicator() {
return playerIndicator;
}
public void setPlayerIndicator(PlayerIndicator playerIndicator) {
this.playerIndicator = playerIndicator;
}
public boolean hasBeenOnScreen() {
return hasBeenOnScreen;
}
public void setHasBeenOnScreen(boolean hasBeenOnScreen) {
this.hasBeenOnScreen = hasBeenOnScreen;
}
public float[] getStartPos() {
return startPos;
}
public void setStartPos(float[] startPos) {
this.startPos = startPos;
}
public float[] getTargetPos() {
return targetPos;
}
public void setTargetPos(float[] targetPos) {
this.targetPos = targetPos;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
}