This discussion is archived
12 Replies Latest reply: Oct 4, 2011 9:30 PM by 875749 RSS

My Attempt at Active Rendering is Very Slow?

875749 Newbie
Currently Being Moderated
Hey, guys! I finally got together my scrolling tile engine for the game I'm working on. I first implemented it with passive rendering, not knowing anything about active rendering, and it turned out very slow. After getting some pointers about active rendering, I reimplemented the engine using active rendering.

However, it's still running just as slow! I'm not sure if I missed something somewhere, but I would appreciate if someone could take a look and see if I messed up my implementation of active rendering. I pretty much used everything straight out of the Java Tutorials and a gamedev.net article, using a BufferStrategy, turning off repaint, and some other items. I will include the relevant classes below.

Basically, the LevelRenderer class inherits a JFrame, creates a full-screen GraphicsEnvironment for itself, handles input to update the level and the player, and handles the BufferStrategy and the other drawing-related tasks in its run method, which is called from main() in another class called GameTest. The LevelRenderer creates a Player and Level object, each of which has its own draw routine. Lastly, the GameTest class just creates a LevelRenderer object and then calls its run method, which takes everything from there.

Thank you guys so much!

Here's the LevelRenderer class that inherits from a JFrame and implements the rendering:
/* This class's job is to manage a Player and Level object and call their render and update routines. */
 
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.JFrame;
import javax.swing.*;
import java.util.Random;
import java.awt.Color;

public class LevelRenderer extends JFrame
{   
    //
    // CONSTANTS
    //
    
    private final int TILE_SIZE = 14;
    private final int SCREEN_WIDTH = 1280;
    private final int SCREEN_HEIGHT = 768;
    
    //
    // END OF CONSTANTS
    //
    
    // will be used as a buffer before everything is drawn to the screen
    private BufferedImage buffer2;
    
    // back buffer
    private BufferStrategy buffer;
    
    // character object
    private Player myPlayer;
    
    // level object
    private Level myLevel;
    
    // screen object
    private Screen s;
    
    // graphics object of the buffer
    private Graphics gr;
    
    // Graphics object for the buffer strategy
    private Graphics graphics;
    
    // boolean to determine when to end the game
    private boolean endGame;
    
    // CONSTRUCTOR
    public LevelRenderer()
    {
        setPreferredSize(new Dimension(1280, 768));
        setIgnoreRepaint( true );
        setUndecorated( true );

        setFocusable(true);
        requestFocus();
        
        setResizable(false);
        
        addKeyListener( new KeyAdapter() 
        {
            public void keyPressed(KeyEvent e)
            { 
                processKey(e);  
            }
            
            public void keyReleased(KeyEvent e)
            {
                processRelease(e);
            }
        });
        
        buffer2 = new BufferedImage(1280, 768, BufferedImage.TYPE_INT_ARGB);
        
        buffer2.createGraphics();
        gr = buffer2.getGraphics();
        
        myPlayer = new Player();
        myLevel = new Level("obstaclemap");
        
        endGame = false;
    }
    
    // method to simply load an image from a path
    public static BufferedImage loadImage(String ref)
    {
        BufferedImage bimg = null;
           
        try
        {
           bimg = ImageIO.read(new File(ref));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
       
        return bimg;
    }
    
    // Run method for class
    public void run(DisplayMode dm)
     {     
        setBackground(Color.WHITE);
          s = new Screen();
        s.setFullScreen(dm, this);
        
        this.createBufferStrategy( 2 );
        buffer = this.getBufferStrategy();

        while (!endGame)
        {
            try
            {   
                // clear back buffer...
                gr = buffer2.createGraphics();
                gr.setColor(Color.BLACK);
                
                // edit player and level
                myLevel.renderLevel();
                myPlayer.animatePlayer();
                myLevel.drawLevel(gr, 0, 0);
                myPlayer.drawPlayer(gr, (SCREEN_WIDTH / 2) - TILE_SIZE / 2, (SCREEN_HEIGHT / 2) - TILE_SIZE);
                
                graphics = buffer.getDrawGraphics();
                graphics.drawImage(buffer2, 0, 0, null);
                
                if( !buffer.contentsLost() )
                {
                    buffer.show();
                }
            }
            catch (Exception ex) 
            { 
                System.err.println("Game Update Error: " + ex);
            }
        }
        
          s.restoreScreen();
     } 
    
    // method to handle inputs and adjust the player accordingly
    public void processKey(KeyEvent e)
    {
        int keyCode = e.getKeyCode();
        boolean moved = false;
        int xDisplace, yDisplace;
        
        // termination key
        if (keyCode == KeyEvent.VK_ESCAPE)
        {
            endGame = true;
        }
        
        // 0 - up
        // 1 - left
        // 2 - right
        // 3 - down
        // 4 - jump
        
        if (keyCode == KeyEvent.VK_UP)
        {
            myPlayer.updatePlayer(0);
            myLevel.updateLevel(0);
        }
        if (keyCode == KeyEvent.VK_LEFT)
        {
            myPlayer.updatePlayer(1);
            myLevel.updateLevel(1);
        }
        if (keyCode == KeyEvent.VK_RIGHT)
        {
            myPlayer.updatePlayer(2);
            myLevel.updateLevel(2);
        }
        if (keyCode == KeyEvent.VK_DOWN)
        {
            myPlayer.updatePlayer(3);
            myLevel.updateLevel(3);
        }
        if (keyCode == KeyEvent.VK_SPACE)
        {
            myPlayer.updatePlayer(4);
            myLevel.updateLevel(4);
        }
    }
    
    // method to handle inputs and adjust the player accordingly
    public void processRelease(KeyEvent e)
    {
        int keyCode = e.getKeyCode();
        boolean moved = false;
        int xDisplace, yDisplace;
        
        // 0 - up
        // 5 - left
        // 6 - right
        // 3 - down
        // 4 - jump
        
        if (keyCode == KeyEvent.VK_UP)
        {
            myPlayer.updatePlayer(0);
        }
        if (keyCode == KeyEvent.VK_LEFT)
        {
            myPlayer.updatePlayer(5);
        }
        if (keyCode == KeyEvent.VK_RIGHT)
        {
            myPlayer.updatePlayer(6);
        }
        if (keyCode == KeyEvent.VK_DOWN)
        {
            myPlayer.updatePlayer(3);
        }
        if (keyCode == KeyEvent.VK_SPACE)
        {
            myPlayer.updatePlayer(4);
        }
    }
}
Here's the Player class that represents the player and his current animation:
/* This class's purpose will be to store the data of the player character for movement and appearance. It will also
 * take input. The player image will be created as a sheet of animation frames and split by the class. */
 
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import java.awt.*;
 
public class Player
{
    //
    // CONSTANTS
    //
    
    private final int TILE_SIZE = 14;
    private final int SCREEN_WIDTH = 1280;
    private final int SCREEN_HEIGHT = 768;
    
    //
    // END OF CONSTANTS
    //
    
    // image to store the player's frames of animation as a sheet/loaded first
    private BufferedImage playerSheet;
    
    // image array to store the individual frames of animation/split by program
    private BufferedImage playerFrames[];
    
    // index used to represent the current frame to draw on the screen of the player
    private int currentIndex = 0;
    
    // enum representing the player's state of movement for animation
    private enum PlayerState {STILL_LEFT, STILL_RIGHT, MOVE_LEFT, MOVE_RIGHT, JUMP}
    
    // variable used to represent the player's current animation state
    private PlayerState currentState;
    
    // variable to keep track of last direction the character was facing when going back to still
    private PlayerState lastState;
    
    // long used to represent the system time, used as a timer
    private long movementTimer;
    
    // long used to represent the previously used time as a timer
    private long stillTimer;
    
    // CONSTRUCTOR
    public Player()
    {
        playerSheet = makeColorTransparent("playersheet1.png", 0xFFFF65F6);
        playerFrames = splitImage(playerSheet, 4, 2);
        movementTimer = System.nanoTime();
        stillTimer = movementTimer;
        currentState = PlayerState.STILL_LEFT;
        lastState = PlayerState.STILL_LEFT;
    }
    
    // this method will draw to whatever graphics context is passed to the method (game window)
    public void drawPlayer(Graphics gr, int x, int y)
    {
        gr.drawImage(playerFrames[currentIndex], x, y, null);
    }
    
    // method to simply load an image from a path
    private static BufferedImage loadImage(String ref)
    {
        BufferedImage bimg = null;
           
        try
        {
           bimg = ImageIO.read(new File(ref));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
       
        return bimg;
    }
    
    // method to create a tile array for tile sets
    private BufferedImage[] splitImage(BufferedImage img, int cols, int rows)
    {
        int w = img.getWidth() / cols;
        int h = img.getHeight() / rows;
        int num = 0;
        
        BufferedImage imgs[] = new BufferedImage[w * h];
        
        for (int y = 0; y < rows; y++)
        {
            for (int x = 0; x < cols; x++)
            {
                imgs[num] = new BufferedImage(w, h, img.getType());
                
                Graphics2D g = imgs[num].createGraphics();
                g.drawImage(img, 0, 0, w, h, w * x, h * y, w * x + w, h * y + h, null);
                g.dispose();
                num++;
            }
        }
        
        return imgs;
    }
    
    // image-loading method that will also alpha the color key for each tile
    public static BufferedImage makeColorTransparent(String ref, int color)
    {
        BufferedImage image = loadImage(ref);
        BufferedImage dimg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = dimg.createGraphics();
        g.setComposite(AlphaComposite.Src);
        g.drawImage(image, null, 0, 0);
        g.dispose();
        
        for (int i = 0; i < dimg.getHeight(); i++)
        {
            for (int j = 0; j < dimg.getWidth(); j++)
            {
                if (dimg.getRGB(j, i) == color)
                {
                    dimg.setRGB(j, i, 0x8F1C1C);
                }
            }
        }
        
        return dimg;
    }
    
    // method to update the player based on user input
    public void updatePlayer(int input)
    {
        // update the still timer to manage when the last key press was
        stillTimer = System.nanoTime();
        
        switch (input)
        {
            // up
            case 0:
                break;
            // left
            case 1:
                if (currentState != PlayerState.MOVE_LEFT)
                {
                    movementTimer = System.nanoTime();
                }
                currentState = PlayerState.MOVE_LEFT;
                lastState = PlayerState.MOVE_LEFT;
                break;
            // right
            case 2:
                if (currentState != PlayerState.MOVE_RIGHT)
                {
                    movementTimer = System.nanoTime();
                }
                currentState = PlayerState.MOVE_RIGHT;
                lastState = PlayerState.MOVE_RIGHT;
                break;
            // down
            case 3:
                break;
            // jump
            case 4:
                break;
            
            // still left
            case 5:
                currentState = PlayerState.STILL_LEFT;
                lastState = PlayerState.STILL_LEFT;
                break;
            
            // still right
            case 6:
                currentState = PlayerState.STILL_RIGHT;
                lastState = PlayerState.STILL_RIGHT;
                break;
        }
    }
    
    // method to manage the player's animation
    public void animatePlayer()
    {   
        switch (currentState)
        {
            case STILL_LEFT:
                currentIndex = 0;
                break;
            case STILL_RIGHT:
                currentIndex = 4;
                break;
            case MOVE_LEFT:
                // if set to a still frame, set it to start running left
                if (currentIndex == 0 || currentIndex == 4)
                {
                    currentIndex = 1;
                }
                // if a 300 nanosecond gap has passed, allow the next frame
                if (System.nanoTime() - movementTimer > 100000000)
                {
                    if (currentIndex == 1)
                    {
                        currentIndex = 2;
                    }
                    else
                    {
                        currentIndex = 1;
                    }
                    
                    movementTimer = System.nanoTime();
                }
                break;
            case MOVE_RIGHT:
                // if set to a still frame, set it to start running right
                if (currentIndex == 0 || currentIndex == 4)
                {
                    currentIndex = 5;
                }
                // if a 300 nanosecond gap has passed, allow the next frame
                if (System.nanoTime() - movementTimer > 100000000)
                {
                    if (currentIndex == 5)
                    {
                        currentIndex = 6;
                    }
                    else
                    {
                        currentIndex = 5;
                    }
                    
                    movementTimer = System.nanoTime();
                }
                break;
            case JUMP:
            
                break;
        }
    }
}
Here's the Level class that represents a level after loading it from an image file and storing the tiles into an array:
/* The purpose of this class will be to load and manage a level, including its camera. */

import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import java.awt.*;

public class Level
{
    //
    // CONSTANTS
    //
    
    private final int TILE_SIZE = 14;
    private final int SCREEN_WIDTH = 1280;
    private final int SCREEN_HEIGHT = 768;
    
    //
    // END OF CONSTANTS
    //
    
    // stores the pixel image of the current level
    private BufferedImage levelImage;
    
    // stores the width and height of the level
    private int width, height;
    
    // stores the name of the level
    private String levelName;
    
    // stores collision map for level
    private LevelCollisions myCollisions;
    
    // stores the tile types in an array as assigned by colors
    private int levelTiles[][];
    
    // image used as the sheet for the level's tiles
    private BufferedImage tileSheet;
    
    // image array used to store the different tiles
    private BufferedImage[] tiles;
    
    // the image which represents the current view of the level
    private BufferedImage cameraImage;
    
    // Graphics context of the camera image
    private Graphics cameraG;
    
    // variables to represent the level's offset from the top left corner while moving
    private int offsetX, offsetY;
    
    // variables to represent the level's pixel map coordinate
    private int coordX, coordY;
    
    // 
    // STATIC COLOR VARIABLES
    //
    
    private static final int SPACE_COLOR = 0xFF000000;
    private static final int WALL_COLOR = 0xFFFFFFFF;
    
    //
    // END OF STATIC COLOR VARIABLES
    //
    
    //
    // CONSTRUCTOR
    //
    public Level(String level)
    {
        // load level image and collision map
        levelName = level;
        levelImage = loadImage(level + ".png");
        myCollisions = new LevelCollisions(level + "Collision");
        levelTiles = loadLevel();   
        
        // create blank camera canvas
        cameraImage = new BufferedImage(1280, 768, BufferedImage.TYPE_INT_ARGB);
        cameraImage.createGraphics();
        cameraG = cameraImage.getGraphics();
        
        // offsets start at 0
        offsetX = offsetY = 0;
        
        // coordinate starts at bottom right
        coordX = 600;
        coordY = 383;
        
        // fill tile images
        tileSheet = loadImage("obstacletiles.png");
        tiles = splitImage(tileSheet, 2, 1);
        
        this.renderLevel();
    }
    
    // method to load the color values into an array
    public int[][] loadLevel()
    {
        height = levelImage.getHeight();
        width = levelImage.getWidth();
        
        int levelValues[][] = new int[width][height];
        
        // fill array with color values layer by layer
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                levelValues[x][y] = levelImage.getRGB(x, y);
            }   
        }
        
        return levelValues;
    }
    
    // method to get the tile color from a given tile
    public int getTile(int x, int y)
    {
        return levelTiles[x][y];
    }
    
    // method to draw the current camera view of the level on the screen
    public void drawLevel(Graphics gr, int x, int y)
    {
        gr.drawImage(cameraImage, x, y, null);
    }
    
    // method to render the actual image before drawing it
    public void renderLevel()
    {
        // keeps track of graphics coordinate
        int x, y;
        
        // keeps track of tile to draw
        int tileX, tileY;
        
        tileY = coordY;
        
        // draw all the tiles based on offsets, layer by layer
        for (y = offsetY; y < SCREEN_HEIGHT + offsetY; y += TILE_SIZE)
        {
            tileX = coordX;
            for (x = offsetX; x < SCREEN_WIDTH + offsetX; x += TILE_SIZE)
            {
                // determine which tile to draw based on tile color in array
                switch (this.getTile(tileX, tileY))
                {
                    case SPACE_COLOR:
                        cameraG.drawImage(tiles[0], x, y, null);
                        break;
                        
                    case WALL_COLOR:
                        cameraG.drawImage(tiles[1], x, y, null);
                        break;
                }
                
                tileX++;
            }
            
            tileY++;
        }
        
        // steps to take in case of an offset
        if (offsetX > 0)
        {
        
        }
        
        if (offsetX < 0)
        {
        
        }
        
        if (offsetY < 0)
        {
        
        }
        
        if (offsetY > 0)
        {
        
        }
    }
    
    // method to update the level's current position for the camera
    public void updateLevel(int input)
    {
        switch (input)
        {
            // up
            case 0:
                // update offset up if not too far up
                if (coordY > 30)
                {
                    offsetY += 2;
                }   
                
                // if a tile length has been moved, then offset becomes 0 and coordY is decreased
                if (offsetY >= TILE_SIZE)
                {
                    offsetY = 0;
                    coordY--;
                }
                break;
            // left
            case 1:
                // update offset to the left if not too far left
                if (coordX > 30)
                {
                    offsetX += 2;
                }
                
                // if a tile length has been moved, then offset becomes 0 and coordX is decreased
                if (offsetX >= TILE_SIZE)
                {
                    offsetX = 0;
                    coordX--;
                }
                break;
            // right
            case 2:
                // update offset to the right if not too far right
                if (coordX < width - 30)
                {
                    offsetX -= 2;
                }
                
                // if a tile length has been moved, then offset becomes 0 and coordX is increased
                if (offsetX <= -TILE_SIZE)
                {
                    offsetX = 0;
                    coordX++;
                }
                break;
            // down
            case 3:
                // update offset down if not too far down
                if (coordY < height - 30)
                {
                    offsetY -= 2;
                }
                
                // if a tile legnth has been moved, then offset becomes 0 and coordY is increased
                if (offsetY <= -TILE_SIZE)
                {
                    offsetY = 0;
                    coordY++;
                }
                break;
            // jump
            case 4:
                break;
        }
    }
    
    // method to simply load an image from a path
    public static BufferedImage loadImage(String ref)
    {
        BufferedImage bimg = null;
           
        try
        {
           bimg = ImageIO.read(new File(ref));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
       
        return bimg;
    }
    
    // method to create a tile array for tile sets
    public static BufferedImage[] splitImage(BufferedImage img, int cols, int rows)
    {
        int w = img.getWidth() / cols;
        int h = img.getHeight() / rows;
        int num = 0;
        
        BufferedImage imgs[] = new BufferedImage[w * h];
        
        for (int y = 0; y < rows; y++)
        {
            for (int x = 0; x < cols; x++)
            {
                imgs[num] = new BufferedImage(w, h, img.getType());
                
                Graphics2D g = imgs[num].createGraphics();
                g.drawImage(img, 0, 0, w, h, w * x, h * y, w * x + w, h * y + h, null);
                g.dispose();
                num++;
            }
        }
        
        return imgs;
    }
    
    // image-loading method that will also alpha the color key for each tile
    public static BufferedImage makeColorTransparent(String ref, int color)
    {
        BufferedImage image = loadImage(ref);
        BufferedImage dimg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = dimg.createGraphics();
        g.setComposite(AlphaComposite.Src);
        g.drawImage(image, null, 0, 0);
        g.dispose();
        
        for (int i = 0; i < dimg.getHeight(); i++)
        {
            for (int j = 0; j < dimg.getWidth(); j++)
            {
                if (dimg.getRGB(j, i) == color)
                {
                    dimg.setRGB(j, i, 0x8F1C1C);
                }
            }
        }
        
        return dimg;
    }
}
Lastly, here's the GameTest code:
/* This class is what controls and runs the main game loop. */

import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;

public class GameTest
{   
    public static void main(String args[])
    {
        // initialize the level, player, renderer, and display mode
        LevelRenderer myRenderer = new LevelRenderer();
        DisplayMode dm = new DisplayMode(1280, 768, 16, DisplayMode.REFRESH_RATE_UNKNOWN);
        
        myRenderer.run(dm);
    }
}
  • 1. Re: My Attempt at Active Rendering is Very Slow?
    EJP Guru
    Currently Being Moderated
    You don't need to keep re-creating 'gr' every time around the loop, especially when you've already created it in the constructor, nor keep setting its background to black either.
  • 2. Re: My Attempt at Active Rendering is Very Slow?
    875749 Newbie
    Currently Being Moderated
    EJP,

    Thank you for the response. I adjusted for that in my code. However, it is still running at the same exact same speed. :/
  • 3. Re: My Attempt at Active Rendering is Very Slow?
    EJP Guru
    Currently Being Moderated
    Well there's lots of suboptimal code here, such as the getTile() method which doesn't even need to exist once you get your co-ordinate system right, and you don't need to check the same keycode for seven different values as you are: use a switch statement, but I guess my fundamental question is does the run() method really need to run continuously? or should it run at short intervals based on the movement quanta?
  • 4. Re: My Attempt at Active Rendering is Very Slow?
    875749 Newbie
    Currently Being Moderated
    EJP,

    Thank you again for your response. I optimized the processKey routines so that they used switch statements as you said, and I can't believe I hadn't thought of that before! However, I'm not sure exactly where to begin in regard to your pointer about the run method. Do you mean loop run() in main instead of calling it just once? I appreciate your help and advice very much.

    Colton
  • 5. Re: My Attempt at Active Rendering is Very Slow?
    EJP Guru
    Currently Being Moderated
    You have a run(DisplayMode) method that loops 'while (!endGame)' and never appears to sleep, unless something it calls does that. I haven't analysed all your code but it seems to me you're just moving players around according to keyboard input or maybe their current course and speed, and you don't need that to run flat chat I would have thought. You're just burning CPU cycles and not giving your other threads a chance to run.
  • 6. Re: My Attempt at Active Rendering is Very Slow?
    875749 Newbie
    Currently Being Moderated
    EJP,

    I actually used to have a sleep call in there previously and ended up taking it out as an experiment and never put it back in. I just did and now the updated class is posted below. However, it didn't appear to change the speed at all.

    The code is actually moving the level around and redrawing the current view of the level based on a multi-dimensional array of tile values (0 or 1, 0 being black and 1 being a white design tile). The Player class just basically encapsulates the current animation of the player in the middle of the screen depending on where the user is moving and how to update this animation. In the end, it's just an illusion of movement, and from what I've learned and read on tile engines, this is how most side scrolling games work, so I chose this design. Eventually, I want this to be a class I can inherit from for different level types that use different tile images that will comprise the image, rather than just 2 tiles right now. It is my first side-scrolling engine, so there is of course much for me to learn and optimize, and the same goes for programming in general, something I probably will never completely master because of its expansive nature.

    Anyways, here is the updated LevelRenderer class, and I appreciate all of your help. I really do hope there's something that can be done to make the renderer function much faster.
    /* This class's job is to manage a Player and Level object and call their render and update routines. */
     
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import java.io.*;
    import javax.imageio.*;
    import javax.swing.JFrame;
    import javax.swing.*;
    import java.util.Random;
    import java.awt.Color;
    
    public class LevelRenderer extends JFrame
    {   
        //
        // CONSTANTS
        //
        
        private final int TILE_SIZE = 14;
        private final int SCREEN_WIDTH = 1280;
        private final int SCREEN_HEIGHT = 768;
        
        //
        // END OF CONSTANTS
        //
        
        // will be used as a buffer before everything is drawn to the screen
        private BufferedImage buffer2;
        
        // back buffer
        private BufferStrategy buffer;
        
        // character object
        private Player myPlayer;
        
        // level object
        private Level myLevel;
        
        // screen object
        private Screen s;
        
        // graphics object of the buffer
        private Graphics gr;
        
        // Graphics object for the buffer strategy
        private Graphics graphics;
        
        // boolean to determine when to end the game
        private boolean endGame;
        
        // CONSTRUCTOR
        public LevelRenderer()
        {
            setPreferredSize(new Dimension(1280, 768));
            setIgnoreRepaint( true );
            setUndecorated( true );
    
            setFocusable(true);
            requestFocus();
            
            setResizable(false);
            
            addKeyListener( new KeyAdapter() 
            {
                public void keyPressed(KeyEvent e)
                { 
                    processKey(e);  
                }
                
                public void keyReleased(KeyEvent e)
                {
                    processRelease(e);
                }
            });
            
            buffer2 = new BufferedImage(1280, 768, BufferedImage.TYPE_INT_ARGB);
            
            buffer2.createGraphics();
            gr = buffer2.getGraphics();
            
            myPlayer = new Player();
            myLevel = new Level("obstaclemap");
            
            endGame = false;
        }
        
        // method to simply load an image from a path
        public static BufferedImage loadImage(String ref)
        {
            BufferedImage bimg = null;
               
            try
            {
               bimg = ImageIO.read(new File(ref));
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
           
            return bimg;
        }
        
        // Run method for class
        public void run(DisplayMode dm)
         {     
            setBackground(Color.WHITE);
              s = new Screen();
            s.setFullScreen(dm, this);
            
            this.createBufferStrategy( 2 );
            buffer = this.getBufferStrategy();
    
            while (!endGame)
            {
                try
                {   
                    // edit player and level
                    myLevel.renderLevel();
                    myPlayer.animatePlayer();
                    myLevel.drawLevel(gr, 0, 0);
                    myPlayer.drawPlayer(gr, (SCREEN_WIDTH / 2) - TILE_SIZE / 2, (SCREEN_HEIGHT / 2) - TILE_SIZE);
                    
                    graphics = buffer.getDrawGraphics();
                    graphics.drawImage(buffer2, 0, 0, null);
                    
                    if( !buffer.contentsLost() )
                    {
                        buffer.show();
                    }
                }
                catch (Exception ex) 
                { 
                    System.err.println("Game Update Error: " + ex);
                }
                
                try
                {
                    Thread.sleep(10);
                }
                catch (Exception ex)
                {
                    System.out.println("Can't sleep!");
                }
            }
            
              s.restoreScreen();
         } 
        
        // method to handle inputs and adjust the player accordingly
        public void processKey(KeyEvent e)
        {
            int keyCode = e.getKeyCode();
            boolean moved = false;
            int xDisplace, yDisplace;
            
            // termination key
            if (keyCode == KeyEvent.VK_ESCAPE)
            {
                endGame = true;
            }
            
            // 0 - up
            // 1 - left
            // 2 - right
            // 3 - down
            // 4 - jump
            
            switch (keyCode)
            {
                case KeyEvent.VK_UP:
                    myPlayer.updatePlayer(0);
                    myLevel.updateLevel(0);
                    break;
                case KeyEvent.VK_LEFT:
                    myPlayer.updatePlayer(1);
                    myLevel.updateLevel(1);
                    break;
                case KeyEvent.VK_RIGHT:
                    myPlayer.updatePlayer(2);
                    myLevel.updateLevel(2);
                    break;
                case KeyEvent.VK_DOWN:
                    myPlayer.updatePlayer(3);
                    myLevel.updateLevel(3);
                    break;
                case KeyEvent.VK_SPACE:
                    myPlayer.updatePlayer(4);
                    myLevel.updateLevel(4);
                    break;
            }
        }
        
        // method to handle inputs and adjust the player accordingly
        public void processRelease(KeyEvent e)
        {
            int keyCode = e.getKeyCode();
            boolean moved = false;
            int xDisplace, yDisplace;
            
            // 0 - up
            // 5 - left
            // 6 - right
            // 3 - down
            // 4 - jump
            
            switch (keyCode)
            {
                case KeyEvent.VK_UP:
                    myPlayer.updatePlayer(0);
                    break;
                case KeyEvent.VK_LEFT:
                    myPlayer.updatePlayer(5);
                    break;
                case KeyEvent.VK_RIGHT:
                    myPlayer.updatePlayer(6);
                    break;
                case KeyEvent.VK_DOWN:
                    myPlayer.updatePlayer(3);
                    break;
                case KeyEvent.VK_SPACE:
                    myPlayer.updatePlayer(4);
                    break;
            }
        }
    }
    Colton
  • 7. Re: My Attempt at Active Rendering is Very Slow?
    EJP Guru
    Currently Being Moderated
    graphics = buffer.getDrawGraphics();
    Do you really need to do that every time around the loop?
  • 8. Re: My Attempt at Active Rendering is Very Slow?
    875749 Newbie
    Currently Being Moderated
    EJP,

    I tried incorporating that into run before the while loop to just call it once, but it ends up just displaying the very first render of the program and never updating after that.
  • 9. Re: My Attempt at Active Rendering is Very Slow?
    EJP Guru
    Currently Being Moderated
    Does all this run standalone?
  • 10. Re: My Attempt at Active Rendering is Very Slow?
    875749 Newbie
    Currently Being Moderated
    EJP,

    I'm sorry, but what do you mean?
  • 11. Re: My Attempt at Active Rendering is Very Slow?
    EJP Guru
    Currently Being Moderated
    I mean is there enough there for me to compile and execute?
  • 12. Re: My Attempt at Active Rendering is Very Slow?
    875749 Newbie
    Currently Being Moderated
    EJP,

    There isn't quite enough with the source code shown above for you to compile because it also requires a couple of image files. I'd be happy to put together a .zip with everything ready to compile and go, if that would be okay with you, sir? If so, would you prefer it sent to your bigpond email or elsewhere? Thank you very much.

    Colton

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points