1

I am creating a basic platforming system. When the player hits the platform, I want the players velocity to be set to the platforms velocity. However, the platforms velocity changes when it is landed upon, as tested through my print statements, despite the platforms velocity not being changed explicitly through the code (to my understanding). I have included the entire source code as I'm not sure where, or how, the platforms velocity is being changed.

The platforms velocity appears to change when the player is intersecting it and the players velocity changes, such as between the print statements "1" and "2".

import pygame
import numpy as np
import random

class player:
    def __init__(self,position,velocity):
        self.position=position
        self.velocity=velocity

    def updatepos(self):
        self.position+=self.velocity

    def draw(self):
        self.updatepos()
        pygame.draw.rect(screen,(255,0,0),(self.position[0],self.position[1]-20,20,20))

class platform:
    def __init__(self,position,length,velocity):
        self.position=position
        self.length=length
        self.velocity=velocity

    def updatepos(self):
        self.position += self.velocity

    def draw(self):
        pygame.draw.rect(screen, (0, 0, 255), (self.position[0], self.position[1], self.length, 5))


width, height= 800,600
screen=pygame.display.set_mode((width,height))

player=player(np.array([100.0,100.0]),np.array([0.0,0.0]))

platforms=[ platform( np.array([100.0,200.0]), 100, np.array([1.0,1.0]) ) ]
#for _ in range(1):
    #platforms+=[platform( np.array( [float(random.randrange(0,800)),float(random.randrange(0,800))]), 50.0, np.array( [float(random.randrange(0,3)),float(random.randrange(0,3))] ))]


wpress=False
apress=False
dpress=False

#main loop
running=True
while running:

    #gravity
    print(str(platforms[0].velocity)+" 1")
    player.velocity+=np.array([0.0,0.5])
    print(str(platforms[0].velocity)+" 2")

    #checking intersections
    startline = player.position
    endline = player.position+player.velocity

    direction=endline-startline

    grounded=False
    for _ in range(len(platforms)):
        if startline[1] <= platforms[_].position[1] and endline[1] >= platforms[_].position[1]:

            scalar= (platforms[_].position[1] - startline[1]) / direction[1]

            x=startline[0]+direction[0]*scalar
            y=platforms[_].position[1]

            if platforms[_].position[0]-20 < x < platforms[_].position[0] + platforms[_].length:

                player.position = np.array( [x,y] )

                player.velocity=platforms[_].velocity

                grounded=True
                break

    #drawing on screen
    for _ in range(len(platforms)):
        platforms[_].position+=platforms[_].velocity
        platforms[_].draw()

    #controls
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.KEYDOWN:

            if event.key == pygame.K_w:
                if grounded:
                    print(str(platforms[0].velocity) + " 21")
                    player.velocity[1]= -8.0
                    print(str(platforms[0].velocity) + " 22")

            elif event.key == pygame.K_a:
                apress=True

            elif event.key == pygame.K_d:
                dpress=True

            elif event.key == pygame.K_SPACE:

                player.position=np.array([100.0,100.0])
                player.velocity=np.array([0.0,0.0])

                platforms=[]
                for _ in range(60):
                    platforms += [
                        platform(np.array([float(random.randrange(0, 800)), float(random.randrange(0, 800))]), 50.0,
                                 np.array([float(random.randrange(0, 3)), float(random.randrange(0, 3))]))]

        elif event.type == pygame.KEYUP:

            if event.key == pygame.K_a:
                apress = False
            elif event.key == pygame.K_d:
                dpress = False

        if apress and dpress or not (apress or dpress):
            print(str(platforms[0].velocity) + " 31")
            player.velocity[0] = 0
            print(str(platforms[0].velocity) + " 32")
        elif apress:
            print(str(platforms[0].velocity) + " 41")
            player.velocity[0]=-5.0
            print(str(platforms[0].velocity) + " 42")
        elif dpress:
            print(str(platforms[0].velocity) + " 51")
            player.velocity[0] = 5.0
            print(str(platforms[0].velocity) + " 52")


    player.draw()
    pygame.display.flip()

    clock = pygame.time.Clock()
    clock.tick(5)
    screen.fill((0,0,0))
Progamer
  • 80
  • 5

1 Answers1

2

You set the player and platform to share the same array for their velocity:

player.velocity=platforms[_].velocity

Since it's a single array that has multiple objects pointing at it, when you change it via the player object, it also changes for the platform object.

Samwise
  • 68,105
  • 3
  • 30
  • 44
  • Thank you, there was no way I would figured this out itself. So, if I am correct, when I set the players velocity to the platforms velocity I am sending the index of the platforms velocity to the players velocity. Is there a function I can use so the players velocity only receives the data of the platforms velocity? – Progamer May 26 '20 at 21:20
  • @Progamer try this `player.velocity = np.copy(platforms[_].velocity)`. That will give you a copy of the platforms velocity array instead of a reference to the same array. – Glenn Mackintosh May 26 '20 at 21:44
  • you could also do `player.velocity[:] = platforms[_].velocity` that way you just copy the values over rather than creating a new array (or just copying the reference as you were doing). see https://stackoverflow.com/q/19676538/1358308 for more explanation – Sam Mason May 27 '20 at 08:46