3.0: Two small questions... (incl. a SUGGESTION now!)

Started by DoorKnobHandle, Fri 16/11/2007 11:12:25

Previous topic - Next topic

DoorKnobHandle

So, I upgraded to 3.0 recently and now I have two tiny questions that used to be no big deal with older versions, but now I'm not so sure anymore:

1. About the old RawDrawing

Is this the correct, best and fastest way to draw:

Code: ags

function CRenderer::StartDrawing ( )
// prepares the renderer for drawing a new frame
{
      // init surface
      this.Surface = Room.GetDrawingSurfaceForBackground ( );
      
      // clear screen
      this.Surface.Clear ( );
}

function CRenderer::EndDrawing ( )
// shuts the renderer down after drawing a frame
{
      // release surface
      this.Surface.Release ( );
}


I call Renderer.StartDrawing ( ) in the beginning of rep_ex ( ) and Renderer.EndDrawing ( ) in the end of rep_ex ( ). In between both calls, I then draw my lines and pixels.


2. About sharing variables in between scripts

I have several modules or scripts in my game to nicely spread the source-code out into several files. The two functions you see above are part of the Renderer-script, for example. Now, I also have a Map- and a Camera-Script. The Map-script holds all information for a - well, you guessed it - map (or level, in which the player can move around) and the Camera-script holds all the information of the - you guessed it again - camera (position, angle).
Now on to the problem: I have a function called Camera.Move ( ) in order to - third time you guessed right - move the camera. This is needed because I have to do some camera-calculations at this point. Those calculations include checking the map, whether the player is going to be standing in a wall and then blocking the movement for collision-detection. This would be no problem, if the Map-script wouldn't need the camera-script to get the position and angle to then draw the map correctly to the screen.
So, basically I have two scripts with structs in them, that both need to know about each other respectively.
My files are set up like this: in the header there's the struct-definition like this:

Code: ags

struct CObject
{
      int a;
      int b;

      import function   Test ( );
};

import CObject Object;


And in my script-file, it looks like this:

Code: ags

CObject Object;

int CObject::Test ( )
// test, test, test
{
      // do the darn test
}

export Object;


This way works great when one script needs a struct from another script (by also moving them in the right order in the hierarchy-pane on the right in the editor), but when I have two scripts that need each other structs, it won't work this way. Is this possible somehow else or will I have to suggest this?

Thanks ahead of time.

Khris

2.: Put the struct definitions and the declaratons of their instances in a third module above the other two.
(Feel free to mock me if I've overlooked something obvious ;))

DoorKnobHandle

That'd be quite possible. But also quite ugly and against the whole script/module split-up in my opinion, thanks for your input, though, I'll be sure to follow your advice if no other possibility turns up... There HAS to be a prettier way though! If there isn't, I strongly suggest a different way to share variables between scripts for AGS, it's quite daunting at the moment, I can only imagine how lost a complete beginner would have to feel here.

monkey0506

Quote from: dkh on Fri 16/11/2007 11:12:251. About the old RawDrawing

Is this the correct, best and fastest way to draw:

I call Renderer.StartDrawing ( ) in the beginning of rep_ex ( ) and Renderer.EndDrawing ( ) in the end of rep_ex ( ). In between both calls, I then draw my lines and pixels.

Assuming you really need to completely clear the screen then draw the entire thing over again every single loop (am I detecting some 3D workings?) then yes, this is probably the best/fastest way.

Quote from: dkh on Fri 16/11/2007 11:12:252. About sharing variables in between scripts

when I have two scripts that need each other structs, it won't work this way. Is this possible somehow else or will I have to suggest this?

Unfortunately there's not really a "nice" way to do this, but it might be possible to do something like:

Code: ags
// 'A' script header
struct A {
  int a;
  int b;
  import function TestA();
  };

import A AObject;

// 'A' main script
A AObject;
export AObject;

function __TestA() {
  AObject.a = 27;
  AObject.b = 89;
  }

/* you can only call the 'A'-specific portion of the A::TestA function here since the 'B' struct hasn't been defined at all */
/* use __TestA() in place of AObject.TestA() here since our 'actual' function hasn't yet been defined */

// 'B' script header
struct B {
  int a;
  int b;
  import function TestB();
  };

import B BObject;

// 'B' main script
B BObject;
export BObject;

import function __TestA();

function __TestB() {
  BObject.a = 95;
  BObject.b = 41;
  }

function A::TestA() {
  __TestA();
  __TestB();
  }

function B::TestB() {
  __TestB();
  __TestA();
  }

/* now you can call AObject.TestA() and BObject.TestB() as needed */


Granted it's a horribly pointless and crappy example, but hopefully it will illustrate what I mean. You can't call a function (in AGS) before it's been defined (even if it's been declared) so even if you had both the 'A' and 'B' struct definitions and instance declarations in the 'A' script header, you still wouldn't be able to access the 'B' instance OR any 'B' member functions before they were defined.

DoorKnobHandle

Okay, thanks for the help here as well, monkey.

Now, my suggestion stands: sharing information between scripts/modules has to become easier and more flexible, please! ;D

Oh, and you're right with your guess there, monkey!

Pumaman

1. Yes that's the best way to do it, but I'd advise against it because RawDrawing to the room background in rep_exec is extremely slow with the Direct3D driver.

2. Although the limitation on one-way dependencies is a limitation of the script compiler, in a way it also enforces a certain standard of cleanliness in script modules... ideally code shouldn't be coupled such that two classes both need to know about each other. But a workaround is, as suggested, to have a third module with the shared stuff in that is then used by both of the dependant modules.

DoorKnobHandle

1. Okay, I need the RawDrawing in rep_ex ( ) for my project here, but I'll take note to advice people to only use the game in DirectDraw-Mode. Actually, in DD-mode, the RawDrawing is reasonably fast. You can paint the 320x200 screen all one color in 320 vertical lines every frame and still be at the 40fps limit, at least on my 5-6 year old pc.

2. I see, I'll resort to one of the work-arounds then. But how would somebody design his classes as in my example (with map and camera) and not need both to interfere with each other? In order to draw the map, you need the camera-position and in order to move the camera, you need to check the map, where the walls are.

Thanks for the interest, everybody.

Snarky

If they're that interdependent, maybe they should be in a single module.

Khris

What about separating map data and map drawage?

Module 1: map data.
Module 2: camera routines, using 1.
Module 3: drawing routines, using both 1+2.

Pumaman


SMF spam blocked by CleanTalk