Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >在Python游戏中模拟重力【Programming(Python)】

在Python游戏中模拟重力【Programming(Python)】

作者头像
Potato
修改于 2019-12-02 03:22:41
修改于 2019-12-02 03:22:41
2.3K00
代码可运行
举报
运行总次数:0
代码可运行

了解如何使用Python的Pygame模块对电子游戏进行编程,并开始操纵重力。

图片来源:Public Domain
图片来源:Public Domain

现实世界充满了运动和生活。 使现实世界变得如此繁忙和动态的是物理。 物理是物质在太空中移动的方式。因为电子游戏世界没有物理,它也没有物理,所以游戏程序员必须模拟物理。

对于大多数电子游戏而言,物理学上基本上只有两个重要方面:重力和碰撞。

在向游戏中添加敌人时,您实现了一些碰撞检测,但是由于重力需要碰撞检测,因此本文添加了更多内容。 考虑一下为什么重力可能涉及碰撞。 如果您无法想到任何原因,请不要担心-当您处理示例代码时,它将变得显而易见。

现实世界中的重力是物体趋向于相互吸引的趋势。 物体越大,它施加的重力影响越大。 在视频游戏物理学中,您不必创建质量足以证明引力合理的对象; 您只需编程一种趋势,即可使物体掉落到视频游戏世界中最大的物体:世界本身。

添加重力函数

记住,你的玩家已经有一个属性来决定运动。 使用此属性将玩家拉向屏幕底部。

在 Pygame 中,越高的数字越接近屏幕的底部边缘。

在现实世界中,引力影响着一切。 然而,在平台构建者中,重力是有选择性的——如果你在整个游戏世界中加入重力,你所有的平台都会掉到地上。 相反,你只是给你的玩家和敌人增加重力。

首先,在你的玩家类中添加一个引力函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 def gravity(self):
  self.movey += 3.2 # how fast player falls

这是一个简单的功能。 首先,无论玩家是否要运动,都将其设置为垂直运动。 换句话说,您已将玩家编程为始终处于下降状态。 这基本上是重力。

为了使重力函数起作用,必须在主循环中调用它。 这样,Python会在循环向您的玩家施加一次下降运动。

在此代码中,将第一行添加到循环中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
     player.gravity() # check gravity
     player.update()

启动你的游戏,看看会发生什么。注意,因为它发生得很快:你的玩家从天上掉下来,就在你的游戏屏幕上。

你的重力模拟起作用了,但也许效果太好了。

作为一个实验,尝试改变玩家下降的速度。

为重力添加地板

您的角色掉落世界的问题是您的游戏无法检测到它。 在某些游戏中,如果玩家摔倒了,该对象将被删除并在新的地方重新生成。 在其他游戏中,玩家失去积分或生命。 当玩家脱离世界时,无论您想发生什么,您都必须能够检测到玩家何时消失在屏幕外。

在Python中,要检查条件,可以使用if语句。

您必须检查玩家是否跌落以及玩家跌落了多远。如果您的玩家跌落到可以到达屏幕底部的程度,那么您可以采取一些措施。为简单起见,请将玩家的位置设置为底部边缘上方20像素。

使您的重力函数看起来像这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 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来使您的玩家弹跳更高:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 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

玩家真正需要的是一种对抗重力的方法。问题在于,除非你有什么东西可以推开,否则你无法抗拒重力。 因此,在下一篇文章中,您将添加地面和平台碰撞以及跳跃能力。 与此同时,试着对敌人施加重力。

到目前为止,所有代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 #!/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 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
使用Pygame在Python游戏中放置平台【Gaming】
这是正在进行的关于使用Pygame模块在Python 3创建视频游戏的系列文章的第6部分。以前的文章有:
五月Rambo
2019/11/18
2.8K0
使用Pygame在Python游戏中放置平台【Gaming】
一个没有对手的英雄是什么体验?如何在你的Python游戏中添加反派
在本系列的前几篇文章(请参阅第1部分,第2部分,第3部分和第4部分)中,您学习了如何使用Pygame和Python在尚未出现的空白游戏世界中构建可玩角色。但是,没有恶人可打的英雄岂不是很难受?
五月Rambo
2019/12/09
1.8K0
一个没有对手的英雄是什么体验?如何在你的Python游戏中添加反派
童年游戏大回顾:飞机大战
记得小学时,每逢放学便会打开电视机,接上红白机/小霸王,插上一张游戏卡带,魂斗罗、超级玛丽、冒险岛、足球小将
不惑
2024/02/27
5704
童年游戏大回顾:飞机大战
使用cursor完成飞机大战
在这篇文章中,我们将使用 Pygame 库创建一个简单的经典射击游戏——《飞机大战》。该游戏具有多个功能,包括玩家飞机、敌机、子弹、道具、Boss 战斗等元素。游戏逻辑相对简单,但却能为新手提供良好的学习案例,帮助理解如何使用 Pygame 开发2D游戏。
远方2.0
2025/01/02
2030
使用cursor完成飞机大战
Pygame入门4——使用精灵类重构
如果你完成了前3章的代码,应该会发现代码很乱。想更改某个代码?查找困难、修改起来更困难!不断添加的新功能让我们的代码越来越复杂,难以阅读。
一只大鸽子
2022/12/06
6980
Pygame入门4——使用精灵类重构
pygame-KidsCanCode系列jumpy-part12-platform图片
目前为止,Player的站立、行走、跳跃都是动画了,只有跳板(即:Platform类)还是难看的矩形,这节我们把Platform也换成图片:
菩提树下的杨过
2019/09/12
4230
使用Pygame做一个乒乓球游戏(2)使用精灵重构
本节没有添加新的功能,而是将前面的功能使用精灵类(pygame.sprite.Sprite[1]) 重构。 顺便使用图片美化了一下程序。
一只大鸽子
2024/03/25
1370
使用Pygame做一个乒乓球游戏(2)使用精灵重构
世界杯太精彩了,带大家用Python做个足球游戏,边玩游戏边看比赛
卡塔尔世界杯正是进行得火热,十六强队伍已经诞生,后面就是越来越紧张的争夺八强的淘汰赛。目前爆冷的赛果让球迷一度情绪失落,比如:日本2-1战胜西班牙,韩国2-1战胜葡萄牙。
Lansonli
2022/12/05
1.1K1
世界杯太精彩了,带大家用Python做个足球游戏,边玩游戏边看比赛
骰子头像 与 flappy bird源代码
视频: 骰子头像源代码: from PIL import Image # 原图太多,设置小一些的尺寸 width,height=(100,100) #转灰度图,并修改大小 img=Image.open("child.png").convert("L").resize((width,height)) # 保存不同点数的骰子图片对象 level_img = [] # 循环打开图片 for i in range(1,7): dice = Image.open(f'dice/dice_{i}.png'
叶子陪你玩
2021/10/21
4930
实战项目:飞机大战
运行程序,英雄飞机出现在屏幕底边的中央区域,飞机中央每隔一秒会自动发射一枚子弹。随着游戏的开始,敌机会在屏幕上方随机不定时的出现在屏幕内向下飞行。英雄飞机需要通过移位躲避敌机或用子弹消灭敌机,避免碰撞导致游戏结束。
佛系编程人
2020/02/25
2K0
pygame-KidsCanCode系列jumpy-part3-重力及碰撞检测
这个游戏叫jumpy,大致玩法就是模拟超级玛丽一样,可以不停在各个档板上跳动,同时受到重力的作用,会向下掉,如果落下时,没有站在档板上,就挂了。
菩提树下的杨过
2019/09/12
8550
pygame-KidsCanCode系列jumpy-part3-重力及碰撞检测
K哥教你用Python摸鱼
玩法:这让我想起了魂斗罗那第几关的boss,有点类似,不过魂斗罗那个难度肯定高点。
Python进击者
2022/03/14
9270
手把手教你用python写游戏
最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏、后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,项目来自《Python编程从入门到实践》(本文将原项目中的部分错误进行修改完善,PS:强烈推荐这本书,真的很赞),来感受下其中的有趣之处。本次开发的游戏叫做alien invasion。
用户7886150
2020/11/27
1.2K0
Python编写的20个小游戏完整版
这个游戏中,玩家需要在10次之内猜出一个1到100之间的随机数字。每次猜测后,程序会告诉玩家猜的数字是偏大还是偏小,直到玩家猜中这个数字或者用完所有的猜测次数为止。如果玩家在规定次数内猜中了这个数字,则游戏胜利;否则游戏失败。
疯狂的KK
2023/05/23
7.6K0
Python编写的20个小游戏完整版
解决Pygame精灵会跳但不会走的问题
根据我从事几年游戏开发的经验,我们知道在Pygame中,精灵(Sprite)是游戏中的基本元素,通常代表游戏中的角色、物体或动画。精灵可以执行各种动作,包括移动、跳跃、碰撞检测等。但是如果我们遇到Pygame精灵能够跳跃但不能走动,可能有多种问题存在,废话不多说,直接看下面详细过程,相信看过了懂的应该都会懂。
华科云商小徐
2024/02/07
1880
手把手教你用python写游戏「建议收藏」
最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏、后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,项目来自《Python编程从入门到实践》(本文将原项目中的部分错误进行修改完善,PS:强烈推荐这本书,真的很赞),来感受下其中的有趣之处。本次开发的游戏叫做alien invasion。
全栈程序员站长
2022/08/31
1.8K0
手把手教你用python写游戏「建议收藏」
用 Python 制作飞机大战小游戏
这次用Python中的pygame模块来完成一个飞机大战的小游戏;基本思路是通过方向键来控制飞机的左右移动射击飞船。先来看下最后的效果
龙哥
2020/10/09
4.4K0
用 Python 制作飞机大战小游戏
pygame-KidsCanCode系列jumpy-part15-PowerUp加速器
这一节我们给游戏增加点额外的奖励,大多数游戏中都会有金币、装备啥的来激励玩家,在jumpy这个游戏中,我们也可以增加类似的道具:加速器。效果图如下:
菩提树下的杨过
2019/09/12
4390
pygame-KidsCanCode系列jumpy-part17-mask-collide碰撞检测
如上图,左侧是默认的检测模式:基于矩形的检测(这也是性能最好的模式), 右侧是基于圆形的检测(性能略差于矩形检测)。
菩提树下的杨过
2019/09/12
7010
Python之pygame学习精灵碰撞做一个躲避球游戏(13)
获取鼠标返回的坐标,用这个坐标来画圆的时候,设置好不能超出边框,结果圆居然能出去????
萌海无涯
2019/08/20
3.3K0
Python之pygame学习精灵碰撞做一个躲避球游戏(13)
相关推荐
使用Pygame在Python游戏中放置平台【Gaming】
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档