PythonのPygameモジュールを使用して、コンピューターゲームをプログラムし、重力の操作を開始する方法を学びます。
現実の世界はスポーツと生活に満ちています。物理学は現実の生活をとても忙しくダイナミックにします。物理学は、物質が宇宙を移動する方法です。コンピュータゲームの世界は問題ではないため、物理法則はなく、ゲームプログラマは物理をシミュレートする必要があります。
ほとんどのコンピューターゲームでは、基本的にここで重要な物理的側面は重力と衝突の2つだけです。
ゲームに敵を追加するときは、いくつかの衝突検出を実装しますが、重力には衝突検出が必要なため、この記事ではさらに多くのものを追加します。重力が衝突を伴う理由を考えてください。理由がわからなくても心配しないでください。サンプルコードを開発するときに機能します。
現実世界の重力は、質量のある物体が互いに引き合う傾向です。オブジェクト(質量)が大きいほど、それが及ぼす重力は大きくなります。コンピュータゲームの物理学では、重力を証明するのに十分な質量のオブジェクトを作成する必要はありません。コンピュータゲームの世界自体で、1つのオブジェクトだけが最大の仮想オブジェクトに落ちる傾向をプログラムできます。
重力関数を追加する
プレーヤーには、アクションを決定する属性がすでにあることに注意してください。この属性を使用して、プレーヤーのスプライトを画面の下部に移動します。
Pygameでは、数値が大きいほど画面の下端に近くなります。
現実の世界では、重力はすべてに影響を与えます。ただし、プラットフォームゲームでは、重力は選択的です。ゲームの世界全体に重力を加えると、すべてのプラットフォームが地面に倒れます。逆に、プレイヤーと敵のスプライトに重力を加えることができます。
まず、 Player
クラスに gravity
関数を追加します。
def gravity(self):
self.movey +=3.2 #プレーヤーはどのくらいの速さで落下しますか
これは単純な関数です。まず、プレーヤーが移動するかどうかに関係なく、プレーヤーを垂直方向に移動するように設定します。つまり、常にドロップするようにプレーヤーをプログラムしました。これは基本的に重力です。
重力関数を有効にするには、メインループで呼び出す必要があります。このように、Pythonは各処理ループ中にプレイヤーに落下モーションを適用します。
このコードでは、ループに最初の行を追加します。
player.gravity() #重力を確認する
player.update()
ゲームを開始して、何が起こるかを確認します。それはすぐに起こるので注意してください:あなたは空から落ちてすぐにゲーム画面から落ちるプレーヤーです。
あなたの重力シミュレーションは機能していますが、多分良すぎます。
実験として、プレーヤーが落ちる速度を変えてみてください。
重力に床を追加する
あなたのゲームがあなたのキャラクターが世界から落ちる問題を発見する方法はありません。一部のゲームでは、プレーヤーが世界から脱落すると、スプライトが削除され、新しい場所にリスポーンします。他のゲームでは、プレイヤーはポイントまたはライフを失います。プレイヤーが世界から脱落したとき、何をしたいのかに関わらず、プレイヤーが画面から消えたときを検出できなければなりません。
Pythonでは、条件を確認するために、ifステートメントを使用できます。
プレーヤーが落下しているかどうか、およびプレーヤーがどの程度落下しているかを確認する必要があります。プレーヤーが画面の一番下に落ちた場合、あなたは何かをすることができます。簡単にするために、プレーヤースプライトの位置を下端から20ピクセル上に設定します。
重力関数を次のようにします。
def gravity(self):
self.movey +=3.2 #プレーヤーはどのくらいの速さで落下しますか
if self.rect.y worldy and self.movey =0:
self.movey =0
self.rect.y = worldy-ty
次に、ゲームを開始します。スプライトはまだ落下していますが、画面の下部で停止します。ただし、1階より上ではエルフが見えない場合があります。簡単な解決策は、スプライトがゲームワールドの下部に衝突した後、新しいY位置に別の-tyを追加して、スプライトのバウンスを高くすることです。
def gravity(self):
self.movey +=3.2 #プレーヤーはどのくらいの速さで落下しますか
if self.rect.y worldy and self.movey =0:
self.movey =0
self.rect.y = worldy-ty-ty
これで、プレーヤーは画面の下部、グラウンドスプライトのすぐ上でバウンドします。
プレイヤーが本当に必要としているのは、重力に抵抗する方法です。重力の問題は、重力を押しのけるものがなければ抵抗できないということです。したがって、次の記事では、地面とプラットフォームの衝突およびジャンプ機能を追加します。この間、敵のスプライトに重力をかけてみてください。
これまでのところ、コード全体は次のとおりです。
#! /usr/bin/env python3
# draw a world
# add a player and player control
# add player movement
# add enemy and basic collision
# add platform
# add gravity
# GNU All-Permissive License
# Copying and distribution ofthis file,with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.import pygame
import sys
import os
'''
Objects
'''
classPlatform(pygame.sprite.Sprite):
# x location, y location, img width, img height, img file
def __init__(self,xloc,yloc,imgw,imgh,img):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(os.path.join('images',img)).convert()
self.image.convert_alpha()
self.rect = self.image.get_rect()
self.rect.y = yloc
self.rect.x = xloc
classPlayer(pygame.sprite.Sprite):'''
Spawn a player
'''
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.movex =0
self.movey =0
self.frame =0
self.health =10
self.score =1
self.images =[]for i inrange(1,9):
img = pygame.image.load(os.path.join('images','hero'+str(i)+'.png')).convert()
img.convert_alpha()
img.set_colorkey(ALPHA)
self.images.append(img)
self.image = self.images[0]
self.rect = self.image.get_rect()
def gravity(self):
self.movey +=3.2 # how fast player falls
if self.rect.y worldy and self.movey =0:
self.movey =0
self.rect.y = worldy-ty-ty
def control(self,x,y):'''
control player movement
'''
self.movex += x
self.movey += y
def update(self):'''
Update sprite position
'''
self.rect.x = self.rect.x + self.movex
self.rect.y = self.rect.y + self.movey
# moving left
if self.movex <0:
self.frame +=1if self.frame ani*3:
self.frame =0
self.image = self.images[self.frame//ani]
# moving right
if self.movex 0:
self.frame +=1if self.frame ani*3:
self.frame =0
self.image = self.images[(self.frame//ani)+4]
# collisions
enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)for enemy in enemy_hit_list:
self.health -=1print(self.health)
ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)for g in ground_hit_list:
self.health -=1print(self.health)classEnemy(pygame.sprite.Sprite):'''
Spawn an enemy
'''
def __init__(self,x,y,img):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(os.path.join('images',img))
# self.image.convert_alpha()
# self.image.set_colorkey(ALPHA)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.counter =0
def move(self):'''
enemy movement
'''
distance =80
speed =8if self.counter =0 and self.counter <= distance:
self.rect.x += speed
elif self.counter = distance and self.counter <= distance*2:
self.rect.x -= speed
else:
self.counter =0
self.counter +=1classLevel():
def bad(lvl,eloc):if lvl ==1:
enemy =Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
enemy_list = pygame.sprite.Group() # create enemy group
enemy_list.add(enemy) # add enemy to group
if lvl ==2:print("Level "+str(lvl))return enemy_list
def loot(lvl,lloc):print(lvl)
def ground(lvl,gloc,tx,ty):
ground_list = pygame.sprite.Group()
i=0if lvl ==1:while i <len(gloc):
ground =Platform(gloc[i],worldy-ty,tx,ty,'ground.png')
ground_list.add(ground)
i=i+1if lvl ==2:print("Level "+str(lvl))return ground_list
def platform(lvl,tx,ty):
plat_list = pygame.sprite.Group()
ploc =[]
i=0if lvl ==1:
ploc.append((0,worldy-ty-128,3))
ploc.append((300,worldy-ty-256,3))
ploc.append((500,worldy-ty-128,4))while i <len(ploc):
j=0while j <= ploc[i][2]:
plat =Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,'ground.png')
plat_list.add(plat)
j=j+1print('run'+str(i)+str(ploc[i]))
i=i+1if lvl ==2:print("Level "+str(lvl))return plat_list
'''
Setup
'''
worldx =960
worldy =720
fps =40 # frame rate
ani =4 # animation cycles
clock = pygame.time.Clock()
pygame.init()
main = True
BLUE =(25,25,200)
BLACK =(23,23,23)
WHITE =(254,254,254)
ALPHA =(0,255,0)
world = pygame.display.set_mode([worldx,worldy])
backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()
backdropbox = world.get_rect()
player =Player() # spawn player
player.rect.x =0
player.rect.y =0
player_list = pygame.sprite.Group()
player_list.add(player)
steps =10 # how fast to move
eloc =[]
eloc =[200,20]
gloc =[]
# gloc =[0,630,64,630,128,630,192,630,256,630,320,630,384,630]
tx =64 #tile size
ty =64 #tile size
i=0while i <=(worldx/tx)+tx:
gloc.append(i*tx)
i=i+1
enemy_list = Level.bad(1, eloc )
ground_list = Level.ground(1,gloc,tx,ty )
plat_list = Level.platform(1,tx,ty )'''
Main loop
'''
while main == True:for event in pygame.event.get():if event.type == pygame.QUIT:
pygame.quit(); sys.exit()
main = False
if event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT or event.key ==ord('a'):print("LEFT")
player.control(-steps,0)if event.key == pygame.K_RIGHT or event.key ==ord('d'):print("RIGHT")
player.control(steps,0)if event.key == pygame.K_UP or event.key ==ord('w'):print('jump')if event.type == pygame.KEYUP:if event.key == pygame.K_LEFT or event.key ==ord('a'):
player.control(steps,0)if event.key == pygame.K_RIGHT or event.key ==ord('d'):
player.control(-steps,0)if event.key == pygame.K_UP or event.key ==ord('w'):print('jump')if event.key ==ord('q'):
pygame.quit()
sys.exit()
main = False
world.blit(backdrop, backdropbox)
player.gravity() # check gravity
player.update()
player_list.draw(world)
enemy_list.draw(world)
ground_list.draw(world)
plat_list.draw(world)for e in enemy_list:
e.move()
pygame.display.flip()
clock.tick(fps)
総括する
Pythonゲームでの重力のシミュレーションに関するこの記事はこれで終わりです。Pythonゲームでの重力のシミュレーションに関するその他の関連コンテンツについては、ZaLou.Cnの以前の記事を検索するか、以下の関連記事を引き続き参照してください。将来的にはZaLou.Cnをたくさんサポートしてください!
Recommended Posts