PDA

View Full Version : scaling of an image from an imagelist?



andyr74
07-01-2003, 12:27 PM
I have following problem:
I would like to build a pattern of blocks (a bit like computerplayers so i use sprites for them). They can move sometimes and they need a collision check. The size of the blocks is depending on some factors so they aren't always the same size. I have five blocks (squares each with their own color) in an imagelist. With the current size (100x100 pixels) of these squares i can buils my pattern.

But now my problem: Two extreme cases: the size of the square can vary between 10 and 100 pixels. It's not practical to add the different sizes to the imagelist.
So if i add the maximum size of the image to an imagelist, how can i scale the image down for use with a sprite? (if it is an image with only one color: maybe only using a part of the image in the list, or getting a part of an external bmp-file and adding that to an imagelist,...)

I hope my problem is clearly explained.

cairnswm
08-01-2003, 06:26 AM
To draw an image from the image list you'll typically use something like this:
DXImageList1.Items[0].Draw(DXDraw1.Surface,10,10,0);


To draw the same image with a different size you can do this:
DXImageList1.Items[0].StretchDraw(DXDraw1.Surface,Rect(200,200,250,250) ,0);

this allows you to draw your blocks the size you want when you want.

[PS. my experience is that StretchDraw can be very slow. If your images are a constant size in the game why not just set the Pattern Height and Width - which will then size your blocks as needed - will obviously only work if your blocks do not have textures.]

andyr74
08-01-2003, 08:05 AM
I use the images in the DXImageList for sprites. I don't draw them directly on the DXDraw surface.
The blocks don't have textures yet. Maybe it will stay this way.
The default patternheight and width is 100 because the blocks are 100x100. But i would like them to be variable from 10x10 to 100x100. Onces the game is started, the size of the blocks doesn't change any more.
I tried to alter the patternwidth and patternheight of an image in the DXImageList in runtime to 50x50 but the default patternheight and width is always used. I use something like this:



...
// altering the imagelist
DXImageList1.Items[0].patternwidth := 50;
DXImageList1.Items[0].patternheight := 50;

// creating sprites
...
playersprite.image := DXImageList1.Items[0];
...


This is the only thing i change in the DXImageList during runtime. Do i need to do something else (updating the list or something)?

cairnswm
08-01-2003, 08:32 AM
The draw function you are probably using is the one declared in the TImageSprite.

procedure TImageSprite.DoDraw;
var
ImageIndex: Integer;
r: TRect;
begin
ImageIndex := GetDrawImageIndex;
r := GetDrawRect;
Image.Draw(FEngine.Surface, r.Left, r.Top, ImageIndex);
end;

I would suggest creating a new sprite class that inherits from TImageSprite that OverRides the DoDraw to implement the stretch draw function.

I think its something like: (Note I havn't tried it)

Type
TMyPlayerSprite = Class(TImageSprite)
Procedure DoDraw; Override;
End;


procedure TImageSprite.DoDraw;
var
ImageIndex: Integer;
r: TRect;
begin
ImageIndex := GetDrawImageIndex;
r := GetDrawRect;
Image.StretchDraw(FEngine.Surface, Rect(r.Left, r.Top,R.Width,R.Height), ImageIndex);
end;

PS. One of the biggest limitations of DelphiX is the use of Draw for all images. I would like to see an alternative drawing system implemented that would allow AlphaDraw, StretchDraw to be used based on a property.

andyr74
08-01-2003, 09:15 AM
I didn't write anything for the drawing itself.
I give a x and y coordinates to the sprite and the sprite is positioned at these points. Maybe override the default draw function.

Is it possible to change the patternheight en width in runtime? (like the ex. in my previous post) If that would be possible then i don't need a scaling function for the normal (non-textured) blocks.

cairnswm
08-01-2003, 09:43 AM
Your exmaple post seems to have been correct. Dont see any obvious reason it doesn;t work - I would have to look at the whole program to be able to do that - if you like ZIP it up and send to me william.cairns@eskom.co.za and I'll have a look.

I do think creating the new sprite class would be better as it would eaily allow textures at a later stage.

andyr74
08-01-2003, 09:57 AM
I'm not at home now but the code is something like this:

...
// altering the imagelist
showmessage(inttostr(DXImageList1.Items[0].patternwidth));
// it shows 100 like it is declared as default in the imagelist
DXImageList1.Items[0].patternwidth := 50;
DXImageList1.Items[0].patternheight := 50;
showmessage(inttostr(DXImageList1.Items[0].patternwidth));
// it shows 50 like I changed it
// end of altering imagelist

// creating new sprites
...
with playersprite do
image := DXImageList1.Items[0];
width := DXImageList1.Items[0].patternwidth;
height := DXImageList1.Items[0].patternwidth;
x := 100;
y := 100;
...
end;


But in runtime the images stay at patternwidth and height of 100x100.
Maybe there is something missing in the code. Telling to actualy use the new values,...?

cairnswm
08-01-2003, 10:50 AM
I did this in the form.create:

PlayerSprite := TImageSprite.Create(DXSpriteEngine1.Engine);
PlayerSprite.Image := DXImageList1.Items[3];
PlayerSprite.Image.PatternHeight := 20;
PlayerSprite.Image.PatternWidth := 20;
PlayerSprite.X := 100;
PlayerSprite.Y := 100;


and it worked fine.

You possibly dont need to change the Sprites Height and Width as it will automatically take these from the Image.

andyr74
08-01-2003, 10:56 AM
I will try some things and see if it works.
I will tell if it does or doesn't.

Useless Hacker
08-01-2003, 12:58 PM
If you want to StretchDraw a sprite, you can use TImageSpriteEx instead of TImageSprite.

andyr74
13-01-2003, 07:36 AM
...
// altering the imagelist
showmessage(inttostr(DXImageList1.Items[0].patternwidth));
// it shows 100 like it is declared as default in the imagelist
DXImageList1.Items[0].patternwidth := 50;
DXImageList1.Items[0].patternheight := 50;
DXImageList1.Items[0].restore;
showmessage(inttostr(DXImageList1.Items[0].patternwidth));
// it shows 50 like I changed it
// end of altering imagelist

// creating new sprites
...
with playersprite do
image := DXImageList1.Items[0];
width := DXImageList1.Items[0].patternwidth;
height := DXImageList1.Items[0].patternwidth;
x := 100;
y := 100;
...
end;



This worked. The restore of the DXImagelist1 was needed. Without this it didn't work.