这是这本书中的代码Beginning Python Games Development With PyGame:

import pygame
from pygame.locals import *
from sys import exit
from math import *

class Vector2:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

        if hasattr(x, "__getitem__"):
            x, y = x
            self._v = [float(x), float(y)]
        else:
            self._v = [float(x), float(y)]

    def __getitem__(self, index):
        return self._v[index]

    def __setitem__(self, index, value):
        self._v[index] = 1.0 * value
        
    def __str__(self):
        return "(%s, %s)"%(self.x, self.y)
    
    def from_points(P1, P2):
        return Vector2(P2[0] - P1[0], P2[1] - P1[1]) 
        # return np.array(P2) - np.array(P1) # using numpy method
        
    def get_magnitude(self):
        return math.sqrt( self.x**2 + self.y**2 )

    def normalize(self):
        magnitude = self.get_magnitude()
        try:
            self.x /= magnitude
            self.y /= magnitude
        except ZeroDivisionError:
            self.x = 0
            self.y = 0

    # rhs stands for Right Hand Side
    def __add__(self, rhs):
        return Vector2(self.x + rhs.x, self.y + rhs.y)
    
    def __sub__(self, rhs):
        return Vector2(self.x - rhs.x, self.y - rhs.y)
    
    def __neg__(self):
        return Vector2(-self.x, -self.y)
    
    def __mul__(self, scalar):
        return Vector2(self.x * scalar, self.y * scalar)

    def __truediv__(self, scalar):
        return Vector2(self.x / scalar, self.y / scalar)


background_image_filename = 'sushiplate.jpg'
sprite_image_filename = 'fugu.png'

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)

background = pygame.image.load(background_image_filename).convert()
sprite = pygame.image.load(sprite_image_filename).convert_alpha()

clock = pygame.time.Clock()

pygame.mouse.set_visible(False)
pygame.event.set_grab(True)

sprite_pos = Vector2(200, 150)
sprite_speed = 300.
sprite_rotation = 0.
sprite_rotation_speed = 360. # Degrees per second

while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            exit()
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                exit()

    pressed_keys = pygame.key.get_pressed()
    pressed_mouse = pygame.mouse.get_pressed()

    rotation_direction = 0.
    movement_direction = 0.

    rotation_direction = pygame.mouse.get_rel()[0] / 3. 

    if pressed_keys[K_LEFT]:
        rotation_direction = +1.
    if pressed_keys[K_RIGHT]:
        rotation_direction = -1.
    if pressed_keys[K_UP] or pressed_mouse[0]:
        movement_direction = +1.
    if pressed_keys[K_DOWN] or pressed_mouse[2]:
        movement_direction = -1.
        
    screen.blit(background, (0,0))

    rotated_sprite = pygame.transform.rotate(sprite, sprite_rotation)
    w, h = rotated_sprite.get_size()
    sprite_draw_pos = Vector2(sprite_pos.x-w/2, sprite_pos.y-h/2)
    screen.blit(rotated_sprite, (sprite_draw_pos.x, sprite_draw_pos.y))

    time_passed = clock.tick()
    time_passed_seconds = time_passed / 1000.0

    sprite_rotation += rotation_direction * sprite_rotation_speed * time_passed_seconds

    heading_x = sin(sprite_rotation*pi/180.)
    heading_y = cos(sprite_rotation*pi/180.)
    heading = Vector2(heading_x, heading_y)
    heading *= movement_direction

    sprite_pos+= heading * sprite_speed * time_passed_seconds

    pygame.display.update()

这个脚本的问题是sprite个CAN disappear从显示屏上.我试图通过在最后一行pygame.display.update()的正上方添加以下代码来解决这个问题

if sprite_pos.x > screen.get_width() or sprite_pos.x < 0:
    sprite_draw_pos.x = 0
        
if sprite_pos.y > screen.get_height() or sprite_pos.y < 0:
    sprite_draw_pos.y = 0  

然而,这个解决方案没有奏效,因为那sprite个仍然消失了?有没有人能解释一下我做错了什么,告诉我如何实现这个目标?谢谢.

推荐答案

您必须判断sprite_draw_pos而不是sprite_pos,因为sprite_draw_pos不是sprite_pos,而是Vector2(sprite_pos.x-w/2, sprite_pos.y-h/2).然而,我建议使用pygame.Rect.containspygame.Rect.clamp:

rotated_sprite = pygame.transform.rotate(sprite, sprite_rotation)
sprite_rect = rotated_sprite.get_rect(center = (sprite_pos.x, sprite_pos.y))
screen_rect = screen.get_rect()
if not screen_rect.contains(sprite_rect):
    sprite_rect = sprite_rect.clamp(screen_rect)
    sprite_pos.x = sprite_rect.centerx
    sprite_pos.y = sprite_rect.centery
screen.blit(rotated_sprite, sprite_rect)

Python相关问答推荐

如何输入提示抽象方法属性并让mypy高兴?

telegram 机器人API setMyName不起作用

如何使用bs 4从元素中提取文本

由于瓶颈,Python代码执行太慢-寻求性能优化

实现的差异取决于计算出的表达是直接返回还是首先存储在变量中然后返回

比较两个数据帧并并排附加结果(获取性能警告)

为什么tkinter框架没有被隐藏?

为什么带有dropna=False的groupby会阻止后续的MultiIndex.dropna()工作?

有症状地 destruct 了Python中的regex?

在Python Attrs包中,如何在field_Transformer函数中添加字段?

Pandas - groupby字符串字段并按时间范围 Select

在Polars(Python库)中将二进制转换为具有非UTF-8字符的字符串变量

聚合具有重复元素的Python字典列表,并添加具有重复元素数量的新键

NP.round解算数据后NP.unique

如何创建一个缓冲区周围的一行与manim?

Pandas—在数据透视表中占总数的百分比

如何根据一列的值有条件地 Select 前N个组,然后按两列分组?

如何从需要点击/切换的网页中提取表格?

在方法中设置属性值时,如何处理语句不可达[Unreacable]";的问题?

如何找出Pandas 图中的连续空值(NaN)?