Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how do i move obstacles faster for dino game

im trying my best to make a dino game replica and im 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 doesnt get detected and ultimatley doesnt spawn the next rock.

i dont know why.

there is no errors except for when the rock doesnt get spawned and get an index out of range:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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 wich 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

ive been trying to work on this for a couple days now and i still cannot solve my issue

>Solution :

The problem is the condition

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

This condition is only True when the obstacle is exactly at a certain position. If the speed changes, the obstacle does not exactly hit the position.

Test on a small range instead of a position. e.g.:

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

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading