Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: magintz on Tue 11/09/2007 17:37:25

Title: RawDrawLine running in background (SOLVED)
Post by: magintz on Tue 11/09/2007 17:37:25
I'm trying to create a puzzle where a laser beam is moving about the screen, but I want the laser to be moving slowly in the background so the user can solve the puzzle before the laser hits them. I've got the movement down to a 'T'. But I need the user to be able to continue playing. Here's what I got for the movement:


ypos = 171;
while (ypos > 134) {
  RawRestoreScreen ();
  RawDrawLine(198,22,47,ypos);
  Wait(1);
  ypos--;
}


The other thing I need is for the line to draw itself above all the other objects in the room; the line currently shows up behind the objects.
Title: Re: RawDrawLine running in background
Post by: GarageGothic on Tue 11/09/2007 17:43:01
It's not possible to RawDraw in front of objects. What you can do is make the laser beam as a sprite, which is then copied to a DynamicSprite, stretched, rotated and placed in the room as an object.
Title: Re: RawDrawLine running in background
Post by: magintz on Tue 11/09/2007 17:45:54
Hmm, that might work :D I assume AGS has functions, which allow the stretching and manipulation of sprites?

Thanks Again,
Magintz
Title: Re: RawDrawLine running in background
Post by: Ashen on Tue 11/09/2007 17:52:36
In the manual: DynamicSprite functions and properties (http://www.adventuregamestudio.co.uk/manual/DynamicSprite%20functions%20and%20properties.htm) (particularly Resize, and probably CreateFromExistingSprite). Or, you could just import the sprites and run it as a standard animation - a bit of a waste of sprite slots, but if it's just a straight line it shouldn't take up much space.
Title: Re: RawDrawLine running in background
Post by: Khris on Tue 11/09/2007 18:02:47
To run it in the background:

int ypos = 171;

function repeatedly_execute() {
  if (ypos > 134) {
    RawRestoreScreen ();
    RawDrawLine(198,22,47,ypos);
    ypos--;
  }
  else kill_player();
}


This code won't work as-is but should get you started.
Title: Re: RawDrawLine running in background
Post by: monkey0506 on Tue 11/09/2007 19:35:40
But that still doesn't solve the issue of making the laser appear in front of objects.

Instead of using DynamicSprite.Resize and DynamicSprite.Rotate every game loop (which the manual specifically says not to do) you could use a combination of the RawDraw functions, a DynamicSprite, and an object.

1. nvm

2. In your room's "on-load" function call RawSaveScreen and RawSetColor.

3. In your room script make a DynamicSprite* (I'll name it dsLaser). Also put your "int ypos = 171;" at the top of your room script.

4. Finally, in your room's repeatedly_execute function, put this:

if (ypos > 134) {
  RawClearScreen(63519);
  RawDrawLine(198, 22, 47, ypos);
  dsLaser = DynamicSprite.CreateFromBackground(GetBackgroundFrame(), 47, 22, 198 - 47, ypos - 22);
  RawRestoreScreen();
  oLaser.Graphic = dsLaser.Graphic;
  ypos--;
  }
else {
  // kill player
  }


The color 63519 is a "magic pink" color that will be drawn as transparent when used by your sprite. So I've cleared the screen out to that color, drawn the laser, and then grabbed the entire rectangular area of the laser into the DynamicSprite. Then you restore the screen back to normal and set the object's graphic. This method should be much faster than trying to resize and rotate the sprite every game loop.
Title: Re: RawDrawLine running in background
Post by: GarageGothic on Tue 11/09/2007 19:43:46
monkey, In my experience, anything using RawRestoreScreen and creating DynamicSprites from background every game loop will pretty much always be slower than pure DynamicSprite deformation (even more so with the new Direct3D engine). Especially as this DynamicSprite would only be one or two pixels wide until rotated. Also, using a sprite would allow for better resolution (if it's a hi-res game) and let you draw the laser beam with gradients.

The only small problem about rotating the sprite, is that you must recalculate the x coordinate for the object every frame. But that's simple geometry and not too complicated.
Title: Re: RawDrawLine running in background
Post by: magintz on Tue 11/09/2007 20:17:31
I've been fiddling around and I managed to sort this out, in case anyone has a similar problem. I will try monkeys script and see how that handles, or I can just put the objects into the background and animate the background manually if I want to change anything with the objects - which I think will work better anyhow as the laser will be gone by then.

Within the game script

/* ---------------
RawDrawLine laser
------------------ */
// Extend Laser
RawSetColor(47104);
RawSaveScreen();
xpos = 212;
ypos = 22;
while (xpos > 59) {
  RawDrawLine(212,22,xpos,ypos);
  Wait(1);
  xpos = xpos - 2;
  ypos = ypos + 2;
}

// Set the timer (see repeatedly execute)
ypos = 173;
SetTimer(1, 25);

/*----------------------
End of RawDrawLine laser
------------------------*/


In repeatedly execute:

// Moves the laser beam in the background
if (IsTimerExpired(1)) {
if (ypos > 134) {
  RawRestoreScreen ();
  RawDrawLine(198,22,47,ypos);
  ypos--;
  SetTimer(1, 25);
}
}


Works a treat except for the overlay thing :P