我正在尝试用pyglet制作一个简单的游戏,它必须包含一个介绍屏幕。不幸的是,它比我预期的要困难得多。
以下代码是我想要做的更简单的版本。
import pyglet
from game import intro
game_window = pyglet.window.Window(800, 600)
intro.play(game_window)
@game_window.event
def on_draw():
game_window.clear()
main_batch.draw()
def update(dt):
running = True
if __name__ == '__main__':
pyglet.clock.schedule_interval(update, 1/120.0)
main_batch = pyglet.graphics.Batch()
score_label = pyglet.text.Label(text = 'RUNNING GAME', x = 400, y = 200, batch=main_batch)
pyglet.app.run()
game / intro.py中写有以下内容:
import pyglet
from time import sleep
def play(game_window):
game_window.clear()
studio = pyglet.text.Label('foo studios', font_size=36, font_name='Arial', x=400, y=300)
studio.draw()
sleep(5)
这将打开一个窗口(介绍窗口)并等待5秒钟,之后会出现“RUNNING GAME”消息,但不显示“foo studios”消息。
显然我做错了。
我对pyglet不太熟悉,但我设法让游戏运行(需要一些调整,但它基本上完成了)。我需要的只是介绍屏幕。
如果有人知道做一个介绍屏幕的好方法(只是用文字,我现在不需要任何动画的动画),我将非常感激。
答案 0 :(得分:0)
您最好根据例如pyglet.sprite.Sprite
创建类,并将这些对象用作" windows"或"屏幕"。
感觉就像我在任何地方都粘贴了这个代码但是使用了这个代码,并且在" def render()`中放置了不同的"场景" /" windows"你当时希望被渲染。
import pyglet
from time import time, sleep
class Window(pyglet.window.Window):
def __init__(self, refreshrate):
super(Window, self).__init__(vsync = False)
self.frames = 0
self.framerate = pyglet.text.Label(text='Unknown', font_name='Verdana', font_size=8, x=10, y=10, color=(255,255,255,255))
self.last = time()
self.alive = 1
self.refreshrate = refreshrate
def on_draw(self):
self.render()
def render(self):
self.clear()
if time() - self.last >= 1:
self.framerate.text = str(self.frames)
self.frames = 0
self.last = time()
else:
self.frames += 1
self.framerate.draw()
self.flip()
def on_close(self):
self.alive = 0
def run(self):
while self.alive:
self.render()
event = self.dispatch_events() # <-- This is the event queue
sleep(1.0/self.refreshrate)
win = Window(23) # set the fps
win.run()
事实上,你有一个渲染函数可以每秒清除和翻转整个图形内存X次,并且你可以在render
函数中确定哪些对象包含在渲染中。
尝试一下,看看它是否有帮助。
以下是使用上述示例的示例,它包含3个内容: *一个主窗口 *介绍屏幕 *菜单屏幕
您可以忽略class Spr()
和def convert_hashColor_to_RGBA()
,这些只是帮助函数,以避免进一步降低重复代码。
我还将继续标记实际做事的重要部分,其余部分只是初始化代码或定位事物。
import pyglet
from time import time, sleep
__WIDTH__ = 800
__HEIGHT__ = 600
def convert_hashColor_to_RGBA(color):
if '#' in color:
c = color.lstrip("#")
c = max(6-len(c),0)*"0" + c
r = int(c[:2], 16)
g = int(c[2:4], 16)
b = int(c[4:], 16)
color = (r,g,b,255)
return color
class Spr(pyglet.sprite.Sprite):
def __init__(self, texture=None, width=__WIDTH__, height=__HEIGHT__, color='#000000', x=0, y=0):
if texture is None:
self.texture = pyglet.image.SolidColorImagePattern(convert_hashColor_to_RGBA(color)).create_image(width,height)
else:
self.texture = texture
super(Spr, self).__init__(self.texture)
## Normally, objects in graphics have their anchor in the bottom left corner.
## This means that all X and Y cordinates relate to the bottom left corner of
## your object as positioned from the bottom left corner of your application-screen.
##
## We can override this and move the anchor to the WIDTH/2 (aka center of the image).
## And since Spr is a class only ment for generating a background-image to your "intro screen" etc
## This only affects this class aka the background, so the background gets positioned by it's center.
self.image.anchor_x = self.image.width / 2
self.image.anchor_y = self.image.height / 2
## And this sets the position.
self.x = x
self.y = y
def _draw(self):
self.draw()
## IntoScreen is a class that inherits a background, the background is Spr (our custom background-image class)
## IntoScreen contains 1 label, and it will change it's text after 2 seconds of being shown.
## That's all it does.
class IntroScreen(Spr):
def __init__(self, texture=None, width=300, height = 150, x = 10, y = 10, color='#000000'):
super(IntroScreen, self).__init__(texture, width=width, height=height, x=x, y=y, color=color)
self.intro_text = pyglet.text.Label('Running game', font_size=8, font_name=('Verdana', 'Calibri', 'Arial'), x=x, y=y, multiline=False, width=width, height=height, color=(100, 100, 100, 255), anchor_x='center')
self.has_been_visible_since = time()
def _draw(self): # <-- Important, this is the function that is called from the main window.render() function. The built-in rendering function of pyglet is called .draw() so we create a manual one that's called _draw() that in turn does stuff + calls draw(). This is just so we can add on to the functionality of Pyglet.
self.draw()
self.intro_text.draw()
if time() - 2 > self.has_been_visible_since:
self.intro_text.text = 'foo studios'
## Then we have a MenuScreen (with a red background)
## Note that the RED color comes not from this class because the default is black #000000
## the color is set when calling/instanciating this class further down.
##
## But all this does, is show a "menu" (aka a text saying it's the menu..)
class MenuScreen(Spr):
def __init__(self, texture=None, width=300, height = 150, x = 10, y = 10, color='#000000'):
super(MenuScreen, self).__init__(texture, width=width, height=height, x=x, y=y, color=color)
self.screen_text = pyglet.text.Label('Main menu screen', font_size=8, font_name=('Verdana', 'Calibri', 'Arial'), x=x, y=y+height/2-20, multiline=False, width=300, height=height, color=(100, 100, 100, 255), anchor_x='center')
def _draw(self):
self.draw()
self.screen_text.draw()
## This is the actual window, the game, the glory universe that is graphics.
## It will be blank, so you need to set up what should be visible when and where.
##
## I've creates two classes which can act as "screens" (intro, game, menu etc)
## And we'll initate the Window class with the IntroScreen() and show that for a
## total of 5 seconds, after 5 seconds we will swap it out for a MenuScreeen().
##
## All this magic is done in __init__() and render(). All the other functions are basically
## just "there" and executes black magic for your convencience.
class Window(pyglet.window.Window):
def __init__(self, refreshrate):
super(Window, self).__init__(vsync = False)
self.alive = 1
self.refreshrate = refreshrate
self.currentScreen = IntroScreen(x=320, y=__HEIGHT__/2, width=50) # <-- Important
self.screen_has_been_shown_since = time()
def on_draw(self):
self.render()
def on_key_down(self, symbol, mod):
print('Keyboard down:', symbol) # <-- Important
def render(self):
self.clear()
if time() - 5 > self.screen_has_been_shown_since and type(self.currentScreen) is not MenuScreen: # <-- Important
self.currentScreen = MenuScreen(x=320, y=__HEIGHT__-210, color='#FF0000') # <-- Important, here we switch screen (after 5 seconds)
self.currentScreen._draw() # <-- Important, draws the current screen
self.flip()
def on_close(self):
self.alive = 0
def run(self):
while self.alive:
self.render()
event = self.dispatch_events()
sleep(1.0/self.refreshrate)
win = Window(23) # set the fps
win.run()