0

I am very new to jquery, javascript and coding generally. I have however set myself the task of making a simcity style javascript game. I am having a number of issues but the first one is the movement of a gif accross the game "board" The images are a top-down veiw of a man with wheel barrow, by moving this image accross the board using jquery to change the css top and left values I hope to imatate movement.

The aim is for these "workmen" is to take resources from a sawmill for example to the warehouse, then return for another load.

I have a function called Animate_Int() which is run every 50 miliseconds using a setinterval which controls the movement of the image. Using a For Loop I move the image 60 (1 pixel every time through the loop) pixels either north, south, east or west and then calls a simple path finding function I have written to determine the next direction to take.

This works perfectly while there is only one image of a "worker" on the page at any one time. The complication arises when a second sawmill is built. The worker from the first sawmill will continue his journey to and from the warehouse perfectly but the second worker will make his first move without fault but then seems to materialise ontop of the first worker to follow his movement.

The website requires a login and previous tasks to be completed before the game so cannot link to an example (although if this is essential I may be able to make a new page outside the login system).

//Update - I have managed to preapare a page outside the login system to show you what the issue is. http://www.tranquilityeden.co.uk/colony/example.php To make the problem happen you must do the following: 1- Use FF as it doesn't seem to work on any other browser currently (seperate issue!)

2- when viewing the game board click on an Ind tile

3-then when the window pops up with options scroll down to the sawmill. click on the upgrade (currently it will only happen when building sawmill)

4-when you have built the sawmill watch the little man make his journey to the warehouse (WH) and he will return home and then repeat the process.

5- build a second sawmill and watch the crazyness!! //

I have included the code below for the Animate_Int() function as I think the problem may be in the this function, although I cannot be sure.

function Animate_Int()
    {
    if(pause ==1)      //stops animation of images if game is paused
    {return;}
    else if(Active_Workers.length !=0) //Stops animation if no sawmills have been built
    {
          for(var i=0;i<=Active_Workers.length;i++)
        {
            var x;
            var y;
            var index = Active_Workers[i];    //An array that holds the ids of each active worker
            var Image = Animate_Image[index];       //Worker ID

            var Current_Coord = Animate_Current_Coord[index];     
                  //An array that holds the imagescurrent coordinate on board
             var pos = $(Image).position();                                    
                   // Finds the exact pixel position of the image
             var    Current_X = pos.left;
             var    Current_Y = pos.top;

            var Target_Coord = Animate_Target_Coord[index];           
                  //Array holding the Target Coordiante
            var    Target_X = xArray[Target_Coord]-15;                       
              //Finds the pixel location for the center of the table cell
            var    Target_Y = yArray[Target_Coord];

            var End_Coord; 
       //This is the destination of the worker for example the warehouse or back to the sawmill
            var End_X= xArray[End_Coord]-15;
            var    End_Y = yArray[End_Coord];           //pixel location of destination

            if(Animate_Delivered[index]==0)                                  
             //works out if worker is on his way, or on his way back from warehouse
            {End_Coord = Animate_End_Coord[index];}
            else
            {End_Coord = index;}


            //Now using the varibles set above I use some if and else statements to tell the browser             what to do in each situation.

            if((Current_X == End_X)&&(Current_Y == End_Y))          
                   //Event: when the image has reached its destination     
            {   
                Current_Coord = Animate_Current_Coord[index];
                var bearing_next_coord;

                if(End_Coord == index){Animate_Delivered[index]=0;}
                else{Animate_Delivered[index]=1;}

                bearing_next_coord=Direction(Current_Coord,End);                
                   //calls the pathfinding  function to find next direction to take.
                var bearing = bearing_next_coord[0];                                      
                  //bearing is "n" (north),"e" (east) etc
                var next_coord = parseInt(bearing_next_coord.substring(1));    
                   //Gives the new coordinate
                Animate_Target_Coord[index]=next_coord;                             
                  //changes the target array

            }
            else if((Current_X == Target_X)&&(Current_Y == Target_Y))          
                   //'Event: has reached the center of the next  cell in the route
            {   
                Current_Coord=Animate_Target_Coord[index];

                var bearing_next_coord = Direction(Current_Coord,End_Coord); 
                  //gets next direction to  take

                var bearing = bearing_next_coord[0];
                var next_coord = parseInt(bearing_next_coord.substring(1));

                switch(bearing)        //switch to choose the image based on travel direction
                {
                    case "n":
                    $(Image).attr("src", "images/animations/sawmill_dude_n.gif");
                    break;
                    case "e":
                    $(Image).attr("src", "images/animations/sawmill_dude_e.gif");
                    break;
                    case "s":
                    $(Image).attr("src", "images/animations/sawmill_dude_s.gif");
                    break;
                    case "w":
                    $(Image).attr("src", "images/animations/sawmill_dude_w.gif");
                    break;
                }

                Animate_Target_Coord[index]=next_coord;      //update target array

            }

            if(Current_X !=Target_X)                                          
                    //Event: image is in between  coordinates and needs to be moved.
            {   
                y= Current_Y;
                if(Current_X < Target_X)
                {x= Current_X+1;}
                if(Current_X > Target_X)
                {x= Current_X-1;}

            }
            if(Current_Y !=Target_Y)
            {   
                x= Current_X;
                if(Current_Y < Target_Y)
                {y= Current_Y+1;}
                if(Current_Y > Target_Y)
                {y= Current_Y-1;}
            }
                      //Now to actuall move the image.
            $(Image).queue(function () {
            $(this).css({left:x,top:y});
            $(this).dequeue();});


        }

    }
    }

I noticed a the following link on your excellent website, What are queues in jQuery?, near the bottom there is an example for moving multiple images. I think that this is what I am after but I really am struggling to understand the code.

If anyone code help me understand how I can apply this code to my scenario I would massivly grateful. the code can be found here: http://jsfiddle.net/enf644/6bX28/2/

I can see how the code matches with the html and css, but I really don't understand how to order (or name) a queue, or realy understand what the roll of the dequeue command. Also in the example above it mentions a "next" in the code (found in blue) I don't see where this variable is defined... in short I need someone to explain the queue system to a jquery dummey :)

Apologies If I have provided the code in the wrong format but as I said I am pretty new to all this stuff!

Thanks for any help, and feel free to ask me any questions if I have not made myself clear (although I may not know the answer :D ).

John

Community
  • 1
  • 1

1 Answers1

0

What you have in Animate_Int is what would traditionally be called a 20Hz (50 millisecond) package. This can be made to work but is a rather old-fashioned approach to coding (I recognise it from projects in the 1970s/1980s), which will not play to javascript's, more particularly jQuery's, strengths.

I would therefore recommend that you move away from the concept of a fixed interval package.

Unfortunately, the alternative requires a completely different mindset and completely different code.

The good news is that the alternative code would be significantly less voluminous than Animate_Int, facilitated principally by jQuery's .animate() method which would handle all movement from point-to-point.

The mindset you need to adopt could be termed "object oriented behaviour", by which you give each type of object (Workers in this case) behaviour(s) that can be invoked as required. Thus you can separate out low-level code (moving around the board) from high-level supervisory (game) code.

For example, you could write a general purpose .walkTo() method that would be attached to Worker objects (and any other type of object that needs to be animated on the board). Then you could call (from wherever is appropriate) thisWorker.walkTo(somePos), where somePos defines the target board coordinates. Calculation of intermediate way-points/directions/icon-variants would be performed within the .walkTo() code.

As I already said, this requires a completely different mindset but it's one worth investing time in learning as it will lead to inherently less voluminous code, but also code that's more readily reusable within the application (hence further reduction). Another advantage, in my opinion, is that help will be more readily available because experienced javascript/jQuery programmers will recognise the overall pattern of the code.

Beetroot-Beetroot
  • 18,022
  • 3
  • 37
  • 44
  • Thankyou for your answer Beetroot, Could you possibly suggest where, or what I should search for to learn this new mindset? I think what you are saying makes perfect sence, but I don't understand how it would translate into actual code. It is interesting that the code I have done is reminisent of the 70-80s. I learnt what little I know from a friend who said most of his coding was done at that time. I see you have an eye for code. – TranquilityEden Apr 21 '12 at 15:03
  • Bookwise, [JavaScript: The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742), is well regarded and this [set of videos](http://video.search.yahoo.com/search//?fr=screen&q=crockford%20javascript) by the same author are also worth a look. Some ovf the videos will be more suitable to get you started than others, so be prepared to see some that are too advanced to not specifically focussed. – Beetroot-Beetroot Apr 21 '12 at 17:03
  • Thanks for the book recomendation I have been reading bits and it is written well although it will take some time to read in full. I understand that to attach a method to an image is as simple as nameOfImage.NameofMethd() but am however confused and cannot find the answer in the book you suggested on where this is first called (I assume when the image is created and displayed in the js code), and how it will call itself again when it has moved from point a-b so that it can move from point b-c. Also will multiple images be able to call the same method at the same time? Thanks for your help! – TranquilityEden Apr 23 '12 at 07:48
  • @TranquilityEden, I haven't forgotten you. I'm trying to put together something that will demonstrate the principles and maybe get you started with the new mindset if you decide you want to go that way. – Beetroot-Beetroot Apr 24 '12 at 20:02