Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

9 years ago by sleenee

I really like this community so I feel like posting another piece of possibly helpful code I use.
With this, your top-down character (like in zelda RPG-type games) will move towards your mouse-click location in a straight line (so it's not a path finding function, your character can get stuck).

It's useful for playable characters if you are tired of using the arrow-keys and just want to get somewhere with a left-mouse-click (which is in my code defined as 'context').

put this in your player-entity update function:


		//MOUSEINPUT
		
		if( ig.input.pressed('context')){
			
			this.destinationx = ig.input.mouse.x + ig.game.screen.x;
			this.destinationy = ig.input.mouse.y + ig.game.screen.y;
		}	
		
		if(this.destinationx < 9999999 && this.destinationy < 9999999 ){
		//character is 48 hoog en 32 breed. corrigeer met 48 op y-as en 32/2 = 16 op x-as
		this.distancetotargetx = this.destinationx - this.pos.x - 16 ;
		this.distancetotargety = this.destinationy - this.pos.y - 48 ;	
				
		if (Math.abs(this.distancetotargetx) > 1 || Math.abs(this.distancetotargety) > 1){	
					
			if (Math.abs(this.distancetotargetx) > Math.abs(this.distancetotargety)){
							
		    if (this.distancetotargetx > 1){
			  this.vel.x = this.movementspeed;
			  this.xydivision = this.distancetotargety / this.distancetotargetx;
			  this.vel.y = this.xydivision * this.movementspeed;	
		      this.currentAnim = this.anims.walkright;
			  this.formerpressed = 'right';
					
			}
		    else{		 		 
		      this.vel.x = -this.movementspeed;
			  this.xydivision = this.distancetotargety / Math.abs(this.distancetotargetx);
			  this.vel.y = this.xydivision * this.movementspeed;
			  this.currentAnim = this.anims.walkleft;
			  this.formerpressed = 'left';
			}
			//einde Math.abs(this.distancetotarget.x) > Math.abs(this.distancetotarget.y)
		}
			else{
			if (this.distancetotargety > 1){			
				this.vel.y = this.movementspeed;
				this.xydivision = this.distancetotargetx / this.distancetotargety;
				this.vel.x = this.xydivision * this.movementspeed;
				this.currentAnim = this.anims.walkdown;
				this.formerpressed = 'down';
			}
			else{
				this.vel.y = -this.movementspeed;
				this.xydivision = this.distancetotargetx / Math.abs(this.distancetotargety);
				this.vel.x = this.xydivision * this.movementspeed;
				this.currentAnim = this.anims.walkup;
				this.formerpressed = 'up';
			}
			}
		  //einde this.distancetotargetx > 0 || this.distancetotargety > 0
		}
		else{
		this.vel.y = 0;
		this.vel.x = 0;
		
		this.destinationx = 99999999;
		this.destinationy = 99999999;
		
		if(this.formerpressed == 'left'){	
			this.currentAnim = this.anims.lookleft;
		}
		else if (this.formerpressed == 'right'){
		    this.currentAnim = this.anims.lookright;
		}
		else if (this.formerpressed == 'up'){
			this.currentAnim = this.anims.lookup;
		}
		else if (this.formerpressed == 'down'){
			this.currentAnim = this.anims.lookdown;
		}  
	    }
		//einde this.distancetotargetx && this.distancetotargety	
		}
			
     //END MOUSEINPUT

side-note:
the following lines might need to be adapted by you

		this.distancetotargetx = this.destinationx - this.pos.x - 16 ;
		this.distancetotargety = this.destinationy - this.pos.y - 48 ;

Per default your character position will be the top-left corner of your collision box. This feels kind of unnatural. My character is 48 pixels high and 32 pixels wide so I adjusted the x-target by 16 (32/2) and the y-target by 48 so your character ends up with his feet where your clicked with the mouse.
The code also corrects for the camera-plugin.
In addition you will want to add these lines to your default arrow-movement code (if you have that). So you can interrupt your movement with the arrow keys if necessary.

			//set this.destinationx and dthis.destination y is for the movement by mouse-click
			this.destinationx = 99999999;
			this.destinationy = 99999999;

so for example in my arrow-movement for going to the left I get this now:

		if( ig.input.state('left') ) {
			this.vel.x = -200;
			this.vel.y = 0;
			this.currentAnim = this.anims.walkleft;
			this.formerpressed = 'left';
			//set this.destinationx and dthis.destination y is for the movement by mouse-click
			this.destinationx = 99999999;
			this.destinationy = 99999999;
			
		}

The character animation code as defined by me in the entity init-function is like this:

		this.addAnim( 'walkleft', 0.1, [4,5,6,7] );
		this.addAnim( 'walkright', 0.1, [8,9,10,11] );
		this.addAnim( 'walkup', 0.1, [12,13,14,15] );
		this.addAnim( 'walkdown', 0.1, [0,1,2,3] );
		this.addAnim( 'lookleft', 1, [4] );	
		this.addAnim( 'lookright', 1, [8] );
		this.addAnim( 'lookup', 1, [12] );	
		this.addAnim( 'lookdown', 1, [0] );	

so I have an animation for walking in all 4 directions and looking (but standing still) in all 4 directions.

Good luck with it and if you have questions , just ask.

Sleenee

9 years ago by bobdabuilda

Hi Sleenee, thanks for this! But I'm not able to get this to work. When I do a click, the game screen turns black. I have to refresh the browser to bring the game back up.

Would you be able to help me figure out what I did wrong?

I did this:

main.js init function:
        ig.input.initMouse();
        ig.input.bind( ig.KEY.MOUSE1, 'lbtn' );

player.js update function (I used the same animation for everything for ease of testing):

        //MOUSEINPUT
        
        if(ig.input.pressed('lbtn')){
            
            this.destinationx = ig.input.mouse.x + ig.game.screen.x;
            this.destinationy = ig.input.mouse.y + ig.game.screen.y;
        }    
        
        if(this.destinationx < 9999999 && this.destinationy < 9999999 ){
        //character is 48 hoog en 32 breed. corrigeer met 48 op y-as en 32/2 = 16 op x-as
        this.distancetotargetx = this.destinationx - this.pos.x - 16 ;
        this.distancetotargety = this.destinationy - this.pos.y - 48 ;    
                
        if (Math.abs(this.distancetotargetx) > 1 || Math.abs(this.distancetotargety) > 1){    
                    
            if (Math.abs(this.distancetotargetx) > Math.abs(this.distancetotargety)){
                            
            if (this.distancetotargetx > 1){
              this.vel.x = this.movementspeed;
              this.xydivision = this.distancetotargety / this.distancetotargetx;
              this.vel.y = this.xydivision * this.movementspeed;    
 //             this.currentAnim = this.anims.walkright;
              this.formerpressed = 'right';
                    
            }
            else{                  
              this.vel.x = -this.movementspeed;
              this.xydivision = this.distancetotargety / Math.abs(this.distancetotargetx);
              this.vel.y = this.xydivision * this.movementspeed;
              this.currentAnim = this.anims.up;
              this.formerpressed = 'left';
            }
            //einde Math.abs(this.distancetotarget.x) > Math.abs(this.distancetotarget.y)
        }
            else{
            if (this.distancetotargety > 1){            
                this.vel.y = this.movementspeed;
                this.xydivision = this.distancetotargetx / this.distancetotargety;
                this.vel.x = this.xydivision * this.movementspeed;
		  this.currentAnim = this.anims.up;
                this.formerpressed = 'down';
            }
            else{
                this.vel.y = -this.movementspeed;
                this.xydivision = this.distancetotargetx / Math.abs(this.distancetotargety);
                this.vel.x = this.xydivision * this.movementspeed;
               this.currentAnim = this.anims.up;
                this.formerpressed = 'up';
            }
            }
          //einde this.distancetotargetx > 0 || this.distancetotargety > 0
        }
        else{
        this.vel.y = 0;
        this.vel.x = 0;
        
        this.destinationx = 99999999;
        this.destinationy = 99999999;
       
        if(this.formerpressed == 'left'){    
            this.currentAnim = this.anims.up;
        }
        else if (this.formerpressed == 'right'){
            this.currentAnim = this.anims.up;
        }
        else if (this.formerpressed == 'up'){
            this.currentAnim = this.anims.up;
        }
        else if (this.formerpressed == 'down'){
            this.currentAnim = this.anims.up;
        } 
 
        }
        //einde this.distancetotargetx && this.distancetotargety    
        }
            
     //END MOUSEINPUT

9 years ago by sleenee

seems like you are using a different paradigm though. apparantly you have only one animation (up) ? in that case, the code could be much shorter for you. Do you still need help on it , I saw you post on the path finder topoc too, are you using the path finder or this way to move your character?

9 years ago by sunnybubblegum

I've implemented your solution for mouse-click movement, and for the most part it's working very nicely. A big thank-you for sharing this.

I'm experiencing a little problem though. Upon arriving at his new position, the player launches into a non-stop jitter. He looks like a jackhammer drilling away, and it's very distracting.

I've tried isolating several parts of my code but I've found no leads. However, when monitoring his velocity, I learned that his position is in fact moving at almost full speed while 'drilling'. So it's not just his animation graphic doing the jittering. This problem occurs on both mouse-clicks and screen-touches.

Do you have any idea what is contributing to this?

In player.js, 'update' method:
// MOUSE INPUT BEGINS

if( ig.input.pressed( 'canvasTouch' ) || ig.input.state( 'canvasTouch' ) ) {
	this.destinationx = ig.input.mouse.x + ig.game.screen.x;
	this.destinationy = ig.input.mouse.y + ig.game.screen.y;
}

// Where the click magic happens..
if( this.destinationx < 9999999 && this.destinationy < 9999999 ) {
	
	// Accounts for center of character's collision area
	this.distancetotargetx = this.destinationx - (this.pos.x + (this.size.x/2));
	this.distancetotargety = this.destinationy - (this.pos.y + (this.size.y/2));
	
	if( Math.abs(this.distancetotargetx) > 1 || Math.abs(this.distancetotargety) > 1 ) {
		
		if( Math.abs(this.distancetotargetx) > Math.abs(this.distancetotargety) ) {
			
			// Move right
			if( this.distancetotargetx > 1 ) {
				this.vel.x = 300;
				this.xydivision = this.distancetotargety / this.distancetotargetx;
				this.vel.y = this.xydivision * 300;
				this.currentAnim = this.anims.walkRight;
			}
			// Move left
			else {
				this.vel.x = -300;
				this.xydivision = this.distancetotargety / Math.abs(this.distancetotargetx);
				this.vel.y = this.xydivision * 300;
				this.currentAnim = this.anims.walkLeft;
			}
		}
		else {
			
			// Move down
			if( this.distancetotargety > 1 ) {
				this.vel.y = 300;
				this.xydivision = this.distancetotargetx / this.distancetotargety;
				this.vel.x = this.xydivision * 300;
				this.currentAnim = this.anims.walkDown;
			}
			// Move up
			else {
				this.vel.y = -300;
				this.xydivision = this.distancetotargetx / Math.abs(this.distancetotargety);
				this.vel.x = this.xydivision * 300;
				this.currentAnim = this.anims.walkUp;
			}
		}
		
		// No movement on either axis?
		if( !this.vel.x && !this.vel.y ) {
		
			// Not already idle? Set 'idle' anim
			if( !this.idle ) {
				this.idle = true;
				
				if( this.currentAnim == this.anims.walkUp ) {
					this.currentAnim = this.anims.faceUp;
				}
				else if( this.currentAnim == this.anims.walkDown ) {
					this.currentAnim = this.anims.faceDown;
				}
				else if( this.currentAnim == this.anims.walkLeft ) {
					this.currentAnim = this.anims.faceLeft;
				}
				else if( this.currentAnim == this.anims.walkRight ) {
					this.currentAnim = this.anims.faceRight;
				}
				else {
					this.currentAnim = this.anims.faceDown;
				}
			}
		}
		else {
			this.idle = false;
		}
		
		// ..end no movement on either axis
		
	}
	
} // ..end where the click magic happens
else {
	this.vel.y = 0;
	this.vel.x = 0;
	
	this.destinationx = 99999999;
	this.destinationy = 99999999;
}

// END MOUSE INPUT

Further down, my keyboard movements basically look like the following for all directions. I haven't been having any problems with them.

if( ig.input.state('up') || ig.input.state('up_alt') ) {
	this.vel.y = -300;
	this.currentAnim = this.anims.walkUp;
	this.destinationx = 99999999;
	this.destinationy = 99999999;
}

9 years ago by sleenee

Ah yes, I think i know what you mean. I had that problem too, though it only showed on an ipad or android in my case so i thought it was device specific at first.

Actually the problem is in the distance to the target that is allowed until the moving subject comes to a stop. In this code it's 1 pixel.
 Math.abs(this.distancetotargetx) > 1 || Math.abs(this.distancetotargety) > 1 )

If however your subject moves more pixels per second than your framerate (which occured in my case on less powerfull devices) , it will pass the target, readjust it's course (move back) and so on for ever or until you are lucky. This looks like he's going crazy, I guess he is :).

So actually in order to be sure that the distance-check has enough time to occur, i changed the code to:

Math.abs(this.distancetotargetx) > 10 || Math.abs(this.distancetotargety) > 10 )

it's a small precision sacrifice but the shiffering should stop. (did in my case)

given your speed is 300 pixels per second and it has a 10 pixel window to detect arriving at the correct destination you will only suffer problems when you go below a framerate of 30 (so if your framerate is even lower, make the window bigger)

greetings,

Sleenee

9 years ago by sleenee

In this same context I build a function (based on the same principles) that allows an NPC to follow another NPC or the player or whatever.

Just include this in the file where you put other functions you call

your entity will require a property "movementspeed" though. If you have that and it is called differently, change it in here.

	function MoveEntityToOtherEntity(entity,target){
	    			
		var destinationx = target.pos.x;
		var destinationy = target.pos.y;
		
		//character is 48 pixels high and 32 wide. correct 48 on y-axis and 32/2 = 16 on x-as
		var distancetotargetx = destinationx - entity.pos.x ;
		var distancetotargety = destinationy - entity.pos.y ;	
				
		if (Math.abs(distancetotargetx) > 20 || Math.abs(distancetotargety) > 20){	
					
			if (Math.abs(distancetotargetx) > Math.abs(distancetotargety)){
							
				if (distancetotargetx > 0){
					entity.vel.x = entity.movementspeed;
					var xydivision = distancetotargety / distancetotargetx;
					entity.vel.y = xydivision * entity.movementspeed;	
					entity.currentAnim = entity.anims.walkright;
					entity.formerpressed = 'right';
				}
				else{		 		 
					entity.vel.x = -entity.movementspeed;
					var xydivision = distancetotargety / Math.abs(distancetotargetx);
					entity.vel.y = xydivision * entity.movementspeed;
					entity.currentAnim = entity.anims.walkleft;
					entity.formerpressed = 'left';
				}
			//einde Math.abs(this.distancetotarget.x) > Math.abs(this.distancetotarget.y)
			}
			else{
				if (distancetotargety > 0){			
					entity.vel.y = entity.movementspeed;
					xydivision =distancetotargetx / distancetotargety;
					entity.vel.x = xydivision * entity.movementspeed;
					entity.currentAnim =entity.anims.walkdown;
					entity.formerpressed = 'down';
				}
				else{
					entity.vel.y = -entity.movementspeed;
					xydivision = distancetotargetx / Math.abs(distancetotargety);
					entity.vel.x = xydivision * entity.movementspeed;
					entity.currentAnim = entity.anims.walkup;
					entity.formerpressed = 'up';
				}
			}
		  //einde this.distancetotargetx > 0 || this.distancetotargety > 0
		}
		else{
			entity.vel.y = 0;
			entity.vel.x = 0;
			
			if(entity.formerpressed == 'left'){	
				entity.currentAnim = entity.anims.lookleft;
			}
			else if (entity.formerpressed == 'right'){
				entity.currentAnim = entity.anims.lookright;
			}
			else if (entity.formerpressed == 'up'){
				entity.currentAnim = entity.anims.lookup;
			}
			else if (entity.formerpressed == 'down'){
				entity.currentAnim = entity.anims.lookdown;
			}  
		}
		//einde this.distancetotargetx && this.distancetotargety	
	}

You can than for instance call this in your NPC update function with a condition.
	if (this.eventfollowplayer == 1){
		MoveEntityToOtherEntity(this,ig.game.player);
	}

so in this case as long as my eventfollowplayer property of the npc is 1, it will follow the player around (restricted by it's speed off course, you can make them get stuck somewhere :p)

given I have seen at least 1 person trying to rebuild zelda : a link to the past and the most epic character in there is the crazy guy that follows you around when you steal his sign, i thought this might be helpfull.

9 years ago by sunnybubblegum

Reading your guidance made sense, but in practice the player still jittered, only wider. So additionally, I rearranged the order of the statements and got it working.

if( ig.input.pressed( 'clickOrTouch' ) || ig.input.state( 'clickOrTouch' ) ) {
	this.destinationx = ig.input.mouse.x + ig.game.screen.x;
	this.destinationy = ig.input.mouse.y + ig.game.screen.y;
}

if( this.destinationx < 9999999 && this.destinationy < 9999999 ) {
	
	// Accounts for center of character's collision area
	this.distancetotargetx = this.destinationx - ( this.pos.x + ( this.size.x / 2 ) );
	this.distancetotargety = this.destinationy - ( this.pos.y + ( this.size.y / 2 ) );
			
	if( Math.abs( this.distancetotargetx ) > 10 || Math.abs( this.distancetotargety ) > 10 ) {
				
		if( Math.abs( this.distancetotargetx ) > Math.abs( this.distancetotargety ) ) {
			
			// Up, down, left, right and idle controls here
			
		}
		// *Added this 'else' statement
		else {
			
			// *Put these here instead
			this.vel.x = 0;
			this.vel.y = 0;
			
			// *And these
			this.destinationx = 99999999;
			this.destinationy = 99999999;
		}
else {
	
	// *Added these here for good measure
	this.distancetotargetx = 0;
	this.distancetotargety = 0;
}

Thanks so much for everything, and I will surely be trying your 'NPC follow' code!

8 years ago by Megalodactyl

Awesome thank you!

8 years ago by jizaymes

This works rather well once it was able to be inserted in with the normal arrow key movement code. Thanks!

8 years ago by Burxat

WARNING! I may sound weird, sorry about my english, just ask if you don't understand any word or sentence i say! ><

Hey guys you did just a great job, but this wasn't working for me. I wanted to use my keyboard movement code with your mouse implementation and i had a lot of trouble.

But at the end it worked, and i'm sharing it with you because it's your job, not mine, i just adapted to my situation.. so if it can help to anyone.. here it is my code!

Thanks guys!

My player.js

ig.module(
    'game.entities.player'
)
.requires(
    'impact.entity'
)
.defines(function(){
    EntityPlayer = ig.Entity.extend({
		animSheet: new ig.AnimationSheet( 'media/entities/player.png', 31, 42 ),
		size: {x: 31, y: 42},
		offset: {x: 0, y: 0},
		flip: false,
		maxVel: {x: 200, y: 200},

		init: function( x, y, settings ) {
			this.parent( x, y, settings );
			this.addAnim( 'idle', 1, [0] );
			this.addAnim( 'left', 0.15, [9,10,11] );
			this.addAnim( 'right', 0.15, [6,7,8] );
			this.addAnim( 'up', 0.15, [3,4,5] );
			this.addAnim( 'down', 0.15, [0,1,2] );
		},
		update: function() {
			
			//For realistic ground movement
			//var accel = this.standing ? this.accelGround : this.accelAir; 
			
			
			//used for movement, using just mouse or keyboard at once
			//if( ig.input.state( 'mousemovement' ) ) {
				
				
				//MOUSEINPUT
				if( ig.input.state( 'mousemovement' ) ) {
					this.destinationx = ig.input.mouse.x + ig.game.screen.x;
					this.destinationy = ig.input.mouse.y + ig.game.screen.y;
				}

				// Cursor position
				if( this.destinationx < 9999999 && this.destinationy < 9999999 ) {
					
					// Accounts for center of character's collision area
					this.distancetotargetx = this.destinationx - (this.pos.x + (this.size.x/2));
					this.distancetotargety = this.destinationy - (this.pos.y + (this.size.y/2));
					
					if( Math.abs(this.distancetotargetx) > 10 || Math.abs(this.distancetotargety) > 10 ) {
						


						if( Math.abs(this.distancetotargetx) > Math.abs(this.distancetotargety) ) {
							// Move right
							if( this.distancetotargetx > 1 ) {
								this.vel.x = 180;
								this.xydivision = this.distancetotargety / this.distancetotargetx;
								this.vel.y = this.xydivision * 180;
								this.currentAnim = this.anims.right;
							}else { // Move left
								this.vel.x = -180;
								this.xydivision = this.distancetotargety / Math.abs(this.distancetotargetx);
								this.vel.y = this.xydivision * 180;
								this.currentAnim = this.anims.left;
							}

						}else {
							// Move down
							if( this.distancetotargety > 1 ) {
								this.vel.y = 180;
								this.xydivision = this.distancetotargetx / this.distancetotargety;
								this.vel.x = this.xydivision * 180;
								this.currentAnim = this.anims.down;
							}else { // Move up
								this.vel.y = -180;
								this.xydivision = this.distancetotargetx / Math.abs(this.distancetotargety);
								this.vel.x = this.xydivision * 180;
								this.currentAnim = this.anims.up;
							}
						}
						

						// No movement on either axis?
						if( !this.vel.x && !this.vel.y ) {
						
							// Not already idle? Set 'idle' anim
							if( !this.idle ) {
								this.idle = true;
								
								if( this.currentAnim == this.anims.up ) {
									this.currentAnim = this.anims.up.rewind();

								}else if( this.currentAnim == this.anims.down ) {
									this.currentAnim = this.anims.down.rewind();
								}else if( this.currentAnim == this.anims.left ) {
									this.currentAnim = this.anims.left.rewind();
								}else if( this.currentAnim == this.anims.right ) {
									this.currentAnim = this.anims.right.rewind();
								}else {
									this.currentAnim = this.anims.down.rewind();
								}	
							}
	
						}else {
							this.idle = false;	
						}
						
						// ..end no movement on either axis
						
					}
					//Stoping mouse movement animation
					if ( this.vel.x == 0 && this.vel.y == 0 ) {
					    this.currentAnim.rewind();
					  }
				}else { // ..end where the click magic happens
					this.vel.y = 0;
					this.vel.x = 0;
					
					this.destinationx = 99999999;
					this.destinationy = 99999999;
					if ( this.vel.x == 0 && this.vel.y == 0 ) {
						
						//keyboard movement
						if( ig.input.state('left') ) {
							this.currentAnim = this.anims.left;
							this.destinationx = 99999999;
							this.destinationy = 99999999;

						}else if( ig.input.state('right') ) {
							this.currentAnim = this.anims.right;
							this.destinationx = 99999999;
							this.destinationy = 99999999;


						}else if( ig.input.state('up') ) {
							this.currentAnim = this.anims.up;
							this.destinationx = 99999999;
							this.destinationy = 99999999;

						}else if( ig.input.state('down') ) {
							this.currentAnim = this.anims.down;
							this.destinationx = 99999999;
							this.destinationy = 99999999;

						}/* Keyboard */else{ //Keyboard. Stopping keyboard movement animation
							this.currentAnim.rewind();
						} //keyboard

						

					}
					
				}
				// move!
				this.parent();
				// END MOUSE INPUT

			//used for movement, using just mouse or keyboard at once
			//}else if( ig.input.state( 'left' ) || ig.input.state( 'right' ) || ig.input.state( 'up' ) || ig.input.state( 'down' )  ) {
				


				//original keyboard movement, works fine alone, needed now to implement mouse movement
				// INIT Keyboard input
				if( ig.input.state('left') ) {
					  this.currentAnim = this.anims.left;
					  this.vel.x = -180;	  
					  this.destinationx = 99999999;
					  this.destinationy = 99999999;

				}else if( ig.input.state('right') ) {
					  this.currentAnim = this.anims.right;
					  this.vel.x = 180;
					  this.destinationx = 99999999;
					  this.destinationy = 99999999;
				} else{
					  this.vel.x = 0;
					  /*if ( this.vel.x == 0 && this.vel.y == 0 ) {
					    this.currentAnim.rewind();
					  }*/
					  
				} 
				// move up and down
				if( ig.input.state('up') ) {
					this.currentAnim = this.anims.up;
					this.vel.y = -180;
					this.destinationx = 99999999;
					this.destinationy = 99999999;

				}else if( ig.input.state('down') ) {
					this.currentAnim = this.anims.down;
					this.vel.y = 180;
					this.destinationx = 99999999;
					this.destinationy = 99999999;
				}else {
					this.vel.y = 0;	
				}

				// move!
				this.parent();
				// END Keyboard input
			
			
			//used for movement, using just mouse or keyboard at once
			//}

		}

    });
});

Page 1 of 1
« first « previous next › last »