Problems with Drawimage

Started by Ethan D, Sat 31/07/2010 18:26:37

Previous topic - Next topic

Ethan D

Here is the code I'm using to determine the number of letters that should appear on the screen.

Code: ags

  int number;
  int iteration;

function room_RepExec()
{
  if (iteration < Difficulty)
  {
  number = Random (52);
  DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
  surface.DrawImage(Random (640), Random (480), number, 0, Game.SpriteHeight[number],     Game.SpriteWidth[number]);
  iteration ++;
  }
}

It chooses from 52 letters half of which are capital and half are lowercase.

My problems are:
(1) The images appear like this:



The actual sprites of the letters are white but when drawn on they appear like above.

(2) I'm not sure how to check if the drawn images are off the edge of the screen or overlapping.  I said in a previous topic i knew how to do this but I was thinking of how characters and objects are checked as overlapping or non-overlapping.  Ryan Timothy mentioned that I should use a struct array to store information about where each one of these are but I'm not sure how to do that.

(3) I'm not sure what the problem is in my code but the images are not being sized at the right size for each of the sprites.

Sorry for all the questions.

Any help is appreciated!


Joe

add this: 'surface.Release();' before 'iteration ++;'
Copinstar © Oficial Site

Kweepa

It looks like you need to import a background that has 16 or 32 bit colour depth.
I believe unless you import a background (which I'm guessing you didn't since it's black), by default the room is 8 bit.
So just save a black image with 32 bit colour depth and import that as your background.

For the second problem, there are several options depending on how many letters are going to be drawn.
The easiest thing (but might be slow if you have hundreds of letters) would be to keep an array of already drawn letters:
Code: ags


struct Letter
{
  int n, x, y;
};

Letter drawn[MAX_LETTERS];
int numDrawn = 0;

function room_RepExec()
{
if (iteration < Difficulty)
{
int n1 = Random(51); // generates 0-51, which is 52 unique numbers
int w1 = Game.SpriteWidth[n1];
int h1 = Game.SpriteHeight[n1];
int x1 = Random(640-w1);
int y1 = Random(480-h1);

int i = 0;
bool hit = false;
while (i < numDrawn && !hit)
{
  int n2 = drawn[i].n;
  int w2 = Game.SpriteWidth[n2];
  int h2 = Game.SpriteHeight[n2];
  int x2 = drawn[i].x;
  int y2 = drawn[i].y;

  //         x1       x1+w1
  //  x2     x2+w2

  if (x1 + w1 >= x2 && x1 <= x2 + w2 && y1 + h1 >= y2 && y2 <= y2 + h2)
  {
     hit = true;
  }
  i++;
}

if (!hit)
{
   drawn[numDrawn].x = x1;
   drawn[numDrawn].y = y1;
   drawn[numDrawn].n = n1;
   numDrawn++;

   surface.Draw...
   iteration++;
}
}
}
Still waiting for Purity of the Surf II

Ethan D

I'm sorry, I seem to be having trouble understanding this script.

Heres the script that I have:
Code: ags

int number;
  int iteration = 0;


struct Letter
{
  int n, x, y;
};

Letter drawn[50];
int numDrawn = 0;

function room_RepExec()
{
if (iteration < Difficulty)
{
int n1 = Random(51); // generates 0-51, which is 52 unique numbers
int w1 = Game.SpriteWidth[n1];
int h1 = Game.SpriteHeight[n1];
int x1 = Random(640-w1);
int y1 = Random(480-h1);

int i = 0;
bool hit = false;
while (i < numDrawn && !hit)
{
  int n2 = drawn[i].n;
  int w2 = Game.SpriteWidth[n2];
  int h2 = Game.SpriteHeight[n2];
  int x2 = drawn[i].x;
  int y2 = drawn[i].y;

  //         x1       x1+w1
  //  x2     x2+w2

  if (x1 + w1 >= x2 && x1 <= x2 + w2 && y1 + h1 >= y2 && y2 <= y2 + h2)
  {
     hit = true;
  }
  i++;
}

if (!hit)
{
   drawn[numDrawn].x = x1;
   drawn[numDrawn].y = y1;
   drawn[numDrawn].n = n1;
   numDrawn++;
   DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
   surface.DrawImage(x1, y1, n1, 0, h1, w1);
   iteration ++;
}
}
}


and it gets me this.



I'm sure that I did something wrong but I don't know what.  Also, when it gets to around 25 letters it starts slowing down quite a bit.

Any ideas?

Ryan Timothy B

The reason why your sprites are being drawn at the incorrect width and height is because you're telling it to.

Take a look at the DrawImage you're using:
Code: ags
surface.DrawImage(x1, y1, n1, 0, h1, w1);

Note how h1 and w1 are reversed. Should be Width before Height.

But! If you're drawing the images at the same sprite and don't require resizing, like in your instance, all you need is this:
Code: ags
surface.DrawImage(x1, y1, n1);

Kweepa

#5
Oh, I see you have confused w1 and h1 in the DrawImage call.
Is there anything else obviously wrong?

Is it painfully slow? I'm not sure what you can do about that actually... it depends what the percentage of coverage is likely to be at the end. If it's less than about 30%, you could have a second black image, and draw white boxes into it that are the size of the current letter plus a border half the size of the largest letter. Then when you generate new x and y, just check if the center of the new letter is white in this image. If so it is likely to hit one of the drawn letters, so try again.

EDIT - beaten by RT

Code: ags


int mw = 0;
int mh = 0;
DynamicSprite *coll;

function room_Enter()
{
int i = 0;
while (i < 52)
{
  int w = Game.SpriteWidth[i];
  int h = Game.SpriteHeight[i];
  if (w > mw) mw = w;
  if (h > mh) mh = h;

  coll = DynamicSprite.Create(640, 480);
}
}

Then, after "bool hit = false;", instead of what you have:
Code: ags

  DrawingSurface *collSurf = coll.GetDrawingSurface();
  if (collSurf.GetPixel(x1 + w1/2, y1 + h1/2) > 0)
  {
    hit = true;
  }
  if (!hit)
  {
    collSurf.DrawingColour = Game.GetColourFromRGB(255,255,255); // is it Color?
    collSurf.DrawRect(x1 - mw/2, y1 - mh/2, w1 + mw, h1 + mh);
    // 
   DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
   surface.DrawImage(x1, y1, n1);
   surface.Release();
   iteration ++;
  }
  collSurface.Release();
Still waiting for Purity of the Surf II

Ethan D

Ah, a miraculously simple cure.

Thanks Ryan and Steve!

I ran a check to see when it stops putting up letters and for some reason the number seems to vary even though difficulty is set to 50 and therefore it should write 50 letters, right?

I've also noticed that the letters seem to group together like in the one above quite often, leaving large spaces totally empty...  Any idea why that would happen?


Kweepa

Hmm, are you still using my first method?
Because I notice I messed up the code.
The big if statement should read:
Code: ags

  if (x1 + w1 >= x2 && x1 <= x2 + w2 && y1 + h1 >= y2 && y1 <= y2 + h2)


That should fix up the gaps. It'll probably run faster too :=
Still waiting for Purity of the Surf II

Ethan D

Wow, the last time it took 14 seconds to finish all the letters being printed on the screen this time it took nearly 3 seconds and they were evenly spread.  I still don't fully understand that line but I think I've got a pretty good idea now.

I'm still using the first method and it seems that it will work just fine.  The second method you showed me I couldn't get to work and I'm not sure why but the problem seems to be solved for now. :)

Thanks!

SMF spam blocked by CleanTalk