python - 为什么我的精灵在与地板碰撞时向左移动得更快?游戏
问题描述
为什么当我接触地面时我的精灵开始增加速度,对不起,没有那么有用的评论。
速度在接触地板时缓慢增加,向左移动直到它撞到墙壁并停止我认为我的一个速度算法运行不正常,请你帮帮我,请注意: 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
解决方案
由于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
推荐阅读
- windows - 使用内部地址解析外部 IP 的 DNS 条目
- angularjs - 如何解决 Wild Web Developer 安装问题
- cvxpy - CVXR 迭代限制
- python - 在 Python 3 中绘制直角三角形
- glsl - GLSL Shadertoy,如何存储变量数据?
- javascript - 创建 NPM 包自定义事件
- c# - Blazor - INSERT 语句与 FOREIGN KEY 约束冲突
- node.js - ./node_modules/fluent-ffmpeg/index.js 中的错误找不到模块:错误:无法解析“./lib-cov/fluent-ffmpeg”
- visual-studio-code - 如何在 VSCode 中忽略 Java Build 中的文件
- sass - FontAwesome 5 - $fa-font-path 未考虑在内