Page 1 of 9 123 ... LastLast
Results 1 to 10 of 87

Thread: Space Shooter Game Editor

  1. #1

    Space Shooter Game Editor

    Hello Everyone ,

    I'm in the process of creating a map editor, but ran into a problem, I'm using tiles 32x32 , my widht is fixed 20x32 (640) , but I can dynamicaly set the length, if I generate say a map that is 1500x32 tiles long that , my editor slows down to a crawl, probably because I'm rendering all the sprites at once, not just the ones visible . How can I render only the visible sprites?

    Attached I have here my entire project. Still lots of stuff to do but I think I'm progressing nicely. Anyway try to generate a map that is say 150 in length, you'll see the FPS drops drasticaly...
    Can someone please help me with this? Only draw what is actually visible.

    Greetings
    Robert
    Attached Files Attached Files

  2. #2
    Unfrtunately I havent been able to compile your project as I don't have all components so I can't offer you exact code changes: But becouse I was doing something similar once I can still give you some hints:

    1. Instead of creating all 1500x32 sprites create just as many sprites as it fits your window. Then you are only changing the sprites texture (Image).
    For instacne you define your map the same way as you do using:
    Code:
    TMap: array of array of Integer;
    Then you define multidimensional array of sprites:
    Code:
    TSprites: array of array of TSprite;
    And then when you move your map you just check which texture should be used for which Sprite like so:
    Code:
    Sprites[X,Y].Texture := Map[X+Left,Y+Top];
    2. Decrease the number of redraws as much as posible. Since you are making a map editor you probably don't even need 30 FPS. So increase the timers interval. Or even better if you are only using static Sprites (no animations) you can forget about constant redraws and actually fire redraws only when there has been any change. This can especially come useful when you are forced to render lots of Sprites (zoomed out view of your map for instance).

    NOTE: All the code examples are purely out of my head so there is great posibility that they have syntax problems in them.

  3. #3
    THANK YOU VERY VERY MUCH!!! I did it, after spending my day here in front of the computer, checkin DraculLin-s Diablo demo, and your advice, I did it. I'm using a 2d map array to store my map, and using a second array of sprites that is
    only as much as needed to fill my rendering surface 640x480 that is 20x15 of 32x32 tiles .

    I'm attaching the code for review, please note the Layer buttons don't do anything at all...neither does the delete... a few of them edits are for debuging .... gona clean up the code, and read layers, then I'll play with using Sprites on this map
    that actualy have animation , like water , lava ... or grass that moves....

    Greetings
    Robert

    ps.: if you try it, please post FPS , on my machine it has 1100 FPS , Core 2 Duo 7500 , Geforce 250GTS , wonder what it does on slower rig....
    Attached Files Attached Files
    Last edited by robert83; 29-12-2012 at 03:39 PM.

  4. #4
    On my laptop (Acer Aspire 6530G with AMD Turion X2 Dual Core 2.0 GHz, ATI Mobility Radeon HD 3650 512 MB VRAM) and Windows 7 I'm getting between 310 and 320 FPS when idle and between 280 and 290 FPS if I do lots of mouse movments which cause selection sprite to move to other tiles.
    The performance isn't affected by the size of the map so you did it.

    BTW you can use any visual component as Aspyhre renderning target. So you don't actually need to create a new form for renderning area but simply use TPanel component for instance. Offcourse having dedicated form is advised if you are making FullScreen mode game to gain aditional performance.
    The reason why I'm telling you this is becouse currently when I launch your program both form sizes exceed the size of my screen so I can't see whole program of yours.

  5. #5
    Thank you very much for the reply. Wow that is great, but how do I do that ? How do I specify AsphyreDevice1 rendring target? I've tried after ApshyreDevice1.Initialize; to add this , AsphyreDevice1.Create(Panel1); but nothing happens...

    Greetings
    Robert

  6. #6
    To be honest I don't know exactly as newest version of Asphyre had some changes in it. But based on the dfm file of your main form AsphyreDevice1 component which has been placed on your MainForm has property WindowHandle which is currently set to 0.
    I belive that changing this property to Panel.Handle should set Panel as rendering target for Asphyre but I'm not sure. You need to change this property prior the Initialization of the engine.

  7. #7
    Did some aditional progress meanwhile, ditched the combobox in favor of ListView, now I can display all them Tiles with Names besides them in a nice manner.

    Also added animated background tiles instead of static.... check out water water_1_1_ani.image,water_1_2_ani.image,water_2_1_ ani.image,water_2_2_ani.image , they are supposed to be assembled in a 64x64 tile...
    like

    Water1,1 ; Water 1,2
    Water2,1 ; Water 2,2

    And damn they move but look darn bad (did it myself... dang, I'm going to have to look for another nicer....way to animate water , that does not overwhelm me, this requires a far better artist then I.

    Anyway please check my latest and greates editor....

    Note : it was designed with 1920x1080 resoltion.

    Greetings
    Robert
    Attached Files Attached Files

  8. #8
    A few more advices:
    1. I see that you are treating every sprite as animation sprite now. This is OK but you don't need to have active animation for every sprite especially if it contains just normal picture and not animatio. Having active animation for sprite which contains just an image slows down everything becouse SpriteEngine still treats it as animation with 1 picture and since you are looping the animation it is always updating its image with the same image. So I recomend you to have active animation only for those sprites which are actually animated.

    2. In DrawLevel procedure you are calling this:
    Code:
    Used_Tile := Images.Item[map.data[i,j+Offset]];
                   BackGround[i, j].ImageName:= Used_Tile.Name;
    This can slow down everything quite a bit since you are searching for needed images using and Image name which can be quite slow.
    Why don't you search for the right image using its index.
    Doesn't TAnimatedSprite alows you to specify its image by directly specifying TAsphyreImage? If it does don't search for proper image using its name but simply specify its Index which should be the same Integer value as you are saving it in Map data.
    Code:
    //Note writen from my head
    BackGround[i, j].Image = Images.Item[map.data[i,j+Offset]];
    3. As for moving water animation the main problem is that you have those white lines which stands out to much. If they would be dark blue it would seen much similar to water than it does now. Infact now it loks more like a bunch of Blue bugs crowding in some place.
    Several picture editing programs low adding watery effect to the pictures so I suggest for you to check it ot if this is supported by your Picture editing programs and the use it. What you actually want is some constant waves movment.

  9. #9
    Hi,

    thank you for the great tips, unfortunately this did not work

    Code:
     BackGround[i, j].ImageIndex = Images.Item[map.data[i,j+Offset]];
    but I'll probably have to spend a bit more time with it, tried it once... but since I was thinking about my water tiles, and then saving loading... , I'll return to this later.

    Also I was wondering if I could solve my sprite animation possible problems later like this ?

    Code:
    procedure TMain.LoadLevel;
    var i,j : integer;
    begin
      for j := 0 to 14 do
        begin
          for i := 0 to 19 do
            begin
                BackGround[i,j] := TBackGround.Create(SpriteEngine);
                BackGround[i,j].ImageName:= 'Empty.image';
                BackGround[i,j].X:=i*32;
                BackGround[i,j].Y:=j*32;
                BackGround[i,j].Z:=1;
                if BackGround[i,j].PatternCount > 1 then
                    begin
                       BackGround[i,j].AnimPos:=random(3);
                       BackGround[i,j].AnimCount:=3;
                       BackGround[i,j].AnimSpeed:=0.010;
                       BackGround[i,j].AnimLooped:=true;
                       BackGround[i,j].DoAnimate:=true;
                   end;
        end;
    end;
    Tried it with my current code, but did not work, nothing moved anymore, maybe it's because I've loaded my images incorrectly into my asdb file? (Will have to check later).

    Anyway here is the latest greates version, now I think my water tile looks like water....added some other tiles. The program is a mess, I know, but I will do the fine tuning later...

    In order to load my test level , you have to click generate level (no need to change 15) , then when you load my level, it will be reset to 30, the length of that level...and you can go up and down in it...change stuff , save it....

    I've found the code on the net, took out some parts I did not need....

    Unfortunately the following did not work with dynamic arrays :

    Code:
     procedure TForm2.Button2Click(Sender: TObject);
    var f:file;
    begin
      if OpenDialog1.Execute then
      begin
        assignFile(f,OpenDialog1.FileName);
        reset(f,1);
        blockread(f,map,sizeof(map)); // load map
        closeFile(f);
        // assign name again
        Edit1.Text:=map.name;
      end;
    end;
    Check out my editor, and leave a comment. The tiles are inspired (and NOT COPIED) from warcraft 2 tileset, I did them myself...

    Greetings
    Robert
    Attached Files Attached Files

  10. #10
    Quote Originally Posted by robert83 View Post
    Hi,

    thank you for the great tips, unfortunately this did not work

    Code:
     BackGround[i, j].ImageIndex = Images.Item[map.data[i,j+Offset]];
    Code:
    Images.Items[map.data[i,j+Offset]]
    is returning a TAspyhreImage result and not Image index.
    Actually you are providing Image index to this line by yourself using:
    Code:
    map.data[i,j+Offset]

    So final code should probably look like this:
    Code:
    BackGround[i, j].Image := Images.Items[map.data[i,j+Offset]];
    asuming that BackGround[i,j].Image is of TAsphyreImage type.


    Quote Originally Posted by robert83 View Post
    Also I was wondering if I could solve my sprite animation possible problems later like this ?

    Code:
    procedure TMain.LoadLevel;
    var i,j : integer;
    begin
      for j := 0 to 14 do
        begin
          for i := 0 to 19 do
            begin
                BackGround[i,j] := TBackGround.Create(SpriteEngine);
                BackGround[i,j].ImageName:= 'Empty.image';
                BackGround[i,j].X:=i*32;
                BackGround[i,j].Y:=j*32;
                BackGround[i,j].Z:=1;
                if BackGround[i,j].PatternCount > 1 then
                    begin
                       BackGround[i,j].AnimPos:=random(3);
                       BackGround[i,j].AnimCount:=3;
                       BackGround[i,j].AnimSpeed:=0.010;
                       BackGround[i,j].AnimLooped:=true;
                       BackGround[i,j].DoAnimate:=true;
                   end;
        end;
    end;
    I belive it should work if PatternCount is automaticly calculated. Try setting a breakpoint inside a if clause to see whether code inside it do executes when needed. If not then probably PatternCount is always returning 1.

    In your program you are using next line:
    Code:
    BackGround[i,j].AnimPos:=random(3);
    This can break animation for continuos tiles like water since neighboring tiles are not synchronized (have different animation position). SO I strongly suggest that you get rid of it. Also you should note that generating random numbers is quite slow so if you call it often it can affect your program performance quite a bit.
    Now I do understand that you would probbably like to have some random animations in case of some animated buildings so that they don't look just like clones of each other. But ass soon as you are dealing with some continuos tiles or contected tiles you need to synchronize their animation ogether.

    Quote Originally Posted by robert83 View Post
    I've found the code on the net, took out some parts I did not need....

    Unfortunately the following did not work with dynamic arrays :
    Code:
     procedure TForm2.Button2Click(Sender: TObject);
    var f:file;
    begin
      if OpenDialog1.Execute then
      begin
        assignFile(f,OpenDialog1.FileName);
        reset(f,1);
        blockread(f,map,sizeof(map)); // load map
        closeFile(f);
        // assign name again
        Edit1.Text:=map.name;
      end;
    end;
    The reason why this probably doesn't work is becouse you would need to first set the size of your arrays manualy by using:
    Code:
    SetLength(Map,Width,Height);
    But I would rather suggest that you make your own map file type which would include all the needed information (width, height, number of layers, map name, etc); Making this would require a bit more code but if done properly would prevent you from having trouble when trying to load unsuported file.
    If you want I can lend you some help in this but I need to know what kinda data structure are you trying to use in your map.

    Also nice work on water texture.
    Last edited by SilverWarior; 31-12-2012 at 07:17 PM.

Page 1 of 9 123 ... LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •