我正在尝试通过调用该方法和我想要移动它的距离将角色移动一定距离。到目前为止,我可以通过调用函数并放置我的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
答案 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()