Sketch running slow

edited April 2017 in Android Mode

So I made this little game with pictures (they are hosted online so anyone can run this script) on my computer it runs fine but when I move to a device with lower specs it starts to drop to like 5fps how would I solve this? also when running this code it could look clitchy since I didn't keep aspect ratios in mind when making it.

EDIT: I made the stupid mistake of not mentioning that when I when I said "a lower spec system" I meant an andriod phone

ArrayList <Bullet> bullets;
int background_y;

PImage background;
PImage player;
PImage enemy;
PImage bullet;

int bullet_traveling;
int bullet_timer1;
int bullet_timer2;
int bullet_shot;
int bullet_side;
int bullet_x;
int bullet_y;

int enemy_health;
int enemy_x;
int enemy_y;

int player_x;
int player_y;

void setup() {
  fullScreen();
  frameRate(60);
  bullets = new ArrayList();

  background = loadImage("https://" + "s21.postimg.org/oubg978af/background.png");
  player = loadImage("https://" + "s13.postimg.org/hy84r98mv/player.png");
  bullet = loadImage("https://" + "s23.postimg.org/45ev766kr/bullet.png");
  enemy = loadImage("https://" + "s27.postimg.org/6njql63gz/enemy.png");

  bullet.resize(bullet.width/3, bullet.height/3);
  background.resize(width, height);

  player_y = height/4*3;
  player_x = width/2;
}

void draw() {
  background();
  for (Bullet temp : bullets) temp.update();
  bullet_enemy();
  player();
  enemy();

  if (mousePressed) {
    if (bullet_timer1 == 0) {
      bullet_timer1 = 1;
      bullet_timer2 = millis();
    }
    if (millis() - bullet_timer2 >= 200) {
      bullet_timer1 = 0;
      if (bullet_side == 1) {
        Bullet temp = new Bullet(player_x+55, player_y);
        bullets.add(temp);
        bullet_side = 0;
      } else {
        Bullet temp = new Bullet(player_x-55, player_y); 
        bullets.add(temp);
        bullet_side = 1;
      }
    }
  }
}

void background() {
  image(background, 0, background_y);
  image(background, 0, background_y-height);
  background_y += 1;
  if (background_y >= height) background_y = 0;
}

void enemy() {
  if (enemy_health == 0) {
    enemy_health = 1;
    enemy_y = -enemy.width/2;
    enemy_x = int(random(enemy.width/2, width-enemy.width/2));
  }
  if (enemy_y-enemy.width/2 >= height) {
    enemy_health = 0;
  }
  enemy_y += 3;

  image(enemy, enemy_x-enemy.width/2, enemy_y-enemy.height/2);
}

void player() {
  if (mousePressed && player_x < mouseX) player_x = player_x + 12;
  if (mousePressed && player_x > mouseX) player_x = player_x - 12;
  image(player, -player.width/2+player_x, -player.height/2+player_y);
}

void bullet_enemy() {
  if (player_x <= enemy_x+100 && player_x >= enemy_x-100 || bullet_traveling == 1) {
    bullet_traveling = 1;
    if (bullet_shot == 0) {
      bullet_x = enemy_x;
      bullet_y = enemy_y;
      bullet_shot = 1;
    }
    rect(bullet_x, bullet_y, 10, 10);
    bullet_y = bullet_y + 30 ;
  }

  if (bullet_x <= player_x+player.width/2 && bullet_x >= player_x-player.width/2 && bullet_y >= player_y) {
    bullet_traveling = 0;
    bullet_shot = 0;
  }
}

class Bullet {
  float x;
  float y;
  float speed;

  Bullet(float tx, float ty) {
    x = tx;
    y = ty;
  }

  void update() {
    image(bullet, -bullet.width/2+x, -bullet.height/2+y);
    y -= 25;
    if (x <= enemy_x+enemy.width/2 && x >= enemy_x-enemy.width/2 && y <= enemy_y) {
      x = -10000;
      enemy_health = 0;
    }
  }
}

Answers

  • edited April 2017

    I don't know, it runs fine for me, around 25-30 fps. Just how low specs is your phone?

  • @Lord_of_the_Galaxy I've got a samsung a5 with 2gb ram and Quad-core 1.2 GHz Cortex-A53 cpu which is pretty average I think? You dont see any mayor buggs in my code which could cause this?

  • To be true, not really.
    I used that "Run on device" option.

  • edited April 2017

    @Lord_of_the_Galaxy I got some new information, I ran it on a more powerful phone but it still ran at about 19fps but when I started shooting it dropped quite quicly to 6fps at which point it started to level. I also changed the code quite a bit you can now see the fps now it doens't look weird on phone nor computer

    Here is the new code

    ArrayList <Bullet> bullets;
    float background_y1;
    float background_y2;
    String aspect;
    PImage background_1;
    PImage background_2;
    PImage player;
    PImage enemy;
    PImage bullet;
    
    int bullet_traveling;
    int bullet_timer1;
    int bullet_timer2;
    int bullet_shot;
    int bullet_side;
    int bullet_x;
    int bullet_y;
    
    int enemy_health;
    int enemy_x;
    int enemy_y;
    
    int player_x;
    int player_y;
    
    void setup() {
      fullScreen();
      frameRate(60);
      smooth(0);
    
      bullets = new ArrayList();
      aspect();
    
      player = loadImage("https://" + "s14.postimg.org/4jsrzwvgx/player.png");
      bullet = loadImage("https://" + "s23.postimg.org/45ev766kr/bullet.png");
      enemy = loadImage("https://" + "s9.postimg.org/ctwwhwpgf/enemy.png");
    
      bullet.resize(bullet.width/3, bullet.height/3);
      background_1.resize(width, height);
      background_2.resize(width, height);
    
      player_y = height/4*3;
      player_x = width/2;
    }
    
    void aspect() {
      if (float(width)/height > 1.7 && float(width)/height < 1.8) {
        background_1 = loadImage("https://" + "s10.postimg.org/jv191w8ft/background_1_9_16.png");
        background_2 = loadImage("https://" + "s27.postimg.org/l4xs5of0z/background_2_9_16.png");
      } 
      if (float(width)/height > 0.5 && float(width)/height < 0.6) {
        background_1 = loadImage("https://" + "s12.postimg.org/gl3y5q55p/background_1_16_9.png");
        background_2 = loadImage("https://" + "s7.postimg.org/yuy798o3v/background_2_16_9.png");
      }
    }
    
    void draw() {
      background();
      for (Bullet temp : bullets) temp.update();
      bullet_enemy();
      player();
      enemy();
    
      if (mousePressed) {
        if (bullet_timer1 == 0) {
          bullet_timer1 = 1;
          bullet_timer2 = millis();
        }
        if (millis() - bullet_timer2 >= 200) {
          bullet_timer1 = 0;
          if (bullet_side == 1) {
            Bullet temp = new Bullet(player_x+55, player_y);
            bullets.add(temp);
            bullet_side = 0;
          } else {
            Bullet temp = new Bullet(player_x-55, player_y); 
            bullets.add(temp);
            bullet_side = 1;
          }
        }
      }
      fill(255);
      text(frameRate, 100, 100);
    }
    
    void background() {
      image(background_1, 0, background_y1);
      image(background_1, 0, background_y1-height);
      background_y1 += 1.2;
      if (background_y1 >= height) background_y1 = 0;
    
      image(background_2, 0, background_y2);
      image(background_2, 0, background_y2-height);
      background_y2 += 1.6;
      if (background_y2 >= height) background_y2 = 0;
    }
    
    
    void enemy() {
      if (enemy_health == 0) {
        enemy_health = 1;
        enemy_y = -enemy.width/2;
        enemy_x = int(random(enemy.width/2, width-enemy.width/2));
      }
      if (enemy_y-enemy.width/2 >= height) {
        enemy_health = 0;
      }
      enemy_y += 3;
    
      image(enemy, enemy_x-enemy.width/2, enemy_y-enemy.height/2);
    }
    
    void player() {
      if (mousePressed && player_x < mouseX) player_x = player_x + 12;
      if (mousePressed && player_x > mouseX) player_x = player_x - 12;
      image(player, -player.width/2+player_x, -player.height/2+player_y);
    }
    
    void bullet_enemy() {
      if (player_x <= enemy_x+100 && player_x >= enemy_x-100 || bullet_traveling == 1) {
        bullet_traveling = 1;
        if (bullet_shot == 0) {
          bullet_x = enemy_x;
          bullet_y = enemy_y;
          bullet_shot = 1;
        }
        rect(bullet_x, bullet_y, 10, 10);
        bullet_y = bullet_y + 30 ;
      }
    
      if (bullet_x <= player_x+player.width/2 && bullet_x >= player_x-player.width/2 && bullet_y >= player_y) {
        bullet_traveling = 0;
        bullet_shot = 0;
      }
    }
    
    class Bullet {
      float x;
      float y;
      float speed;
    
      Bullet(float tx, float ty) {
        x = tx;
        y = ty;
      }
    
      void update() {
        image(bullet, -bullet.width/2+x, -bullet.height/2+y);
        y -= 25;
        if (x <= enemy_x+enemy.width/2 && x >= enemy_x-enemy.width/2 && y <= enemy_y) {
          x = -10000;
          enemy_health = 0;
        }
      }
    }
    
  • I'll test this new code as soon as I can - I don't really use Android so much, so I must wait for some fateful friend to come by.

  • Can you test it using the p2D renderer and see if you get a boost in performance,

    I also notice that you add bullets to your ArrayList but you never remove them. And since you are drawing every bullet in your array, you are wasting resources.... Notice that when removing objects from an array, you need to proceed backwards if you iterate through your array. Review the entry for ArrayList in the reference.

    Kf

  • edited April 2017

    Hmm, good point. Perhaps the sketch slows down with time? My given speed of 25-30 fps is right after starting the sketch.

    I arrived at the value by just showing it as text, like in your new code.

  • @kfrajer I just tried using p2D but it gives this error

    java.lang.ArrayIndexOutOfBoundsException:
    length=2052000; index=2052000
    

    and the console shows

    OpenGL error 1280 at bot beginDraw(): invalid enum
    (HTTPLog)-Static: isSBSettingEnabled false
    (HTTPLog)-Static: isSBSettingEnabled false
    (HTTPLog)-Static: isSBSettingEnabled false
    (HTTPLog)-Static: isSBSettingEnabled false
    (HTTPLog)-Static: isSBSettingEnabled false
    (HTTPLog)-Static: isSBSettingEnabled false
    (HTTPLog)-Static: isSBSettingEnabled false
    (HTTPLog)-Static: isSBSettingEnabled false
    (HTTPLog)-Static: isSBSettingEnabled false
    (HTTPLog)-Static: isSBSettingEnabled false
    OpenGL error 1280 at top endDraw(): invalid enum
    java.lang.ArrayIndexOutOfBoundsException: length=2052000; index=2052000
     at processing.opengl.Texture.convertToRGBA(Unknown Source)
     at processing.opengl.Texture.set(Unknown Source)
     at processing.opengl.Texture.set(Unknown Source)
     at processing.opengl.PGraphicsOpenGL.initCache(Unknown Source)
     at processing.opengl.PGraphicsOpenGL.getTexture(Unknown Source)
     at processing.opengl.PGraphicsOpenGL$TexCache.getTexture(Unknown Source)
     at processing.opengl.PGraphicsOpenGL.flushPolys(Unknown Source)
     at processing.opengl.PGraphicsOpenGL.flush(Unknown Source)
     at processing.opengl.PGraphicsOpenGL.endDraw(Unknown Source)
     at processing.core.PApplet.handleDraw(Unknown Source)
     at processing.opengl.PGLES$AndroidRenderer.onDrawFrame(Unknown Source)
     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1649)
     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1354)
    

    I was aware of the problem with my bullets but I tought "I will solve it once it becomes a problem" (I do realise this is a bad way to think) but I suppose it just became a problem so I will look into how to remove an object from an array list since I dont know how I would do that

  • Simple -

    ArrayList <Bullet> bullets;
    float background_y1;
    float background_y2;
    String aspect;
    PImage background_1;
    PImage background_2;
    PImage player;
    PImage enemy;
    PImage bullet;
    
    int bullet_traveling;
    int bullet_timer1;
    int bullet_timer2;
    int bullet_shot;
    int bullet_side;
    int bullet_x;
    int bullet_y;
    
    int enemy_health;
    int enemy_x;
    int enemy_y;
    
    int player_x;
    int player_y;
    
    void setup() {
      fullScreen();
      frameRate(60);
      smooth(0);
    
      bullets = new ArrayList();
      aspect();
    
      player = loadImage("https://" + "s14.postimg.org/4jsrzwvgx/player.png");
      bullet = loadImage("https://" + "s23.postimg.org/45ev766kr/bullet.png");
      enemy = loadImage("https://" + "s9.postimg.org/ctwwhwpgf/enemy.png");
    
      bullet.resize(bullet.width/3, bullet.height/3);
      background_1.resize(width, height);
      background_2.resize(width, height);
    
      player_y = height/4*3;
      player_x = width/2;
    }
    
    void aspect() {
      if (float(width)/height > 1.7 && float(width)/height < 1.8) {
        background_1 = loadImage("https://" + "s10.postimg.org/jv191w8ft/background_1_9_16.png");
        background_2 = loadImage("https://" + "s27.postimg.org/l4xs5of0z/background_2_9_16.png");
      } 
      if (float(width)/height > 0.5 && float(width)/height < 0.6) {
        background_1 = loadImage("https://" + "s12.postimg.org/gl3y5q55p/background_1_16_9.png");
        background_2 = loadImage("https://" + "s7.postimg.org/yuy798o3v/background_2_16_9.png");
      }
    }
    
    void draw() {
      background();
      for (int i = bullets.size()-1; i >= 0; i--) if(bullets.get(i).update())bullets.remove(i);
      bullet_enemy();
      player();
      enemy();
    
      if (mousePressed) {
        if (bullet_timer1 == 0) {
          bullet_timer1 = 1;
          bullet_timer2 = millis();
        }
        if (millis() - bullet_timer2 >= 200) {
          bullet_timer1 = 0;
          if (bullet_side == 1) {
            Bullet temp = new Bullet(player_x+55, player_y);
            bullets.add(temp);
            bullet_side = 0;
          } else {
            Bullet temp = new Bullet(player_x-55, player_y); 
            bullets.add(temp);
            bullet_side = 1;
          }
        }
      }
      fill(255);
      text(frameRate, 100, 100);
    }
    
    void background() {
      image(background_1, 0, background_y1);
      image(background_1, 0, background_y1-height);
      background_y1 += 1.2;
      if (background_y1 >= height) background_y1 = 0;
    
      image(background_2, 0, background_y2);
      image(background_2, 0, background_y2-height);
      background_y2 += 1.6;
      if (background_y2 >= height) background_y2 = 0;
    }
    
    
    void enemy() {
      if (enemy_health == 0) {
        enemy_health = 1;
        enemy_y = -enemy.width/2;
        enemy_x = int(random(enemy.width/2, width-enemy.width/2));
      }
      if (enemy_y-enemy.width/2 >= height) {
        enemy_health = 0;
      }
      enemy_y += 3;
    
      image(enemy, enemy_x-enemy.width/2, enemy_y-enemy.height/2);
    }
    
    void player() {
      if (mousePressed && player_x < mouseX) player_x = player_x + 12;
      if (mousePressed && player_x > mouseX) player_x = player_x - 12;
      image(player, -player.width/2+player_x, -player.height/2+player_y);
    }
    
    void bullet_enemy() {
      if (player_x <= enemy_x+100 && player_x >= enemy_x-100 || bullet_traveling == 1) {
        bullet_traveling = 1;
        if (bullet_shot == 0) {
          bullet_x = enemy_x;
          bullet_y = enemy_y;
          bullet_shot = 1;
        }
        rect(bullet_x, bullet_y, 10, 10);
        bullet_y = bullet_y + 30 ;
      }
    
      if (bullet_x <= player_x+player.width/2 && bullet_x >= player_x-player.width/2 && bullet_y >= player_y) {
        bullet_traveling = 0;
        bullet_shot = 0;
      }
    }
    
    class Bullet {
      float x;
      float y;
      float speed;
    
      Bullet(float tx, float ty) {
        x = tx;
        y = ty;
      }
    
      boolean update() {
        image(bullet, -bullet.width/2+x, -bullet.height/2+y);
        y -= 25;
        if (x <= enemy_x+enemy.width/2 && x >= enemy_x-enemy.width/2 && y <= enemy_y) {
          enemy_health = 0;
          return true;
        }
        return false;
      }
    }
    
  • Sorry... no p2D but P2D... my mistake.

    Kf

  • Sorry... no p2D but P2D... my mistake.

    What!? @Sjors Don't tell me you didn't actually notice that?

  • @kfrajer that was a typo in my reply I used P2D correctly in my code but still get the same error. to be exact is just this code

    fullScreen(P2D);

    that should work right?

    Also @Lord_of_the_Galaxy thanks for the fix I didn't excpect it to be so easy

  • fullScreen(P2D);

    That is correct. I am taking a wild guess here, but I think your error is related to loading images. Two tests I would do if I were you:

    1. Run a sinmple application using P2D. It should work
    2. In your program, try loading your iamges from your local file storage instead of retrieving it from the web.

    Those steps won't solve any problem yet but more for sanity check.

    Kf

  • @kfrajer a simple application using P2D works indeed (I stored the picture local) but when I ran the code I posted here (pictures still stored local) it gave the same error.

    here's the simple application I tested

    PImage background_2;
    void setup() {
      fullScreen(P2D);
      background_2 = loadImage("background_2 16_9.png");
    }
    
    void draw() {
      image(background_2, 0, 0);
    }
    
  • edited April 2017

    @Lord_of_the_Galaxy also on my computer when running the updated code you send, I noticed that the framerate started at 48 and dropped to 35 and then jumped back to 48.

    After saving the frame rate every second and exporting it to excel I think the framerate might lower because of the background movement? Since the background_y creeps up until it becomes the height of the screen after which it jumps to zero, at which point the frame ratejumps back to 48 (I think).

  • edited April 2017

    Quick update, I found the problem in the resize void, after removing every void and running the code so that took a while. When I found the more specific problem I'll update this one more

    UPDATE: So I found a bug (I dont know if its the only one) when using this line

      background_2.resize(screen_width, screen_height);
    

    It runs just fine but when I add

      background_1.resize(screen_width, screen_height); 
    

    The same error pops up again? I have no clue why so maybe someone else knows. The code which selects background_1 and background_2 is

      if (float(width)/height > 1.7 && float(width)/height < 1.8) {
        background_1 = loadImage("background_1 9_16.png");
        background_2 = loadImage("background_2 9_16.png");
      } 
    
      if (float(width)/height > 0.5 && float(width)/height < 0.6) {
        background_1 = loadImage("background_1 16_9.png");
        background_2 = loadImage("background_2 16_9.png");
      }
    }
    

    I've also linked the pictures below from which the program chooses (it should be noted that the program loads background_1 16_9.png and background_2 16_9.png on my case so that might change the error I would get?)

    https://s10.postimg.org/jv191w8ft/background_1_9_16.png https://s27.postimg.org/l4xs5of0z/background_2_9_16.png https://s12.postimg.org/gl3y5q55p/background_1_16_9.png https://s7.postimg.org/yuy798o3v/background_2_16_9.png

  • This is confusing.

  • edited April 2017

    @Lord_of_the_Galaxy I just got part of the answer, I took a look at background_1 to see if there was something wrong with the resolution and it turns out that the size was 1080 x 1900 which should be 1080 x 1920 after I changed it that part of the code ran fine but I dont understand why it didn't just stretch the picture to fit the screen?

    I think the resize fucntion doesn't work at al since right now it doesn't have to resize anything since background_1 is the same size as my phone screen but it if change it to

    background_1.resize(width+10, height+10);
    

    it crashes again?

    Now the remaing problem (still inside the resize void) is this piece of code

          if (width > height) {
            player.resize(height/3, height/3);
            enemy.resize(height/3, height/3);
          } else if (width < height) {
            player.resize(width/3, width/3);
            enemy.resize(width/3, width/3);
          } else {
            player.resize(height/3, height/3);
            enemy.resize(height/3, height/3);
          }
    

    and I've got no clue why it wont just resize the picture like it does normally (without J2D)

  • edited April 2017

    I think something is wrong with resize. It may be specific to your device, though, as I think it relies on the graphics processor.

    I think the only solution will be to file a bug report, as there is no sensible reason why it shouldn't work.

    File it here - https://github.com/processing/processing-android/issues, but remember that they may take a week or so to respond.

    EDIT changed to Processing Android page, don't know how I made that mistake.

  • If it is a problem that is specific to android mode, then file your issue here:

  • @jeremydouglass Oops, sorry, I meant to give that link only :(|)

  • Thanks to you all I will report it until they responde I will just load the right resolution instead of scaling it :)

  • @Sjors

    When a run your code using the default renderer, it didn't run at first. Do you have the internet permission enabled? I am loading the images from internet and it runs fine after enabling the permission. I confirm and I am having the same issue when running in P2D. I suggest you continue using the default renderer for now. If you start a ticket for this bug, please post the ticket in this post so people having the same issue can track it as well.

    Just to confirm, I removed any reference to bullet and enemy. Then The only elements being resized where both background images. Enabling these resize lines under P2D causes the app to crash. If I disable resize and run in P2D, no problems at all.

    Kf

  • I reported the problem and here is the link https://github.com/processing/processing-android/issues/332

    @kfrajer I did have internet permission enabled

Sign In or Register to comment.