2013-11-21 44 views
0

我想通過調用該方法和我想移動它的距離來移動一定距離的字符。到目前爲止,我可以通過調用函數並放置我的x和y值來確定字符位置。當用戶點擊一個鼠標。在主要方法中,我希望移動方法被調用。我試過兩種移動實現,第一步移動和第二步move_c,都沒有工作。我使用python3和pygame通過一種方法移動一個字符 - python

有什麼建議嗎?

繼承人我的代碼

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 
+0

究竟不起作用? – Mailerdaimon

+0

也許嘗試縮小你的問題。究竟你的最新方法沒有工作?代碼導致問題的部分是什麼? – Lycha

+0

一個矩形的移動,它現在不移動,即使通過一個距離 –

回答

0

工作主循環

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() 
+0

謝謝你的這個furas!但是我不想讓精靈跟隨鼠標,我想讓精靈在用戶定義的指定距離移動,例如,如果用戶單擊鼠標或者即使他們按了左箭頭。然後精靈會移動。因此,如果用戶說移動(30),那麼精靈應該移動30的距離。 –

+0

??任何想法如何 –

+0

你也提供的代碼不工作 –

相關問題