I'm trying my best to make a dino game replica and I'm stuck at increasing the speed of the obstacles that comes towards the character. The speed of 5 just seems to be the magic number but when I change it to six the rock doesn't get detected and ultimately doesn't spawn the next rock.
I don't know why.
there are no errors except for when the rock doesn't get spawned and I get an index out of range:
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
here is what I got:
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
and I suspect the issue is in the spawn function in the Game class in main.py
I've been trying to work on this for a couple days now and I still cannot solve my issue.