Jump to content
  • Advertisement
Sign in to follow this  
nerozero

Map Clipping

This topic is 2106 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Guys,

 

I have a sprite that moves at a velocity of 1,1 across a background image. I want to draw the background image with the sprite always at the centre as the background is about 2000x2000. My problem is as the sprite moves the background repositions but its as if the sprite is moving at 2,2 and the background is moving at 1,1. So the sprite gradually moves off the screen even though the sprite is moving at 1,1 and the background surely cant be moving slower than that?

 

To update the velocity of sprite:

		Point car = new Point(
				((GameBoard) findViewById(R.id.the_canvas)).getCarX(),
				((GameBoard) findViewById(R.id.the_canvas)).getCarY());
		car.x = car.x + carVelocity.x;
		car.y = car.y + carVelocity.y;
		((GameBoard) findViewById(R.id.the_canvas))
				.setCarLocation(car.x, car.y);

Definition of velocity:

		carVelocity = new Point(1, 1);

Drawing the map around the car:

	public void drawMap(Canvas canvas) {

		if (car.x > 0) {

			int x = car.x - getWidth() / 2;
			int y = car.y - getHeight() / 2;

			Bitmap clipArea = Bitmap.createBitmap(map, x, y, getWidth(),
					getHeight());
			canvas.drawBitmap(clipArea, 0, 0, null);
		}
	}

So i can't see why the car would move off the screen as it looks to me as the background should always draw with the car in the middle of the screen. I have put logging on both and they both increase by 1 on the X and Y each time. 

 

Any help would be appreciated!

Share this post


Link to post
Share on other sites
Advertisement

I think you can solve the problem by replacing your cars displacement update code with 

        car.x = car.x + carVelocity.x;
        car.y = car.y + carVelocity.y;

 

It looks like findViewById and setCarLocation is unnecessary because i *think* those values are referring to the screen location, which in your case is going to be constant.

 

I think the application is getting the cars Draw location (pixel X, pixel Y) confused with the cars world position (carX, carY).

Edited by Paragon123

Share this post


Link to post
Share on other sites

Hi Paragon, 

 

Thanks for the response. I have to use .setLocation as I have a custom view that holds the canvas and so I am passing the car location to this so it can be drawn. 

 

Here is my cars draw method:

if (car.x > 0) {
    m.reset();
    m.postTranslate((float) (getWidth() / 2), (float) (getHeight() / 2));
    m.postRotate(carRotation,
            (float) (getWidth()/2 + carBounds.width() / 2.0),
            (float) (getHeight()/2 + carBounds.height() / 2.0));
    canvas.drawBitmap(carBitmap, m, null);
}

The above works but once I reach the end of the bitmap the car stay in the middle and i cant reach the true edge beacuse of getWidth()/2 and getHeight()/2. If i change this to car.x and car.y which is what it should be then the car gradually dissapears. The .setLocation method updates the cars coords car.x and car.y in my custom view ( the velocity calculations are seperate from the drawing). 

Share this post


Link to post
Share on other sites

Sorry a bit confused. You have a car sprite, and you have a background image. Ignoring the specifics of how it is implemented there is two ways to have it look like the car is driving around.

 The first is to move the car and keep the image still, this means that the car can move toward the edges of the drawing area, but will go off the screen at some point.

  The second is to move the image and keep the car still, this means the car is always at the center of the screen but at some point you'll reach the edge of the background and you'll end up driving on a point where there is no background.

 

 In the original post, the problem sounded like you were moving both the background and the car... thus moving the car 1 to the left and moving the image 1 to the right, causing it to seem like the car was moving left 2 instead of 1. 

 

There is a Third method, but it is more a combination of the two. In the third method, as long as none of the background edges line up with the drawing area edges move the background, but if the a background edge does line up with a drawing edge, instead move the car. This sounds like what you are trying to accomplish in your most recent post.

 

Assume the drawing area is 100 x 100, and the background is 500 x 500 .

As long as 50<car.x<450 and 50<car.y<450 we can move the background and leave the car in the middle of the drawing area. As it turns out, there are 9 cases we must consider. 

1) car.x<50 and car.y<50

2) 50<car.x<450 and car.y<50

3) 450<car.x and car.y<50

4) car.x<50 and 50<car.y<450

5) 50<car.x<450 and 50<car.y<450

6) 450<car.x and 50<car.y<450

7) car.x<50 and 450<car.y

8) 50<car.x<450 and 450<car.y

9) 450<car.x and 450<car.y

 

Given a car position car.x, car.y we need to first translate it to drawing positions with a function like:

           : x<50 = x             

px(x)=  : 50<x<450=50

           : 450<x=x-400 

and

          :  x<50=x

py(x)= : 50<x<450 = 50

          : 450<x=x-400

 

so P(car)=(px(car.x), py(car.y))

px and py are separate functions but in the case of a square viewing area they are equivalent, in a rectangular viewing area they would be different.

 

Then we need to find the top left coord of the background clipping area. Cx and Cy

            x<50=0

Cx(x) = 50<x<450=x-50

          450<x= 400

 

              x<50=0

Cy(x)= 50<x<450 = x-50

         450<x = 400

 
And the clipping cord ends up being 
C(car)=(Cx(car.x),Cy(car.y))
 
Car.x and Car.y still needs to be constrained to 0<Car.x<500 and 0<Car.y<500
 
In all the above, you can replace
50 by either CanvasWidth/2 or CanvasHeight/2 depending on working with x or y
450 by BackgroundWidth-CanvasWidth/2 or Backgroundheight-CanvasHeight/2  depending on working with x or y
400 by BackgroundWidht-CanvasWidth or BackgroundHeight-CanvasHeight depending on working with x or y
Edited by Paragon123

Share this post


Link to post
Share on other sites

 

Sorry a bit confused. You have a car sprite, and you have a background image. Ignoring the specifics of how it is implemented there is two ways to have it look like the car is driving around.

 The first is to move the car and keep the image still, this means that the car can move toward the edges of the drawing area, but will go off the screen at some point.

  The second is to move the image and keep the car still, this means the car is always at the center of the screen but at some point you'll reach the edge of the background and you'll end up driving on a point where there is no background.

 

 In the original post, the problem sounded like you were moving both the background and the car... thus moving the car 1 to the left and moving the image 1 to the right, causing it to seem like the car was moving left 2 instead of 1. 

 

There is a Third method, but it is more a combination of the two. In the third method, as long as none of the background edges line up with the drawing area edges move the background, but if the a background edge does line up with a drawing edge, instead move the car. This sounds like what you are trying to accomplish in your most recent post.

 

Assume the drawing area is 100 x 100, and the background is 500 x 500 .

As long as 50<car.x<450 and 50<car.y<450 we can move the background and leave the car in the middle of the drawing area. As it turns out, there are 9 cases we must consider. 

1) car.x<50 and car.y<50

2) 50<car.x<450 and car.y<50

3) 450<car.x and car.y<50

4) car.x<50 and 50<car.y<450

5) 50<car.x<450 and 50<car.y<450

6) 450<car.x and 50<car.y<450

7) car.x<50 and 450<car.y

8) 50<car.x<450 and 450<car.y

9) 450<car.x and 450<car.y

 

Given a car position car.x, car.y we need to first translate it to drawing positions with a function like:

           : x<50 = x             

px(x)=  : 50<x<450=50

           : 450<x=x-400 

and

          :  x<50=x

py(x)= : 50<x<450 = 50

          : 450<x=x-400

 

so P(car)=(px(car.x), py(car.y))

px and py are separate functions but in the case of a square viewing area they are equivalent, in a rectangular viewing area they would be different.

 

Then we need to find the top left coord of the background clipping area. Cx and Cy

            x<50=0

Cx(x) = 50<x<450=x-50

          450<x= 400

 

              x<50=0

Cy(x)= 50<x<450 = x-50

         450<x = 400

 
And the clipping cord ends up being 
C(car)=(Cx(car.x),Cy(car.y))
 
Car.x and Car.y still needs to be constrained to 0<Car.x<500 and 0<Car.y<500
 
In all the above, you can replace
50 by either CanvasWidth/2 or CanvasHeight/2 depending on working with x or y
450 by BackgroundWidth-CanvasWidth/2 or Backgroundheight-CanvasHeight/2  depending on working with x or y
400 by BackgroundWidht-CanvasWidth or BackgroundHeight-CanvasHeight depending on working with x or y

 

 

Hi, 

 

I see what you mean and I think the above will work but is this always how this is implemented? It seems very complicated I assumed I could just draw the background around the cars location which is what I was trying to achieve. 

 

So the car moves in a direction and then I clip the background at car.x-getWidth()/2 and car.y-getHeight()/2 and I thought this should keep the camera moving along with the car but this doesn't work? Am I missing something or is the way you said above the only way to achieve this?

 

Thanks for your time!

Share this post


Link to post
Share on other sites

I think I am seeing what you mean though, if the car is in the corner of the background then drawing around the car wouldn't work as there isn't anymore background to draw. I guess your way is the way and I was oversimplifying :)

Share this post


Link to post
Share on other sites

Or is the proper way to follow the car with the camera until it reaches one of the corner zones and then just draw the background corner area. This way seems the 'real' way to me but then I have the original problem.

 

I will give your third method a try though! thanks

Edited by nerozero

Share this post


Link to post
Share on other sites

I think fundamentally the problem is that you need to move the viewport, not the world.

 

You need to be thinking about everything internally in world-space coordinates, and only convert to screen-coordinates just before rendering. Doing anything else will cause you to lose your sanity.

 

You need to independently maintain the location of the viewport and the car, even if one is derived from the other.

 

http://marksverbiage.blogspot.co.uk/2012/04/move-viewport-not-world.html

Share this post


Link to post
Share on other sites

I think fundamentally the problem is that you need to move the viewport, not the world.

 

You need to be thinking about everything internally in world-space coordinates, and only convert to screen-coordinates just before rendering. Doing anything else will cause you to lose your sanity.

 

You need to independently maintain the location of the viewport and the car, even if one is derived from the other.

 

http://marksverbiage.blogspot.co.uk/2012/04/move-viewport-not-world.html

Hi Markr,

 

I do have the car in world-space coordinates this being car.x and car.y. I then clip the background image at car.x-getWidth()/2 and car.y-getHeight()/2. So I think I am doing it right, however when I draw the car at car.x and car.y the car will gradually move off the screen when it moves even though the background is being drawn like I just said. This is what I am having trouble with. i now see why it doesn't work as the velocity is moving the car across the view and the bitmap I guess but I can't figure away around this unless i draw the car at getWidth()/2 and getHeight()/2 and then check for when it reaches the corners as Paragon said. 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!