Processing 3.2.1, Game Control Plus library, java Exception

Asked

Viewed 77 times

1

Good!

I am studying Games & Apps Development and in our first semester we are doing a game in Processing. In my game I’m using a PS4 controller with the help of the library Game Control Plus. If I press a button enough times, my game crashes and gives me this on the console: (the 'Uarma' plug is the function that executes the code when you press the button)

java.lang.reflect.InvocationTargetException
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gamecontrolplus.Plug.call(Unknown Source)
    at org.gamecontrolplus.ControlButton.callPlugs(Unknown Source)
    at org.gamecontrolplus.ControlButton.update(Unknown Source)
    at org.gamecontrolplus.ControlDevice.update(Unknown Source)
    at org.gamecontrolplus.ControlIO.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.AssertionError
    at org.jbox2d.dynamics.World.createBody(World.java:339)
    at shiffman.box2d.Box2DProcessing.createBody(Box2DProcessing.java:203)
    at Meon$Bullet.<init>(Meon.java:202)
    at Meon.Uarma(Meon.java:294)
    ... 9 more
java.lang.RuntimeException: Error on calling plug: Uarma
    at org.gamecontrolplus.Plug.call(Unknown Source)
    at org.gamecontrolplus.ControlButton.callPlugs(Unknown Source)
    at org.gamecontrolplus.ControlButton.update(Unknown Source)
    at org.gamecontrolplus.ControlDevice.update(Unknown Source)
    at org.gamecontrolplus.ControlIO.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

My knowledge of Java is not much, so any help about what might be causing this error is appreciated!

From now on, thank you!

Here’s all the code involved in the process:

//Variaveis
ControlIO controlo;
ControlDevice comando;

//inicia o ControlIO (vai ver que comandos estao ligados)
controlo = ControlIO.getInstance(this);

//procura comandos compativeis
comando = controlo.getMatchedDevice("playerControl");

//associa funçoes a botoes (Botão para Função)
BpFp1(); //p1 = player 1

void BpFp1() {

  comando.getButton("jump").plug(this, "salto", ControlIO.ON_PRESS);
  comando.getButton("punch").plug(this, "murro", ControlIO.ON_PRESS);
  comando.getButton("grabWep").plug(this, "Aarma", ControlIO.ON_PRESS);
  comando.getButton("useWep").plug(this, "Uarma", ControlIO.ON_PRESS);
}

void Uarma() {

  println("usar armas? check");  
  bullets.add(new Bullet(player1.playerPos.x + 20, player1.playerPos.y, 5, 5));
}

Constructor Bullet:

class Bullet {

  Vec2 bulletPos;
  Body bulletbody;
  float dbulletLarg;
  float dbulletAlt;

  Bullet(float bulletX, float bulletY, float bulletLarg, float bulletAlt) {

    //definir o corpo
    BodyDef bulletbd = new BodyDef();
    bulletbd.type = BodyType.DYNAMIC;
    bulletbd.bullet = true;
    bulletbd.position.set(box2d.coordPixelsToWorld(bulletX, bulletY));

    //criar o corpo
    bulletbody = box2d.createBody(bulletbd);

    //forma
    PolygonShape bulletps = new PolygonShape();
    bulletps.setAsBox(box2d.scalarPixelsToWorld(bulletLarg/2), box2d.scalarPixelsToWorld(bulletAlt/2));


    //o que cola a forma ao corpo
    FixtureDef bulletfd = new FixtureDef();
    bulletfd.shape = bulletps;

    //parametros que afetam a fisica do objeto
    bulletfd.density = 0;

    //colar a forma ao corpo
    bulletbody.createFixture(bulletfd);

    dbulletLarg = bulletLarg;
    dbulletAlt = bulletAlt;

    bulletbody.applyLinearImpulse(new Vec2(100, 0), bulletbody.getWorldCenter(), true);
  }

  void display() {

    bulletPos = box2d.getBodyPixelCoord(bulletbody);

    pushMatrix();
    translate(bulletPos.x, bulletPos.y);
    rectMode(CENTER);
    rect(0, 0, dbulletLarg, dbulletAlt);
    popMatrix();
  }
}

Here comes the whole Meon class:

//Sprites: biblioteca de sprites (arte do jogo)
import sprites.*;
import sprites.maths.*;
import sprites.utils.*;

//Box2D for Processing: biblioteca de physX (mais outra)
import shiffman.box2d.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.contacts.*;

//Game Control Plus: biblioteca controlo (ps4 neste caso)
import net.java.games.input.*;
import org.gamecontrolplus.*;
import org.gamecontrolplus.gui.*;

//Variaveis
ControlIO controlo;
ControlDevice comando;
ControlDevice comando2;

Box2DProcessing box2d;

float fx1;
float fx2;

Player player1;
Player player2;

Platform floor;
Platform sideRight;
Platform sideLeft;
Platform ceiling;

//s: small, m: medium,  b: big | b: bottom, m: middle, t: top
Platform stleft;
Platform smleft;
Platform sbleft;

Platform stright;
Platform smright;
Platform sbright;

Platform mbleft;
Platform mtleft;

Platform mbright;
Platform mtright;

Platform bbcenter;
Platform btcenter;

ArrayList<Bullet> bullets;

//WeaponPUP weaponpup;

void setup() {

  size(1280, 720);
  frameRate(60);

  //inicia o ControlIO (vai ver que comandos estao ligados)
  controlo = ControlIO.getInstance(this);

  //procura comandos compativeis
  comando = controlo.getMatchedDevice("playerControl");
  //comando2 = controlo.getMatchedDevice("player2Control");

  //associa funçoes a botoes (Botão para Função)
  BpFp1(); //p1 = player 1
  //BpFp2();

  box2d = new Box2DProcessing(this);
  box2d.createWorld();
  box2d.setGravity(0, -90);
  box2d.listenForCollisions();

  player1 = new Player(280, 80, 39, 55);
  player2 = new Player(1000, 80, 39, 55);

  floor = new Platform(640, 720, 1300, 80);
  sideLeft = new Platform(0, 360, 1, 3280);
  sideRight = new Platform(1280, 360, 1, 3280);
  ceiling = new Platform(640, 0, 3280, 1);

  stleft = new Platform(60, 90, 240, 10);
  smleft = new Platform(60, 340, 120, 10);
  sbleft = new Platform(60, 590, 120, 10);

  stright = new Platform(1220, 90, 240, 10);
  smright = new Platform(1220, 340, 120, 10);
  sbright = new Platform(1220, 590, 120, 10);

  mbleft = new Platform(390, 520, 330, 10);
  mtleft = new Platform(390, 270, 330, 10);

  mbright = new Platform(890, 520, 330, 10);
  mtright = new Platform(890, 270, 330, 10);

  bbcenter = new Platform(640, 150, 500, 10);
  btcenter = new Platform(640, 400, 500, 10);


  bullets = new ArrayList<Bullet>();

  //weaponpup = new WeaponPUP(450, 570, 20, 20);
}

void draw() {

  background(0);
  box2d.step();

  fx1 = comando.getSlider("movX").getValue();
  //fx2 = comando2.getSlider("movX").getValue();

  floor.display();
  stleft.display();
  smleft.display();
  sbleft.display();
  stright.display();
  smright.display();
  sbright.display();
  mbleft.display();
  mtleft.display();
  mbright.display();
  mtright.display();
  bbcenter.display();
  btcenter.display();


  player1.display();
  p1Move();

  player2.display();
  p2Move();

  texts();

  //weaponpup.display();

  for (int i = 0; i<bullets.size(); i++) {
    bullets.get(i).display();
  }
}

void texts() {

  fill(255);
  textSize(16);
  textAlign(LEFT);
  text("HP: "+round(player1.hpoints), 10, 20);
  textAlign(LEFT);
  text("HP: "+round(player2.hpoints), 1220, 20);
}
  • It’s hard to know what’s wrong with just this information. This is a generic error that came from somewhere in Uarma and this error does not give more details about what went wrong, the only thing he reports is that it was something in Uarma. You could post some snippet of source code that helps others replicate the problem?

  • @Victorstafusa already put in the original post the source code. Thank you

  • The mistake only happens when you press the useWep?

  • What is inside the builder of Bullet?

  • @Victorstafusa put in the original post

  • @Victorstafusa yes, the error only happens with the useWep. must have something to do with the Bullet constructor not?

  • I found a clue: https://github.com/jbox2d/jbox2d/blob/master/jbox2d-library/src/main/java/jbox2d/dynamics/World.java#L339 - This error is caused because your world is in a blocked state. However I do not know under what circumstances he enters or leaves this state. Furthermore, the ideal would be for the Box2d to launch a IllegalStateException instead of validating the state with a assert, or at least gave some information on assert. However, we already know the origin of the problem, although this is not enough to understand it.

  • Well, you’re doing something wrong with the variable box2d. You can post the class Meon entire?

  • @Victorstafusa already is. I really appreciate this help!

  • That doesn’t seem to be your whole class, since there isn’t public class Meon after the Imports and the method BpFp1. However, the fact that you are altering your world within the draw with the box2d.step(); Seems extremely suspicious to me. In order for the world to be rendered on the screen, it must be "frozen", and can only be changed outside the context in which it is drawn. You may be violating this concept by adding objects to the world while it is being designed.

Show 5 more comments

1 answer

0

This is a thread problem. The ControlIO uses its own thread to receive input, as evidenced by:

at org.gamecontrolplus.ControlIO.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

However, Box2d (underneath Processing) manipulates your virtual world into its own thread as well. You shouldn’t manipulate virtual worlds outside the thread used by Box2d. Doing this is risky and may cause data corruption issues due to cluttered interference between threads.

To protect against this type of problem, Box2d blocks your virtual worlds to avoid unexpected manipulation. However, it uses asserts instead of IllegalArgumentExceptions or ConcurrentModificationExceptions that most other frameworks in Java use to check this sort of thing. So you have a AssertionError being released from this point in the Box2d code.

Unfortunately, that’s exactly what you’re doing. By creating a Bullet, you do it from the thread of ControlIO thread. The constructor of Bullet tries to add to Bullet to the virtual world. Box2d does not like this and makes the mistake in assert.

The solution would be not to create the Bullet from within the method Uarma. Instead, put an object in some list (with proper synchronization) that says a Bullet should be created in a certain position. Back to your class Meon that manipulates the virtual world in the Box2d thread, you consume the list and add the Bullets corresponding in the virtual world when calling the constructor.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.