Hi everyone,

having trouble coming up with the right code for 8 directional movement [ up, upright, right, downright, down, downleft, left, upleft]

My keypress handling is:

if event.type == KEYDOWN:
            if event.key == K_LEFT:
                player.moveLeft = True
                player.moveRight = False
            if event.key == K_RIGHT:
                player.moveRight = True
                player.moveLeft = False
            if event.key == K_UP:
                player.moveUp = True
                player.moveDown = False
            if event.key == K_DOWN:
                player.moveDown = True
                player.moveUp = False
        if event.type == KEYUP:
            if event.key == K_LEFT:
                player.moveLeft = False
            if event.key == K_RIGHT:
                player.moveRight = False
            if event.key == K_UP:
                player.moveUp = False
            if event.key == K_DOWN:
                player.moveDown = False

And my directional checking is:

if self.moveRight == True and self.moveUp == True:
            print "MOVE UPRIGHT"
        if self.moveRight == True and self.moveDown == True:
            print "MOVE DOWNRIGHT"
        if self.moveRight == True and self.moveUp == False and self.moveDown == False:
            print "MOVE RIGHT"
        if self.moveLeft == True and self.moveUp == True:
            print "MOVE UPLEFT"
        if self.moveLeft == True and self.moveDown == True:
            print "MOVE DOWNLEFT"
        if self.moveLeft == True and self.moveUp == False and self.moveDown == False:
            print "MOVE LEFT"
        if self.moveUp == True:
            print "MOVE UP"
        if self.moveDown == True:
            print "MOVE DOWN"

It worked fine until I added the last two statements for moving up and down: It fires off MOVE UP and MOVE UPRIGHT at the same time, for example.

This also seems more complicated than it needs to be. Can you help make this work, and if possible, help me find a more efficient, easier solution?

Thanks

1 You set the opposite action to false in your event handling for the keydown, so don't need to worry about that condition later.

2 make them else-ifs as only one thing is going to happen.

3 if x=true, x==true returns true and x==false returns false, so the ==true is redundant as it just returns the value of x.

if self.moveRight and self.moveUp:
            print "MOVE UPRIGHT"
        elif self.moveRight and self.moveDown:
            print "MOVE DOWNRIGHT"
        elif self.moveRight:
            print "MOVE RIGHT"
        elif self.moveLeft and self.moveUp:
            print "MOVE UPLEFT"
        elif self.moveLeft and self.moveDown:
            print "MOVE DOWNLEFT"
        elif self.moveLeft:
            print "MOVE LEFT"
        elif self.moveUp:
            print "MOVE UP"
        elif self.moveDown:
            print "MOVE DOWN"

:) hope this helped!

You want to group the moveUp under one if statement, and the same for moveDown, otherwise moveUp also prints for (moveUp and moveLeft) or (moveUp and moveRight).

if self.moveUp:
    if self.moveRight:      ## moveUp and moveRight
        print "MOVE UPRIGHT"
    elif self.moveLeft:     ## moveUp and moveLeft
        print "MOVE UPLEFT"
    else:                 ## moveRight and moveLeft both = False
        print "MOVE UP"

And I would use a dictionary to contain everything, which would also show errors, if up and down were both true for example, which your original code would not catch as an error. In the example below, the self.moveRIght, etc. fields are kept for illustration only. You would probably use a tuple, as in the down+right test, and eliminate all of the self.moveLeft, etc. as they would be redundant.

class TestMove:
    def __init__(self):
        self.initialize_test_dict()

        ## test left
        self.initialize_to_false()
        self.moveLeft = True
        self.print_result()

        ## test left, up
        self.initialize_to_false()
        self.moveLeft = True
        self.moveUp = True
        self.print_result()

        self.initialize_to_false()

        ## test down, right
        test_tuple = (False, True, False, True)
        self.dictionary_lookup(test_tuple)

    def dictionary_lookup(self, test_tuple):
        if test_tuple in self.test_dict:
            print self.test_dict[test_tuple]
        else:
            print test_tuple, "is not a legal move"


    def initialize_to_false(self):
        self.moveUp = False
        self.moveDown = False
        self.moveRight = False
        self.moveLeft = False


    def initialize_test_dict(self):
        """ A dictionary of tuples
            each tupe = (Up, Down, Left, Right)
        """
        self.test_dict = {}
        self.test_dict[(True, False, False, False)] = 'MOVE UP'
        self.test_dict[(True, False, True, False)]  = 'MOVE UPLEFT'
        self.test_dict[(True, False, False, True)]  = 'MOVE UPRIGHT'
        self.test_dict[(False, False, False, True)] = 'MOVE RIGHT'
        self.test_dict[(False, False, True, False)] = 'MOVE LEFT'
        self.test_dict[(False, True, False, False)] = 'MOVE DOWN'
        self.test_dict[(False, True, True, False)] = 'MOVE DOWNLEFT'
        self.test_dict[(False, True, False, True)] = 'MOVE DOWNRIGHT'


    def print_result(self):
        test_tuple = (self.moveUp, self.moveDown, self.moveLeft, self.moveRight)
        self.dictionary_lookup(test_tuple)


TM = TestMove()

Edited 6 Years Ago by woooee: n/a

1 You set the opposite action to false in your event handling for the keydown, so don't need to worry about that condition later.

2 make them else-ifs as only one thing is going to happen.

3 if x=true, x==true returns true and x==false returns false, so the ==true is redundant as it just returns the value of x.

if self.moveRight and self.moveUp:
            print "MOVE UPRIGHT"
        elif self.moveRight and self.moveDown:
            print "MOVE DOWNRIGHT"
        elif self.moveRight:
            print "MOVE RIGHT"
        elif self.moveLeft and self.moveUp:
            print "MOVE UPLEFT"
        elif self.moveLeft and self.moveDown:
            print "MOVE DOWNLEFT"
        elif self.moveLeft:
            print "MOVE LEFT"
        elif self.moveUp:
            print "MOVE UP"
        elif self.moveDown:
            print "MOVE DOWN"

:) hope this helped!

I am not sure what you were referring to with your Point 1, but your solution worked fine. All I had to do was make the other options elifs to make sure only 1 option went off at a time. Jeez I was so close :-P

Thanks for the help!

glad to hear it!

first part:

when the button up is pressed, you set button down to false, so you know when up is true down is false. That means when you don't need to worry about down being false when you're checking, you just need to know that up is true. (did that make any sense at all?)

This article has been dead for over six months. Start a new discussion instead.