Pressing 2 keys at once!

Im having trouble being able to move the player round the screen the way i want. I dont seem to be able to press 2 keys at once (i.e. if i hold the up key he walks up, and if i press right while still holding up nothing happens). Im just using basic keyListeners…

public void keyPressed(KeyEvent e)
      {
        
            if(e.getKeyCode() == KeyEvent.VK_D)
            { //move right

            }

            if(e.getKeyCode() == KeyEvent.VK_A)
            { //move left

            }

You need to separate things out slightly, make the method return a boolean and when you pass in a key that is recognised (and pushed) return true. Then in the method that calls it, check every possible key (up,down,left,right,etc.) and if they are pushed, then affect the character/player. That way you’ll be able to apply two or more affects during the same cycle.

ok thanks, ill try that. Aswell at this, im finding it hard to keep track of the players x,y. This is because the player can move round in 8 directions (its top-down view). At the moment, if i press UP then i -speed from his current y value. But this is only right if the player is facing up when he presses up. If he is facing at and angle, like up-right, then pressing UP will not simple -speed from his current y, it should affect his x value too.
Whats the best way to keep track of the players true x,y values?

Try my tutorial:

http://www.gamelizard.com/JavaGameProgrammingPresentation.htm

use affinetransform

Can u be more specific? I currently use AffineTransforms for all player moving and rotating.

I’m not sure what Valodim was trying to suggest. Are you still having any problems?

yeah i am, so any help is appreciated :wink: Just this problem…

im finding it hard to keep track of the players x,y. This is because the player can move round in 8 directions (its top-down view). At the moment, if i press UP then i -speed from his current y value. But this is only right if the player is facing up when he presses up. If he is facing at and angle, like up-right, then pressing UP will not simple -speed from his current y, it should affect his x value too.
Whats the best way to keep track of the players true x,y values?

[quote]ok thanks, ill try
Whats the best way to keep track of the players true x,y values?
[/quote]
this was what I was refering to in my previous post :slight_smile:

anyways, for 8-direction movement, I’d probably use something like this

AffineTransform playercoords;
static final AffineTransform moveupaffine = AffineTransform.getTranslateInstance(0, -10), moverighttaffine = AffineTransform.getTranslateInstance(10, 0), moveuprightaffine = AffineTransform.getTranslateInstance(8, -8 );
int movement;

// press button
if(e.getKeyCode() == KeyEvent.VK_D)
{ //move right, set first bit
movement += 1
}
if(e.getKeyCode() == KeyEvent.VK_W)
{ //move up, set 2nd bit
movement += 2
}

// release button
if(e.getKeyCode() == KeyEvent.VK_D)
{ // stop moving right, unset first bit
movement -= 1
}
if(e.getKeyCode() == KeyEvent.VK_W)
{ //move up, unset 2nd bit
movement -= 2
}
// missing break, I’m lazy :stuck_out_tongue:
switch(movement){
// right
case 1:
coords.concatenace(moverightaffine);

// up
case 2:
coords.concatenace(moveupaffine);

// up-right
case 3:
coords.concatenace(moveuprightaffine);

}

that way, you can easily check what direction the char is moving, check for specific directions (binary AND operator) etc.

may be necessary to add a check if the movement variable isn’t out of range (who knows, maybe someone manages to push a button twice without releasing…)

thanks, ill give it a go.

or how about this:


private static final double ROTATION = Math.PI/4, ACCELERATION = 0.5;

if (leftPressed) {
     theta += ROTATION;
}
if (rightPressed) {
     theta -= ROTATION;
}
if (upPressed) {
     velocityX += Math.cos(theta)*ACCELERATION;
     velocityY += Math.sin(theta)*ACCELERATION;
}
if (downPressed) {
     velocityX -= Math.cos(theta)*ACCELERATION;
     velocityY -= Math.sin(theta)*ACCELERATION;
}
x += velocityX;
y += velocityY;

Now pass the x and y into your affine transform and rotate with theta, and you’re good to go. That’s just basic intro physics stuff.

Thanks for both your replies, im sure it’ll be of great help to me.

Could you explain your code a little more for me Malohkan? At the moment if the player simply moves up, down, left (straffe) or right (straffe) then i create an Affinetransform called transMove like this

transMove = player.getTransMove();
                        transMove.translate(player.getSpeed(), 0);
      
                        player.setX(player.getX()+player.getSpeed());
                        player.setTransMove(transMove);
                        
                        player.setRotate(false);
                        player.setMove(true);

And if the player rotates left or right i create an AffineTransform called transRotate like this


            Point2D before = new Point2D.Double(player.getX() , player.getY());
            Point2D after = new Point2D.Double();
            
            transRotate = player.getTransRotate();
            transRotate.translate(player.getX(), player.getY());
            transRotate.translate(-player.getX(), -player.getY());
            transRotate.rotate(Math.toRadians(angle), xRot , yRot);
            
            after = transRotate.transform(before, after);

            player.setX((int)transRotate.getTranslateX());
            player.setY((int)transRotate.getTranslateY());
            
            player.setTransRotate(transRotate);


            player.setRotate(true);
            player.setMove(false);

Then when i paint, i have to check weather the players moved or rotated and draw him like this


//if he simply moved
g.drawImage(player.getImage(), player.getTransMove(), null);
.
.
//if he rotated
g.drawImage(player.getImage(), player.getTransRotate(), null);

I know this is a terrible way of doing this, thats why im hoping u can help me create an AffineTransfrom a better way, and maybe be able to draw using only the 1 AffineTransform.

Hope you can help, thanks.

just curious… if the player is facing straight down, not moving and you press up, should he turn instantly and start moving straight up or do a sort of U-Turn type motion?

basically, is the turning effect only meant to be for when he is already moving?

now, this is a very simple way to do it, and might not give the best effect, but if it is only for when he’s already moving, you could just have speedX and speedY and each loop, add speedX to X and add speedY to Y… left and right buttons control speedX, up and down buttons control speedY… not pressing a button causes the character to slow down and stop… this will give you an effect like when you release left and press up, he’ll do a curve, but if he’s not moving at all, he’ll just turn and start going straight in the direction pressed.

then you can animate based on the values of speedX and speedY…

when i press W he walks 10 pixels forward (10 is what his speed is set to) in the direction he is facing. If i press S he goes 10 pixels backwards, if i press A he straffes 10 pixels to his left, and D straffes 10 pixels to his right. Pressing O makes him rotate 45 degrees anti-clockwise and P makes him rotate 45 degrees anti-clockwise. If he is facing down, and i want him to start walking up, id have to rotate the player using the rotate keys.
The problem is, if im holding down a key, like W, he keeps walking forward but i cant press a different key until i release W. I want to be able to walk in all 8 directions without having to let go of each key and stop moving each time i want to change direction.

This is what i want: up, down, left and right keys will make him walk up, down, left and right reguardless of the direction he is currently facing. If i hold the up & right keys together, i want him to walk up & right at the same time, i.e walk north-east at a 45 degree angle. this would eliminate the need for rotation keys. Any ideas how i can do this?

BTW, this is a top-down view game like sensible soccer style view

most games use a loop for their logic and rendering… you seem to be using the AWT actionListener events to update your logic which is ok for board games or maybe tetris, but for smooth animation and to avoid hogging the AWT thread which is only meant to manage the GUI, you need to use a loop…

here is a simple source you can compile and run to see what i mean… the most the AWT ever has to do in its KeyListener is set boolean variables. this removes our dependency on the key’s repeat rate too.

http://www.adam.com.au/kellyjones/YABB/BufferedFrame.java

it does not take care of the direction you are facing, but it does show an example how to use two keys at once.

let’s just say in this example we change speedX and speedY to just one ‘speed’ variable here, and instead of accelleration we just use a flat
if(pressed) speed = 10; rather than bothering with accelleration.

you can then add speed to X and Y based on the direction he’s facing, and the button you’re pressing.

it still will make it tricky if you want him to have to move foward and backward and strafe at diferent speeds… that will not work when you press two buttons, and you’ll need to split it into speedX and speedY again…

I just want to move the man around exactly like the man in sensible soccer, so forget about straffe now.
i.e. when u hold UP he walk up the screen (even if he was originally facing down at the time, he will instantly appear facing up and start walking up). If i hold UP + RIGHT he should instantly face north-east at 45 degrees and walk in that direction.

somone must have done this before for a game?

Its ok, ive fixed it. I can now run round like the sensible soccer man and im only using 1 AffineTransform :smiley:

woohoo!