Search code examples
javaawtjava-2dcoordinate-systemsrectangles

Java game, Rectangle for the background is moving


I hope that the title has not made this post more confusing than it already is. The problem I am having may be better explained if I tell you exactly what I have done so far:

The Game

I have made a very simple 2D game, the basics are, a player moves around a 2D map with keyboard input (up, down, left. right arrows) this game is kind of like a pokemon view where the view is from the top, his speed is set simply by using the following code for each keyboard input:

 if(input.isKeyDown(Input.KEY_DOWN)){
    bucky = movingDown;
    buckyPositionY -= 2;
    if(buckyPositionY<-550){//this is used to stop player from leaving the map
        buckyPositionY += 2;}}

The same is done for the other 3 keyboard inputs.

The Problem

I have made the game where the player can move around but the problem is I have objects on the map and at the moment my player just walks through them, so I need to set up collisions, I know how to set up collisions using the rectangle method but the problem is actually making the rectangles. I know it is a simple task but on this game whenever I place my Rectangle down it moves when I move my player, I tested for this by drawing the rectangle with the following code:

g.fillRect(0,0,100,100);

Thats the coordinates for an obstacle on my map, when I draw the rectangle it appears on the top left cornor of my screen and when I move my player it stays there (it keeps moving to stay in the top left cornor), now this is a big problem for me because if my rectangles are moving how is my collision supposed to work. I think the reason that this is happening is because my map is very big meaning that rather than showing the full thing I just centered my player on the center of my screen and when he moves the screen also moves with him to show the rest of the map.

The Code

Here is the code in my game class, it has methods such as render, init and update in it but I think the only code required to fix this problem is the render method and the variables so here they are (if the full code is required please tell me)

The Variables

 Animation bucky, movingUp, movingDown, movingLeft, movingRight
Image worldMap;
boolean quit = false;
int[] duration = {200, 200};
int buckyPositionX = 0;
int buckyPositionY = 0;
int shiftX = buckyPositionX + 320;
int shiftY = buckyPositionY + 160;

The render Method

public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
worldMap.draw(buckyPositionX, buckyPositionY);//position 0,0
bucky.draw(shiftX, shiftY);//makes him appear at center of map

if(quit==true){
    g.drawString("Resume(R)", 250, 100);
    g.drawString("Main(M)", 250, 150);
    g.drawString("Quit Game(Q)", 250, 200);      
    if(quit==false){
        g.clear();
    }}}

I am sorry about this thread being so long bit if you could please take the time to help me and answer my question I would really appreciate it.

Thank you.


Solution

  • As I said the rectangles(obstacles) are moving because the drawing coordinates are defined with respect to the screen, not the game map. That is when the character moves and you repaint the game map the rectangle is still drawn at (0,0) i.e. top-left of the screen.

    Here are some suggestions.

    • Use a seperate offscreen Image for the game map. The image size will be of the same size as of the game map.
    • Rectangles(obstacles) & other stuff excluding the character should be drawn on this image by getting a graphic context of this image using getGraphics
    • Finally when the character moves you paint a part of the image on screen using drawImage(Image img, int dstx1, int dsty1, int dstx2, int dsty2, int srcx1, int srcy1, int srcx2, int srcy2, ImageObserver observer) method. The explanation of this method is avaliable here. You have to calculate which part of the image to paint from the position of the character

    A thing to keep in mind is the character should only be drawn on screen, not on the game map Image. The character should be drawn on screen after drawing the game map image.