Page 3 of 9 FirstFirst 12345 ... LastLast
Results 21 to 30 of 87

Thread: Space Shooter Game Editor

  1. #21
    Is this about drawing visible map section of 2D grid? You don't need to add any variables to that for background class. It's just small tricks you do in the Draw (DrawLevel?) function.

    1) You have worldX, worldY: single, floating point coords yeah? To get deltaX, deltaY, you can use function frac() for frac(worldX), drac(worldY). I don't know about your scaling, but on all maps i have done, 1.0 value in coords matches size of 1 tile. So if i draw player on 0.5, 0.5, it's in the middle of first tile.

    2) Getting drawable area should be done from the rendering context, be it TForm, TPanel or TOpenGLContext. SX:=context.Width div TileWidth, SY:=context.Height div TileHeight.

    3) When it comes to drawing...
    Code:
    iX:=floor(worldX);
    iY:=floor(worldY);
    for j:=iY-1 to iY+SY do
      if (j>=0) and (j<SizeY) then
        for i:=iX-1 to iX+SX do
          if (i>=0) and (i<SizeX) then begin
            DrawTile(i-iX+deltaX, j-iY+deltaY, @tile[i, j]);
          end;
    That's just from memory though, should work without much modifications.
    Last edited by User137; 03-01-2013 at 10:23 PM.

  2. #22
    You don't need to use more units. the only reason for using more uits is when you are trying to make part of the code so that it can be reusable in some other project of yours (you just add existing unit to another project).
    Also you don't need to make procedure or function for about everyting. You only use procedures or functions for comonly repeated parts of code.

    What I do suggest is simply use basic comenting of your code (you write simple coment on top of your procedure or series of source lines so nex time when you will look at that coude you will know what it is for.
    I'm not usre which development IDE are you using but if your development IDE supports using of Regions (available in Delphi XE or newer and in FPC) learn how to use them.
    The best feature of Regions is that they alow you to make foldable parts of your code and even name them. While regions don't affect the program execution they do provide a way to make your code easily redable.

    About scrolling capabilities while removing smoth capability to scroll your map up and down isn't needed for your editor do make sure that you leave yourself the ability to scroll by line othervise you will just make life for yourself a bit more compicated

  3. #23
    Damn I can't seem to get old Asphyre 3.1.0 eXtreme to sucsessfully compile on my Delphi XE3.
    Also the sprite engine itself is being dependant on some Units that are not present in newest Asphyre Sphinx so I can't get your sprite engine to work with newest Asphre engine.

    Which development IDE are you using anywhay?
    EDIT: Don't mind my last question I already got an answer using PE Explorer

    I gues I need to get my old laptop out of all that dust which acumulated over past years on it, fire up Delphi 7 and try to make precompiled packages for both Asphyre 3.1.0 eXtreme and SpriteEngine so I might be able to use them with Delphi XE3
    Last edited by SilverWarior; 04-01-2013 at 12:53 AM.

  4. #24
    Hello,

    thank you, I've modified myself the Asphyre eXtreme source I use, since dxbase.pas conflicted with devExpress components I use, attached I give you the modified Asphyre eXtreme sources directory zipped , only changed unit names where needed in order to work along with devExpress.

    Maybe I wasn't clear, I do intend to leave alone line by line scrolling for the editor.

    I only intend to remove smooth scrolling in both directions, that is not needed only complicates my life, I will be only scrolling one way trough the game world anyway. Will only keep smooth scrolling up. That is what I meant. The finel editor
    should allow me to test the level , so it would look like the real game, enemy ships comming down and shooting at the player , only the player would be not affacted by this . That reminds me, I will also need to specify for example if Layer3 will only include enemy ships and maybe power up's , I will need to specify in which direction and with which speed will they go, how many lives will they have etc...Will need to think this trough , but I think it would be logical and simple if the map data would hold enemy ship type , life, direction data no? (but this is a bit down on the road...)

    I'm using Delphi 7 SE , works fine on Windows 7 here.

    About the Units I've said, I wanted to seperate em like this, anything related to level loading, drawing etc... will be in unit level for example.
    Everything related to enemies will be in a unit enemies.

    Right now I have some programing to finish here for the company I work for, so I'll be back on programing this editor tomorrow hopefully.

    EDIT :

    meanwhile I've managed to test my editor, on a Duron 1400, SIS661FX_760_741, 512MB ram, Windows XP, got 30 FPS , only thing is in non full screen mode, the screen flickers ... on the Draw surface, but it dissapears in Full Screen mode, this is good. This is quiet a low spec system, Windows XP barelly works on it, not to mention the "GPU".

    Greetings
    Robert
    Attached Files Attached Files
    Last edited by robert83; 04-01-2013 at 06:41 PM.

  5. #25
    Hello,

    SilverWarriror, I've changed my map layout to the one youv'e suggested :
    Code:
       TTileData=record
             ImageIndex: integer; // Tile Number
             AnimStart: integer; // Tile Animation Start Position
             AnimSpeed: Single; // Tile Animation Speed
             AnimCount: Integer; // Tile Animation Count
            end;
      TMapLine=array [0..19] of TTileData; // Stores one line of tile data
      TMap=record
             name:string[20];  // Name of the Map
             map_length:integer; // Length of the Map
             Lines: array of TMapLine; // stores the Entire map [0,0..19] , first value is 0 till map_length (vertical), second value is 0..19 (horizontal)
           end;
    I've also managed to get smooth scrolling working in one direction using your method (took me a while I know, had some brainfog issues, was sitting before this damn computer for many hours and nothing, couldn't even start...then yesterday it suddenly hit me.

    This is the code that moves the map down ( I'll reverse my logic...and guess it'll work for up )

    Code:
     procedure TMain.TestExecute(Sender: TObject);
    var x,y : integer;
        new_line : boolean;
    begin
      if Offset < Map.map_length-14 then    // -14 , Number of Tile Lines Drawn on Screen
        begin
        inc(Counter,1);         // I'm using this to check if I've scrolled down one tile Height (32), if I did
        if Counter = 32 then    // then I'm increasing Offset by 1 and reseting Counter to 0, Offset is used to tell the new line of sprites which Line of TileData
          begin                 // to read from the array
            Inc(offset,1);
            Counter:=0;
          end;
        for y:=0 to 15 do
          begin
            for x :=0 to 19 do
              begin
                BackGround[x,y].Y:=BackGround[x,y].Y-1;
                if BackGround[x,y].Y = -32 then
                  begin
                    BackGround[x,y].Dead;
                    new_line := true;
                  end;
                if new_line = true then
                  begin
                    BackGround[x,y]:= TBackGround.Create(SpriteEngine);
                    Edit9.Text:=inttostr(offset);
                    BackGround[x,y].ImageName:= Images.Item[map.Lines[offset+15,x].ImageIndex].Name;
                    if BackGround[x,y].PatternCount = 1 then
                      begin
                        BackGround[x,y].DoAnimate:=false;
                      end
                    else
                      begin
                         BackGround[x,y].AnimStart:=0;
                         BackGround[x,y].AnimCount:=map.Lines[offset+15,x].AnimCount;
                         BackGround[x,y].AnimSpeed:=map.Lines[offset+15,x].AnimSpeed;
                         BackGround[x,y].AnimPos:=(GlobalAnimCounter mod BackGround[x,y].AnimCount)+map.Lines[offset+15,x].AnimStart;
                         BackGround[x,y].DoAnimate:=true;
                         BackGround[x,y].AnimLooped:=true;
                      end;
                    BackGround[x,y].X:=x*32;
                    BackGround[x,y].Y:=480;
                    BackGround[x,y].Z:=1;
                    new_line:=false;
                  end;
              end;
          end;
      end;
    end;

    Everything is nice with this, works like magic, but I have one problem... the animation is not in sync, I'm using GlobalAnimationCount as you've suggested (it works when I scroll trough the map line by line, but not when I do this smooth scrolling)

    EDIT : actually the newly created TILE Lines are in sync , meaning each New line which has 15 Sprites , all of them 15 sprites are in sync, but everytime a new line is created it's not in sync with the previous line.

    This is how GlobalAnimationCount is increased
    Code:
       if GlobalAnimCounter = 1000 then GlobalAnimCounter:=0;
      inc(GlobalAnimCounter,1);
    This above is defined on AsphyreDevice1.Render.


    Any idea why my anim is out of sync when "smooth" scrolling down, but not out of sync when scrolling line by line. I'm doing the same thing on Drawlevel and there it works :

    Code:
    procedure TMain.CreateSprites;
    var x,y : integer;
    begin
    // this procedure creates the starting sprites for one screen and fills them with Empty.image
      for y := 0 to 15 do  // vertically
        begin
          for x := 0 to 19 do   // horizontally
            begin
                BackGround[x,y] := TBackGround.Create(SpriteEngine);
                BackGround[x,y].ImageName:= 'Empty.image';
                BackGround[x,y].X:=x*32;
                BackGround[x,y].Y:=y*32;
                BackGround[x,y].Z:=1;
            end;
        end;
    end;
    
    procedure TMain.DrawSprites;
    var x,y: Integer;
    begin
    // this procedure changes the images for every sprite created at startup, creating the illusion of scrolling trough the map
    // line-by-line
         for y := 0 to 15 do   // vertically
            begin
              for x := 0 to 19 do // horizontally
                begin
                
                 BackGround[x,y].ImageName:= Images.Item[map.Lines[y+Offset,x].ImageIndex].Name;
                 if BackGround[x,y].PatternCount = 1 then
                    begin
                      BackGround[x,y].DoAnimate:=false;
                    end
                  else
                    begin
                       BackGround[x,y].AnimStart:=0;
                       BackGround[x,y].AnimCount:=map.Lines[y+Offset,x].AnimCount;
                       BackGround[x,y].AnimSpeed:=map.Lines[y+Offset,x].AnimSpeed;
                       BackGround[x,y].AnimPos:=(GlobalAnimCounter mod BackGround[x,y].AnimCount)+map.Lines[y+Offset,x].AnimStart;
                       BackGround[x,y].DoAnimate:=true;
                       BackGround[x,y].AnimLooped:=true;
                    end;
                end;
            end;
    end;
    EDIT : I was thinking that maybe I should use another counter , which would count the time between two created sprites ?

    1 I create the initial sprites 16 lines 0..15 .
    2 I start moving the sprites up (lines 0..15) and start the differential_timer
    3 I destroy spriteline which is -32 , and add a new sprite line and reset differential timer to 0 ( here I'm not sure... I maybe do this ?
    Code:
                          BackGround[x,y].AnimPos:=(GlobalAnimCounter-differential_timer mod BackGround[x,y].AnimCount)+map.Lines[offset+15,x].AnimStart;
    )

    and I keep repeating step 1,2,3 till I reach the end. This idea any good?
    Greetings
    Robert
    Last edited by robert83; 10-01-2013 at 01:22 PM.

  6. #26
    From your code I see that you are resetting your Global Animation Counter when it reches 1000. If I remember corectly your water animation has 3 pictures. So as 1000 is not dividable by 3 this creates a problem. So you should reset your counter at 999 and you should go and reset it to1 or if you have first animation picture at index 0 you should reset your counter at 998 and then reset it to 0.
    But there will be even bigger problem once you introduce animation with varios speeds and various lenghts. Why? Becouse you will need to find a right point when to reset your counter (first point when all animations would reach the starting position).
    Best way to do this is to calculate how much time each animation loop lasts (animation lenght * animation speed - where animation speed determines time between animation updates) and then find a time when all these animations will reach to starting position at the same time.
    You do this by finding first number which is dividable with all theese loop times. If my memory servews me correct there is a function in Math unit to do this. Do note that this function can be quite slow at some times.
    Workaround for this is to simply multiply all these loop times between each other as this will give you certain point in time when all these animations do get to starting position but ti might not be the first time when this happens.
    So for instance if you have three different animations first lasts two seconds, second lasts three seconds and third lasts 5 seconds you will the time when all of theese gets to starting position at the same time using 2*3*5=30. So int this case you could reset your Global Animation Counter every 30 seconds.

    I hope my explanation is understandable enough. I'm also sorry that I haven't yet prepared my programing enviroment to be able to compile your project. After about thee years I had some problems with my laptop for the first time which required some troublehunting. In the end it turned out that some files belonging to Eset antivirus software were damaged which in some ocasions caused unexpected program behavior. Also I noticed some system slowdows incase of large HDD activity but I'm not yet sure whether this is due to some software problem or it is hardware related (HDD S.M.A.R.T reports shows no anomalies or problems, but there is ocasional clickig sound coming from HDD but no Bad sectors yet).
    Best solution would be for me to buy a new disk drive probbably SSD and instal it as second drive (my laptop actually supports usage of two SATA 3 hard drives) and reinstal my whole operating system. This would alow me to keep all the old data so that incase I screw up something I don't use any data (I do have lots of important data on my Laptop and no space to make a safety backup of it). And another problem is that as I didn't had Windows 7 before my data isn't quite organized.
    Last edited by SilverWarior; 10-01-2013 at 03:36 PM.

  7. #27
    Hi,

    OFFTOPIC

    or use Virtual Machine with Windows 7 , I actually use windows xp virtual machine to administer my samba domain controllers...
    or just install Delphi 7 on Win7 , or Delphi 7SE if you wish...it works.

    OFFTOPIC

    Anyway I've decieded to attach my latest source, I've redid the entire window, this should be fully visible on your laptop screen (it is on mine... think it's 1280x800 or something....)

    You open up the editor...then click on FILE-OPEN level02.map ...then press the up arrow key (don't ask...why I used it for down )

    I've completely removed the GlobalAnimCounter reset...as you can see it goes till it reaches it's limit and probably makes the app crash or something....

    As you can see when you press UP arrow , and the map moves down... each new sprite line is created (every sprite on the new line is in sync with each other) , but each NEW sprite line is a bit off from the previous creating my wave effect....

    Greetings
    Robert
    Attached Files Attached Files

  8. #28
    If you must use such global animation counter, couldn't you make it single type, and run from [0.0 .. 1.0[ (means 1.0 isn't included)? Then just scale each animation to its specific framecount.
    Code:
    AniPos:=trunc(GlobalCounter*FrameCount);
    Code:
    GlobalCounter:=GlobalCounter+0.02; 
    if GlobalCounter>=1 then GlobalCounter:=GlobalCounter-1;
    Last edited by User137; 11-01-2013 at 09:00 AM.

  9. #29
    PGD Staff / News Reporter phibermon's Avatar
    Join Date
    Sep 2009
    Location
    England
    Posts
    524
    Ok so your basic issue is synchronizing the animation of sprites, that may of been added at any time during the animation of the others.

    There are many ways you could do this (although unless you have two co-dependant animations I can't see why you'd want this) but rather than incrementing every single sprite for the next frame of animation, how about you group the same sprites together or sprites that have the same number of frames? IE:

    SpriteGroup1_FrameNumber = 3

    for I := 0 to SpriteGroup1_SpriteCount-1 do
    Spites[I].CurrentFrame = spritegroup1_framenumber;


    That way you can ensure that for animations of the same speed/number of frames, that they are always rendered on the same frame, regardless if one was added halfway thru the animation cycle.

    Now as far as synchronzing animations of different lengths, why? scheduling so they start at the same time will mean that at some point, you'll have something that should be on screen, but isn't because it's waiting for the start of the next cycle.

    if you have animations of different lengths that you wish to synchronize, then you should scale the frame-rate of one of the animations so they both take the same amount of time to run.

    --

    I'm currently extending my 3D animation lib with better interpolation between animations. Here's an example to get you thinking :

    Walk animation -15 frames - 0.8 second cycle from left foot to left foot. actual movement Speed = 3
    Run animation - 20 frames - 0.4 second cycle """ actual movement Speed = 5

    So how do you smoothly interpolate the skeleton between frames so you can blend walk into run and visa versa?

    The trick is (other than other artist/bone related stuff to make animations that will blend well) that you scale both
    animations at the same time. so if walk has an anim cycle of 0.8, and run 0.4, then halfway through the blend, both animations are scaled so they both have a cycle of 0.6 and a speed of 4 (exactly half way between the two).

    So it doesn't matter where in the animation you start running or walking, it'll always be able to interpolate fairly well.

    --

    As far as sprites are concerned, what's so offputting about the non synchronized animations? if you created a forest you want all the trees to sway in sync?

    Like I say, unless your animations are co-dependant and require sync (two sprites throwing a ball at each other) then you should probably not bother.

    Oh and if you absolutely must sync different length anims so they start on the same frame, then just add dummy frames to the shorter one so it's the same number of frames. yes that'll use slightly more more memory but you'll save yourself a whole bunch of code. Combine that with grouping of sprites
    Last edited by phibermon; 11-01-2013 at 01:17 PM.
    When the moon hits your eye like a big pizza pie - that's an extinction level impact event.

  10. #30
    I must have perfectly synced sprites somehow, I don't want to complicate my life with Sprite Groups...
    For example I might want to have some object that consists of 4 tiles do something out of sync, other times in a certain order, or in perfect sync. I believe it should be doable to sync newly created tiles with previously created tiles, only problem is this seems to be beyond my knowledge right now...

    I've tried to do it like this :

    1. Created a new 2d array , that is responsible for holding the current animation position for every tile on my tile map ( I though baaammmmmmm eat this EVIL sprite engine time offset demon )
    Code:
      TAnimTable=array of array [0..19] of single;
    2. I've created the following procedure :
    Code:
    procedure TMain.AnimCounter;
    var i,j: integer;
    begin
          for i:=0 to Map.map_length do
            begin
              for j:=0 to 19 do
                begin
                  if map.Lines[i,j].AnimCount > 1 then
                    begin
                      AnimTable[i,j]:=AnimTable[i,j]+(1*map.Lines[i,j].AnimSpeed);
                    end
                  else
                    begin
                      AnimTable[i,j]:=1;
                    end;
                  if AnimTable[i,j] > map.Lines[i,j].AnimCount then AnimTable[i,j]:=0;
                end;
            end;
    end;
    This I've checked (using a few EDIT boxes ) works, for example Animated Sprite at 0,0 has 3 animation positions , and it's speed is 0,01 ... I've checked the position goes up with the apropriate speed.
    I've added another Sprite at 0,1 which has 6 animation positions, and it's speed is 0,5 , I've checked it again it goes at a much faster rate...

    I thought to myself YEAH I solved this darn problem... (and the program is still pretty fast, even on me amd duron 1400+ , with my test level...which is not to long , but I don't plan to make enormous levels...a dude has to start somewhere...)

    I've modified my smooth scroll test procedure a bit :

    Code:
    procedure TMain.TestExecute(Sender: TObject);
    var x,y : integer;
        new_line : boolean;
    begin
      if Offset < Map.map_length-14 then    // -14 , Number of Tile Lines Drawn on Screen
        begin
        inc(Counter,1);         // I'm using this to check if I've scrolled down one tile Height (32), if I did
        if Counter = 32 then    // then I'm increasing Offset by 1 and reseting Counter to 0, Offset is used to tell the new line of sprites which Line of TileData
          begin                 // to read from the array
            Inc(offset,1);
            Counter:=0;
          end;
    
        for y:=0 to 15 do
          begin
            for x :=0 to 19 do
              begin
                BackGround[x,y].Y:=BackGround[x,y].Y-1;
                if BackGround[x,y].Y = -32 then
                  begin
                    BackGround[x,y].Dead;
                    new_line := true;
                  end;
                if new_line = true then
                  begin
                    BackGround[x,y]:= TBackGround.Create(SpriteEngine);
                    Edit9.Text:=inttostr(offset);
                    BackGround[x,y].ImageName:= Images.Item[map.Lines[offset+15,x].ImageIndex].Name;
    
                    if BackGround[x,y].PatternCount = 1 then
                      begin
                        BackGround[x,y].DoAnimate:=false;
                      end
                    else
                      begin
                       BackGround[x,y].DoAnimate:=true;
                       BackGround[x,y].AnimLooped:=true;
                      end;
                    BackGround[x,y].X:=x*32;
                    BackGround[x,y].Y:=480;
                    BackGround[x,y].Z:=1;
                    new_line:=false;
                   end;
                   BackGround[x,y].AnimStart:=round(AnimTable[x,y+Offset]);
                   BackGround[x,y].AnimCount:=map.Lines[y+Offset,x].AnimCount;
                   BackGround[x,y].AnimSpeed:=map.Lines[y+Offset,x].AnimSpeed;
              end;
          end;
      end;
    end;
    The AnimCounter procedure is executed at AsphyreDevice1Render .

    And I still get the cursed wave effect , how....is....this....possible ?

    Now that I think of it...maybe the problem is...that now since I'm doing the position calculation... maybe I should manually step the images? Can I do that somehow?
    The idea here was to calculate all animation positions for every tile , even uncreated... thus eliminating the lag caused by it's creation... I think it should work...if I could somehow manually step the Sprite Position
    every time when the TEST action runs to my AnimTable[x,y] position... I can even add Animation Offset into this combo...


    Greetings
    Robert
    Last edited by robert83; 11-01-2013 at 07:28 PM.

Page 3 of 9 FirstFirst 12345 ... 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
  •