def change_direction(self, new_direction): direction = new_direction need_cut = False if 2 * abs(direction[0]) < abs(direction[1]): direction[0] = 0 direction[1] = signum(direction[1]) elif 2 * abs(direction[1]) < abs(direction[0]): direction[1] = 0 direction[0] = signum(direction[0]) else: direction[0] = signum(direction[0]) direction[1] = signum(direction[1]) need_cut = True if direction == self.direction: return self.direction = direction degrees = { ( 0, 0): 0, ( 0,-1): 0, (-1,-1): 45, (-1, 0): 90, (-1, 1): 135, ( 0, 1): 180, ( 1, 1): 225, ( 1, 0): 270, ( 1,-1): 315}[tuple(self.direction)] if degrees % 90 == 0: self.image = pygame.transform.rotate(self.image_list[0], degrees) else: self.image = pygame.transform.rotate(self.image_list[1], degrees - 45) if need_cut: bound_rect = self.image.get_bounding_rect() self.image = self.image.subsurface(bound_rect)
def calculate_speed(self, dt, friction): """Calculates the car's new speed based on its current speed, the amount of time passed and physical properties like the friction and the car's mass.""" # Work with a copy of the speed, since we don't want to alter the # state directly. speed = self.speed accel_sig = signum(self.accel_dir) speed_sig = signum(speed) if speed_sig == 0 and accel_sig == 0: # Standing still and not accelerating. return 0 elif accel_sig == speed_sig or speed_sig == 0: # We are accelerating in the same direction as we are currently # heading. Use a multiplier per direction, since we can accelerate # forward more quickly than we can in reverse. accel_multiplier = self.accel_multiplier * self.accel_dir * ACCEL_MULTIPLIERS[ accel_sig] # The terrain friction will be used in the calculation. speed_multiplier = accel_multiplier * (friction / 255.0) speed += speed_multiplier * dt # Cap the speed. max_speed = speed_multiplier if abs(speed) > abs(max_speed): speed = max_speed else: if accel_sig == 0: # Let the friction slow down the car. slow_down_multiplier = self.friction_multiplier else: # We want to apply brake power, but correct it with the amount # of brake power applied by the player. Make sure it doesn't # get below the friction multiplier; there is no brake that # negatively influences physical friction. slow_down_multiplier = max( self.friction_multiplier, self.brake_multiplier * abs(self.accel_dir)) # We use a large constant in the calculation to increase the effect # of slowing down. speed -= speed_sig * slow_down_multiplier * 2000 * (friction / 255.0) * dt # Cap the speed. if speed * speed_sig < 0: speed = 0 if self.stopping: self.accel_dir = 0 return speed
def side(self,p): """ Find the side of the line on which the point lies return < 0 if it lies on one side, > 0 if on the other side, = 0 if it lies on this Line """ return signum(A * p.x() + B * p.y() + C)
def update(self, dt): """Update the car's state.""" friction = self.track.get_friction_at(self.position) self.speed = self.calculate_speed(dt, friction) rot_factor = min(1, abs(self.speed) / 200) self.rotation = (self.rotation + (rot_factor * ROTATION_SPEED * self.rot_dir * signum(self.speed) * dt)) % 360 tyre_rotation = MAX_TYRE_ROTATION * self.rot_dir for tyre in self.front_tyres: tyre.rotation = tyre_rotation # Change dirt properties. self.dirt.speed = self.speed # Make the engine sound pitch relative to the speed. self.engine_sound.pitch = 0.7 + min(abs(self.speed) / 1000 * 0.7, 0.7) self.engine_sound.volume = 0.1 + min(abs(self.speed) / 1000 * 0.2, 0.2) r = math.radians(self.rotation) s = dt * self.speed target_x = self.x + math.sin(r) * s target_y = self.y + math.cos(r) * s if self.is_valid_move((target_x, target_y)): self.x = target_x self.y = target_y
def orientation(p, q, r): """ Compute the orientation of three given points return < 0 if it's a left turn, > 0 if it's a right turn, = 0 if points are aligned """ return signum((p.x() - r.x()) * (q.y() - r.y()) - (p.y() - r.y()) * (q.x() - r.x()));