我如何更快地移动恐龙游戏中的障碍物

how do i move obstacles faster for dino game

我正在尽最大努力制作恐龙游戏复制品,但我一直坚持提高障碍物到达角色的速度。 5 的速度似乎是一个神奇的数字,但当我将其更改为 6 时,岩石没有被检测到,最终也不会产生下一块岩石。

我不知道为什么。

没有错误,除了当岩石没有生成并且我得到一个超出范围的索引时:

Traceback (most recent call last):
  File "C:\Users\austi\OneDrive\Desktop\scroller game\main.py", line 109, in <module>
    main()
  File "C:\Users\austi\OneDrive\Desktop\scroller game\main.py", line 102, in main
    if game.collide():
  File "C:\Users\austi\OneDrive\Desktop\scroller game\main.py", line 71, in collide
    olh = self.obstacles[0].hitBox[0]
IndexError: list index out of range

这是我得到的:

main.py

import pygame
import math
import random
from player import Player
from objects import Obstacle
WIDTH, HEIGHT = 700, 400

class Game:
    def __init__(self, playerSprite=None, obSprite= None):
        self.playerSprite = playerSprite
        self.obSprite = obSprite
        self.player = Player(50, 50, 50, 50, 8, (0, 0, 0), None)
        self.obstacle = Obstacle(1, (800, 350, 50, 50), 5, None)
        self.obstacles = [self.obstacle]
        self.spawnGap = -100
        self.speed = 5
    def spawn(self):
        for obstacle in self.obstacles:
            #if its at the specific spot than spawn a rock
            if obstacle.pos.x + obstacle.w == WIDTH/2 + self.spawnGap:

                #get shape of rock
                type = round(random.randint(0, 3))

                rect = (700, 350, 50, 50)
                if self.obSprite != None:
                    self.obSprite = pygame.transform.scale(self.obSprite, (50, 50))
                if type == 1:
                    rect = (700, 350, 25, 50)
                    if self.obSprite != None:
                        self.obSprite = pygame.transform.scale(self.obSprite, (25, 50))
                if type == 2 :
                    rect = (700, 375, 50, 25)
                    if self.obSprite != None:
                        self.obSprite = pygame.transform.scale(self.obSprite, (50, 25))
                if type == 3:
                    rect = (700, 350, 75, 50)
                    if self.obSprite != None:
                        self.obSprite = pygame.transform.scale(self.obSprite, (75, 50))
                #increase the place in which the rock spawns
                self.spawnGap += 10
                #create a new obstacle and append it to the obstacle array
                self.obstacle = Obstacle(type, rect, 5, None)
                self.obstacles.append(self.obstacle)
            #delete obstacle when its at the end
            if obstacle.pos.x < -obstacle.w:
                index = self.obstacles.index(obstacle)
                del self.obstacles[index]

    def draw(self, win):
        self.spawn()
        self.hitBoxes()
        self.player.draw(window)
        for obstacle in self.obstacles:
            obstacle.draw(window)
        
    def collide(self):
        plh = self.player.hitBox[0]
        prh = self.player.hitBox[0] + self.player.hitBox[2]
        pth = self.player.hitBox[1]
        pbh = self.player.hitBox[1] + self.player.hitBox[3]
        olh = self.obstacles[0].hitBox[0]
        orh = self.obstacles[0].hitBox[0] + self.obstacles[0].hitBox[2]
        oth = self.obstacles[0].hitBox[1]
        obh = self.obstacles[0].hitBox[1] + self.obstacles[0].hitBox[3]
        if prh >= olh and plh <= orh:
            if pbh >= oth:
                return True
        else:
            return False
    def hitBoxes(self):
        key = pygame.key.get_pressed()
        if key[pygame.K_a]:
            self.player.showHitBoxes = True
            for obstacle in self.obstacles:
                obstacle.showHitBoxes = True
        if key[pygame.K_s]:
            self.player.showHitBoxes = False
            for obstacle in self.obstacles:
                obstacle.showHitBoxes = False

def main():
    done = False
    pressed = False
    game = Game()
    time = pygame.time.Clock()
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT: 
                done = True
        window.fill((255, 255, 255))
        game.draw(window)
        if game.collide():
            done = True
        pygame.draw.line(window, (255, 0, 0), (WIDTH/2, 0), (WIDTH/2, HEIGHT))
        pygame.draw.line(window, (0, 0, 255), (WIDTH/2 + game.spawnGap, 0), (WIDTH/2 + game.spawnGap, HEIGHT))
        pygame.display.update()
        time.tick(60)
    pygame.quit()
main()

objects.py

import pygame
from pygame.math import Vector2

class Obstacle:
    def __init__(self, type, rect, speed, rockSprite=None):
        self.obSprite = rockSprite
        self.xSpawn = rect[0]
        self.ySpawn = rect[1]
        self.pos = Vector2(self.xSpawn, self.ySpawn)
        self.w = rect[2]
        self.h = rect[3]
        self.type = type
        self.speed = speed
        self.hitBox = ()
        self.showHitBoxes = False
    def draw(self, win):
        self.hitBox = (self.pos.x, self.pos.y, self.w, self.h)
        if self.showHitBoxes:
            pygame.draw.rect(win, (255, 0, 0), self.hitBox, 2)
        if self.obSprite != None:
            win.blit(self.obSprite, self.pos)
        else:
            pygame.draw.rect(win, (0, 0, 0), (self.pos.x, self.pos.y, self.w, self.h))
        self.update()
    def update(self):
        self.pos.x -= self.speed

player.py

import pygame
from pygame.math import Vector2
WIDTH, HEIGHT = 700, 400

class Player:
    def __init__(self, x, y, w, h, jumpVel, color, sprite=None):
        self.playerSprite = sprite
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.pos = Vector2(self.x, self.y)
        self.color = color
        self.gravity = 0.3
        self.vel = self.gravity
        self.jVel = jumpVel
        self.touching_surface = False
        self.canJump = True
        self.jumping = False
        self.hitBox = ()
        self.showHitBoxes = False
    def draw(self, win):
        self.hitBox = (self.pos.x + 0, self.pos.y + 10, 50, 30)
        if self.showHitBoxes:
            pygame.draw.rect(win, (255, 0, 0), self.hitBox, 2)
        if self.playerSprite != None:
            win.blit(self.playerSprite, self.pos)
        else:
            pygame.draw.rect(win, (255, 0, 0), (self.pos.x, self.pos.y, 50, 50))
        self.update()
    def update(self):
        mouse = pygame.mouse.get_pressed()

        if self.pos.y + self.h >= HEIGHT:
            self.touching_surface = True
            self.vel = 0
            self.pos.y = HEIGHT - self.h
        else:
            self.touching_surface = False
            self.vel += self.gravity
        if self.pos.x <= 0:
            self.pos.x = 0
        elif self.pos.x + self.w >= WIDTH:
            self.pos.x = WIDTH - self.w 

        if self.touching_surface:
            self.canJump = True
        else:
            self.canJump = False

        if mouse[0] == 1 and self.canJump and not self.jumping:
            self.jumping = True
            self.canJump = False
            self.vel = -self.jVel 
        if mouse[0] == 0:
            self.jumping = False

        self.pos.y += self.vel

我怀疑问题出在 main.py

游戏 class 的生成函数中

几天来我一直在努力解决这个问题,但我仍然无法解决我的问题。

问题是条件

if obstacle.pos.x + obstacle.w == WIDTH/2 + self.spawnGap:
   # [...]

只有当障碍物恰好在某个位置时,这种情况才会True。如果速度发生变化,障碍物并没有准确命中位置。

在小范围而不是位置上进行测试。例如:

right = obstacle.pos.x + obstacle.w
target = WIDTH/2 + self.spawnGap
if traget <= right < traget + speed:
    # [...]