首页 > 解决方案 > 为什么我的精灵在与地板碰撞时向左移动得更快?游戏

问题描述

为什么当我接触地面时我的精灵开始增加速度,对不起,没有那么有用的评论。

速度在接触地板时缓慢增加,向左移动直到它撞到墙壁并停止我认为我的一个速度算法运行不正常,请你帮帮我,请注意: from character import Character from fuses import Fuses import这:

import pygame

class Character(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        super().__init__()
        self.image = pygame.Surface([width, height])
        pygame.draw.rect(self.image, color, [0, 0, width, height])
        self.image = pygame.image.load("Fuses.png").convert_alpha()
        self.rect = self.image.get_rect()

还有这个

import pygame


class Fuses(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        super().__init__()
        self.image = pygame.Surface([width, height])
        pygame.draw.rect(self.image, color, [0, 0, width, height])
        self.image = pygame.image.load("Fuses.png").convert_alpha()
        self.rect = self.image.get_rect()
import ctypes
import random
import threading
import pygame
from character import Character
from fuses import Fuses
# starting game
pygame.init()
#initiates
if True:
    # initiating
    debug = True
    clock = pygame.time.Clock()
    user32 = ctypes.windll.user32
    screen_size = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
    screen = pygame.display.set_mode(screen_size)
    screen_width, screen_height = screen_size
    font = pygame.font.SysFont('Comic Sans MS', 30)
    pygame.display.set_caption("Slingy")
    player = Character((0, 0, 0), 37, 63)
    player.rect.centerx = screen_width / 2
    player.rect.centery = screen_height / 2
    fuse = Fuses((0, 0, 0), 30, 40)
    fuse.rect.centerx = random.randint(21, screen_width - 21)
    fuse.rect.centery = random.randint(16, screen_height - 16)
    all_sprites_list = pygame.sprite.Group()
    all_sprites_list.add(fuse, player)
    fuse_count, velx, vely, click_count, debug_counter = 300, 0, 0, 0, 0
    carryOn = True
def update():
    # updates player position
    player.rect.centerx += velx
    player.rect.centery += vely

def collide():
    # check collision
    global fuse_count, velx, vely
    if fuse.rect.colliderect(player):
        print("Player has earnt 2 fuses")
        fuse_count += 2
        while fuse.rect.colliderect(player):
            fuse.rect.centerx = random.randint(21, screen_width - 21)
            fuse.rect.centery = random.randint(16, screen_height - 16)
    if player.rect.centerx < 37 / 2:
        player.rect.centerx = 37 / 2
        velx = velx * 0.85
    if player.rect.centerx > screen_width - 37 / 2:
        player.rect.centerx = screen_width - 37 / 2
        velx = velx * 0.85
    if player.rect.centery < 63 / 2:
        player.rect.centery = 63 / 2
        vely = vely * 0.90
    if player.rect.centery > screen_height - 63 / 2 + 1:
        player.rect.centery = screen_height - 63 / 2 + 1
        vely = vely * 0.90
        velx = velx * 0.85
def vel():
    # Slowly decreasing velocity
    global velx, vely
    if velx > 0.1:
        velx -= velx * 0.02 + 0.001
    if velx < 0.1:
        velx += velx * 0.02 + 0.001
    vely += abs(vely) / 50 + 0.3

def key():
    # gets input
    global click_count, fuse_count, velx, vely, carryOn
    mouseX, mouseY = pygame.mouse.get_pos()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            carryOn = False
        if event.type == pygame.MOUSEBUTTONUP:
            click_count += 1
            print(f"Click count: {click_count} \nFuse count: {fuse_count}")
            if fuse_count > 0:
                fuse_count -= 1
                vely = 0
                velx += (mouseX - player.rect.centerx) * 0.05
                vely += (mouseY - player.rect.centery) * 0.05
            else:
                print("You are out of fuses")

def debugging():
    #prints velocities
    global debug_counter
    if debug_counter % 70 == 0:
        print(f"Velocity x: {velx} \nVelocity y: {vely}")
    debug_counter += 1

# Start of the game render
print(f"Starting... \nSprites: {all_sprites_list} \nClicks: {click_count} \n Fuses: {fuse_count}")
while carryOn:
    #game render
    clock.tick(70)
    velocity_t = threading.Thread(target=vel())
    collision_t = threading.Thread(target=collide())
    draw_t = threading.Thread(target=update())
    if debug:
        # print velocities
        debug_t = threading.Thread(target=debugging())
        debug_t.start()
    input_t = threading.Thread(target=key())
    input_t.start()
    input_t.join()
    collision_t.start()
    collision_t.join()
    velocity_t.start()
    velocity_t.join()
    draw_t.start()
    draw_t.join()
    textsurface = font.render("You have " + str(fuse_count) + " fuses", False, (0, 0, 0))
    screen.fill((255, 255, 255))
    screen.blit(textsurface, (0, 0))
    all_sprites_list.update()
    all_sprites_list.draw(screen)
    pygame.display.flip()
# quits the game
pygame.quit()
# game ended

标签: pythonpygame

解决方案


由于pygame.Rect应该代表屏幕上的一个区域,一个pygame.Rect对象只能存储整数数据。

Rect 对象的坐标都是整数。[...]

当对象的新位置分配给Rect对象时,坐标的小数部分会丢失。这会导致对象向左移动比向右移动更快。

如果要以浮点精度存储对象位置,则必须将对象的位置存储在单独的变量和属性中并同步pygame.Rect对象。round坐标并将其分配给.topleft矩形的位置(例如):

class Character(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        super().__init__()
        self.image = pygame.Surface([width, height])
        pygame.draw.rect(self.image, color, [0, 0, width, height])
        self.image = pygame.image.load("Fuses.png").convert_alpha()
        self.rect = self.image.get_rect()
        self.x, self.y = self.rect.center

    def update(self):
        self.rect.center = round(self.x), round(self.y)
def update():
    # updates player position
    player.x += velx
    player.y += vely
    player.update()

def collide():
    # [...]

    if player.x < 37 / 2:
        player.x = 37 / 2
        velx = velx * 0.85
    if player.x > screen_width - 37 / 2:
        player.x = screen_width - 37 / 2
        velx = velx * 0.85
    if player.y < 63 / 2:
        player.y = 63 / 2
        vely = vely * 0.90
    if player.y > screen_height - 63 / 2 + 1:
        player.y = screen_height - 63 / 2 + 1
        vely = vely * 0.90
        velx = velx * 0.85

推荐阅读