通过方法移动角色 - python

时间:2013-11-21 14:57:27

标签: python pygame

我正在尝试通过调用该方法和我想要移动它的距离将角色移动一定距离。到目前为止,我可以通过调用函数并放置我的x和y值来确定字符位置。当用户单击鼠标时。在main方法中,我希望调用move方法。香港专业教育学院尝试了两个移动,第一个移动和第二个move_c的实现,都没有工作。我使用python3和pygame

有什么建议吗?

继承我的代码

import pygame, math
from pygame.locals import *
pygame.init()

class Vector():
    '''

            creates operations to handle vectors such
            as direction, position, and speed
        '''
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self): # used for printing vectors
        return "(%s, %s)"%(self.x, self.y)

    def __getitem__(self, key):
        if key == 0:
            return self.x
        elif key == 1:
            return self.y
        else:
            raise IndexError("This "+str(key)+" key is not a vector key!")

    def __sub__(self, o): # subtraction
        return Vector(self.x - o.x, self.y - o.y)

    def length(self): # get length (used for normalize)
        return math.sqrt((self.x**2 + self.y**2)) 

    def normalize(self): # divides a vector by its length
        l = self.length()
        if l != 0:
            return (self.x / l, self.y / l)
        return None



class Sprite(pygame.sprite.Sprite):

    def __init__(self):
        '''
        Class:
            creates a sprite
        Parameters:
            - self
        '''
        self.image = pygame.image.load("Images/green.png").convert() # load image
        self.rect = self.image.get_rect()


        self.speed = 10 # movement speed of the sprite
        self.speedX = 0 # speed in x direction
        self.speedY = 0 # speed in y direction
        self.target = None # starts off with no target

    def set_position(self, x,y):
        self.rect.centerx= x
        self.rect.centery= y
        self.rect.center=(self.rect.centery, self.rect.centery)

    def get_position(self):
        return self.rect.center


    def move(self, distance):
        if self.target:
            direction =self.get_direction(self.target)
            position = self.get_position() # create a vector from center x,y value
            direction = Vector(direction[0], direction[1]) # and one from the target x,y
            distance = target - position # get total distance between target and position
        return distance

    def get_direction(self, target):
        '''
        Function:
            takes total distance from sprite.center
            to the sprites target
            (gets direction to move)
        Returns:
            a normalized vector
        Parameters:
            - self
            - target
                x,y coordinates of the sprites target
                can be any x,y coorinate pair in
                brackets [x,y]
                or parentheses (x,y)
        '''
        if self.target: # if the square has a target
            position = Vector(self.rect.centerx, self.rect.centery) # create a vector from center x,y value
            target = Vector(target[0], target[1]) # and one from the target x,y
            self.dist = target - position # get total distance between target and position

            direction = self.dist.normalize() # normalize so its constant in all directions
            return direction


    def distance_check(self, dist):
        '''
        Function:
            tests if the total distance from the
            sprite to the target is smaller than the
            ammount of distance that would be normal
            for the sprite to travel
            (this lets the sprite know if it needs
            to slow down. we want it to slow
            down before it gets to it's target)
        Returns:
            bool
        Parameters:
            - self
            - dist
                this is the total distance from the
                sprite to the target
                can be any x,y value pair in
                brackets [x,y]
                or parentheses (x,y)
        '''
        dist_x = dist[0] ** 2 # gets absolute value of the x distance
        dist_y = dist[1] ** 2 # gets absolute value of the y distance
        t_dist = dist_x + dist_y # gets total absolute value distance
        speed = self.speed ** 2 # gets aboslute value of the speed

        if t_dist < (speed): # read function description above
            return True


    def update(self):
        '''
        Function:
            gets direction to move then applies
            the distance to the sprite.center
            ()
        Parameters:
            - self
        '''        
        self.dir = self.get_direction(self.target) # get direction
        if self.dir: # if there is a direction to move
            if self.distance_check(self.dist): # if we need to stop
                self.rect.center = self.target # center the sprite on the target

            else: # if we need to move normal

                self.rect.centerx += (self.dir[0] * self.speed) # calculate speed from direction to move and speed constant
                self.rect.centery += (self.dir[1] * self.speed)
                self.rect.center = (round(self.rect.centerx),round(self.rect.centery)) # apply values to sprite.center

    def move_c(self,distance):
        self.dir = self.get_direction(self.target) # get direction
        if self.dir: # if there is a direction to move

            if self.distance_check(self.dist): # if we need to stop
                self.rect.center = self.target # center the sprite on the target

            else: # if we need to move normal
                self.rect.centerx += (self.dir[0] * self.speed) # calculate speed from direction to move and speed constant
                self.rect.centery += (self.dir[1] * self.speed)
                self.rect.center = (round(self.rect.centerx),round(self.rect.centery)) # apply values to sprite.center
        return distance
def main():

    screen = pygame.display.set_mode((640,480))
    pygame.display.set_caption("Test game")
    background_color = pygame.Surface(screen.get_size()).convert()
    background_color.fill((240,50,0))

##    line_points = [] # make a list for points
##    line_color = (0, 255, 255) # color of the lines

    sprite = Sprite() # create the sprite
    clock = pygame.time.Clock()
    sprite.set_position(100,400)

    running = True

    while running:
        clock.tick(30)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            if event.type == MOUSEBUTTONDOWN:
                  sprite.move(100)
##                  sprite.move_c(150)
##                sprite.target = event.pos # set the sprite.target to the mouse click position


        screen.blit(background_color, (0,0))

##        sprite.update() # update the sprite

        screen.blit(sprite.image, sprite.rect.topleft) # blit the sprite to the screen


        pygame.display.flip()

    pygame.quit() # for a smooth quit
if __name__ == "__main__":
    main()

这是移动方法之一,我通过给出想要移动精灵的距离来移动精灵。我得到当前位置精灵的方向。通过位置计算距离i减去目标并返回位置。但是当我调用这个函数时:

sprite.move(50):

精灵根本不会移动50个。

def move(self, distance):
        if self.target:
            direction =self.get_direction(self.target)
            position = self.get_position() # create a vector from center x,y value
            direction = Vector(direction[0], direction[1]) # and one from the target x,y
            distance = target - position # get total distance between target and position
        return distance

1 个答案:

答案 0 :(得分:0)

使用mainloop

while running:
    clock.tick(30)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == MOUSEBUTTONDOWN:
            sprite.target = event.pos # set the sprite.target to the mouse click position


    sprite.move_c(100)

    screen.blit(background_color, (0,0))
    screen.blit(sprite.image, sprite.rect.topleft) # blit the sprite to the screen
    pygame.display.flip()

您每帧都调用move_c()来改变精灵位置。

顺便说一下 - 您可以sprite.update()代替sprite.move_c(),但sprite.move()不起作用。


if event.type == MOUSEBUTTONDOWN:

    当你按下鼠标键时,
  • 只有一次;
  • 按下按钮时不是这样。

如果只在按下鼠标按钮时需要做某事,你必须这样做:

is_pressed = False

while running:
    clock.tick(30)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == MOUSEBUTTONDOWN:
            is_pressed = True

        if event.type == MOUSEBUTTONUP:
            is_pressed = False

    if is_pressed:
         sprite.target = pygame.mouse.get_pos()
         sprite.move_c(100)

    screen.blit(background_color, (0,0))
    screen.blit(sprite.image, sprite.rect.topleft) # blit the sprite to the screen
    pygame.display.flip()

这种精灵跟随鼠标。


修改

我没有更多以前的工作代码,因为同时我做了修改 - 现在你只能使用箭头(左,右,上,下)来移动精灵。一键 - 一次移动(距离:100)。

此时完整代码(您必须更改位图文件名)

import pygame, math
from pygame.locals import *
pygame.init()

class Vector():
    '''

            creates operations to handle vectors such
            as direction, position, and speed
        '''
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self): # used for printing vectors
        return "(%s, %s)"%(self.x, self.y)

    def __getitem__(self, key):
        if key == 0:
            return self.x
        elif key == 1:
            return self.y
        else:
            raise IndexError("This "+str(key)+" key is not a vector key!")

    def __sub__(self, o): # subtraction
        return Vector(self.x - o.x, self.y - o.y)

    def length(self): # get length (used for normalize)
        return math.sqrt((self.x**2 + self.y**2)) 

    def normalize(self): # divides a vector by its length
        l = self.length()
        if l != 0:
            return (self.x / l, self.y / l)
        return None



class Sprite(pygame.sprite.Sprite):

    def __init__(self):
        '''
        Class:
            creates a sprite
        Parameters:
            - self
        '''
        self.image = pygame.image.load("ball1.png").convert() # load image
        self.rect = self.image.get_rect()


        self.speed = 10 # movement speed of the sprite
        self.speedX = 0 # speed in x direction
        self.speedY = 0 # speed in y direction
        self.target = None # starts off with no target

    def set_position(self, x,y):
        self.rect.centerx= x
        self.rect.centery= y
        #self.rect.center=(self.rect.centery, self.rect.centery)

    def get_position(self):
        return self.rect.center


    def move(self, distance):
        if self.target:
            direction = self.get_direction(self.target)
            position = self.get_position() # create a vector from center x,y value
            direction = Vector(direction[0], direction[1]) # and one from the target x,y
            distance = self.target - position # get total distance between target and position
        return distance

    def get_direction(self, target):
        '''
        Function:
            takes total distance from sprite.center
            to the sprites target
            (gets direction to move)
        Returns:
            a normalized vector
        Parameters:
            - self
            - target
                x,y coordinates of the sprites target
                can be any x,y coorinate pair in
                brackets [x,y]
                or parentheses (x,y)
        '''
        if self.target: # if the square has a target
            position = Vector(self.rect.centerx, self.rect.centery) # create a vector from center x,y value
            target = Vector(target[0], target[1]) # and one from the target x,y
            self.dist = target - position # get total distance between target and position

            direction = self.dist.normalize() # normalize so its constant in all directions
            return direction


    def distance_check(self, dist):
        '''
        Function:
            tests if the total distance from the
            sprite to the target is smaller than the
            ammount of distance that would be normal
            for the sprite to travel
            (this lets the sprite know if it needs
            to slow down. we want it to slow
            down before it gets to it's target)
        Returns:
            bool
        Parameters:
            - self
            - dist
                this is the total distance from the
                sprite to the target
                can be any x,y value pair in
                brackets [x,y]
                or parentheses (x,y)
        '''
        dist_x = dist[0] ** 2 # gets absolute value of the x distance
        dist_y = dist[1] ** 2 # gets absolute value of the y distance
        t_dist = dist_x + dist_y # gets total absolute value distance
        speed = self.speed ** 2 # gets aboslute value of the speed

        if t_dist < (speed): # read function description above
            return True


    def update(self):
        '''
        Function:
            gets direction to move then applies
            the distance to the sprite.center
            ()
        Parameters:
            - self
        '''        
        self.dir = self.get_direction(self.target) # get direction
        if self.dir: # if there is a direction to move
            if self.distance_check(self.dist): # if we need to stop
                self.rect.center = self.target # center the sprite on the target

            else: # if we need to move normal

                self.rect.centerx += (self.dir[0] * self.speed) # calculate speed from direction to move and speed constant
                self.rect.centery += (self.dir[1] * self.speed)
                self.rect.center = (round(self.rect.centerx),round(self.rect.centery)) # apply values to sprite.center

    def move_c(self,distance):
        self.dir = self.get_direction(self.target) # get direction
        if self.dir: # if there is a direction to move

            if self.distance_check(self.dist): # if we need to stop
                self.rect.center = self.target # center the sprite on the target

            else: # if we need to move normal
                self.rect.centerx += (self.dir[0] * self.speed) # calculate speed from direction to move and speed constant
                self.rect.centery += (self.dir[1] * self.speed)
                self.rect.center = (round(self.rect.centerx),round(self.rect.centery)) # apply values to sprite.center
        return distance

    def move_d(self):
        if self.target:
            if abs(self.rect.x - self.target.x) > abs(self.speedX):
                self.rect.x += self.speedX
            else:
                self.rect.x = self.target.x

            if abs(self.rect.y - self.target.y) > abs(self.speedY):
                self.rect.y += self.speedY
            else:
                self.rect.y = self.target.y

            if self.rect == self.target:
                self.target = None

    def set_move_left(self, distance):
        if not self.target: 
            self.target = self.rect.copy()
            self.target.centerx -= distance 
            self.speedX = -self.speed
            self.speedY = 0

    def set_move_right(self, distance):
        if not self.target: 
            self.target = self.rect.copy()
            self.target.centerx += distance 
            self.speedX = self.speed
            self.speedY = 0

    def set_move_up(self, distance):
        if not self.target: 
            self.target = self.rect.copy()
            self.target.centery -= distance 
            self.speedX = 0
            self.speedY = -self.speed

    def set_move_down(self, distance):
        if not self.target: 
            self.target = self.rect.copy()
            self.target.centery += distance 
            self.speedX = 0
            self.speedY = self.speed

    def set_move(self, distance, pos):
        if not self.target: 
            self.target = self.rect.copy()
            dx = (pos[0] - self.rect.x)
            dy = (pos[1] - self.rect.y)

            if dx == 0 :
                ay = 0
            else:
                ay = float(distance)/dx

            if dy == 0 :
                ax = 0
            else:
                ax = float(dx)/dy

            self.target.centerx += distance * ax
            self.target.centery += distance * ay
            self.speedX = self.speed * ax
            self.speedY = self.speed * ay

            print "dx/dy:", dx, dy,
            print "ax/ay:", ax, ay

def main():

    screen = pygame.display.set_mode((640,480))
    pygame.display.set_caption("Test game")
    background_color = pygame.Surface(screen.get_size()).convert()
    background_color.fill((240,50,0))

##    line_points = [] # make a list for points
##    line_color = (0, 255, 255) # color of the lines

    sprite = Sprite() # create the sprite
    clock = pygame.time.Clock()
    sprite.set_position(100,400)

    running = True

    is_pressed = False

    while running:
        clock.tick(30)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            elif event.type == MOUSEBUTTONDOWN:
                #sprite.set_move(100, event.pos)
                pass

            elif event.type == KEYDOWN:
                if event.key == K_LEFT:                 
                    sprite.set_move_left(100)
                elif event.key == K_RIGHT:                  
                    sprite.set_move_right(100)
                elif event.key == K_UP:
                    sprite.set_move_up(100)
                elif event.key == K_DOWN:
                    sprite.set_move_down(100)


        sprite.move_d()

        screen.blit(background_color, (0,0))
        screen.blit(sprite.image, sprite.rect.topleft) # blit the sprite to the screen
        pygame.display.flip()

    pygame.quit() # for a smooth quit

if __name__ == "__main__":
    main()