Python “几个屏幕”;重叠“;皮加梅
我今天开始用pygame编程一个游戏。背景是一种网格,您将在其上玩游戏。但我注意到,通过一个while循环来更新屏幕,网格每次都会被重新绘制,这是一种资源浪费,因为那里没有任何变化。现在我考虑不在后台更新网格屏幕,而是创建一个新的屏幕来播放,该屏幕将被更新。但后来我遇到了一个问题:当pygame启动一个新屏幕时,最后一个屏幕关闭。 那么,每次重新绘制游戏板是明智之举,还是有另一种方法可以让您在不更新项目的情况下将其保留在后台?非常感谢你的帮助。遵循代码和(错误的)方法 main.pyPython “几个屏幕”;重叠“;皮加梅,python,pygame,Python,Pygame,我今天开始用pygame编程一个游戏。背景是一种网格,您将在其上玩游戏。但我注意到,通过一个while循环来更新屏幕,网格每次都会被重新绘制,这是一种资源浪费,因为那里没有任何变化。现在我考虑不在后台更新网格屏幕,而是创建一个新的屏幕来播放,该屏幕将被更新。但后来我遇到了一个问题:当pygame启动一个新屏幕时,最后一个屏幕关闭。 那么,每次重新绘制游戏板是明智之举,还是有另一种方法可以让您在不更新项目的情况下将其保留在后台?非常感谢你的帮助。遵循代码和(错误的)方法 main.py impor
import field, game
import ctypes
# Variables
def main():
width, height = ctypes.windll.user32.GetSystemMetrics(0), ctypes.windll.user32.GetSystemMetrics(1)
width_scale, height_scale = 5 / 10, 9 / 10
black = (0, 0, 0)
white = (255, 255, 255)
background_color = (214, 237, 255)
refresh_rate = 60
field_size = [10, 18]
screen = pg.display.set_mode([int(width * width_scale), int(height * height_scale)], pg.NOFRAME)
while True:
for event in pg.event.get():
if event.type == pg.KEYDOWN:
pass
screen.fill(background_color)
box_size = field.draw_boxes(screen.get_width(), screen.get_height(), field_size, screen)
field.draw_next_hand()
pg.display.flip()
game.main(width, height, box_size, field_size)
if __name__ == '__main__':
main()
pg.quit()
field.py
import pygame as pg
def draw_boxes(w, h, size, screen):
global start_x, box_size, g_screen, grey, s
g_screen = screen
s = size
box_size = int(w / 2 / (size[0]+1))
start_x = int(w / 2 - size[0] / 2 * box_size)
grey = (122, 122, 122)
for column in range(0, size[0], 1):
for row in range(0, size[1], 1):
pg.draw.rect(screen, grey, [start_x + column * box_size, box_size + row * box_size, box_size, box_size], width= 1)
return box_size
def draw_next_hand():
global box_size, start_x, g_screen, grey
next_hand_size = 4
next_hand_distance = 1
for column in range(0, next_hand_size, 1):
for row in range(0, next_hand_size, 1):
pg.draw.rect(g_screen, grey, [start_x - 2*box_size*next_hand_distance - column * box_size, box_size + row * box_size, box_size, box_size], width=1)
pg.draw.rect(g_screen, grey, [start_x + box_size*s[0] + box_size * next_hand_distance + column * box_size, box_size + row * box_size, box_size, box_size], width=1)
game.py
import pygame as pg
from main import main
def main(width, height, box_size, f_size):
# Variables
white = (255, 255, 255)
black = (0, 0, 0)
grey = (122, 122, 122)
refresh_rate = 60
g_screen = pg.display.set_mode([int(f_size[0] * box_size), int(f_size[1] * box_size)], pg.NOFRAME)
while True:
g_screen.fill(white)
pg.display.flip()
pg.time.delay(refresh_rate)
在我添加新屏幕之前,我使用了“pg.time.delay(refresh_rate)”而不是“game.main()”,这导致背景不断被重新绘制,所以我尝试在其上绘制另一个屏幕,当然这不起作用^^
我已经发现了一些关于堆栈溢出的条目,但它们不符合我的问题,因为有人建议更改屏幕,例如main=False和game=True,但这不会阻止重新绘制棋盘。有几种方法可以提高背景图像的性能
- 绘制一次-可以将背景图像存储在曲面对象中,因此只需生成一次。Pygame将在隐藏或最小化时保留屏幕
- 仅重绘更新的部分-在屏幕上设置一个剪切矩形,以便在重绘背景时仅刷新某些像素
- 仅在需要时重新绘制-需要游戏循环,但您可以有条件地重新渲染背景
- 高效绘图-使用
pygame.time.Clock().tick()方法减慢游戏循环
import pygame as pg
import time
from datetime import datetime as dt
from random import randint
WIDTH = 480
HEIGHT = 600
pg.init()
screen = pg.display.set_mode((WIDTH, HEIGHT))
def rnd(rg): # save some typing
return randint(0,rg)
font_name = pg.font.match_font('arial')
def draw_text(surf, text, size, x, y): # draw text on screen in rect
font = pg.font.Font(font_name, size)
text_surface = font.render(text, True, (rnd(255),rnd(255),rnd(255)))
text_rect = text_surface.get_rect()
text_rect.midtop = (x, y)
surf.blit(text_surface, text_rect)
def make_bg(): # create background image
surf_bg = pg.Surface((WIDTH, HEIGHT))
surf_bg.fill((0,0,0)) # start with black
for i in range(500): # 500 circles
pg.draw.circle(surf_bg,(rnd(255),rnd(255),rnd(255)), (rnd(WIDTH),rnd(HEIGHT)), 15+rnd(50))
return surf_bg
surf_bg = make_bg() # generate circles once, store surface object
#initial background
screen.blit(surf_bg, screen.get_rect()) # draw background, only needed once in Windows
screen.set_clip((10, HEIGHT/2 - 20, WIDTH-10, HEIGHT/2 + 20)) # set active region on screen
lasttick = pg.time.get_ticks() # milliseconds since init
while True:
pg.time.Clock().tick(5) # run loop 5 times per second
pg.event.get() # required in Windows for OS events
if pg.key.get_pressed()[pg.K_SPACE]: quit() # press space to quit
if (pg.time.get_ticks() - lasttick < 1000): continue # only redraw time each second
lasttick = pg.time.get_ticks()
screen.blit(surf_bg, screen.get_rect()) # background, update clip region only
draw_text(screen, str(dt.now()), 30, WIDTH / 2, HEIGHT / 2 - 10) # draw time
pg.display.flip() # swap screen buffer
将pygame导入为pg
导入时间
从日期时间导入日期时间作为dt
从随机导入randint
宽度=480
高度=600
第init页()
屏幕=pg.display.set_模式((宽度、高度))
def rnd(rg):#保存一些键入内容
返回randint(0,rg)
font\u name=pg.font.match\u font('arial')
def draw_text(冲浪、文本、大小、x、y):#在屏幕上以矩形绘制文本
font=pg.font.font(字体名称、大小)
text\u surface=font.render(text,True,(rnd(255)、rnd(255)、rnd(255)))
text_rect=text_surface.get_rect()
text_rect.midtop=(x,y)
冲浪板(文字表面,文字直线)
def make_bg():#创建背景图像
表面(宽度、高度)
冲浪背景填充((0,0,0))#从黑色开始
对于范围(500)内的i:#500个圆
pg.draw.圆(表面背景,(径向直径(255),径向直径(255),径向直径(255)),(径向直径(宽度),径向直径(高度)),15+径向直径(50))
返回surf_bg
surf_bg=生成_bg()#生成一次圆,存储曲面对象
#初始背景
screen.blit(surf_bg,screen.get_rect())35;在Windows中只需绘制一次背景
屏幕。设置剪辑((10,高度/2-20,宽度-10,高度/2+20))#在屏幕上设置活动区域
lasttick=pg.time.get_ticks()#自初始化以来的毫秒数
尽管如此:
pg.time.Clock().勾选(5)#每秒运行循环5次
pg.event.get()#Windows中操作系统事件需要
如果按下pg.key.get_()[pg.K_SPACE]:退出()#按空格退出
if(pg.time.get_ticks()-lasttick<1000):继续#每秒只重新绘制时间
lasttick=pg.time.get_ticks()
screen.blit(surf_bg,screen.get_rect())#背景,仅更新剪辑区域
绘制文字(屏幕,str(dt.now()),30,宽/2,高/2-10)#绘制时间
pg.display.flip()#交换屏幕缓冲区
通常在每一帧中重新绘制场景。在一个简单的游戏中,这似乎是无用的,也是对资源的浪费,但在现代游戏中,几乎每一帧都有变化的动态场景中,这并没有什么区别。不要浪费时间。一个简单的方法是仅在一个帧中处理了至少一个事件时才更新显示。