locked
Index was outside the bounds of the array RRS feed

  • Question

  • Hey guys, 

    Upon hosting the game that I am making, and having three friends join up (four including me were in the game) The game gave me an error I haven't seen before. I figured I'd show yall' and hopefully get some insight on how to fix it.

    I think this has to do with the LD physics extension, because that is where I'm using LDPhysics.AddMovingShape

    Here is the error:

    This is what my code looks like for adding the shapes:

    For i = 1 To NumShips
      For h = 1 To WeaponArrays[WeaponNumber[i]]["BallCount"]
        Explosion[h][i] = LDShapes.AddAnimatedImage(Program.Directory + "\" + WeaponArrays[WeaponNumber[i]]["Animation"],"False",WeaponArrays[WeaponNumber[i]]["AnimCountx"],WeaponArrays[WeaponNumber[i]]["AnimCounty"])
        Shapes.HideShape(Explosion[h][i])
        If WeaponArrays[WeaponNumber[i]]["ProjectileAniX"] = 1 And WeaponArrays[WeaponNumber[i]]["ProjectileAniY"] = 1 Then
          Bullet[h][i] = Shapes.AddImage(Program.Directory + "/" + WeaponArrays[WeaponNumber[i]]["Projectile"])
        Else
          Bullet[h][i] = LDShapes.AddAnimatedImage(Program.Directory + "/" + WeaponArrays[WeaponNumber[i]]["Projectile"],"True",WeaponArrays[WeaponNumber[i]]["ProjectileAniX"],WeaponArrays[WeaponNumber[i]]["ProjectileAniY"])
        EndIf
        LDPhysics.AddMovingShape(Bullet[h][i],0.7,0.7,0.7)
        LDPhysics.SetBullet(Bullet[h][i])
        LDPhysics.SetPosition(Bullet[h][i],10000 + (i*200),10000 + (h * 200),0)
        LDPhysics.SetVelocity(Bullet[h][i],0,0)
      EndFor
    EndFor

    Also note that this only happens if there are more that a few players.

    Thanks!!


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11


    Sunday, January 11, 2015 3:08 PM
    Answerer

Answers

  • OK, my test code after a little checking... (simplify as much as possible - main debug rule)

    GraphicsWindow.Width = 500
    GraphicsWindow.Height = 500
    For i = 1 To 90
      ball = Shapes.AddEllipse(50,50)
      TextWindow.WriteLine(ball)
      'Shapes.Move(ball,Math.GetRandomNumber(500),Math.GetRandomNumber(500))
      LDPhysics.AddMovingShape(ball,0.7,0.7,0.7)
    EndFor

    Uncomment the line and it works.

    It looks like there is a limit to the number of shapes that can be on top of each other - not surprising really!

    So I think you need to do something like I did or maybe better only add the bullets or other shapes to the physics engine when you want to use them - you can create all the shapes first but only add to LDPhysics when they are to interact e.g. when a bullet is fired.

    PS your game looks brilliant another Zock epic!

    • Edited by litdev Sunday, January 11, 2015 7:16 PM
    • Marked as answer by Zock77Editor Monday, January 12, 2015 7:53 PM
    Sunday, January 11, 2015 7:13 PM

All replies

  • This is going to be tricky to debug unless I can reproduce it - on a multi-player setup this may be hard and best if you do the testing, so some initial questions - if you could answer these first.

    1. Can you reliably reproduce it?
    2. Do you know which AddMovingShape it is? - if not then some debug output to a file or TextWindow.
    3. There are serveral errors listed so does the game continue OK?
    4. Is the code sample that causes the problem called from the main UI thread or from a Timer/Event (i.e. asynchronously)?

    So the first step is to get to a point where it can be reproduced as easily as possible, then I can add some further debug output inside the methods to try to determine what is happening - some test builds of the extension.

    One issue is that there is a lot of code in this function (much of it Box2D) so its not easy to see what might be the issue by visually inspecting the code.  There may be some Box2D limits or some kind of threading issue or something else.

    Sunday, January 11, 2015 3:40 PM
  • So as for the questions:

    1) Yes I can. With four PC in the game, It always happens

    2) I am not 100% positive yet, but I'm pretty sure I know which.

    3) the reason I fairly sure is because the game continues alright, but for one ore two people only being able to fire 50% of the time. I think its because not all their bullets were created.

    4) It seems to happen while the game is loading. And the PCs get the errors one after another. Just as if it was loading them like this:

    For i = 1 To NumShips
      For h = 1 To NumBullets
          Bullet[h][i] = Shapes.AddEllipse(10,10)
         LDPhysics.AddMovingShape(Bullet[h][i],0.7,0.7,0.7)
      EndFor
    EndFor



    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Sunday, January 11, 2015 4:15 PM
    Answerer
  • I think It might be better if you saw for yourself :D

    https://www.youtube.com/watch?v=qENSX9oYlfI&feature=youtu.be


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11


    Sunday, January 11, 2015 4:16 PM
    Answerer
  • OK, thanks for this.  I'm just trying to narrow things down a bit before proceeding.

    1. I assume it works OK with fewer players?
    2. Does it also fail with multi-players on different PCs?
    3. Why do you click Host Game for the clients?
    4. Is the server also running on the same PC?

    If it can be recreated on a single PC, can you zip up the whole thing (i.e. + images + other extension dlls etc) so I can run it like in your youtube.  Was the server also running on the same PC.

    Basically if it can be reproduced on 1 PC I can test and find out what is going on.

    Sunday, January 11, 2015 5:06 PM
  • 1) Yes it works well with two players, but I haven't tried three yet :D

    2) And It also fails with 4 PCs. That was where I found the issue.

    3) Thats kinda tricky. So the server is in the same program as the client program. So the way it works is if the player presses "Host game", then the program will host a server and then connect to itself. That way I can use only one program for the server and client. The buggy thing about it, is the extension will only host one server at a time. So the other players on the same PC will try to host a server, Fail at it, and then try to join itself. which works because there is already a server hosted on that PC :D

    4) I think that also answers number 4 too.

    Here is the program all packed up: http://www.mediafire.com/download/2m2guvx7kfkz42r/Armored_Assault.zip


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Sunday, January 11, 2015 5:30 PM
    Answerer
  • Thanks, downloaded and see the error.  I actually get an exception, but assume it is the same and will report back.

    Sunday, January 11, 2015 5:51 PM
  • OK, my test code after a little checking... (simplify as much as possible - main debug rule)

    GraphicsWindow.Width = 500
    GraphicsWindow.Height = 500
    For i = 1 To 90
      ball = Shapes.AddEllipse(50,50)
      TextWindow.WriteLine(ball)
      'Shapes.Move(ball,Math.GetRandomNumber(500),Math.GetRandomNumber(500))
      LDPhysics.AddMovingShape(ball,0.7,0.7,0.7)
    EndFor

    Uncomment the line and it works.

    It looks like there is a limit to the number of shapes that can be on top of each other - not surprising really!

    So I think you need to do something like I did or maybe better only add the bullets or other shapes to the physics engine when you want to use them - you can create all the shapes first but only add to LDPhysics when they are to interact e.g. when a bullet is fired.

    PS your game looks brilliant another Zock epic!

    • Edited by litdev Sunday, January 11, 2015 7:16 PM
    • Marked as answer by Zock77Editor Monday, January 12, 2015 7:53 PM
    Sunday, January 11, 2015 7:13 PM
  • There also seems to be a limit on the number of physics engine shapes that can be added, it is 512 and this is also exceeded.  I could increase this limit, but it may have other cinsequences - I suggest consider trying not to exceed this limit.

    I have uploaded a beta version (usual place) with this limit raised to 1024, which works for your game with 4 players with n alterations, but I suggest consider reducing the number of active objects and only adding when needed, also limit the initialisation of large numbers of shapes on top of each other.

    Sunday, January 11, 2015 8:41 PM
  • Great! I just found that about 450 of my Physics objects were just bricks! It'll need a bit of optimization there :D

    I do have some other physic extension related questions for you though:

    1) For whatever the reason, none of the physics objects will respond to  anything if gravity is set to (0,0) (or anything less than about 5) I have no clue why, so I thought I'd bring it up here. (See line 388 in the program)

    2) I was hoping you might add something to the extension that would enable me to set the rotation of the object without setting the position. This would be helpful with objects that have been attached with rotation.

    3) I wanted some advise on checking collision. Right now I have a For statement going through all the bullets, and checking them individually. I am wondering if there is a better way to do it. Here is my checkhit code:

    Sub CheckBulletCollision
      For CheckS = 1 To NumOfShips
        For CheckB = 1 To WeaponArrays[WeaponNumber[CheckS]]["BallCount"]
          Collision = LDPhysics.GetCollisions(Bullet[CheckB][CheckS])
          If Collision <> "" Then 
            LDPhysics.SetPosition(Bullet[CheckB][CheckS],10000 + (CheckS*200),10000 + (CheckB * 200),0)
            LDPhysics.SetVelocity(Bullet[CheckB][CheckS],0,0)
            Shapes.Move(Explosion[CheckB][CheckS],LDShapes.GetLeft(Bullet[CheckB][CheckS]),LDShapes.GetTop(Bullet[CheckB][CheckS])-32)
            LDShapes.AnimationSet(Explosion[CheckB][CheckS],1)
            Shapes.ShowShape(Explosion[CheckB][CheckS])
          EndIf
          If Collision[1] = Ship[UserNum] Then
            TankHealth[UserNum] = TankHealth[UserNum] - WeaponArrays[WeaponNumber[CheckS]]["Damage"]
          EndIf
        EndFor
      EndFor
    EndSub
    Thank you very much!


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11



    Monday, January 12, 2015 6:16 PM
    Answerer
  • 1] Check out physics-samples/physics-samples-water.sb and physics-samples/pool.sb, both examples with 0 gravity - float about until hit by something or an impuse applied.

    2] Setting position and angle should usually only be done at the start - interactions are by applied forces, impulses and torques.  Having said that I added (uploaded to beta) SetAngle (internally just calls getPosition, then setPosition with the new angle).

    3] Check out LDPhysics.GetCollisions physics-samples/Example9.sb for bullet hit test.

    Monday, January 12, 2015 7:35 PM
  • With regard to the zero graviy - I see that in your game you set position and velocity to control things - really the physics engine calculates these so you should be setting forces, impulses and torques and letting the engine calculate the movements.  The physics just runs accourding to applied forces (gravity is just another acceleration force).  This is abit more like reality (we move something by applyng a force to it - we cannot instantly change something's velocity or position - that would be teleportation which Newton et al wouldn't like).

    Its a biit of a paradigm shift from standard Small Basic movement where you calculate velocity and position.

    Monday, January 12, 2015 7:59 PM
  • I would really like to use force and impulse to control them, but I haven't yet figured out a way to make a proper movement that looks like a tank moving. This is because there is no friction at all in the "Z" axis (Down for the tank) This means that if the tank is pointing downwards on the screen, and I apply force to it, it will start moving as it should, but if I turn the tank to the left or right, it will still move down. 

    As for the setting of position, I see no way around that for the multiplayer part of having to move an object to the other players tank location.

    If there is a better way to do it, I would LOVE to hear it :D


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Monday, January 12, 2015 10:23 PM
    Answerer
  • I agree its tricky, the Box2D is really suited to 2D platform type games with collidin, rolling bricks etc.
    Tuesday, January 13, 2015 6:30 PM
  • Check this out! http://www.iforce2d.net/b2dtut/top-down-car

    Unfortunately I don't know to much physics, so this may take a while to Decipher. :) 


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Tuesday, January 13, 2015 7:05 PM
    Answerer
  • Exactly so, the tyres exert forces on the ground such that they roll in their direction and don't skid sideways.  But as you see there is quite a bit of geometry to keep appying correcting tyre forces.

    If you take this approach I would start with a simple test (a rectangle car and accelerate(W), brake(S), stear left(A) stear right(D) controls) and treat the whole car as just one tyre that:

    1. All in 0 gravity
    2. Rolls easily in direction pointed - can accelerate(W) or brake(S) in easily in this direction - impules applied in this direction
    3. Some resistance to motion - drag - like a small continuous brake (possibly velocity dependent like air resistance)
    4. No lateral skidding - forces must be calculated and applied to prevent this - especially when changing direction - the  lateral velocity (momentum) calculated then oppsite force applied.
    5. The direction can be changed by stearing

    A realy nice challenge and I may have a go at a simple setup for this, and if it looks nice may add a tyre object to the engine - no timescale and no guantees but sounds like fun trying.

    Tuesday, January 13, 2015 10:19 PM
  • Sounds great! I too will have a go at it!

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Tuesday, January 13, 2015 10:24 PM
    Answerer
  • I DID IT!!! :D 

    RQG397

    GraphicsWindow.Width = 800
    GraphicsWindow.Height = 600
    
    Wheel = Shapes.AddRectangle(40,100)
    Shapes.Rotate(Wheel,0)
    Shapes.Move(Wheel,100,200)
    
    LDPhysics.AddMovingShape(Wheel,0.8,0.8,0.8)
    LDPhysics.SetVelocity(Wheel,20,20)
    
    LDPhysics.SetGravity(0,0)
    
    For i = 1 To 5
      Text[i] = Shapes.AddText("")
      Shapes.Move(Text[i],100,20*i)
    EndFor
    
    While 1 = 1
      Program.Delay(10)
      
      LDPhysics.DoTimestep()
      GlobalVelocityArray = LDPhysics.GetVelocity(Wheel)
      
      GlobalVelocity = Math.SquareRoot((GlobalVelocityArray[1]*GlobalVelocityArray[1]) + (GlobalVelocityArray[2]*GlobalVelocityArray[2]))
      
      
      'Get movement direction
      OldX = X
      OldY = Y
      X = LDShapes.GetLeft(Wheel)
      Y = LDShapes.GetTop(Wheel)
      MovementAngle = Math.Round(Zock77Math.GetAngle(X,OldX,Y,OldY))
      
      'Get Lateral Direction
      LateralAngle = LDPhysics.GetAngle(Wheel) + 90
      If LateralAngle >= 360 Then
        LateralAngle = LateralAngle - 360
      EndIf
      
      'Get angle difference
      Difference = Math.Remainder(Math.abs(LateralAngle - MovementAngle),360)
      if(Difference > 180) Then
        Difference = 360 - Difference
      EndIf
    
      
      'Get the Lateral Velocity 
      LateralVelocity = Math.Sin(Math.GetRadians(Difference+90)) * GlobalVelocity
      
      'Get the X and Y impulses
      YImpulse = Math.Cos(Math.GetRadians(LateralAngle)) * (LateralVelocity * LDPhysics.GetMass(Wheel))
      XImpulse = Math.Sin(Math.GetRadians(LateralAngle)) * (LateralVelocity * LDPhysics.GetMass(Wheel))
      
      'Aplly the impulses
     LDPhysics.SetImpulse(Wheel,-XImpulse,YImpulse)
      
      Shapes.SetText(Text[1],"GlobalVelocity: " + GlobalVelocity)
      Shapes.SetText(Text[2],"MovementAngle: " + MovementAngle)
      Shapes.SetText(Text[3],"XImpulse: " + -XImpulse)
      Shapes.SetText(Text[4],"YImpulse: " + -YImpulse)
      Shapes.SetText(Text[5],"LateralVelocity: " + LateralVelocity)
      
      If LDUtilities.KeyDown("Right") Then
        LDPhysics.SetRotation(Wheel,10)
      EndIf
      If LDUtilities.KeyDown("Left") Then
        LDPhysics.SetRotation(Wheel,-10)
      EndIf
    EndWhile


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Wednesday, January 14, 2015 8:40 PM
    Answerer
  • And here is a car with four wheels on it! ZRZ228

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Wednesday, January 14, 2015 10:28 PM
    Answerer
  • Wow - that is great Nice job....  You have really got the hang of Box2D.  Its all forces, impuses and torques - there is much more in it than I expose in SB, perhaps have a go in C# too.

    Here is my first pass at extending LDPhysics (beta extension uploaded).  More tweeking probably needed.

    Here is my test code to go with it.

    'carImage = ImageList.LoadImage(Program.Directory+"\car.png")
    LDGraphicsWindow.State = 2
    carImage = ImageList.LoadImage("http://litdev.co.uk/game_images/car.png")
    MakeCar()
    'TextWindow.WriteLine(LDPhysics.GetTireProperties(car))
    LDPhysics.SetGravity(0,0)
    
    While ("True")
      Update()
      LDPhysics.DoTimestep()
      Program.Delay(20)
    EndWhile
    
    Sub Update
      If (LDUtilities.KeyDown("Left")) Then
        LDPhysics.TurnTire(car,-250)
      EndIf
      If (LDUtilities.KeyDown("Right")) Then
        LDPhysics.TurnTire(car,250)
      EndIf
      If (LDUtilities.KeyDown("Up")) Then
        LDPhysics.MoveTire(car,150)
      EndIf
      If (LDUtilities.KeyDown("Down")) Then
        LDPhysics.MoveTire(car,-150)
      EndIf
      If (LDUtilities.KeyDown("Space")) Then
        LDPhysics.BrakeTire(car)
      EndIf
    EndSub
    
    Sub MakeCar
      car = Shapes.AddImage(carImage)  
      LDPhysics.AddMovingShape(car,0.8,0.05,1)
      LDPhysics.SetPosition(car,GraphicsWindow.Width/2,GraphicsWindow.Height/2,0)  
      LDPhysics.SetTire(car)
      LDPhysics.SetTireProperties(car,"AntiSkid=5;") 'Reduced skid from default (3)
    EndSUb


    • Edited by litdev Wednesday, January 14, 2015 10:45 PM
    Wednesday, January 14, 2015 10:44 PM
  • Thats great!! It feels perfect!

    Is there a reason why you set the car as a tire instead of making four tires and adding them to the car?


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Wednesday, January 14, 2015 11:46 PM
    Answerer
  • It would be cool if there was a way to tell if it was skidding, so I could add skid marks :)

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Thursday, January 15, 2015 12:21 AM
    Answerer
  • Is there a reason why you set the car as a tire instead of making four tires and adding them to the car?


    Yes, just for simplicity and using a car image doesn't need wheels added.  The name tire for the object is just a name and means anything that behaves like a tire.
    Thursday, January 15, 2015 9:23 AM
  • Added (uploaded new beta) with method to get tire information, currently just "Skid".  My test sample: KNS884

    The value is just impulse.Length() in the skidding section:

      //in updateFriction, lateral velocity handling section
      b2Vec2 impulse = m_body->GetMass() * -getLateralVelocity(); //existing code
      if ( impulse.Length() > maxLateralImpulse )
          impulse *= maxLateralImpulse / impulse.Length();
      m_body->ApplyLinearImpulse( impulse, m_body->GetWorldCenter() ); //existing code
    And Crash Information, XDS296

    • Edited by litdev Thursday, January 15, 2015 7:55 PM
    Thursday, January 15, 2015 7:11 PM