PDA

View Full Version : Editing the Image of a sprite



Diaboli
28-08-2007, 02:50 PM
How can i edit the Image of a sprite directly (like drawing something to it)?


Background.Image:= fMain.Diverse.Items.Find('background');

TempPic:= Background.Image.Picture;
MaxTile:= fMain.Tiles.Items.Count;

TempPic.Free;
TempPic:= TPicture.Create;

TempPic.Bitmap.Canvas.FillRect(Rect(0,0,TempPic.Wi dth,TempPic.Height));

TempPic.Bitmap.SetSize(Room[CurrentRoom].Width*32,Room[CurrentRoom].Height*32);

for z := 0 to High(Room[CurrentRoom].Layer) do
begin
for y := 0 to Room[CurrentRoom].Height -1 do
begin
for x := 0 to Room[CurrentRoom].Width-1 do
begin
if (x >= 0) and (y >= 0) then //check so x or y is not too low
begin
Tile:= Room[CurrentRoom].Layer[z].Tile[x,y]; //Get the tile for the coordinates x,y in layer l
if (Tile <MaxTile>= 0) then //Check so Tile does not contain an illegal value
TempPic.Bitmap.Canvas.Draw((32*x),(32*y),fMain.Til es.Items[Tile].Picture.Graphic); //Draw the tile in place
end;
end;
end;
end;
TempPic.Graphic:= TempPic.Bitmap;



this does not work properly (it works once, but not twice. dont know why)

jasonf
28-08-2007, 03:33 PM
Why do you want to do this?

If it's for a tile engine, then you'll be rendering everything twice, each frame.

It's far better to render directly to the surface in the correct order.

FNX
28-08-2007, 03:35 PM
A brief description of what you're trying to achive would be useful ;)

Diaboli
28-08-2007, 04:10 PM
What i want to do is:
when a player enters a room, they load the bg into a TBackgroundSprite. that is the function i pasted. so that the engine does not have to draw every individual tile in place again every fram, but only draw one large bitmap that is the "room" bg.

like this:
Player enters room -> Loads the tilemap into a TBackgroundSprite

then i draw that TBackgroundSprite every frame, instead of calculating tiles every frame...

but maybe that isnt a good way to do it?

jasonf
28-08-2007, 04:38 PM
OK, I understand what you're trying to do now.. but I still don't understand why it's important for you to draw one large bitmap. You will lose a lot of flexibility but won't gain much from what you've told us so far.

You're basically writing a flip screen game I think.
In which a character moves from one side of a fixed 2D screen to another, then the screen flips as he enters another room.. like in Manic Miner and Another World.

Using your normal tile system is fine for this. You're not going to gain anything by cutting out the loop which renders the small tiles. It looks like it's doing more work, but it's actually quite fast. it also means that you can have objects in front of the player and behind if you also include the player in your rendering list.

Flip screen games are great fun and it's a shame there aren't many around these days.

One reason to have a single image as the background is if you want to employ a dirty rectangle system.. only updating the parts of the screen which have changed since the previous frame. This was done to squeeze every last drop of speed from very slow processors..

The other main reason is to save time if rendering your tiles takes much too long.. like if you've got some expensive lighting calculations which end up being a static image or if you're doing ray-tracing.. the obvious alternative to that would be pre-rendered backgrounds like in Abe's Odyssey.

So, unless you're doing one of those things.. (or something I've not mentioned which could be equally valid ;)) then I'd strongly suggest that you render the tiles as you need them. It also means you can have very dynamic parts to your scene.. lights flickering, candles, bats outside.. etc..

What you're trying is possible and the right thing to do... in some situations.

Diaboli
28-08-2007, 04:40 PM
ok, then i'll just make a normal tile-engine...

its actually a flip-screen MORPG :P

but its VERY early in development. more like in prototype stage...

EDIT: Does anyone have a good tutorial on how to use a tiled TBackgroundSprite?

JSoftware
28-08-2007, 07:00 PM
Disable double buffering and just redraw tiles where the player has moved over or has interacted with?

FNX
29-08-2007, 08:21 AM
Does anyone have a good tutorial on how to use a tiled TBackgroundSprite?




var
MyTiledBack : TBackGroundSprite;

//.........

procedure YourForm.loadLevel; //whatever... the one that load tiles into your bg
var
X, Y : Integer;
begin
if (MyTiledBack = nil) then
begin

MyTiledBack := TBackGroundSprite.Create(YourForm.DXSpriteEngine.E ngine);
with TBackGroundSprite(MyTiledBack) do
begin
Image := YourForm.DXImageList.Items.Find('tiles');
SetMapSize(Round(YourForm.DXDraw.SurfaceWidth/TILESIZE), YourForm.DXDraw.SurfaceHeight/TILESIZE)
Tile := False;
Z := 0; //or a value less than sprites' Z
end;
end;

for X := 0 to Round(YourForm.DXDraw.SurfaceWidth/TILESIZE) do
for Y := 0 to Round(YourForm.DXDraw.SurfaceHeight/TILESIZE) do
MyTiledBack.Chips[X, Y] := TileValue; // read it from a txt, res, xml and so on

end;

procedure YourForm.TimerTimer...
begin
//.....
DXSpriteEngine.Draw; // no need to call specifically MyTiledBack.Draw
//.....
end;



Now, to change tiles when some event happen, just modify the procedure
loadLevel adding some parameters like "offset", or "room" or whatever you need, and change where you start reading tiles. That should be enough i think ;)

Please don't copy-past code, if you understand it, try to write it yourself :)

Diaboli
29-08-2007, 01:38 PM
EDIT: Moved to "help me!"