Having fps problems each time I use sprites (images).

For my game I started using simply figures for testing. Now that I had that working, I implemented sprites using images, but my fps starts going down quickly. I can not figure out how to fix this issue.

Answers

  • Without seeing the code, neither can we

  • edited November 2017

    When done right this shouldn't slow things down

    some generic advice:

    https://forum.processing.org/two/discussion/comment/109112/

    e.g.

    • calling loadImage() every time draw() loops (BAD)

    • using resize() outside setup, using image() with 5 parameters (instead of 3)

  • edited November 2017
    function gameScreen(){
    
      var score;
      var samurai;
      var ninjas;
      var planks;
      var backgroundImg;
      var pauseAreaClicked;
      var isPaused;
      var pauseCreated;
      var firstRun;
    
      this.setup = function(){
        createCanvas(windowWidth, windowHeight);
        samurai = new Samurai();
        ninjas = [];
        planks = [];
        score = 0;
    
        //Create the Pause Button
        pauseAreaClicked = false;
        firstRun = true;
        isPaused = false;
        pauseButton = createButton("| |");
        pauseButtonCSSSetup(pauseButton, 0.6);
        pauseButton.mousePressed(pauseGame);
      }
    
      this.reset = function(){
        this.setup();
      }
    
      this.getScore = function(){
        return score;
      }
    
      this.draw = function(){
        if(isPaused){
          return;
        }
    
        //Background Setup
        background(193, 154, 107);
    
        if(firstRun){
          for(var i = 0; i < windowHeight; i++){
            if(i % 50 == 0){
              planks.push(new plank(i));
            }
          }
          firstRun = false;
        }
    
        for(var i = planks.length - 1; i >= 0; i--){
          planks[i].show();
          planks[i].update();
    
          if(planks[i].offscreen()){
            planks.splice(i, 1);
            planks.push(new plank(0));
          }
        }
    
        //Text
        fill(255);
        textAlign(CENTER, CENTER);
        textSize(25);
        text("Score: " + score, windowWidth/2, windowHeight * .05)
    
        //Watch for framerate
        var fps = frameRate();
        stroke(0);
        text("FPS:" + fps.toFixed(2), windowWidth / 2, height - 20);
    
        samurai.update();
        samurai.show();
    
        //Update enemy position every frame.
        for(var i = ninjas.length - 1; i >= 0; i--){
          ninjas[i].show();
          ninjas[i].update();
    
          //If enemies go offscreen delete them to free up memory.
          if(ninjas[i].offscreen()){
            ninjas.splice(i, 1);
          }
    
          if(ninjas[i].collision(samurai)){
            if(samurai.attacking){
              score++;
            }
            else{
              clear();
              removeElements();
              //ninjas.splice(i,1);
              this.sceneManager.showScene(gameOverScene);
            }
            ninjas.splice(i, 1);
          }
        }
    
        //Spawn new enemies every 120 frames.
        if(frameCount % 120 == 0){
          ninjas.push(new ninja());
        }
      }
    
      this.mousePressed = function(){
        if(!pauseAreaClicked){
          if(mouseX > (windowWidth / 2) * 1.5){
            samurai.switchLanes("right");
          }
    
          else if(mouseX < (windowWidth / 2) * 0.5){
            samurai.switchLanes("left");
          }
    
          else{
            samurai.attack();
          }
        }
    
        else{
          if(isPaused){
            isPaused = false;
          }
    
          else{
            isPaused = true;
            if(pauseCreated){
              oPause = this.sceneManager.findScene(pauseScreen).oScene;
              oPause.reset();
            }
    
            pauseCreated = true;
            this.sceneManager.showScene(pauseScreen);
          }
    
          pauseAreaClicked = false;
        }
      }
    
        /**
          CSS STYLING FOR BUTTONS :D
        */
      function pauseButtonCSSSetup(button, YpositionMultiple){
        button.style("width", "35px");
        button.style("height", "35px");
        button.style("text-align", "center");
        button.style("font-size", "150%");
        button.style("font-weight", "bold")
        button.style("color", "#FFF");
        button.style("background", "#C19A6B");
        button.style("border-radius", "4px");
        button.style("display", "inline-block");
        button.style("border", "none");
        button.style("outline", "none");
    
        //NOT CSS
        //Center Button
        button.position(windowWidth  >> 6, windowHeight/100);
      }
    
      function pauseGame(){
        pauseAreaClicked = true;
      }
    
      this.unpause = function(){
        isPaused = false;
      }
    }
    
    
    
    And this will be my character:
    
     function Samurai(){
      var sam;
      this.x = windowWidth / 2;
      this.y = windowHeight * 0.85;
      this.velocityX = 0;
      this.velocityY = 0;
      this.attacking = false;
      this.alreadyScored = false;
      this.hit = false;
      var previousX = windowWidth / 2;
      var leftTranslation = (windowWidth / 2) * 0.5;
      var rightTranslation = (windowWidth / 2) * 1.5;
      var upTranslation = (windowHeight / 2) * 1.5;
      this.size = windowWidth * 0.15;
    
      this.show = function(){
        sam = createSprite(this.x, this.y, this.size, this.size);
        sam.setCollider('circle', 0, 0, 40);
        sam.addImage(samImg);
        updateSprites(false);
    
        // fill(10);
        // ellipse(this.x, this.y, this.size, this.size);
        //
        // fill(50);
        // ellipse(this.x, this.y, windowWidth * 0.07, windowWidth * 0.07);
      }
    
      //NOT BEING USED
      this.update = function(){
        drawSprite(sam);
    
        //Update Players position based on gestures.
        this.x += this.velocityX;
        this.y += this.velocityY;
    
        //IF Left Right or Middle lane have been reached, stop updating
        //the character's position.
        //Dont allow for both directions to be pressed
        if(this.x >= rightTranslation
        || this.x <= leftTranslation
        || (this.x == windowWidth / 2 && (previousX != windowWidth / 2))){
          this.velocityX = 0;
        }
    
        if(this.y <= upTranslation){
          this.attacking = false;
          this.velocityY = 15;
        }
    
        else if(this.y == windowHeight * 0.85){
          this.velocityY = 0;
        }
    
      }
    
      //Initiate movement from lane to lane.
      this.switchLanes = function(leftOrRight){
        if(leftOrRight == "right"){
          if(!(this.x >= rightTranslation)){
            this.velocityX = 12;
          }
        }
        if(leftOrRight == "left"){
          if(!(this.x <= leftTranslation)){
            this.velocityX = -12;
          }
        }
        previousX = this.x;
      }
    
      this.attack = function(){
        this.attacking = true;
    
        if(!(this.y <= upTranslation)){
          this.velocityY = -15;
        }
      }
    }
    
  • edited November 2017

    My images are loaded in my first set up function.

    var backgroundImage;
    var samImg;
    var ninImg;
    var ninImg2;
    var ninImg3;
    
    function preload() {
      samImg = loadImage('Sprites/wolf.png');
      ninImg = loadImage('Sprites/goblin.png');
      ninImg2 = loadImage('Sprites/evilSamurai.png');
      ninImg3 = loadImage('Sprites/wolf.png');
    }
    
    function setBackgroundImage(){
      backgroundImage = "url('./Textures/StartScreenBackground2.jpeg')";
      document.body.style.backgroundSize = "100% 100%";
    }
    
    function setup(){
      createCanvas(windowWidth, windowHeight);
      setBackgroundImage();
    
      var sceneManager = new SceneManager();
      sceneManager.backgroundImage = backgroundImage;
      sceneManager.wire();
      sceneManager.showScene(startScreen);
    }
    
  • not sure if you posted your ninja class. Because you use it when you spawn. Do you use loadimage there?

  • edited November 2017

    Nope.

    /*
      Enemies
    */
    function ninja(){
      var ninj;
      //Hashmap for spots X spots to spawn enemies
      var dict = {};
      dict[0] = (windowWidth / 2) * 0.46;
      dict[1] =(windowWidth / 2) * 1.54;
      dict[2] = windowWidth / 2;
    
      //RNG to choose where
      rand = getRandomInt(0, 2);
      rand2 = getRandomInt(0,2);
      this.x = dict[rand];
      this.y = -100;
      this.size = windowWidth * 0.07
      this.velocity = 5;
    
      this.show = function(){
        // fill(255);
        // ellipse(this.x, this.y, this.size, this.size);
        ninj = createSprite(this.x, this.y, this.size, this.size);
        ninj.setCollider('circle', 0, 0, 40);
        updateSprites(false);
        ninj.addImage(ninImg);
    
        // if(rand2 == 0)
        //   ninj.addImage(ninImg);
        // else if(rand2 == 1)
        //   ninj.addImage(ninImg2);
        // else if(rand2 == 2)
        //   ninj.addImage(ninImg3);
      }
    
      this.update = function(){
        drawSprite(ninj);
        this.y += this.velocity;
      }
    
      this.offscreen = function(){
        return this.y > windowHeight;
      }
    
      this.collision = function(player){
        if(player.x < (this.x + this.size) && player.x > (this.x - this.size)){
          if(player.y < (this.y + this.size) && player.y > (this.y - this.size)){
            return true;
          }
        }
      }
    
      function getRandomInt(min, max){
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min;
      }
    }
    
  • Does addImage count?

  • I don't know.

    Can't you load the image and use it when spawning?

  • edited November 2017

    Not sure. Im using a js library called scene manager, which helps me change through different views, would that interfere?

    //
    // p5 SceneManager helps you create p5.js sketches with multiple states / scenes
    // Each scene is a like a sketch within the main sketch. You focus on creating
    // the scene like a regular sketch and SceneManager ensure scene switching
    // routing the main setup(), draw(), mousePressed(), etc. events to the 
    // appropriate current scene.
    //
    // Author: Marian Veteanu
    // http://github.com/mveteanu
    //
    function SceneManager(p)
    {
        this.scenes = [];
        this.scene = null;
    
        // Wire relevant p5.js events, except setup()
        // If you don't call this method, you need to manually wire events
        this.wire = function()
        {
            var me = this;
            var o = p != null ? p : window;
    
            o.draw = function(){ me.draw(); };
            o.mousePressed = function(){ me.mousePressed(); };
            o.keyPressed = function(){ me.keyPressed(); };
    
            return me;
        }
    
        // Add a scene to the collection
        // You need to add all the scenes if intend to call .showNextScene()
        this.addScene = function( fnScene )
        {
            var oScene = new fnScene(p);
    
            // inject p as a property of the scene
            this.p = p;
    
            // inject sceneManager as a property of the scene
            oScene.sceneManager = this;
    
            var o = {   fnScene: fnScene, 
                        oScene: oScene,
                        hasSetup : "setup" in oScene,
                        hasEnter : "enter" in oScene,
                        hasDraw : "draw" in oScene,
                        hasMousePressed : "mousePressed" in oScene,
                        hasKeyPressed : "keyPressed" in oScene,
                        setupExecuted : false,
                        enterExecuted : false };
    
            this.scenes.push(o);
            return o;
        }
    
        // Return the index of a scene in the internal collection
        this.findSceneIndex = function( fnScene )
        {
            for(var i = 0; i < this.scenes.length; i++)
            {
                var o = this.scenes[i]; 
                if ( o.fnScene == fnScene )
                    return i;
            }
    
            return -1;
        }
    
        // Return a scene object wrapper
        this.findScene = function( fnScene )
        {
            var i = this.findSceneIndex( fnScene );
            return i >= 0 ? this.scenes[i] : null;
        }
    
        // Returns true if the current displayed scene is fnScene
        this.isCurrent = function ( fnScene )
        {
            if ( this.scene == null )
                return false;
    
            return this.scene.fnScene == fnScene;
        }
    
        // Show a scene based on the function name
        // Optionally you can send arguments to the scene
        // Arguments will be retrieved in the scene via .sceneArgs property
        this.showScene = function( fnScene, sceneArgs )
        {
            var o = this.findScene( fnScene );
    
            if ( o == null )
                o = this.addScene( fnScene );
    
            // Re-arm the enter function at each show of the scene
            o.enterExecuted = false;
    
            this.scene = o;
    
            // inject sceneArgs as a property of the scene
            o.oScene.sceneArgs = sceneArgs;
        }
    
        // Show the next scene in the collection
        // Useful if implementing demo applications 
        // where you want to advance scenes automatically
        this.showNextScene = function( sceneArgs )
        {
            if ( this.scenes.length == 0 )
                return;
    
            var nextSceneIndex = 0;
    
            if ( this.scene != null )
            {
                // search current scene... 
                // can be optimized to avoid searching current scene...
                var i = this.findSceneIndex( this.scene.fnScene );
                nextSceneIndex = i < this.scenes.length - 1 ? i + 1 : 0;
            }
    
            var nextScene = this.scenes[nextSceneIndex];
            this.showScene( nextScene.fnScene, sceneArgs );
        }
    
        // This is the SceneManager .draw() method
        // This will dispatch the main draw() to the 
        // current scene draw() method
        this.draw = function()
        {
            if ( this.scene == null )
                return;
    
            if ( this.scene.hasSetup && !this.scene.setupExecuted  )
            {
                this.scene.oScene.setup();
                this.scene.setupExecuted = true;
            }
    
            if ( this.scene.hasEnter && !this.scene.enterExecuted  )
            {
                this.scene.oScene.enter();
                this.scene.enterExecuted = true;
            }
    
            if ( this.scene.hasDraw )
            {
                this.scene.oScene.draw();
            }
        }
    
        // This will dispatch .mousePressed() to the 
        // current scene .mousePressed() method
        this.mousePressed = function()
        {
            if ( this.scene == null )
                return;
    
            if ( this.scene.hasMousePressed )
            {
                this.scene.oScene.mousePressed();
            }
        }
    
        // This will dispatch .keyPressed() to the
        // current scene .keyPressed() method
        this.keyPressed = function()
        {
            if ( this.scene == null )
                return;
    
            if ( this.scene.hasKeyPressed )
            {
                this.scene.oScene.keyPressed();
            }
        }
    }
    
  • edited November 2017

    I start with around 60fps, but after a few seconds it starts going down.

  • edited November 2017

    Capture

    If you would like to take a deeper view, I can upload my code to github and then post the link.

  • I can't help you with that

    Formatting

    but you can go back and edit your old posts above

    (click on the gear and then "Edit")

    format your code better:

    • empty line before and after the entire code section

    • select entire code with the mouse

    • hit ctrl-o

    • OR us the small 'C' in the command bar

  • (i've done it)

  • What have you done? @koogs

  • i'd say createSprite and addImage are odd things to have in show(). sound more like they belong in the constructor, not called every frame. but then, javascript ¯_(ツ)_/¯

  • in which way?

Sign In or Register to comment.