- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我是 pygame 的新手,我正在尝试获取基础知识。我想创建障碍物并检测玩家矩形的哪一侧(代表 Sprite 的碰撞框)与障碍物矩形碰撞。这样我就可以在游戏中创建基本的物理原理。
这就是我所做的:
import pygame
class Player (pygame.sprite.Sprite):
def __init__(self, x=0, y=0, s=100):
super(Player,self).__init__()
self.image = pygame.transform.scale(pygame.image.load("player.png"), (s, s))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Block (pygame.sprite.Sprite):
def __init__(self, x=0, y=500, s=100):
super(Block, self).__init__()
self.image = pygame.transform.scale(pygame.image.load("wall.png"),(s, s))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
pygame.init()
display = pygame.display.set_mode((800,600))
player = Player()
block = Block()
sprites = pygame.sprite.Group()
living = pygame.sprite.Group()
noliving = pygame.sprite.Group()
sprites.add(player)
sprites.add(block)
living.add(player)
noliving.add(block)
gravity = 1
xCh = 0
yCh = 0
speed = 1
while True:
display.fill((159, 159, 159))
for liv in living:
for noliv in noliving:
if(not pygame.sprite.collide_rect(liv, noliv)):
player.rect.y += gravity
for event in pygame.event.get():
if(event.type == pygame.KEYDOWN):
if(event.key == pygame.K_ESCAPE):
quit()
elif(event.key == pygame.K_a or event.key == pygame.K_LEFT):
xCh = -speed
elif(event.key == pygame.K_d or event.key == pygame.K_RIGHT):
xCh = speed
elif(event.type == pygame.KEYUP):
xCh = 0
yCh = 0
elif(event.type == pygame.QUIT):
quit()
player.rect.x += xCh
sprites.draw(display)
pygame.display.update()
玩家在接触方 block 时会停止掉落,但如果我向左或向右移动,然后进入方 block ,玩家会直接进入方 block 并从那里停止掉落。我希望玩家无法穿过方 block 。如何做到这一点?
最佳答案
这是您的代码,其中包含建议的修复方法以及其他一些改进建议。
首先要做的事情是:错误在于你从未检查水平移动是否会使方 block 发生碰撞。您只进行了一项检查,并且它实际上仅在发生任何碰撞之后才执行任何操作。在这种情况下,它会阻止“重力”做任何事情。由于您是逐像素更新玩家的,因此碰撞已经发生的事实几乎没有被注意到。解决方法是创建一个检查来验证移动 block 是否可以移动到某个位置,然后才允许它。并且对所有的运动都这样做,而不仅仅是重力运动。
所以,在这里我将解释可以让这个示例代码演变成一个完整游戏的改进。
消除模块级别的“ float 代码”并将所有内容放入函数内。这对于 future 任何游戏来说都是至关重要的,即使是像开始屏幕(可能还有“再玩一次”屏幕)这样简单的东西。我创建了两个函数,一个用于创 build 置您的游戏环境并创建您的对象以及主要游戏功能。将来你应该进一步分离“设置”阶段,能够创建更多游戏对象或不同的游戏级别。
重用您的代码。您的 __init__ 方法中的行大部分在两个类之间重复,但对于初始位置和图像名称常量而言。因此,您实际上只需要一个类,并为这些属性传递不同的值。由于您暗示通过使用组等您将拥有两种不同的游戏类型的对象,因此我保留了这两个类,但提取了通用代码。
帧延迟:您的代码将简单地“尽可能快地”移动 - 这将在不同的计算机中创建不同的游戏速度,并使用 100% 的 CPU - 导致可能的机器速度减慢和过多的电力使用。我添加了 30 毫秒的硬编码暂停 - 这将使您的游戏以接近 30 FPS 的速度移动,并在不同设备上保持速度稳定。所需的另一个更改是重力和速度的硬编码“1”值,这将使玩家一次移动 1 像素,必须更改为更大的值。
最后但并非最不重要的一点是,“我可以移动到那里”逻辑:它实际上看起来很广泛 - 但会发现检查“这个对象可以移动到那个位置”的简单英语描述很长。该方法本质上是:“存储当前位置”。 “用给定的 x 和 y 位移伪造一个位置”。 “检查我是否与某些东西发生碰撞”。 “如果不是,则恢复之前的位置,并说允许移动”。 “否则,恢复y位置,检查X方向是否有碰撞,如果有,限制水平移动”。 “恢复x位置,将y位置移动所需的量,检查是否发生碰撞。如果是,则限制y方向的移动”。 “如果在 x 或 y 方向上的运动不受限制,则只是组合运动导致碰撞:限制两个方向上的运动是公平的”。 “恢复原始位置,返回允许的 x 和 y 位置更改,以及我们要碰撞的对象”。所有这些逻辑都放在“活的”对象类本身内部,因此可以随时使用,只需在主游戏逻辑中添加一行代码即可。
代码:
import pygame
class GameObject(pygame.sprite.Sprite):
def __init__(self, x=0, y=0, s=100, image=""):
super(GameObject, self).__init__()
if not image:
image = self.image
self.image = pygame.transform.scale(pygame.image.load(image), (s, s))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Player(GameObject):
image = "player.png"
def can_move(self, xCh, yCh, group):
old_pos = self.rect.x, self.rect.y
self.rect.x += xCh
self.rect.y += yCh
collided_with = pygame.sprite.spritecollideany(self, group)
if not collided_with:
# No Collisions at all - allow movement
self.rect.x = old_pos[0]
self.rect.y = old_pos[1]
return True, xCh, yCh, None
# Check if the colision was due to horizontal movement:
self.rect.y = old_pos[1]
if pygame.sprite.spritecollideany(self, group):
# Yes, then indicate horizontal movement should be 0
xCh = 0
# check if collision was due to vertical movement:
self.rect.y += yCh
self.rect.x = old_pos[0]
if pygame.sprite.spritecollideany(self, group):
# Yes - indicate vertical movemnt should be 0
yCh = 0
# if only diagonal movement causes collision, then
# cancel movrment in both axes:
# (i.e. just the diagonal movement would hit the
# obstacle )
if not xCh == 0 and not yCh == 0:
xCh = 0
yCh = 0
self.rect.x = old_pos[0]
self.rect.y = old_pos[1]
return False, xCh, yCh, collided_with
class Block(GameObject):
image = "wall.png"
def setup():
global display, player, living, noliving, gravity, speed, sprites
pygame.init()
display = pygame.display.set_mode((800,600))
player = Player()
block = Block(y=500)
sprites = pygame.sprite.Group()
living = pygame.sprite.Group()
noliving = pygame.sprite.Group()
sprites.add(player)
sprites.add(block)
living.add(player)
noliving.add(block)
gravity = 10
speed = 10
def main():
xCh = 0
yCh = 0
while True:
display.fill((159, 159, 159))
for event in pygame.event.get():
if(event.type == pygame.KEYDOWN):
if(event.key == pygame.K_ESCAPE):
quit()
elif(event.key == pygame.K_a or event.key == pygame.K_LEFT):
xCh = -speed
elif(event.key == pygame.K_d or event.key == pygame.K_RIGHT):
xCh = speed
elif(event.type == pygame.KEYUP):
xCh = 0
yCh = 0
elif(event.type == pygame.QUIT):
quit()
yCh = gravity
for liv in living:
if liv == player:
check_x_ch = xCh
else:
check_x_ch = 0
can_move, xCh, yCh, obstacle = liv.can_move(xCh, yCh, noliving)
liv.rect.x += xCh
liv.rect.y += yCh
# Do other actions if "can_move" indicates a block was hit...
sprites.draw(display)
pygame.display.update()
pygame.time.delay(30)
setup()
main()
关于python - Pygame sprites - 获取矩形碰撞面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45948995/
Surface.blit在 1.8 中有一个新参数:混合。定义了以下值: BLEND_ADD BLEND_SUB BLEND_MULT BLEND_MIN BLEND_MAX BLEND_RGBA_A
import sys import pygame import pygame.locals as pgl class Test: def __init__(self): pyg
我对 PyGame 比较陌生。我正在尝试制作一个简单的程序来显示表示鼠标在屏幕上的位置的字符串。 import pygame, sys from pygame.locals import * pyga
我有总是在后台运行的音乐和一些在触发时会播放声音的事件。音乐效果很好。 pygame.mixer.music.load(os.path.join(SOUND_FOLDER, 'WateryGrave.
我有这些代码 FONT = pygame.font.Font("font/calibri.ttf", 50) FONT.size = 25 但是编译器说 AttributeError: 'pygame
有我正在导入的图像: look_1 = pygame.image.load('data\\png\\look1.png').convert_alpha() 我试图减少它的大小是这样的: pygame.
我正在为我的 pygame 制作一个帮助屏幕,每当我运行它时,我都会收到此错误消息: > self.surface.blit(self.helpscreen) TypeError: argument
在 pyGame 中应用程序,我想渲染 SVG 中描述的无分辨率 GUI 小部件。 我怎样才能做到这一点? (我喜欢 OCEMP GUI 工具包,但它的渲染似乎依赖于位图) 最佳答案 这是一个完整的例
有没有办法将多首歌曲加载到 Pygame 中?我不是在谈论这样的音效; crash_sound = pygame.mixer.Sound("crash.ogg") #and pygame.mixer.
我还有一个问题。当我尝试运行我的代码时,pygame 启动然后立即停止。 这是我的代码: import pygame import os import time import random pygam
我正在使用 pymunk 和 pygame 开发一个项目。我正在使用 PivotJoint 约束将我的 body 连接在一起。如果可能的话,我想让关节不可见 - 有什么办法可以做到这一点吗?现在关节在
我使用 fedora 20、Python 2.7 和 virtualenv 1.10.1。我想在 virtualenv 中安装 pygame,我得到了 You are installing a pot
尝试将文本添加到矩形中并使用箭头键在屏幕上移动矩形。我想让文字不会超出边缘。到目前为止,我已经在没有将其放入 Rect 中的情况下工作了,但我想让 Rect 函数工作。现在文本只是反弹回来,我不知道要
我是第一次玩 pygame(总的来说我是 python 的新手),想知道是否有人可以帮助我... 我正在制作一款小型射击游戏,希望能够为坏人创建一个类。我的想法是类应该继承自 pygame.Surfa
我在 Windows 10 机器上运行了 python 3.9.1。我通过 pip 在我的机器上安装了 pygame 2.0.1 (python -m pip install https://gith
错误: File "/home/alien/cncell/core/animator.py", line 413, in create_animation_from_data pygame
这是代码。 5000 个弹跳旋转的红色方块。 (16x16 png) 在 pygame 版本上,我获得 30 fps,但使用 pyglet 获得 10 fps。对于这种事情,OpenGl 不应该更快吗
我以为 pygame.font.Font 是用来加载 .ttf 字体的,如果没有 .ttf 文件在同一个目录下就无法加载字体,但我看过一个视频,有人在没有 .ttf 文件的情况下加载字体。 ttf 字
我正在尝试使用 Travis CI 设置一个项目。项目也使用 pygame。我曾多次尝试设置它 - 但它似乎失败了。 我得到的最接近的是以下内容: .travis.yml : language: py
这个问题已经有答案了: Python error "ImportError: No module named" (38 个回答) 已关闭 3 年前。 我正在使用 Mac 并输入 pip install
我是一名优秀的程序员,十分优秀!