了解如何使用Python的Pygame模块对电子游戏进行编程,并开始操纵重力。
现实世界充满了运动和生活。 使现实世界变得如此繁忙和动态的是物理。 物理是物质在太空中移动的方式。因为电子游戏世界没有物理,它也没有物理,所以游戏程序员必须模拟物理。
对于大多数电子游戏而言,物理学上基本上只有两个重要方面:重力和碰撞。
在向游戏中添加敌人时,您实现了一些碰撞检测,但是由于重力需要碰撞检测,因此本文添加了更多内容。 考虑一下为什么重力可能涉及碰撞。 如果您无法想到任何原因,请不要担心-当您处理示例代码时,它将变得显而易见。
现实世界中的重力是物体趋向于相互吸引的趋势。 物体越大,它施加的重力影响越大。 在视频游戏物理学中,您不必创建质量足以证明引力合理的对象; 您只需编程一种趋势,即可使物体掉落到视频游戏世界中最大的物体:世界本身。
记住,你的玩家已经有一个属性来决定运动。 使用此属性将玩家拉向屏幕底部。
在 Pygame 中,越高的数字越接近屏幕的底部边缘。
在现实世界中,引力影响着一切。 然而,在平台构建者中,重力是有选择性的——如果你在整个游戏世界中加入重力,你所有的平台都会掉到地上。 相反,你只是给你的玩家和敌人增加重力。
首先,在你的玩家类中添加一个引力函数:
def gravity(self):
self.movey += 3.2 # how fast player falls
这是一个简单的功能。 首先,无论玩家是否要运动,都将其设置为垂直运动。 换句话说,您已将玩家编程为始终处于下降状态。 这基本上是重力。
为了使重力函数起作用,必须在主循环中调用它。 这样,Python会在循环向您的玩家施加一次下降运动。
在此代码中,将第一行添加到循环中:
player.gravity() # check gravity
player.update()
启动你的游戏,看看会发生什么。注意,因为它发生得很快:你的玩家从天上掉下来,就在你的游戏屏幕上。
你的重力模拟起作用了,但也许效果太好了。
作为一个实验,尝试改变玩家下降的速度。
您的角色掉落世界的问题是您的游戏无法检测到它。 在某些游戏中,如果玩家摔倒了,该对象将被删除并在新的地方重新生成。 在其他游戏中,玩家失去积分或生命。 当玩家脱离世界时,无论您想发生什么,您都必须能够检测到玩家何时消失在屏幕外。
在Python中,要检查条件,可以使用if语句。
您必须检查玩家是否跌落以及玩家跌落了多远。如果您的玩家跌落到可以到达屏幕底部的程度,那么您可以采取一些措施。为简单起见,请将玩家的位置设置为底部边缘上方20像素。
使您的重力函数看起来像这样:
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
然后启动您的游戏。 您的玩家仍会掉落,但会停在屏幕底部。 不过,您可能无法在地面层后面看到玩家。 一个简单的解决方法是在达到游戏世界最低点之后,通过在其新的Y位置添加另一个-ty来使您的玩家弹跳更高:
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
玩家真正需要的是一种对抗重力的方法。问题在于,除非你有什么东西可以推开,否则你无法抗拒重力。 因此,在下一篇文章中,您将添加地面和平台碰撞以及跳跃能力。 与此同时,试着对敌人施加重力。
到目前为止,所有代码如下:
#!/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 of this 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
'''
class Platform(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
class Player(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 in range(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 += 1
if self.frame > ani*3:
self.frame = 0
self.image = self.images[self.frame//ani]
# moving right
if self.movex > 0:
self.frame += 1
if 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 -= 1
print(self.health)
ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)
for g in ground_hit_list:
self.health -= 1
print(self.health)
class Enemy(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 = 8
if 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 += 1
class Level():
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=0
if lvl == 1:
while i < len(gloc):
ground = Platform(gloc[i],worldy-ty,tx,ty,'ground.png')
ground_list.add(ground)
i=i+1
if lvl == 2:
print("Level " + str(lvl) )
return ground_list
def platform(lvl,tx,ty):
plat_list = pygame.sprite.Group()
ploc = []
i=0
if 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=0
while j <= ploc[i][2]:
plat = Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,'ground.png')
plat_list.add(plat)
j=j+1
print('run' + str(i) + str(ploc[i]))
i=i+1
if 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=0
while 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)
这是关于使用 Pygame 模块在 Python 3中创建视频游戏的系列文章的第六部分。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。