tags:

views:

134

answers:

2

I have a game that uses layers as a way to organize depth. It works fine but I have stumbled into a silly problem...and despite being simple I can't get it to work EXACTLY as I need. The idea is that once a graphic is completely out of the game area (as it its right side has completely traveled through the area's left side, so it's not visible anymore), it should be transported to the opposite side of the area.

This is the culprit code, checked every cycle to see if the object is within boundaries, and in the special case of an "infinite" layer, this code is executed:

if(world.layer[object[i].layer].infinite){
 sw = object[i].rect.w * 0.5;
 sh = object[i].rect.h * 0.5;
 if(object[i].rect.x + sw < world.fieldw[0] && world.layer[object[i].layer].speedX < 0){
  dif = world.fieldw[0] - (object[i].rect.x + sw);
  object[i].rect.x = ((world.fieldw[1]+sw) + dif);
 }
 else if(object[i].rect.x - sw > world.fieldw[1] && world.layer[object[i].layer].speedX > 0){
  dif = (object[i].rect.x - sw) - world.fieldw[1];
  object[i].rect.x = ((world.fieldw[0]-sw) - dif);
 }

 if(object[i].rect.y + sh < world.fieldh[0] && world.layer[object[i].layer].speedY < 0){
  dif = world.fieldh[0] - (object[i].rect.y + sh);
  object[i].rect.y = ((world.fieldh[1]+sh) + dif);
 }
 else if(object[i].rect.y - sh > world.fieldh[1] && world.layer[object[i].layer].speedY > 0){
  dif = (object[i].rect.y - sh) - world.fieldh[1];
  object[i].rect.y = ((world.fieldh[0]-sh) - dif);
 }

It works, but as the objects loop around, they lose their original formation, what distorts the backdrops. What am I doing wrong here? I know it's nowhere a complex issue, but I have tried and can't find an exact result.
EDIT: fieldw[0] is the left boundary of the area, fieldw[1] is the right. Same for h[0/1] in vertical space. Layer speedX/Y are the constant speed used in the layer (to keep it scrolling, like in the Flintstones and their repeating backgrounds) . Also, should I take speed in consideration when doing the move?

A: 

I think this is due to the fact that in your current code the looping period ( in space ) depends on the object size.

If you want to keep the objects at the same relative place, they should be moved by the exact field witdh : world.fieldw[1] - world.fieldw[0] when crossing the field border.

Also depending on the field size versus display size you may need to display the objects multiple times ( when field size is less than the display size ).

Think it as a texture.

fa.
In other words: the smaller objects go through the world limits faster than larger objects.
pmg
Although the other reply was more in-depth, this was very useful as well.
DalGr
A: 

All objects should snap back at the same point out of the field of vision.

So the way to do it is to determine the biggest object and take this width. And this is the point outside of the view where objects are snapped back to the right side of the screen.

If you can't determine the biggest object, you could also take the width of the screen (given that objects are never wider than the screen).

so your code would look like this (pseudocodeish):

 int biggestObjectWidth = 200;

 loop:
      if(object.x < (layer.x-biggestObjectWidht)) 
      {
           object.x += biggestObjectWidth + layer.width;
      }

so all objects are snapped back the same amount

What you can also do is just Modulo the object positions.

 drawObject((object.x % (biggestObjectWidth+layer.width)) - biggestObjectWidth, object.y)

this way you don't need to snap objects back yourself... they'll be done automatically. beware of negative object.x values though, since than the modulo trick will work against you ;^)

Toad
Thank you for the example and information, I finally solved it. No matter how much I move it around, the positions are respected perfectly. I was doing a lot when I just had to sum the screen width/height as pointed in the other answer. Thank you very much, again!
DalGr