Python Forum
How to move the player upwards and downwards?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to move the player upwards and downwards?
#1
Hello everybody.

I am making a little game and somehow I can't figure out how to move my player sprite upwards or downwards without needing to rotate the player image.

So here is my code:

vec = pg.math.Vector2
class Player(pg.sprite.Sprite):
    def get_keys(self):
        self.rot_speed = 0
        self.vel = vec(0, 0)
        keys = pg.key.get_pressed()
        if keys[pg.K_LEFT] or keys[pg.K_a]:
            self.vel = vec(-PLAYER_SPEED / 2, 0).rotate(-self.rot)
        if keys[pg.K_RIGHT] or keys[pg.K_d]:
            self.vel = vec(PLAYER_SPEED, 0).rotate(-self.rot)
        if keys[pg.K_UP] or keys[pg.K_w]:
            pass
        if keys[pg.K_DOWN] or keys[pg.K_s]:
            pass

   
Can anybody tell me how to do this? Thanks, would be nice. Smile
Piethon
Reply
#2
I don't really understand the question. Why is it not as simple as changing the y-coordinate by whatever amount you want?
Reply
#3
Are you maybe mixing up two kinds of movement? The way you have it there makes me think of where the left and right rotate and the up and down do forward and back based on where the player is facing.

As ndc85430 says, you can bind the keys to +/- to the x and y axes.
Reply
#4
1. You can use pygame.Vector2 over pygame.math.Vector2.

Example how I do it. Using pure Vector2 math.
import os
import pygame
from pygame.sprite import Group, Sprite

class Engine:
    @staticmethod
    def center_screen():
        os.environ['SDL_VIDEO_CENTERED'] = '1'

    def __init__(self, caption, width, height, flags=0):
        pygame.display.set_caption(caption)
        self.surface = pygame.display.set_mode((width, height), flags)
        self.rect = self.surface.get_rect()
        self.clock = pygame.time.Clock()
        self.running = False
        self.delta = 0
        self.fps = 60

    def idle(self):
        self.delta = self.clock.tick(self.fps)

    def quit(self):
        self.running = False

class SimpleSprite(Sprite):
    def __init__(self, image, position, anchor="topleft"):
        Sprite.__init__(self)
        self.image = image
        self.rect = self.image.get_rect(**{anchor: position})

class Movement:
    def __init__(self, sprite, speed, angle=180):
        self.sprite = sprite
        self.speed = speed * 0.01
        self.original_image = sprite.image
        self.velocity = pygame.Vector2(0, 0)
        self.center = pygame.Vector2(sprite.rect.center)
        self.rotation_speed = 8 * 0.01

        self.angle = angle
        self.vector = self.get_vector()
        self._move = None
        self._rotate = None

    def get_vector(self):
        vector = pygame.Vector2(0, 0)
        vector.from_polar((1, self.angle))
        vector.x, vector.y = vector.y, vector.x
        return vector

    def up_action(self):
        self._move = self.move_up

    def down_action(self):
        self._move = self.move_down

    def left_action(self):
        self._rotate = self.rotate_left

    def right_action(self):
        self._rotate = self.rotate_right

    def move_up(self, delta):
        self.center += self.vector * self.speed * delta
        self.sprite.rect.center = self.center

    def move_down(self, delta):
        self.center += -self.vector * self.speed * delta
        self.sprite.rect.center = self.center

    def rotate_left(self, delta):
        self.angle = (self.angle + self.rotation_speed * delta) % 360
        self.update_rotation()

    def rotate_right(self, delta):
        self.angle = (self.angle - self.rotation_speed * delta) % 360
        self.update_rotation()

    def update_rotation(self):
        self.sprite.image = pygame.transform.rotate(self.original_image, self.angle)
        self.sprite.rect = self.sprite.image.get_rect(center=self.center)
        self.vector = self.get_vector()

    def move(self, delta):
        if self._rotate:
            self._rotate(delta)

        if self._move:
            self._move(delta)

        self._move = None
        self._rotate = None

class MovementKeys:
    def __init__(self, movement, up, down, left, right):
        self.movement = movement
        self.up = self.wrap(up)
        self.down = self.wrap(down)
        self.left = self.wrap(left)
        self.right = self.wrap(right)

    def update(self, delta, keys_pressed):
        keys = lambda pressed, key: any(pressed[k] for k in key)
        if keys(keys_pressed, self.up):
            self.movement.up_action()

        if keys(keys_pressed, self.down):
            self.movement.down_action()

        if keys(keys_pressed, self.right):
            self.movement.right_action()

        if keys(keys_pressed, self.left):
            self.movement.left_action()

        self.movement.move(delta)

    def wrap(self, item):
        if isinstance(item, list):
            return item
        elif isinstance(item, tuple):
            return list(item)
        else:
            return [item]

class Player:
    def __init__(self, rect):
        image = pygame.Surface((20, 20), pygame.SRCALPHA)
        image.fill(pygame.Color('dodgerblue'))

        self.sprite = SimpleSprite(image, rect.center, "center")
        self.movement = Movement(self.sprite, 8)
        self.movement_keys = MovementKeys(self.movement,
                                          (pygame.K_UP, pygame.K_w),
                                          (pygame.K_DOWN, pygame.K_s),
                                          (pygame.K_LEFT, pygame.K_a),
                                          (pygame.K_RIGHT, pygame.K_d))

    def update(self, delta, keys_pressed):
        self.movement_keys.update(delta, keys_pressed)

class Scene:
    def __init__(self, engine):
        self.engine = engine
        self.background = pygame.Color("black")
        self.player = Player(engine.rect)
        self.sprites = Group(self.player.sprite)

    def on_draw(self, surface):
        surface.fill(self.background)
        self.sprites.draw(surface)

    def on_event(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.engine.quit()

    def mainloop(self):
        self.engine.running = True
        while self.engine.running:
            self.on_event()
            self.on_update(self.engine.delta)
            self.on_draw(self.engine.surface)
            pygame.display.flip()
            self.engine.idle()

    def on_update(self, delta):
        keys_pressed = pygame.key.get_pressed()
        self.player.update(delta, keys_pressed)

def main():
    pygame.init()
    Engine.center_screen()
    engine = Engine("Movement Example", 600, 600)
    scene = Scene(engine)
    scene.mainloop()

main()
99 percent of computer problems exists between chair and keyboard.
Reply
#5
Thanks.
But should the position of "SimpleSprite" be?

def __init__(self, image, position, anchor="topleft"):
?

Thanks
Reply
#6
I use a tuple. (x, y)
99 percent of computer problems exists between chair and keyboard.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020