Скольжение игроков и платформы движутся неправильно (Python / Pygame) - PullRequest
0 голосов
/ 16 октября 2018

В настоящее время я строю небольшую платформу для своего проекта A-Level и столкнулась с проблемой, которую я или мои друзья не можем решить.Игрок, кажется, много скользит вправо, а не влево (обратите внимание: небольшое скольжение слева - это то, что нужно), и платформы, кажется, тоже не двигаются правильно, некоторые делают по мере необходимости, как стены, но затем полы не делаюти все клипы на правой стороне экрана.Любые предложения будут полезны.

import pygame as pg
import random
import time
vec = pg.math.Vector2
#Player Props
PLAYER_ACC = 1.5
PLAYER_FRICTION = -0.12
PLAYER_GRAV = 0.8
#Display
WIDTH = 1800
HEIGHT = 1000
#Colours
WHITE = (225,225,255)
BLACK = (0,0,0)
RED = (225,0,0)
BLUE = (0,0,225)
PURPLE = (95, 11, 239)
ORANGE = (250,123,10)

class Player(pg.sprite.Sprite):
    def __init__(self, game):
        #Player spawn and location
        pg.sprite.Sprite.__init__(self)
        self.game = game
        self.image = pg.Surface((32, 32))
        self.image.fill(PURPLE)
        self.rect = self.image.get_rect()
        self.pos = vec(WIDTH/2, 200)
        self.vel = vec(0, 0)
        self.acc = vec (0, 0)

    def jump(self):
        #Jumping  when standing on playform
        self.rect.x += 1
        hits = pg.sprite.spritecollide(self, self.game.platformsA, False)
        self.rect.x -= 1
        if hits:
            self.vel.y = -20

    def update(self):
        #Player Movement/Gravity
        self.acc = vec (0, PLAYER_GRAV)
        self.vy = 1
        keys = pg.key.get_pressed()
        if keys[pg.K_LEFT]:
            self.acc.x = -PLAYER_ACC 
        if keys[pg.K_RIGHT]:
            self.acc.x = PLAYER_ACC 
        #Accelaration/Friction
        self.acc.x += self.vel.x * PLAYER_FRICTION
        self.vel += self.acc
        if self.vel[1]> 10:
            self.vel[1] = 10
        self.pos += self.vel + 0.25 * self.acc
        self.rect.midbottom = self.pos


class Platform(pg.sprite.Sprite):
    def __init__(self, x, y, w, h):
        #Building Platforms
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((w, h))
        self.rect = self.image.get_rect()
        self.image.fill(WHITE)
        self.rect.x = x
        self.rect.y = y


class Game:
    def __init__(self):
        #initialize game window etc
        pg.init()
        pg.mixer.init()
        self.screen = pg.display.set_mode((WIDTH, HEIGHT))
        self.screen.fill(BLACK)
        pg.display.update()
        pg.display.set_caption('Fur-Rush')
        self.clock = pg.time.Clock()
        self.running = True

    def new(self):
        #start new game/spawn everything
        self.all_sprites = pg.sprite.Group()
        self.platforms = pg.sprite.Group()
        self.platformsA = pg.sprite.Group()
        self.platformsB = pg.sprite.Group()
        self.platformsWa = pg.sprite.Group()
        self.platformsWb = pg.sprite.Group()
        self.player = Player(self)
        self.all_sprites.add(self.player)
        #Read platform dimensions from platforms.txt
        with open ('platforms.txt','r') as me:
            allplat = (me.read().split('\n'))
            newplat = [x.replace(',','').split(' ') for x in allplat]
        #Recursive loop to add platforms
        for x in range(len(newplat)):
            name = str(newplat[x][0])
            plat = Platform(int(newplat[x][1]), int(newplat[x][2]), int(newplat[x][3]), int(newplat[x][4]))
            self.all_sprites.add(plat)
            self.platforms.add(plat)
            if 'A' in str(name):
                self.platformsA.add(plat)
            elif 'B' in str(name):
                self.platformsB.add(plat)
            elif 'Wa' in str(name):
                self.platformsWa.add(plat)
            elif 'Wb' in str(name):
                self.platformsWb.add(plat)
        self.run()

    def run(self):
        #game loop
        self.playing = True
        while self.playing:
                self.clock.tick(60)
                self.events()
                self.update()
                self.draw()

    def update(self):
        #game loop - update
        self.all_sprites.update()
        #Top of platform
        hits = pg.sprite.spritecollide(self.player, self.platformsA, False)
        if hits:
            self.player.pos.y = hits[0].rect.top
            self.player.vel.y = 0
        #Bottom of platform
        hits2 = pg.sprite.spritecollide(self.player, self.platformsB, False)
        if hits2:
            self.player.pos.y = (hits2[0].rect.top + 42)
            self.player.vel.y = 0
        #Walls for left dectection
        hits3 = pg.sprite.spritecollide(self.player, self.platformsWa, False)
        if hits3:
            self.player.pos.x = (hits3[0].rect.right+16)
            self.player.vel.x = 0
        #Walls for right dectection
        hits4 = pg.sprite.spritecollide(self.player, self.platformsWb, False)
        if hits4:
            self.player.pos.x = (hits4[0].rect.left - 16)
            self.player.vel.x = 0

        #moving camra/display with player
            #left
        if self.player.rect.left <= WIDTH/3:
            self.player.pos.x += abs(self.player.vel.x)
            for plat in self.platforms:
                plat.rect.x += abs(self.player.vel.x)

            #right (ISSUES)
        if self.player.rect.right >=WIDTH/1.5:
            self.player.pos.x -= abs(self.player.vel.x)
            for plat in self.platforms:
                plat.rect.x -= abs(self.player.vel.x)

            #bottom
        if self.player.rect.top >= HEIGHT/1.25:
            self.player.pos.y += 0.1
            for plat in self.platforms:
                plat.rect.y -= 7

            #top
        if self.player.rect.bottom <= HEIGHT/5:
            self.player.pos.y -= 0.1
            for plat in self.platforms:
                plat.rect.y += 7

    def events(self):
        #game loop - events
        for event in pg.event.get():
            #check for closed window
            if event.type == pg.QUIT:
                if self.playing:
                    self.playing = False
                self.running = False
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_UP:
                    self.player.jump()

    def draw(self):
        # Game loop draw
        self.screen.fill(BLACK)
        self.all_sprites.draw(self.screen)
        #after drawing everything, flip
        pg.display.flip()

    def show_start_screen(self):
        #start screen
        pass

    def show_end_screen(self):
        #Level end screen
        pass

g = Game()
g.show_start_screen()
while g.running:
    g.new()
    g.show_end_screen()

pg.quit()

Файл, необходимый для запуска кода, должен называться «platform.txt» и иметь следующее:

plA, -300, 126, 1500, 10
plB, -300, 136, 1500, 10
plA2, -300, 536, 1100, 10
plB2, -300, 546, 1100, 10
plA3, -100, 336, 1300, 10
plB3, -100, 346, 1300, 10
plA4, 1000, 536, 200, 10
plB4, 1000, 546, 200, 10
plA5, 800, 1526, 200, 10
plB5, 800, 1536, 200, 10
plWa, -300, 136, 20, 400
plWb, 1180, 136, 20, 400
plWa2, 800, 546, 20, 1000
plWb2, 1000, 546, 20, 1000

1 Ответ

0 голосов
/ 16 октября 2018

Я не запустил полный код, но при быстром взгляде проблема, кажется, здесь:

if keys[pg.K_LEFT]:
    self.acc.x = -PLAYER_ACC 
if keys[pg.K_RIGHT]:
    self.acc.x = PLAYER_ACC 
#Accelaration/Friction
self.acc.x += self.vel.x * PLAYER_FRICTION

PLAYER_FRICTION положительно, и вы добавляете / умножаете его без изменения направлениятрения.

Вы можете либо определить, к какому направлению вы хотите применить (умножив его на -1 в зависимости от направления), либо использовать отдельные трения для отдельных направлений, если вы хотите применить некоторыекакой-то странный эффект.

Итак, у вас есть что-то вроде этого:

PLAYER_FRICTION_LEFT = 0.12
PLAYER_FRICTION_RIGHT = -0.12
...
...
    if keys[pg.K_LEFT]:
        self.acc.x = -PLAYER_ACC 
        self.acc.x += self.vel.x * PLAYER_FRICTION_LEFT
    if keys[pg.K_RIGHT]:
        self.acc.x = PLAYER_ACC 
        self.acc.x += self.vel.x * PLAYER_FRICTION_RIGHT

Или что-то вроде этого:

if keys[pg.K_LEFT]:
    self.acc.x = -PLAYER_ACC
    friction = -PLAYER_FRICTION
if keys[pg.K_RIGHT]:
    self.acc.x = PLAYER_ACC
    friction = PLAYER_FRICTION

self.acc.x += self.vel.x * friction
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...