所以我在 PyGame 中制作了一個游戲,我制作了一個生成一堆樹木和巖石的系統。這些是呼叫update()函式的物件,在該函式中對其位置進行了一些必要的計算,然后將它們顯示在螢屏上。我正在嘗試制作一個程式,當它在螢屏上可見時才真正更新樹葉物件,所以我制作了一個函式,如果它在螢屏上則回傳。
所以我添加了一個if運行這個函式的陳述句,突然我得到了 600 FPS 的平均值,但由于某種原因,玩家移動得非常慢,而影片進行得非常快。我使用可能與它有關的增量時間系統,但我不確定。
這是github
import pygame
from pygame.locals import *
from random import randint, choice
import time
screen_width = 800#int(1500/1.5)
screen_height = 800#int(1500/1.5)
flags = HWSURFACE|DOUBLEBUF|NOFRAME #| FULLSCREEN
screen = pygame.display.set_mode((screen_width, screen_height), flags, 1000000000)
fps = 0
clock = pygame.time.Clock()
last_time = time.time()
time_now = last_time
dt = 0
images = {
"players" : {
"base_right" : [
pygame.image.load("images/player/baseplr1.png").convert_alpha(),
pygame.image.load("images/player/baseplr2.png").convert_alpha(),
],
"base_left" : [
pygame.transform.flip(pygame.image.load("images/player/baseplr1.png").convert_alpha(),True, False),
pygame.transform.flip(pygame.image.load("images/player/baseplr2.png").convert_alpha(),True, False),
],
},
"enemies" : {
"simple" : [
pygame.image.load("images/enemies/zombie.png").convert_alpha()
]
},
"foliage" : {
"tree" : pygame.image.load("images/foliage/tree.png").convert_alpha() ,
"rock" : pygame.image.load("images/foliage/rock.png").convert_alpha() ,
},
"background" : pygame.transform.scale(pygame.image.load("background.png").convert_alpha(),(1000,1000)),
}
class Player(pygame.sprite.Sprite):
def __init__(self, pos, stats, skin, ori):
pygame.sprite.Sprite.__init__(self)
self.dmg = stats[0]
self.hp = stats[1]
self.speed = stats[2]
self.skin = skin
self.ori = ori
self.index_max = len(images["players"][self.skin "_" self.ori])
self.index = 0
self.image = images["players"][self.skin "_" self.ori][self.index]
self.count = False
self.timer = 0
self.anim_max = 16
self.rect = self.image.get_rect(center = pos)
self.x, self.y = self.rect.x, self.rect.y
def update(self):
self.movement()
self.animate()
def movement(self):
self.keys = pygame.key.get_pressed()
self.count = False
if self.keys[K_d]:
self.x = self.speed * dt
self.ori = "right"
self.count = True
if self.keys[K_a]:
self.x -= self.speed * dt
self.ori = "left"
self.count = True
if self.keys[K_s]:
self.y = self.speed* dt
self.count = True
if self.keys[K_w]:
self.y -= self.speed * dt
self.count = True
self.rect.x = self.x - main_cam.scroll[0]
self.rect.y = self.y - main_cam.scroll[1]
def animate(self):
if self.count:
self.timer = 1
if self.timer >= self.anim_max:
self.timer = 0
self.index = 1
if self.index == self.index_max:
self.index = 0
self.image = images["players"][self.skin "_" self.ori][self.index]
class Foliage:
def __init__(self, pos, type):
self.image = images["foliage"][type]
self.rect = self.image.get_rect()
self.x = pos[0]
self.y = pos[1]
def update(self):
self.rect.x = self.x - main_cam.scroll[0]
self.rect.y = self.y - main_cam.scroll[1]
screen.blit(self.image, (self.rect.x,self.rect.y))
def on_screen(self):
return self.rect.x > 0 and self.rect.x < screen_width and self.rect.y > 0 and self.rect.y < screen_width
class Camera:
def __init__(self, speed):
self.scroll = [5,5]
self.speed = speed
def move_on_command(self):
keys = pygame.key.get_pressed()
if keys[K_UP]:
self.scroll[1] -= self.speed * dt
if keys[K_DOWN]:
self.scroll[1] = self.speed * dt
if keys[K_RIGHT]:
self.scroll[0] = self.speed * dt
if keys[K_LEFT]:
self.scroll[0] -= self.speed * dt
def follow(self, obj, speed=12):
if (obj.x - self.scroll[0]) != screen.get_width()/2:
self.scroll[0] = ((obj.x - (self.scroll[0] screen.get_width()/2))/speed ) * dt
if obj.y - self.scroll[1] != screen.get_height()/2:
self.scroll[1] = ((obj.y - (self.scroll[1] screen.get_height()/2))/speed) * dt
class Folliage_Manager:
def __init__(self, multi=1):
self.foliage = []
self.foliage_amount = multi
def spawn_foliage(self, amount):
for i in range(int(amount*self.foliage_amount)):
cord = (randint(-10000,10000), randint(-10000, 100000))
e = randint(0,6)
if e > 4:
newfol = Foliage(cord, choice(["tree", "rock"]))
self.foliage.append(newfol)
# Instantiation of stuff
main_cam = Camera(1)
playerGroup = pygame.sprite.Group()
player = Player((500,500), [25, 100, 2], "base", "right")
playerGroup.add(player)
fm = Folliage_Manager(multi=0.8)
fm.spawn_foliage(30000)
# settings
def get_dt():
global last_time
dt = 0
time_now = time.time()
dt = time_now - last_time
last_time = time_now
return dt * 300
left_border = -10000
right_border = 10000
top_border = -10000
bottom_border = 10000
def spawnBackground(res):
global left_border, top_border, right_border, bottom_border
for i in range(int(-1000*res/2),int(1000*res/2), 1000):
for x in range(int(-1000*res/2),int(1000*res/2), 1000):
screen.blit(images["background"], (main_cam.scroll[0]*-1 i, main_cam.scroll[1]*-1 x))
#print(i)
def render(groups):
spawnBackground(10)
main_cam.follow(player, 60)
for fol in fm.foliage:
#if fol.rect.x > 0 and fol.rect.x < screen_width and fol.rect.y >0 and fol.rect.y > screen_height:
if fol.on_screen():
fol.update()
#print("PRINTING R")
for group in groups:
group.update()
group.draw(screen)
screen.blit(images["enemies"]["simple"][0], (500-main_cam.scroll[0],300-main_cam.scroll[1]))
pygame.event.set_allowed([QUIT,KEYDOWN])
fpse = []
run = True
while run:
clock.tick(fps)
dt = int(get_dt())
render([playerGroup])
for event in pygame.event.get():
if event.type == QUIT:
run = False
if event.type == KEYDOWN and event.key == K_ESCAPE:
run = False
fpse.append(int(clock.get_fps()))
pygame.display.update()
print(f"""
MAX FPS: {max(fpse)}
LEAST FPS: {min(fpse)}
AVERAGE FPS: {int(sum(fpse)/len(fpse))}
""")
quit()
uj5u.com熱心網友回復:
主要問題是您的代碼使用time.time()的粒度為十進制秒。它乘以 300,但這看起來像是加快速度的軟糖??
最好在所有游戲時間都使用 PyGame函式 pygame.time.get_ticks()。此函式回傳自程式啟動以來的毫秒數。所以改變你的get_dt():
def get_dt():
global last_time
dt = 0
time_now = pygame.time.get_ticks() # milliseconds since game start
dt = time_now - last_time
last_time = time_now
#return dt * 300
return dt
使玩家移動得更快,并修復了我看到的偶爾出現的奇怪減速問題——也許這是從time.time()? (我沒有調查原因。)
您的播放器影片使用簡單的基于“計數器”的幀控制。這意味著影片的速度與螢屏上的幀速率直接相關。如果此影片速率與 PyGame 時鐘相關聯,效果可能會更好。
采取的方法是存盤下一幀變化的時間。然后代碼查看當前時間,將其與未來時間進行比較。如果那個時間是now,影片幀被改變,并且未來時間重新計算。我也改為Player.count(Player.animating布林值)。
class Player(pygame.sprite.Sprite):
def __init__(self, pos, stats, skin, ori):
pygame.sprite.Sprite.__init__(self)
# [...]
self.ANIMATION_RATE = 50 # milliseconds between animation updates
self.animating = False # is the animation running (replaces self.count)
# Future time of next animation frame
self.next_anim_time = pygame.time.get_ticks() self.ANIMATION_RATE
def movement(self):
self.keys = pygame.key.get_pressed()
self.animating = False
if self.keys[K_d]:
self.x = self.speed * dt
self.ori = "right"
self.animating = True
# [...] Rest of identical changes omitted for the sake of brevity
def animate(self):
if ( self.animating ):
time_now = pygame.time.get_ticks()
# Is it time to do change the animation frame
if ( time_now > self.next_anim_time ):
self.next_anim_time = time_now self.ANIMATION_RATE # set time for next frame
self.index = 1
if ( self.index >= self.index_max ):
self.index = 0
self.image = images["players"][self.skin "_" self.ori][self.index]
另請注意,影片功能每次都在更改影像(主要是回傳相同的內容),而不是在實際需要更改時。
哦,我在測驗中從未見過像石頭或樹葉這樣的東西。也許這里還有一個問題,或者它們是稀有物品。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/533228.html
標籤:Python表现优化游戏
