Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (536)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  I can't quite figure out how to render my entities and map...  (Read 853 times)
0 Members and 1 Guest are viewing this topic.
Offline tyeeeee1
« Posted 2013-10-29 22:13:56 »

Hey,

I've been having a bit of trouble figuring out how to use a camera to move around my map and render the player and other entities onto the map with working zooming.

If someone has some tips, suggestions, or sees a way to do this properly with my current code that would be appreciated.

Rendering the map:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
package valkryst.area.map;

import java.awt.Graphics;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import valkryst.area.Area;
import valkryst.area.map.tile.GrassTile;
import valkryst.area.map.tile.VoidTile;
import valkryst.core.Camera;

/**
 * This class adds the map to the pixel array that will be rendered onto the screen.
 *
 * @author Valkryst
 * --- Last Edit 24-Oct-2013
 */

public class RenderMap {
   public static String[] map;
   private static int currentMapID = -1;
   
   private static VoidTile voidTile = new VoidTile();
   private static GrassTile grassTile = new GrassTile();
   
   /**
    * Renders the map to the canvas.
    * @param g The graphics object to use to render things to the canvas with.
    * @param area The area that the player is currently in.
    * @param p The player.
    * @param width The width of the canvas.
    * @param height The height of the canvas.
    */

   public void render(final Graphics g, final Area area, final Camera c, final int width, final int height, final int scaleMultiplier) {
      int areaID = area.getMapID();
      if(areaID != currentMapID || currentMapID == -1) {
         loadMapFromFile(areaID);
         currentMapID = areaID;
      }
     
      int xOffset = c.getOriginX() >> 5; // The x-axis tile coordinate of where the cameras origin is currently.
     int yOffset = c.getOriginY() >> 5; // The y-axis tile coordinate of where the cameras origin is currently.
     int numberOfXTiles = (width >> 5); // Takes whatever the width of the canvas is, divides it by 32 and then that's then number of XTiles to draw.
     int numberOfYTiles = (height >> 5); // Takes whatever the height of the canvas is, divides it by 32 and then that's then number of YTiles to draw.
     
      if(width > 0 && height > 0) { // If there is no room on the screen to render the map then don't bother rendering it.
        for(int y = 0 + yOffset; y < yOffset + numberOfYTiles + 2; y++) {
            for(int x = 0 + xOffset; x < xOffset + numberOfXTiles + 2; x++) {
               try {
                  switch(map[y].charAt(x)) {
                     case 'A': {
                        g.drawImage(grassTile.getTileImage(), (x - xOffset) * scaleMultiplier, (y - yOffset) * scaleMultiplier, scaleMultiplier, scaleMultiplier, null);
                        break;
                     }
                     default: {
                        g.drawImage(voidTile.getTileImage(), (x - xOffset) * scaleMultiplier, (y - yOffset) * scaleMultiplier, scaleMultiplier, scaleMultiplier, null);
                     }
                  }
               } catch(Exception e) {
                  continue;
               }
            }
         }
      }
   }
   
   public void loadMapFromFile(final int mapID) {
      List<String> loadedMap = new ArrayList<String>();
     
      InputStream is = this.getClass().getClassLoader().getResourceAsStream("Areas/Area" + mapID + ".txt");
      try {
         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
           String line = null;
           while ((line = bufferedReader.readLine()) != null) {
               loadedMap.add(line);
           }
           bufferedReader.close();
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
     
      map = loadedMap.toArray(new String[loadedMap.size()]);
      System.out.println("Sucessfully finished loading Areas/Area" + mapID + ".txt");
   }
}


The Camera:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
package valkryst.core;

import valkryst.area.Area;
import valkryst.core.graphics.Frame;

public class Camera {
   private int mapSizeInPixels;
   /** The origin for the are that the camera is currently viewing. */
   private int originX = 0, originY = 0;
   /** The start and end bounds of the map. */
   private int start = 0, end;
   
   public Camera(final Area currentAreaIn) {
      mapSizeInPixels = currentAreaIn.getMapSize() * (32 * Frame.scale);
      end = mapSizeInPixels;
   }
   
   /**
    * Moves the camera's origin.
    * @param x The value to add to the originX variable.
    * @param y The value to add to the originY variable.
    */

   public void moveOrigin(int x, int y) {
      originX += x;
      originY += y;
     
      checkBounds();
   }
   
   public void checkBounds() {
      // Checks if the originX is below 0, if it is then set it to 0.
     if(originX < start) {
         originX = start;
      }
     
      // Checks if the originY is below 0, if it is then set it to 0.
     if(originY < start) {
         originY = start;
      }
   }
   
   /**
    * Sets the bounds of the map.
    * @param currentArea The area to create bounds for.
    */

   public void changeBounds(final Area currentAreaIn) {
      mapSizeInPixels = currentAreaIn.getMapSize() * (32 * Frame.scale);
      end = mapSizeInPixels;
   }
   
   ///////////////////////////////////////// Get methods here: ////////////////////////////////////////////////////
 
    /**
     * Returns the originX variable of the camera.
     * @return Returns the originX variable of the camera.
     */

   public int getOriginX() {
      return originX;
   }
   
   /**
     * Returns the originY variable of the camera.
     * @return Returns the originY variable of the camera.
     */

   public int getOriginY() {
      return originY;
   }
}


The Player:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
package valkryst.entity;

import java.awt.Graphics;
import java.awt.event.KeyEvent;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import valkryst.area.Area;
import valkryst.core.Camera;
import valkryst.core.graphics.Frame;
import valkryst.enums.BattleDecision;
import valkryst.enums.CombatType;

/**
 * This class defines a player object.
 *
 * @author Valkryst
 * --- Last Edit 24-Oct-2013
 */

public class Player extends Entity {
    private BattleDecision battleDecision = null;
   
    /**
     * The constructor for the player object.
     * @param nameIn The name of the player being constructed.
     * @param playerLevelIn The level of the player being constructed.
     * @param playerMaxLevelIn The maximum level of the player being constructed.
     * @param combatTypeIn The combat type of the player being constructed.
     */

    public Player(final String nameIn, final int playerLevelIn, final int playerMaxLevelIn, final CombatType combatTypeIn) {
      setName(nameIn);
      setUsesArmor(true);
      setUsesWeapon(true);
      setLevel(playerLevelIn);
      setMaxLevel(playerMaxLevelIn);
      setExperience(0);
      double health = (playerLevelIn * 25.0);
      setHealth(health);
      setMaxHealth(health);
   
     
      switch (combatTypeIn) {
           case MELEE:
               setEnergy(100.0);
               setMaxEnergy(100.0);
               setUsesEnergy(true);
               break;
           case RANGED:
               setEnergy(100.0);
               setMaxEnergy(100.0);
               setUsesEnergy(true);
               break;
           case CASTER:
               setMana(100.0);
               setMaxMana(100.0);
               setUsesMana(true);
               break;
           default: {
              final Logger LOGGER = LoggerFactory.getLogger(Player.class);
              LOGGER.info("Unsupported type of CombatType: " + combatTypeIn);
           }
      }
     
      setBaseDamage(3.5 * getLevel());
      setArmorPoints(0.0);
      setup(true);
    }

    /**
     * Updates the player in preparation to be rendered.
     */

    public void updateLogic(final Area currentArea, final Camera camera) {
       // Checks whether the player entity is visible on the screen or not.
      if(xCoord + sprite.getSpriteImage(0).getWidth(null) < camera.getOriginX() && yCoord + sprite.getSpriteImage(0).getHeight(null) < camera.getOriginY()) {
          isVisible = false;
       } else if (!isVisible){
          isVisible = true;
       }
       
       // Moves + or - one pixel and + or - 1/32 of a tile for every pixel moved.
      if(Frame.KEYBOARD_INPUT.isKeyPressed(KeyEvent.VK_UP)) {
         move(0, -1, 0, -0.03125);
         camera.moveOrigin(0, -1);
      }
      if(Frame.KEYBOARD_INPUT.isKeyPressed(KeyEvent.VK_DOWN)) {
         move(0, 1, 0, 0.03125);
         camera.moveOrigin(0, 1);
      }
      if(Frame.KEYBOARD_INPUT.isKeyPressed(KeyEvent.VK_LEFT)) {
         move(-1, 0, -0.03125, 0);
         camera.moveOrigin(-1, 0);
      }
      if(Frame.KEYBOARD_INPUT.isKeyPressed(KeyEvent.VK_RIGHT)) {
         move(1, 0, 0.03125, 0);
         camera.moveOrigin(1, 0);
      }
     
      // Checks if the player entity is off of bounds and if it is then move it back onto the map.
     if(xCoord < 0 || tileX < 0) {
         xCoord = 0;
         tileX = 0;
      }
     
      if(yCoord < 0 || tileY < 0) {
         yCoord = 0;
         tileY = 0;
      }
     
      int mapSize = currentArea.getMapSize();
      int scale = (32 * Frame.scale);
      int mapSizeInPixels = (mapSize * scale);
     
      if(xCoord > mapSizeInPixels || tileX > mapSize) {
         System.out.println("Test1");
         xCoord = mapSizeInPixels;
         tileX = mapSize-1;
      }
     
      if(yCoord > mapSizeInPixels || tileY > mapSize) {
         System.out.println("Test2");
         yCoord = mapSizeInPixels;
         tileY = mapSize - 1;
      }
    }
   
    /**
     * Renders the player to the screen.
     */

    public void render(final Graphics g, final int scaleMultiplier) {
       if(isVisible) {
          g.drawImage(getSprite().getSpriteImage(0), xCoord, yCoord, scaleMultiplier, scaleMultiplier , null);
       }
    }
   
    ///////////////////////////////////////// Get methods here: ////////////////////////////////////////////////////
   public BattleDecision getBattleDecision() {
       return battleDecision;
    }

    ///////////////////////////////////////// Set methods here: ////////////////////////////////////////////////////
   public void setMyBattleDecision(final BattleDecision b) {
       battleDecision = b;
    }
}


The Creature:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
package valkryst.entity;

import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import valkryst.enums.CombatType;
import valkryst.systems.Drops;
import valkryst.systems.battle.AITactics;

/**
 * This class defines a creature object.
 *
 * @author Valkryst
 * --- Last Edit 24-Oct-2013
 */

public class Creature extends Entity {
   public final AITactics TACTICS = new AITactics();
   /** The id of the creature. */
   final int CREATURE_ID;
   /** The drop table of the creature. */
   private Drops drops;
   /** Whether the creature has been looted or not. If the creature has been looted then it can be removed from the area it's on. */
   private boolean hasBeenLooted = false;

   /**
    * The constructor method for the Creature object.
    * @param creatureIdIn The ID of the creature being created.
    * @param nameIn The name of the creature being created.
    * @param creatureLevelIn The level of the creature being created.
    * @param creatureMaxLevelIn The maximum level of the creature being created.
    * @param combatTypeIn The combat type of the creature being created.
    */

    public Creature(final int creatureIdIn, final String nameIn, final int creatureLevelIn, final int creatureMaxLevelIn, final CombatType combatTypeIn) {
       CREATURE_ID = creatureIdIn; // Set the creature's ID.
       setName(nameIn);// Set the creature's name.

        int level = -1;
        while(level <= 0) { // Prevents the creature's level from being 0 or below.
          // Generates a random integer that is within playerLevel-3 and playerLevel+3.
          level = (creatureLevelIn - 3) + (int) (Math.random() * (((creatureLevelIn + 3) - (creatureLevelIn - 3)) + 1));
        }
        setLevel(level);
        setMaxLevel(creatureMaxLevelIn);
        setExperience(0);

        // Figure out the creature's health.
       final Random RANDOM = new Random();
        double health = 0;
        while(health <= 0 || health == -1) {
           health = (level * 25.0) + RANDOM.nextInt((level * 10) + 1);
        }
        setHealth(health);
        setMaxHealth(health);
       
        // Figure out the creature's aggressiveness. REWORK LATER ON
       if(level >= creatureLevelIn) {
           setAggressiveness(Math.random() + (level - creatureLevelIn)/100); // Tested multiple times and has never gone to 1.0 or above. Do extensive testing if it ever does tho.
       } else if(getAggressiveness() == -1) {
           setAggressiveness(Math.random());
        }
       
        // Set the creature's energy/mana depending on it's combatType.
       switch (combatTypeIn) {
            case MELEE: {
                setEnergy(100.0);
                setMaxEnergy(100.0);
                setUsesEnergy(true);
                break;
            }
            case RANGED: {
                setEnergy(100.0);
                setMaxEnergy(100.0);
                setUsesEnergy(true);
                break;
            }
            case CASTER: {
                setMana(100.0);
                setMaxMana(100.0);
                setUsesMana(true);
                break;
            }
            default: {
              final Logger LOGGER = LoggerFactory.getLogger(Creature.class);
              LOGGER.info("Unsupported type of CombatType: " + combatTypeIn);
           }
        }

        setBaseDamage(2.5 * level); // Set the creature's base damage.
       setArmorPoints(0.0); // Set the armor points of the creature.
       setup(false);
    }
   
    public void createDropTable(final int[] dropTable, final double[] dropChance) {
       drops.createDropTable(dropTable, dropChance);
    }

    /**
     * Updates the creature in preparation to be rendered.
     */

    public void updateLogic() {
    }
   
    /**
     * Renders the player to the screen.
     */

    public void render() {
       
    }
   
    ///////////////////////////////////////// Set methods here: ////////////////////////////////////////////////////
   
    /**
     * Sets whether the creature has been looted or not.
     * @param b The variable to set the hasBeenLooted variable to.
     */

    public void setHasBeenLooted(boolean b) {
       hasBeenLooted = b;
    }
   
    ///////////////////////////////////////// Get methods here: ////////////////////////////////////////////////////
   
    /**
     * Returns the drop variable of the creature.
     * @return Returns the drop variable of the creature.
     */

    public Drops getDrops() {
       return drops;
    }
   
    /**
     * Returns whether the creature has been looted or not.
     * @return Returns whether the creature has been looted or not.
     */

    public boolean getHasBeenLooted() {
       return hasBeenLooted;
    }
}


The Game Loop:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
package valkryst.core.graphics;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;

import javax.swing.SwingUtilities;

import valkryst.area.Area;
import valkryst.area.map.RenderMap;
import valkryst.core.Camera;
import valkryst.entity.Player;
import valkryst.enums.CombatType;
import valkryst.spell.Cast;


/**
 * @author Valkryst
 * --- Last Edit 24-Oct-2013
 */

public class Screen extends Canvas implements Runnable{
   private static final long serialVersionUID = 4532836895892068039L;
   
   private Thread gameThread;
   private boolean isGameRunning = false;
   
   private int WIDTH = Frame.WIDTH, HEIGHT = Frame.HEIGHT, SCALE = Frame.scale;
   
   private BufferStrategy BS = getBufferStrategy();
   private Area currentArea = new Area(0, 10, "TestArea"); // area shouldn't be created here.
  int lastFrameScale = 0, scaleMultiplier = (32 * Frame.scale);
   
   
   private RenderMap renderMap = new RenderMap();
   private Camera camera;
   
   public Screen() {  
      setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
      setFocusable(true);
      setVisible(true);
   }

   public void run() {
      long lastLoopTime = System.nanoTime();
       final int TARGET_FPS = 60;
      final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;  
      double delta = 0;
     
      // Keep looping until the game ends.
     while (isGameRunning) {
         long now = System.nanoTime();
         long updateLength = now - lastLoopTime;
         lastLoopTime = now;
          delta += updateLength / ((double)OPTIMAL_TIME); // Work out how long its been since the last update. This will be used to calculate how far the entities should move this loop.
         
          //Update the game's logic and then render the screen.
         while(delta >= 1) {
             updateLogic(delta);
             delta--;
          }
         
          render();
           
          // we want each frame to take 10 milliseconds, to do this
         // we've recorded when we started the frame. We add 10 milliseconds
         // to this and then factor in the current time to give
         // us our final value to wait for
         // remember this is in ms, whereas our lastLoopTime etc. vars are in ns.
         try {
             long tempLong = (lastLoopTime-System.nanoTime() + OPTIMAL_TIME)/1000000;
             if(tempLong <= 0) { continue; } // Skips the sleep()
           Thread.sleep(tempLong);
         } catch (InterruptedException e) {
            continue;
         }
      }
      stop();
   }
   
   public synchronized void start() {
      // TEMPORARY
     currentArea.addPlayerToArea(new Player("Test", 1, (short)60, CombatType.CASTER));
      // END OF TEMPORARY
     
      camera = new Camera(currentArea);
     
      setBackground(Color.black);
      isGameRunning = true;
      gameThread = new Thread(this, "Display");
      gameThread.start();
   }

   public synchronized void stop() {
      try {
         gameThread.join();
      } catch(InterruptedException e) {
         e.printStackTrace();
      }
   }

   // When called this updates all of the game's logic.
  public void updateLogic(double delta) {
      Cast.setCurrentTime();
      currentArea.pruneCreatures(); // Removes all creatures that have been looted from the area.
     currentArea.updateLogic(camera);
   }

   // When called this updates the screen.
  public void render() {
      // If Frame.scale has changed then re-size all tile images.
     if(Frame.scale != lastFrameScale) {
         scaleMultiplier = (32 * Frame.scale);
      }
      lastFrameScale = Frame.scale;
           
      // Forces the canvas to use triple buffering.
     BS = getBufferStrategy();
        if (BS == null) {
           SwingUtilities.invokeLater(new Runnable() {
               public void run() {
                   createBufferStrategy(3);
               }
           });
           return;
        }
     
        // Creates the graphics object and then clears the screen.
       Graphics g = BS.getDrawGraphics();
        g.clearRect(0, 0, getWidth(), getHeight());
        renderMap.render(g, currentArea, camera, getWidth(), getHeight(), scaleMultiplier);
      currentArea.render(g, scaleMultiplier);
        g.dispose();
      BS.show();
   }
}


Thanks for any replies!
Offline opiop65

JGO Kernel


Medals: 153
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #1 - Posted 2013-10-29 22:25:35 »

Well, in Java2D I would recommend creating a rectangle that is the same size of the viewport, and every time the camera position changes, check through all the tiles and see if they are intersecting rectangle, if they are, render them.

Offline tyeeeee1
« Reply #2 - Posted 2013-10-29 22:46:22 »

Well, in Java2D I would recommend creating a rectangle that is the same size of the viewport, and every time the camera position changes, check through all the tiles and see if they are intersecting rectangle, if they are, render them.

Wouldn't that require me to create rectangles for every single tile and test for intersection every time?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online Jimmt
« League of Dukes »

JGO Kernel


Medals: 128
Projects: 4
Exp: 3 years



« Reply #3 - Posted 2013-10-29 23:58:14 »

http://gamedev.stackexchange.com/questions/16858/rendering-only-what-is-on-the-screen
Google, please.
Offline tyeeeee1
« Reply #4 - Posted 2013-10-30 00:04:00 »


I've already googled it. If you look at my code it works.

What I can't do is render the map using the camera and then have the outside of the map and then somehow render onto the map when they're in view.
Offline ricardo

Senior Member


Medals: 2
Projects: 3



« Reply #5 - Posted 2013-10-30 00:35:16 »

You need to calculate the left-top corner of the screen and add width and height:
1  
Camera = [left_top_x, left_top_y, left_top_x + width, left_top_y + height];


Draw only tiles on screen:
i dont know how you have your map, but if it is something like this:
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0

you can loop each tile and calculate x and y position. if position is on screen you can draw.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
int y = 0;
for (int line : map) {
    int x = 0;
    for (int tile : line) {
        if (x >= camera[0] && y >= camera[1] && x <= camera[2] && y <= camera[3] {
            g.draw(tiles[tile], x, y, zoom_x, zoom_y, null);
            x += tiles_size_width;
        }
    }
    y += tiles_size_height;


Use the same method with player, enemies, objects etc.
Calculate first your "camera" position (i calculate mine with left-top corner and add width and height) and check if everything is on screen to draw.
To use zoom, g.draw(image, x , y, ZOOM x, ZOOM y, null).
I don't see much difference with performance scaling this before draw. Just do it for everything you need to draw.

This is pseudo-code. Sorry for my english.
If you need more help show me your map file.
Offline tyeeeee1
« Reply #6 - Posted 2013-10-30 14:54:39 »

This is what my map file looks like:

AAAAAAAAAA
AAAAAAAAAA
AAAAAAAAAA
AAAAAAAAAA
AAAAAAAAAA
AAAAAAAAAA
AAAAAAAAAA
AAAAAAAAAA
AAAAAAAAAA
AAAAAAAAAA

It must always have the same width and height, I'll probably change that limitation eventually.

I've managed to figure out your example, mostly. I'm not sure how the for loops you wrote so I changed them to what I thought would work but the rest was fairly easy to integrate with my camera. The code I currently have is:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
int mapSize = area.getMapSize(); // Size of map, in tiles.

      int y = 0;
      for (int i = 0; i < mapSize;i++) {
          int x = 0;
          for (int j = 0; j < mapSize;j++) {
              if (x >= c.getOriginX() && y >= c.getOriginY() && x <= c.getEndX() && y <= c.getEndY()) {
                 switch(map[y].charAt(x)) {
                  case 'A': {
                     g.drawImage(grassTile.getTileImage(), x, y, scale, scale, null);
                     break;
                  }
                  default: {
                     g.drawImage(voidTile.getTileImage(), x, y, scale, scale, null);
                  }
                 
                     x += (scale * 32);
                 }
              }
              y += (scale * 32);
          }
      }


This doesn't currently display anything to the screen. It's just black.


For the camera I'm doing:
1  
2  
3  
4  
5  
6  
7  
8  
9  
/** The origin for the are that the camera is currently viewing. */
   private int originX = 0, originY = 0;
   /** The start and end bounds of the map. */
   private int endX = 0, endY = 0;
   
   public Camera(final int widthIn, final int heightIn) { // Width and Height of the canvas.
     endX = originX + widthIn;
      endY = originY + heightIn;
   }
Offline ricardo

Senior Member


Medals: 2
Projects: 3



« Reply #7 - Posted 2013-10-30 15:52:18 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
String[] list = new String[] {A,A,A,A,A};

for (String s : list) System.out.println(s);

for (int i = 0; i < list.size(); i++) System.out.println(list.get(i));

/*
console output:
     A
     A
     A
     A
     A
*/


They have the same output. The first loop is just more readable (for me) and use less lines of code.
s parse your list and temporary store each value (in this case, A).


"This doesn't currently display anything to the screen. It's just black."
Make sure your x and y are in camera range. I will check your code (first post) soon and give some feedback.
Offline tyeeeee1
« Reply #8 - Posted 2013-10-30 16:33:02 »

Ah, the for loop makes more sense now, but I don't see how it'll work with a one dimensional array. My map is in a String[] array.

I've managed to get the map to display properly, but when I move the camera it disappears.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
int y = 0;
      for (int i = 0; i < mapSize;i++) {
          int x = 0;
          for (int j = 0; j < mapSize;j++) {
              if (x >= c.getOriginX() && y >= c.getOriginY() && x <= c.getEndX() && y <= c.getEndY()) {
                 try {
                  switch(map[i].charAt(j)) {
                     case 'A': {
                        g.drawImage(grassTile.getTileImage(), x, y, scale, scale, null);
                        break;
                     }
                     default: {
                        g.drawImage(voidTile.getTileImage(), x, y, scale, scale, null);
                     }
                  }
               } catch(Exception e) {
                  continue;
               }
                  x += 32;
              }
          }
          y += 32;
      }



Edit:
There may be a bug in one of my other classes causing this issue, I'm looking into it now.

Edit 2:
The bug is mostly fixed. The map works if you only move along the Y-axis, but if you move along the X-axis the map will disappear after you move one tile to the right.

The current camera code is:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
package valkryst.core;

/**
 * This class defines a Camera object.
 *
 * @author Valkryst
 * --- Last Edit 30-Oct-2013
 */

public class Camera {
   /** The map size in pixels. */
   private int mapSizeInPixels = -1;
   private int widthOfScreen = -1, heightOfScreen = -1;
   /** The origin for the are that the camera is currently viewing. */
   private int originX = 0, originY = 0;
   /** The start and end bounds of the map. */
   private int endX = 0, endY = 0;
   
   public Camera(final int widthIn, final int heightIn, final int mapSizeInPixelsIn, final int widthOfScreenIn, final int heightOfScreenIn) { // Width and height of canvas
     mapSizeInPixels = mapSizeInPixelsIn;
      endX = originX + widthIn;
      endY = originY + heightIn;
      widthOfScreen = widthOfScreenIn;
      heightOfScreen = heightOfScreenIn;
   }
   
   /**
    * Moves the camera's origin.
    * @param x The value to add to the originX variable.
    * @param y The value to add to the originY variable.
    */

   public void moveOrigin(int x, int y) {
      originX += x;
      originY += y;
     
      checkBounds();
      System.out.println(originX + " " + originY);
   }
   
   public void checkBounds() {
      // Checks if the originX is below 0, if it is then set it to 0.
     if(originX < 0) {
         originX = 0;
      }
     
      // Checks if the originY is below 0, if it is then set it to 0.
     if(originY < mapSizeInPixels) {
         originY = 0;
      }
           
      // Checks if the originX is nearing the end of the screen on the x-axis, if it is then set it to the map size in pixels minus the screen width.
     if(originX > ((originX + widthOfScreen) - mapSizeInPixels)) {
         originX = mapSizeInPixels - widthOfScreen;
      }
     
      // Checks if the originY is nearing the end of the screen on the y-axis, if it is then set it to the map size in pixels minus the screen height.
     if(originY > ((originY + heightOfScreen) - mapSizeInPixels)) {
         originY = mapSizeInPixels - heightOfScreen;
      }
   }
   
   public void updateCamera(final int widthIn, final int heightIn, final int mapSizeInPixelsIn, final int widthOfScreenIn, final int heightOfScreenIn) {
      mapSizeInPixels = mapSizeInPixelsIn;
      endX = originX + widthIn;
      endY = originY + heightIn;
      widthOfScreen = widthOfScreenIn;
      heightOfScreen = heightOfScreenIn;
   }
   
   ///////////////////////////////////////// Get methods here: ////////////////////////////////////////////////////
 
    /**
     * Returns the originX variable of the camera.
     * @return Returns the originX variable of the camera.
     */

   public int getOriginX() {
      return originX;
   }
   
   /**
     * Returns the originY variable of the camera.
     * @return Returns the originY variable of the camera.
     */

   public int getOriginY() {
      return originY;
   }
   
   /**
     * Returns the endX variable of the camera.
     * @return Returns the endX variable of the camera.
     */

   public int getEndX() {
      return endX;
   }
   
   /**
     * Returns the endY variable of the camera.
     * @return Returns the endY variable of the camera.
     */

   public int getEndY() {
      return endY;
   }
}


The current rendering code is:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
int mapSize = area.getMapSize(); // Size of map, in tiles.

      int y = 0;
      for (int i = 0; i < mapSize;i++) {
          int x = 0;
          for (int j = 0; j < mapSize;j++) {
              if (x >= c.getOriginX() && y >= c.getOriginY() && x <= c.getEndX() && y <= c.getEndY()) {
                 try {
                  switch(map[i].charAt(j)) {
                     case 'A': {
                        g.drawImage(grassTile.getTileImage(), x, y, scale, scale, null);
                        break;
                     }
                     default: {
                        g.drawImage(voidTile.getTileImage(), x, y, scale, scale, null);
                     }
                  }
               } catch(Exception e) {
                  continue;
               }
                  x += 32;
              }
          }
          y += 32;
      }
Offline ricardo

Senior Member


Medals: 2
Projects: 3



« Reply #9 - Posted 2013-10-30 20:56:28 »

I think the map disappears because this conditions is false:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
if (x >= c.getOriginX() && y >= c.getOriginY() && x <= c.getEndX() && y <= c.getEndY()) {
                 try {
                  switch(map[i].charAt(j)) {
                     case 'A': {
                        g.drawImage(grassTile.getTileImage(), x, y, scale, scale, null);
                        break;
                     }
                     default: {
                        g.drawImage(voidTile.getTileImage(), x, y, scale, scale, null);
                     }
                  }
               } catch(Exception e) {
                  continue;
               }
                  x += 32;
              }


Add this in the second line and give me feedback:
1  
2  
3  
4  
if (x >= c.getOriginX() && y >= c.getOriginY() && x <= c.getEndX() && y <= c.getEndY()) {
System.out.println("CONDITION IS TRUE");

(...)


After you move right, it should not print CONDITION IS TRUE.

Also, in the last lines, try to switch down x += 32:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
               } catch(Exception e) {
                  continue;
               }
                 // NOT HERE
             }

               // HERE
              x += 32;

          }
          y += 32;
     
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline tyeeeee1
« Reply #10 - Posted 2013-10-30 22:52:20 »

It always returns true.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
int mapSize = area.getMapSize(); // Size of map, in tiles.

      int y = 0;
      for (int i = 0; i < mapSize;i++) {
          int x = 0;
          for (int j = 0; j < mapSize;j++) {
              if (x >= c.getOriginX() && y >= c.getOriginY() && x <= c.getEndX() && y <= c.getEndY()) {
                 System.out.println("true");
                 try {
                  switch(map[i].charAt(j)) {
                     case 'A': {
                        g.drawImage(grassTile.getTileImage(), x, y, scale, scale, null);
                        break;
                     }
                     default: {
                        g.drawImage(voidTile.getTileImage(), x, y, scale, scale, null);
                     }
                  }
               } catch(Exception e) {
                  continue;
               }
              }
              x += 32;
          }
          y += 32;
      }


The map now works, but whenever the player moves onto a new tile, the row or column (depends if the player moves up, down, left, or right) behind the player disappears.
Offline Longarmx
« Reply #11 - Posted 2013-10-31 05:03:25 »

Are you changing your origin by too much so that it is clear off to the right or something?

Offline tyeeeee1
« Reply #12 - Posted 2013-10-31 15:48:41 »

Are you changing your origin by too much so that it is clear off to the right or something?

The origin changes by -1 or +1. From the printouts it's working as intended, so I don't see that causing anything.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Riven (15 views)
2014-07-29 18:09:19

Riven (10 views)
2014-07-29 18:08:52

Dwinin (10 views)
2014-07-29 10:59:34

E.R. Fleming (28 views)
2014-07-29 03:07:13

E.R. Fleming (10 views)
2014-07-29 03:06:25

pw (40 views)
2014-07-24 01:59:36

Riven (39 views)
2014-07-23 21:16:32

Riven (27 views)
2014-07-23 21:07:15

Riven (29 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!