あなたが直接スプライトを使用してpygameのといくつかのプログラミングをやって起動したい場合、アプリケーションがGUIを使用して、ユーザーを処理できる方法をいくつかの基本的な理解を得るために利用可能なチュートリアルのいくつかのより多くの予備調査を行うには良いでしょうイベントは一般的に機能します。
もう一つの選択肢は、必要な(グループとクラスを必要とするスプライトに)大量の予備コードを書くことなく、結果を直接見ることができる、より簡単なものから始めることです。
Pygameスプライトのチュートリアルは難解ですが、コードの良い例と優れた説明を提供するものもあります。
Introduction to sprites --- sprite_collect_blocks.py
、その後、もしあれば、さらに質問をここに戻ってくる:私はあなたを詳しく見てみ示唆しています。
以下、私は2つのコードを提供しています。そのため、あなたは私が上記で話したことを互いに比較することができます。
2つのうちの最初の部分は、わずかな変更を加えた独自のコードです。それは画面上に3つのブロックを作成し、実際にはスプライトとは関係ありません(別の答えの場合も同様)が、表示されたPygameスクリーンに長方形を設定する方法を示します。自分のコードに付随する問題についての良い説明を提供するので、別の答えも注意深く読んでください。
ここ
import pygame
WHITE = (255,255,255)
BLACK = (0,0,0)
RED = (255,0,0)
BLUE = (0,0,255)
# Set the height and width of the screen:
DISPLAY_width = 640
DISPLAY_height = 480
DISPLAY = pygame.display.set_mode([DISPLAY_width, DISPLAY_height])
DISPLAY.fill(WHITE)
# See here: [(3) stackoverflow.com/.../pygame-drawing-a-rectangle][3]
pygame.draw.rect(DISPLAY,BLACK,(120,40,50,50))
pygame.draw.rect(DISPLAY,RED ,(520,355,50,50))
pygame.draw.rect(DISPLAY,BLUE ,(320,240,50,50))
pygame.display.flip() # without .flip() you get only black screen
pygame.display.init() # IMPORTANT !
clock = pygame.time.Clock()
tick = 0
while tick < 100:
clock.tick(10)
tick += 1
# BETTER do it as follows:
"""
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
"""
pygame.quit()
import sys
sys.exit()
コードは、上記作成もののスクリーンショット:
コードの他の部分は、実際のコードを使用スプライトです。スプライトは通常画像とともに使用されます。これは、最初のscriptsディレクトリにいくつかの画像を取得することが必要になり:
そしてここで、画面上の多くのMOTIONを生成(TRUEスプライトとの)コードの第二の部分を(行きますここでは静的なスクリーンショットのみです)。ドットの全ては、異なる速度が黄色で最初に黒画面を充填して移動している:
strPythonScriptHeader = """
# pygCodeSample_UsageOfGroupsAndSprites.py updated: 2017-04-12 09:17
# Copyright (c) 2005, Claudio at stackoverflow.com created: 2005-01-24 19:43
"""
# #############################################################################
# VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
def pygCodeSample_UsageOfGroupsAndSprites():
strMainInfo = """/*
WATCH OUT using pygame.sprite.Sprite and pygame.sprite.RenderClear classes:
- the order of Sprites in a Group is not necessary the order in which the
Sprites are drawn to the screen.
- the .clear() method of a Group clears the entire image square, not as
expected only the non-transparent part of it.
*/"""
print(strMainInfo)
strSpriteTutorial = """/*
The 'pygame.sprite' library provides classes representing images and
group of images which are to be drawn to the screen during the game.
The concept of a 'Sprite' is to provide a class which objects represent
real-world physical objects which can be viewed on the computer screen.
The Sprite class is not used directly. It is used to derive own classes
of customized Sprites from it:
class CustomizedSpriteDerivedFromSpriteClass(pygame.sprite.Sprite): ...
Within the definition of the CustomizedSpriteDerivedFromSpriteClass
it is necessary to define a member variable
.image (class CustomizedSpriteDerivedFromSpriteClass)
storing an 'Image' object which is to draw to the screen and the
member variable
.rect (class CustomizedSpriteDerivedFromSpriteClass)
storing a 'Rect' object holding the target position of the 'Image'
on the screen.
Usually both variables are set when running the
.__init__() (class CustomizedSpriteDerivedFromSpriteClass)
function which should contain as first command:
pygame.sprite.Sprite.__init__(self)
Further is it necessary to define also an
.update() (class CustomizedSpriteDerivedFromSpriteClass)
function which provides the code of rules telling how the by the Sprite
graphically represented physical objects should change when the .update()
function is executed.
The main purpose of a 'Sprite' is to be added to a container(called Group)
which is an object of the pygame.sprite.RenderClear class:
pGobjGroupOfSprites = pygame.sprite.RenderClear()
ready to hold any number of Sprite objects. A single Sprite is added to it
using
pGobjGroupOfSprites.add(pGobjCustomizedSpriteDerivedFromSpriteClass)
call.
The pGobjGroupOfSprites object of the pygame.sprite.RenderClear class is
equipped with following methods:
pGobjGroupOfSprites.clear(pGobjSCREENsurface, pGobjImage_SCREENsurfaceBackground)
pGobjGroupOfSprites.update()
pGobjGroupOfSprites.draw(pGobjSCREENsurface)
.draw() draws all Sprites to as parameter passed pGobjSCREENsurface
using the .image and .rect properties defined as member variables
within the CustomizedSpriteDerivedFromSpriteClass class.
.clear() draws those parts of the pGobjImage_SCREENsurfaceBackground image
to the pGobjSCREENsurface which are the Rects representing the
positions of the Sprites on the screen using the .rect property of Sprites.
.update() runs the .update() method of each Sprite stored in the GroupOfSprites.
Finally the main game loop looks like:
while True:
evaluateInputEvents()
pGobjGroupOfSprites_Hero.clear(pGobjSCREENsurface, pGobjImage_SCREENsurfaceBackground)
pGobjGroupOfSprites_Hero.update()
pGobjGroupOfSprites_Hero.draw(pGobjSCREENsurface)
pGobjGroupOfSprites_Enemy.clear(pGobjSCREENsurface, pGobjImage_SCREENsurfaceBackground)
pGobjGroupOfSprites_Enemy.update()
pGobjGroupOfSprites_Enemy.draw(pGobjSCREENsurface)
pGobjGroupOfSprites_Widgets.clear(pGobjSCREENsurface, pGobjImage_SCREENsurfaceBackground)
pGobjGroupOfSprites_Widgets.update()
pGobjGroupOfSprites_Widgets.draw(pGobjSCREENsurface)
adjustFrameRateTo(intTargetFrameRate) # time.sleep()/time.clock()
pGdefUpdateScreenWithDataStoredIn_pGobjSCREENsurface # == pygame.display.flip
#:while
How many and which Groups should be used and how to spread all the Sprites
used in the game over the defined Groups is part of the architecture of
the game code which is designed according to the needs of the game and the
individual programming style.
*/"""
print(strSpriteTutorial)
mPGvDctRectOfSCREENsurface = { 'left' : 0, 'right' : 640, 'top' : 0, 'bottom' : 480 }
mPGvIntScreenOriginX = mPGvDctRectOfSCREENsurface['left']
mPGvIntScreenOriginY = mPGvDctRectOfSCREENsurface['top']
mPGvIntScreenWidth = mPGvDctRectOfSCREENsurface['right'] - mPGvDctRectOfSCREENsurface['left']
mPGvIntScreenHeight = mPGvDctRectOfSCREENsurface['bottom'] - mPGvDctRectOfSCREENsurface['top']
mPGvTplScreenSize = (mPGvIntScreenWidth, mPGvIntScreenHeight)
import pygame
pGdefUpdateScreenWithDataStoredIn_pGobjSCREENsurface = pygame.display.flip
class pGobjCustomizedSprite_Dot(pygame.sprite.Sprite):
def __init__(self, strColorOfDot, tplVelocity):
# Intialize the Sprite class:
pygame.sprite.Sprite.__init__(self)
# .image property is used by the pGobjGroup hosting the sprite, so it is
# necessary to set it here in order to make this Sprite useful:
self.image = pygame.image.load(
r'dot-32x32_'+strColorOfDot+'.gif'
) # picture shows a coloured dot and has a transparent background
# .rect property is used by the pGobjGroup hosting the sprite, so it is
# necessary to set it here in order to make this Sprite useful:
self.rect = self.image.get_rect()
self.rect.centerx = 320
self.rect.centery = 240
# definition of other properties not necessary for usage of this class
# as a Sprite, but useful for internal purposes of setting the position
# of the rectangle within the .update() method:
self.x_velocity = tplVelocity[0]
self.y_velocity = tplVelocity[1]
#:def
# .update() method is used by the pGobjGroup hosting the sprite in its
# .update() command, so it is necessary to define it here in order to
# make this Sprite useful:
def update(self):
self.rect.move_ip((self.x_velocity, self.y_velocity))
if(self.rect.left <= 0 or self.rect.right >= mPGvIntScreenWidth):
self.x_velocity = -(self.x_velocity)
#:if
if self.rect.top <= 0 or self.rect.bottom >= mPGvIntScreenHeight:
self.y_velocity = -(self.y_velocity)
#:if
#:def
#:class
pygame.init()
# pGobjSCREENsurface = pygame.display.set_mode(mPGvTplScreenSize, pygame.constants.DOUBLEBUF)
pGobjSCREENsurface = pygame.display.set_mode(mPGvTplScreenSize) # faster than with DOUBLEBUF
pGobjGroupOfSprites_spriteDot = pygame.sprite.RenderClear()
pGobjImage_SCREENsurfaceBackground = pygame.image.load(
r'rect-640x480_yellow.bmp'
) # picture shows yellow background
intLstLength = 0
dctTplVelocity = {}
import random
while(intLstLength < 5):
tplVelocity = (random.randint(1, 5), random.randint(1, 5))
if(tplVelocity in dctTplVelocity): pass
else:
intLstLength+=1
dctTplVelocity[tplVelocity] = intLstLength
#:if/else
#:while
lstTplVelocity = list(dctTplVelocity.keys())
# pGspriteRedDot = pGobjCustomizedSprite_Dot('red' ,lstTplVelocity[0])
# pGspriteWhiteDot = pGobjCustomizedSprite_Dot('purple',lstTplVelocity[1])
# pGspriteGreyDot = pGobjCustomizedSprite_Dot('grey' ,lstTplVelocity[2])
# pGspriteBlueDot = pGobjCustomizedSprite_Dot('blue' ,lstTplVelocity[3])
# pGspriteOrangeDot = pGobjCustomizedSprite_Dot('orange',lstTplVelocity[4])
pGobjGroupOfSprites_spriteDot.add(pGobjCustomizedSprite_Dot('red' ,lstTplVelocity[0]))
pGobjGroupOfSprites_spriteDot.add(pGobjCustomizedSprite_Dot('purple',lstTplVelocity[1]))
pGobjGroupOfSprites_spriteDot.add(pGobjCustomizedSprite_Dot('grey' ,lstTplVelocity[2]))
pGobjGroupOfSprites_spriteDot.add(pGobjCustomizedSprite_Dot('blue' ,lstTplVelocity[3]))
pGobjGroupOfSprites_spriteDot.add(pGobjCustomizedSprite_Dot('orange',lstTplVelocity[4]))
print
print(' target frame rate [frames/second] == 100.0 : ')
intLoopCounter = 0
import time
clock = time.clock
sleep = time.sleep
import sys
fltTime=clock()
fltStartTime = clock()
blnExitMainGameLoop = False
fltFrameRate = 100.0
fltTimeToNextFrame = 1.0/fltFrameRate
import time
while True:
time.sleep(0.03)
# ---
# -----------------------------------------------------
# Processing of user input:
pGlstObjEvent = pygame.event.get()
for pGobjEvent in pGlstObjEvent:
if pGobjEvent.type == pygame.constants.QUIT:
blnExitMainGameLoop = True
#:if
if pGobjEvent.type == pygame.constants.KEYDOWN:
if pGobjEvent.key == pygame.constants.K_ESCAPE:
blnExitMainGameLoop = True
if pGobjEvent.key == pygame.constants.K_s:
time.sleep(21)
blnExitMainGameLoop = False
#:if
#:if
#:for
if(blnExitMainGameLoop):
pygame.display.quit()
break
#:if
# ---
# -----------------------------------------------------
# output of texts with infos to console window:
if(intLoopCounter%100 == 99):
print(' %5.2f '%(fltFrameRate/(clock()-fltTime),),)
fltTime=clock()
#:if
intLoopCounter += 1
# print intLoopCounter,
# ---
# -----------------------------------------------------
# preparing and drawing graphic output to screen:
pGobjGroupOfSprites_spriteDot.update()
pGobjGroupOfSprites_spriteDot.clear(pGobjSCREENsurface, pGobjImage_SCREENsurfaceBackground)
pGobjGroupOfSprites_spriteDot.draw(pGobjSCREENsurface)
# ---
# -----------------------------------------------------
# adjusting frame rate to 100 frames/second:
# fltFrameRate = 100.0
# fltTimeToNextFrame = 1.0/fltFrameRate
fltTargetTime = fltTimeToNextFrame*intLoopCounter
fltTimeDiff = fltTargetTime-(clock()-fltStartTime)
if(fltTimeDiff > 0.8*fltTimeToNextFrame): sleep(0.8*fltTimeToNextFrame)
fltTimeDiff = fltTargetTime-(clock()-fltStartTime)
if(fltTimeDiff > 0.1*fltTimeToNextFrame): sleep(0.1*fltTimeToNextFrame)
fltTimeDiff = fltTargetTime-(clock()-fltStartTime)
while(fltTimeDiff > 0):
fltTimeDiff = (fltTimeToNextFrame*intLoopCounter)-(clock()-fltStartTime)
#:while
# ---
# -----------------------------------------------------
# displaying prepared graphic output:
pGdefUpdateScreenWithDataStoredIn_pGobjSCREENsurface()
#:while
#:def pygCodeSample_UsageOfGroupsAndSprites()
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if __name__ == '__main__':
print(strPythonScriptHeader)
pygCodeSample_UsageOfGroupsAndSprites()
import sys
if int(sys.version[0]) < 3 : # Python 2 :
raw_input('(exit with ENTER) #> OK? ')
sys.exit()
else: # Python 3 :
input('(exit with ENTER) #> OK? ')
sys.exit()
#:if
pygameConstantsForUsageInKeyEVENTS = ['ACTIVEEVENT', 'ANYFORMAT', 'ASYNCBLIT', 'AUDIO_S16', 'AUDIO_S16LSB', 'AUDIO_S16MSB', 'AUDIO_S16SYS', 'AUDIO_S8', 'AUDIO_U16', 'AUDIO_U16LSB', 'AUDIO_U16MSB', 'AUDIO_U16SYS', 'AUDIO_U8', 'BIG_ENDIAN', 'BLEND_ADD', 'BLEND_MAX', 'BLEND_MIN', 'BLEND_MULT', 'BLEND_PREMULTIPLIED', 'BLEND_RGBA_ADD', 'BLEND_RGBA_MAX', 'BLEND_RGBA_MIN', 'BLEND_RGBA_MULT', 'BLEND_RGBA_SUB', 'BLEND_RGB_ADD', 'BLEND_RGB_MAX', 'BLEND_RGB_MIN', 'BLEND_RGB_MULT', 'BLEND_RGB_SUB', 'BLEND_SUB', 'BUTTON_X1', 'BUTTON_X2', 'DOUBLEBUF', 'FULLSCREEN', 'GL_ACCELERATED_VISUAL', 'GL_ACCUM_ALPHA_SIZE', 'GL_ACCUM_BLUE_SIZE', 'GL_ACCUM_GREEN_SIZE', 'GL_ACCUM_RED_SIZE', 'GL_ALPHA_SIZE', 'GL_BLUE_SIZE', 'GL_BUFFER_SIZE', 'GL_DEPTH_SIZE', 'GL_DOUBLEBUFFER', 'GL_GREEN_SIZE', 'GL_MULTISAMPLEBUFFERS', 'GL_MULTISAMPLESAMPLES', 'GL_RED_SIZE', 'GL_STENCIL_SIZE', 'GL_STEREO', 'GL_SWAP_CONTROL', 'HAT_CENTERED', 'HAT_DOWN', 'HAT_LEFT', 'HAT_LEFTDOWN', 'HAT_LEFTUP', 'HAT_RIGHT', 'HAT_RIGHTDOWN', 'HAT_RIGHTUP', 'HAT_UP', 'HWACCEL', 'HWPALETTE', 'HWSURFACE', 'IYUV_OVERLAY', 'JOYAXISMOTION', 'JOYBALLMOTION', 'JOYBUTTONDOWN', 'JOYBUTTONUP', 'JOYHATMOTION', 'KEYDOWN', 'KEYUP', 'KMOD_ALT', 'KMOD_CAPS', 'KMOD_CTRL', 'KMOD_LALT', 'KMOD_LCTRL', 'KMOD_LMETA', 'KMOD_LSHIFT', 'KMOD_META', 'KMOD_MODE', 'KMOD_NONE', 'KMOD_NUM', 'KMOD_RALT', 'KMOD_RCTRL', 'KMOD_RMETA', 'KMOD_RSHIFT', 'KMOD_SHIFT', 'K_0', 'K_1', 'K_2', 'K_3', 'K_4', 'K_5', 'K_6', 'K_7', 'K_8', 'K_9', 'K_AMPERSAND', 'K_ASTERISK', 'K_AT', 'K_BACKQUOTE', 'K_BACKSLASH', 'K_BACKSPACE', 'K_BREAK', 'K_CAPSLOCK', 'K_CARET', 'K_CLEAR', 'K_COLON', 'K_COMMA', 'K_DELETE', 'K_DOLLAR', 'K_DOWN', 'K_END', 'K_EQUALS', 'K_ESCAPE', 'K_EURO', 'K_EXCLAIM', 'K_F1', 'K_F10', 'K_F11', 'K_F12', 'K_F13', 'K_F14', 'K_F15', 'K_F2', 'K_F3', 'K_F4', 'K_F5', 'K_F6', 'K_F7', 'K_F8', 'K_F9', 'K_FIRST', 'K_GREATER', 'K_HASH', 'K_HELP', 'K_HOME', 'K_INSERT', 'K_KP0', 'K_KP1', 'K_KP2', 'K_KP3', 'K_KP4', 'K_KP5', 'K_KP6', 'K_KP7', 'K_KP8', 'K_KP9', 'K_KP_DIVIDE', 'K_KP_ENTER', 'K_KP_EQUALS', 'K_KP_MINUS', 'K_KP_MULTIPLY', 'K_KP_PERIOD', 'K_KP_PLUS', 'K_LALT', 'K_LAST', 'K_LCTRL', 'K_LEFT', 'K_LEFTBRACKET', 'K_LEFTPAREN', 'K_LESS', 'K_LMETA', 'K_LSHIFT', 'K_LSUPER', 'K_MENU', 'K_MINUS', 'K_MODE', 'K_NUMLOCK', 'K_PAGEDOWN', 'K_PAGEUP', 'K_PAUSE', 'K_PERIOD', 'K_PLUS', 'K_POWER', 'K_PRINT', 'K_QUESTION', 'K_QUOTE', 'K_QUOTEDBL', 'K_RALT', 'K_RCTRL', 'K_RETURN', 'K_RIGHT', 'K_RIGHTBRACKET', 'K_RIGHTPAREN', 'K_RMETA', 'K_RSHIFT', 'K_RSUPER', 'K_SCROLLOCK', 'K_SEMICOLON', 'K_SLASH', 'K_SPACE', 'K_SYSREQ', 'K_TAB', 'K_UNDERSCORE', 'K_UNKNOWN', 'K_UP', 'K_a', 'K_b', 'K_c', 'K_d', 'K_e', 'K_f', 'K_g', 'K_h', 'K_i', 'K_j', 'K_k', 'K_l', 'K_m', 'K_n', 'K_o', 'K_p', 'K_q', 'K_r', 'K_s', 'K_t', 'K_u', 'K_v', 'K_w', 'K_x', 'K_y', 'K_z', 'LIL_ENDIAN', 'MOUSEBUTTONDOWN', 'MOUSEBUTTONUP', 'MOUSEMOTION', 'NOEVENT', 'NOFRAME', 'NUMEVENTS', 'OPENGL', 'OPENGLBLIT', 'PREALLOC', 'QUIT', 'RESIZABLE', 'RLEACCEL', 'RLEACCELOK', 'SCRAP_BMP', 'SCRAP_CLIPBOARD', 'SCRAP_PBM', 'SCRAP_PPM', 'SCRAP_SELECTION', 'SCRAP_TEXT', 'SRCALPHA', 'SRCCOLORKEY', 'SWSURFACE', 'SYSWMEVENT', 'TIMER_RESOLUTION', 'USEREVENT', 'USEREVENT_DROPFILE', 'UYVY_OVERLAY', 'VIDEOEXPOSE', 'VIDEORESIZE', 'YUY2_OVERLAY', 'YV12_OVERLAY', 'YVYU_OVERLAY', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
上記コード膨大なコメントを備えています。何年も前にパイゲームから始めてスプライトを理解しようとしてきたので、わかりやすく書けるようにすることが目標でした。今では、私が自己説明的な変数命名法のスタイルと、提供された説明と情報のどれが成功したかを自分で判断することができます。
あなたは白で塗りつぶして、白のカラーキーを設定しています。カラーキーを削除しても問題ありません。 colorkeys [here](http://stackoverflow.com/documentation/pygame/7079/drawing-on-the-screen/23788/transparency#t=201704140013573679697) –
についてはこれよりも間違っています。 – jsbueno