Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (522)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (590)
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  
  Tiled map with camera following player  (Read 2084 times)
0 Members and 1 Guest are viewing this topic.
Offline KittyHopHop

Junior Newbie





« Posted 2012-09-13 11:44:47 »

Hello, i'm very new to java and have been programing for a few days, and, im a bit stuck..
I want to draw tiles in the background, and make the player move around and have the screen follow the player.
The tiles should be in a fixed XY as the player move around to increase its position XY..

I've searched the forum for examples but all links and downloads where outdated/not working and was from <2003..

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  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
234  
235  
236  
237  
238  
239  
240  
241  
242  
243  
244  
245  
246  
247  
248  
249  
250  
251  
252  
253  
import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.net.URL;

public class Game extends Applet implements Runnable, KeyListener
{
   Thread gameloop;
   BufferedImage backbuffer;
   Graphics2D g2d;
   AffineTransform identity = new AffineTransform();
   Player player = new Player();
   
   boolean leftPressed = false;
   boolean upPressed = false;
   boolean rightPressed = false;
   boolean downPressed = false;
   boolean spacePressed = false;
   
    int mapArray[][] = new int[MAP_WIDTH][MAP_HEIGHT];
    static final int MAP_WIDTH = 100;
    static final int MAP_HEIGHT = 100;
    static final int TILE_WIDTH = 32;
    static final int TILE_HEIGHT = 32;
    static final int GRASS_TILE = 0;
    static final int WALL_TILE = 1;
    int tileOffsetX = 0;
    int tileOffsetY = 0;
    int startTileX = 0;
    int startTileY = 0;
    int VIEW_LIMIT_X = 0;
    int VIEW_LIMIT_Y = 0;
    private Image tilesheet;
   
   public static void main(String[] args)
   {
      new Game().run();
   }
   
   public void init()
   {
      gameloop = new Thread(this);
      backbuffer = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
      g2d = backbuffer.createGraphics();
      setSize(800, 600);
     
      URL urlImage = getClass().getResource("img/tilesheet.png");
      tilesheet = Toolkit.getDefaultToolkit().getImage(urlImage);
     
        // Horizontal walls
        for(int i = 0; i < MAP_WIDTH; i++)
        {
            mapArray[i][0] = WALL_TILE;
            mapArray[i][MAP_HEIGHT-1] = WALL_TILE;
        }
       
      // Fill remaining tiles
      for(int i = 1; i < MAP_WIDTH - 1; i++)
        {
         for(int j = 1; j < MAP_HEIGHT - 1; j++)
         {
               mapArray[i][j] = GRASS_TILE;
            }
        }
     
      player.setX(800 / 2);
      player.setY(600 / 2);
     
      addKeyListener(this);
   }
   
   public void run()
   {  
      Thread thread = Thread.currentThread();
     
      while (thread == gameloop)
      {
         try
         {
            gameUpdate();
            Thread.sleep(1000 / 60);
         }
         catch(InterruptedException e)
         {
            e.printStackTrace();
         }
         
         repaint();
      }
   }

   public void update(Graphics g)
   {
      g2d.setTransform(identity);
        g.translate(-(int)player.getX() + 800 / 2, -(int)player.getY() + 600 / 2);
     
      g2d.setPaint(Color.DARK_GRAY);
      g2d.fillRect(0, 0, getSize().width, getSize().height);
       
        int srcX = 0;
        int tileX = 0;
        int tileY = 0;
       
     
        for(int x = tileOffsetX; x < VIEW_LIMIT_X; x += TILE_WIDTH)  
        {
            tileY = startTileY;
            for(int y = tileOffsetY; y < VIEW_LIMIT_Y; y += TILE_HEIGHT)
            {
                srcX = mapArray[tileX][tileY]*TILE_WIDTH;
               
                g2d.drawImage(tilesheet, x, y, x+TILE_WIDTH, y+TILE_HEIGHT, srcX, 0, srcX+TILE_WIDTH, TILE_HEIGHT, null);
                tileY++;
            }
            tileX++;
        }
       
       
      g2d.setFont(new Font("Arial", Font.PLAIN, 9));
      g2d.setColor(Color.WHITE);
      g2d.drawString("Player: " + Math.round(player.getX()) + "," + Math.round(player.getY()) , 10, 50);
       
      drawPlayer();
       
      paint(g);
   }
   
   private void gameUpdate()
   {
      if(leftPressed)
      {
         player.setX(player.getX() - 1);
      }
      if(rightPressed)
      {
         player.setX(player.getX() + 1);
      }
      if(upPressed)
      {
         player.setY(player.getY() - 1);
      }
      if(downPressed)
      {
         player.setY(player.getY() + 1);
      }
   }
   
   public void start()
   {
      gameloop.start();
   }

   public void paint(Graphics g)
   {
      g.drawImage(backbuffer, 0, 0, this);
   }
   
   public void drawPlayer()
   {
      g2d.setTransform(identity);
      g2d.translate(player.getX(), player.getY());
      g2d.rotate(Math.toRadians(player.getFaceAngle()));
      g2d.setColor(Color.RED);
      g2d.draw(player.getShape());
   }

   public void keyPressed(KeyEvent e)
   {
      int keyCode = e.getKeyCode();
      switch (keyCode)
      {
         case KeyEvent.VK_ESCAPE:
            stop();
            break;
         case KeyEvent.VK_LEFT:
            leftPressed = true;
            break;
         case KeyEvent.VK_RIGHT:
            rightPressed = true;
            break;
         case KeyEvent.VK_UP:
            upPressed = true;
            break;
         case KeyEvent.VK_DOWN:
            downPressed = true;
            break;
         case KeyEvent.VK_A:
            leftPressed = true;
            break;
         case KeyEvent.VK_D:
            rightPressed = true;
            break;
         case KeyEvent.VK_W:
            upPressed = true;
            break;
         case KeyEvent.VK_S:
            downPressed = true;
            break;
         case KeyEvent.VK_SPACE:
            spacePressed = true;
            break;
      }
      e.consume();
   }
   
   public void keyReleased(KeyEvent k)
   {
      switch(k.getKeyCode())
      {
         case KeyEvent.VK_LEFT:
            leftPressed = false;
            break;
         case KeyEvent.VK_UP:
            upPressed = false;
            break;
         case KeyEvent.VK_RIGHT:
            rightPressed = false;
            break;
         case KeyEvent.VK_DOWN:
            downPressed = false;
            break;
         case KeyEvent.VK_A:
            leftPressed = false;
            break;
         case KeyEvent.VK_W:
            upPressed = false;
            break;
         case KeyEvent.VK_D:
            rightPressed = false;
            break;
         case KeyEvent.VK_S:
            downPressed = false;
         break;
         case KeyEvent.VK_SPACE:
            spacePressed = false;
            break;
         default:
            break;
      }
   }
   
   public void keyTyped(KeyEvent e)
   {
   }
}
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #1 - Posted 2012-09-13 12:23:49 »

It is generally better to do it the other way around. So the map moves, and the player is static in the middle.
So what you do is draw the player at the exact middle of the screen, and use playerPosition and middleOfScreenPoint to translate the rendering of the tiles.

- Jonas
Offline jonjava
« Reply #2 - Posted 2012-09-13 12:27:28 »

It is generally better to do it the other way around. So the map moves, and the player is static in the middle.
So what you do is draw the player at the exact middle of the screen, and use playerPosition and middleOfScreenPoint to translate the rendering of the tiles.

I prefer moving the player around.

But no matter which way you do it, you're going to have to move the whole game world around to accommodate the "physical" screen. The monitor can't move, so the game has to shift the world ever which way to look like its moving.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline KittyHopHop

Junior Newbie





« Reply #3 - Posted 2012-09-14 12:10:57 »

I dont want to move the world around, anyhows here's another problem.
The screen follow my ship but doesnt draw anything outside the screen box or something.
Also the score and other texts doesnt follow the screen, its printed at a fixed position.. Any help or fix?



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  
   public void update(Graphics g)
   {
      //start off transforms at identity
      g2d.setTransform(identity);
     
      //erase the background
      g2d.setPaint(Color.BLACK);
      g2d.fillRect(0, 0, getSize().width, getSize().height);
     

      g.translate(-(int)ship.getX() + ScreenWidth / 2, -(int)ship.getY() + ScreenHeight / 2);
      // Set Background IMG
      g2d.drawImage(bg, 0, 0, null);
     
     
      // Calc FPS
      long currentTime = System.currentTimeMillis();
      if (currentTime > nextSecond)
      {
         nextSecond += 1000;
         frameInLastSecond = framesInCurrentSecond;
         framesInCurrentSecond = 0;
      }
      framesInCurrentSecond++;
       
      // FPS
      g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
      g2d.setColor(Color.WHITE);
      g2d.setFont(new Font("Arial", Font.PLAIN, 20));
      g2d.drawString(frameInLastSecond + " fps", 10, 30);
      g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
       
      //print some status information
      g2d.setFont(new Font("Arial", Font.PLAIN, 9));
      g2d.setColor(Color.LIGHT_GRAY);
      g2d.drawString("Ship: " + Math.round(ship.getX()) + "," + Math.round(ship.getY()) , 10, 60);
      g2d.drawString("Move angle: " + Math.round(ship.getMoveAngle())+90, 10, 70);
      g2d.drawString("Face angle: " + Math.round(ship.getFaceAngle()), 10, 80);
      g2d.drawString("Ship VelX: " + Math.round(ship.getVelX()), 10, 90);
      g2d.drawString("Ship VelY: " + Math.round(ship.getVelY()), 10, 100);
      g2d.drawString("Version: " + GameVersion, 10, 110);
      g2d.drawString("Asteroids: " + AsteroidsAlive, 10, 120);
     
      // Print Score
      g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
      g2d.setColor(Color.WHITE);
      g2d.setFont(new Font("Arial", Font.PLAIN, 20));
      g2d.drawString("Score: " + Score, 360, 30);
     
      // Draw the game graphics
      drawShip();
      drawBullets();
      drawAsteroids();
     
      // Repaint the applet window
      paint(g);
     
   }
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #4 - Posted 2012-09-14 15:52:24 »

You have to render things with different translation-points.
Now that it seems like you can move around (?), you will want your HUD (head-up-display with score and health and such) to always be rendered in the same place.

I've changed a few things in your code here, and added a bunch of comments to tell you what is happening.

Pastebin Link

Extra things:
An update-method shouldn't do drawing, it should do game-logic. Although it seems you have no game-logic in this update-method, it is a rather confusing name for a method that draws everything.
The normal game-loop setup looks like this:

registerControls(); // Logs which keys are pressed, for use in the update-method. Some people do this in their update-method, and some do it separately.

update(long deltaTime); // updates everything according to the time passed since the last frame finished. This makes sure your game runs at a steady pace, and doesn't go slower when the computer lags and skips some frames. This means that even if your computer slows to 5 fps for 1 second, it'll still move things the same amount of pixels as if it was running 60fps, because the updates are now relative to time, and not to how many times you've looped through this game-loop.

draw(Graphics2D g); // draws everything, and does not under any circumstance have any logic-calculations. Only things that have to do with graphics.

Then some sort of sleep-function to keep the framerate steady.

Repeat


This is a very simple demonstration-setup, and I really recommend you read up on game-loops, as they are crucial to how your game runs. Also, if you're not overriding the paint-method, you should probably look into that.

- Jonas
Offline jonjava
« Reply #5 - Posted 2012-09-16 21:40:37 »

I dont want to move the world around

Well unless you want the character to walk outside of the field of view, you're going to have to.

Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #6 - Posted 2012-09-17 02:45:02 »

I do move my character, but then I translate my world to follow his position. That's one way to do it.

- Jonas
Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 138
Projects: 4
Exp: 3 years



« Reply #7 - Posted 2012-09-17 04:07:02 »

Still essentially "moving"
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.

trollwarrior1 (29 views)
2014-11-22 12:13:56

xFryIx (71 views)
2014-11-13 12:34:49

digdugdiggy (50 views)
2014-11-12 21:11:50

digdugdiggy (44 views)
2014-11-12 21:10:15

digdugdiggy (38 views)
2014-11-12 21:09:33

kovacsa (62 views)
2014-11-07 19:57:14

TehJavaDev (67 views)
2014-11-03 22:04:50

BurntPizza (64 views)
2014-11-03 18:54:52

moogie (80 views)
2014-11-03 06:22:04

CopyableCougar4 (80 views)
2014-11-01 23:36:41
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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!