私はpygameで作成しようとしているplatformerのゲームの仕組みに問題があります。私は初心者ですので、これは基本的に私がチュートリアルのオンラインやここで見つかった情報のスニペットから使用したコードですので、Pythonを学ぼうとしています。 誰も助けることができますか?pygameスプライトの移動の仕組み
問題は、プレーヤーのスプライトが(左矢印キーを押すことによって)左へ移動するときに、右方向に移動するときのように安定した停止にならないことです。 エラーの原因を見つけることができません。
コード:
import pygame as pg
GAME_TITLE = "Plat Game"
SCREEN_WIDTH = 400
SCREEN_HEIGHT = 400
FPS = 60
GAME_WINDOW = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
GAME_TIMER = 0
RUNNING_GAME = True
PLAYER_SIZE_X = 20
PLAYER_SIZE_Y = 20
PLAYER_FRICTION = -0.1
PLAYER_GRAVITY = 0.8
PLAYER_SPEED = 0.5
PLAYER_VELOCITY_X = 0.0
PLAYER_VELOCITY_Y = PLAYER_GRAVITY
PLAT_SIZE_X = 4
PLAT_SIZE_Y = 4
player_move_left_key = pg.K_LEFT
player_move_right_key = pg.K_RIGHT
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
BACK_GROUND_COLOUR = BLACK
PLAYER_COLOUR = RED
class Player(pg.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pg.Surface([PLAYER_SIZE_X, PLAYER_SIZE_Y])
self.image.fill(RED)
self.rect = self.image.get_rect()
self.PLAYER_VELOCITY_X = 0
self.PLAYER_VELOCITY_Y = 0
self.PLAYER_ACCELERATION_X = 0
self.PLAYER_ACCELERATION_Y = 0
def calc_x_movement(self):
self.PLAYER_ACCELERATION_X += self.PLAYER_VELOCITY_X * PLAYER_FRICTION
self.PLAYER_VELOCITY_X += self.PLAYER_ACCELERATION_X
self.rect.x += self.PLAYER_VELOCITY_X + 0.5 * self.PLAYER_ACCELERATION_X
def calc_gravity(self):
self.PLAYER_ACCELERATION_Y += PLAYER_GRAVITY
self.PLAYER_VELOCITY_Y += self.PLAYER_ACCELERATION_Y
self.rect.y += self.PLAYER_VELOCITY_Y + 0.5 * self.PLAYER_ACCELERATION_Y
def check_for_V_collisions(self):
block_hit_list = pg.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:
if self.PLAYER_VELOCITY_Y > 0:
self.rect.bottom = block.rect.top
self.PLAYER_Y = self.rect.bottom
self.PLAYER_VELOCITY_Y = 0
def controls(self):
keys = pg.key.get_pressed()
if keys[player_move_left_key]:
self.PLAYER_ACCELERATION_X = -PLAYER_SPEED
if keys[player_move_right_key]:
self.PLAYER_ACCELERATION_X = PLAYER_SPEED
for event in pg.event.get():
if event.type == pg.QUIT:
quitGame()
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
pg.quit()
sys.exit()
if event.type == pg.QUIT:
quitGame()
def movement(self):
self.PLAYER_ACCELERATION_X = 0
self.PLAYER_ACCELERATION_Y = 0
self.PLAYER_GRAVITY = PLAYER_GRAVITY
self.controls()
self.calc_x_movement()
self.calc_gravity()
self.check_for_V_collisions()
class Platform(pg.sprite.Sprite):
def __init__(self, width, height):
super().__init__()
self.image = pg.Surface([width, height])
self.image.fill(YELLOW)
self.rect = self.image.get_rect()
class Level():
def __init__(self, player):
self.platform_list = pg.sprite.Group()
self.enemy_list = pg.sprite.Group()
self.player = player
self.level = []
def update(self):
self.platform_list.update()
def draw(self, screen):
screen.fill(BACK_GROUND_COLOUR)
self.platform_list.draw(screen)
class Level_01(Level):
def __init__(self, player):
Level.__init__(self, player)
level = [[1000, 10, 0, 300]]
for platform in level:
block = Platform(platform[0], platform[1])
block.rect.x = platform[2]
block.rect.y = platform[3]
block.player = self.player
self.platform_list.add(block)
showStats = True
class Game:
def __init__(self):
pg.init()
pg.font.init()
pg.mixer.init()
pg.display.set_caption(GAME_TITLE)
self.clock = pg.time.Clock()
self.screen = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
self.fontTypeA = pg.font.SysFont("Comic Sans MS", 10)
self.GAME_TIMER = 0
self.running = True
def new(self):
self.player = Player()
level_list = []
level_list.append(Level_01(self.player))
self.current_level_no = 0
self.current_level = level_list[self.current_level_no]
self.active_sprite_list = pg.sprite.Group()
self.player.level = self.current_level
self.player.rect.x = 200
self.player.rect.y = 0
self.active_sprite_list.add(self.player)
self.run()
def run(self):
self.playing = True
while self.playing:
self.update()
self.draw()
def update(self):
self.active_sprite_list.update()
self.current_level.update()
self.player.movement()
self.GAME_TIMER += (1/FPS)
self.clock.tick(FPS)
def draw(self):
self.current_level.draw(GAME_WINDOW)
self.active_sprite_list.draw(GAME_WINDOW)
if showStats is True:
self.display_player_stats()
pg.display.flip()
def draw_text(self, font_name, text, size, colour, x, y):
font = pg.font.SysFont(font_name, size)
text_surface = font.render(text, True, colour)
text_rect = text_surface.get_rect()
text_rect.midtop = (x, y)
GAME_WINDOW.blit(text_surface, text_rect)
def display_player_stats(self):
text1 = "Vel.Y = " + ("%.2f" % self.player.PLAYER_VELOCITY_Y)
text2 = "Acc.Y = " + ("%.2f" % self.player.PLAYER_ACCELERATION_Y)
text3 = "Pos.Y = " + ("%.2f" % self.player.rect.y)
text4 = "Vel.X = " + ("%.2f" % self.player.PLAYER_VELOCITY_X)
text5 = "Acc.X = " + ("%.2f" % self.player.PLAYER_ACCELERATION_X)
text6 = "Pos.X = " + ("%.2f" % self.player.rect.x)
text7 = "Timer = " + ("%.2f" % self.GAME_TIMER)
self.draw_text("Comic Sans MS", text1, 10, GREEN, 40, 5)
self.draw_text("Comic Sans MS", text2, 10, GREEN, 40, 15)
self.draw_text("Comic Sans MS", text3, 10, GREEN, 40, 25)
self.draw_text("Comic Sans MS", text4, 10, YELLOW, 40, 40)
self.draw_text("Comic Sans MS", text5, 10, YELLOW, 40, 50)
self.draw_text("Comic Sans MS", text6, 10, YELLOW, 40, 60)
self.draw_text("Comic Sans MS", text7, 10, WHITE, SCREEN_WIDTH - 50, 5)
g = Game() while g.running:
g.new()
pg.quit()
はStackOverflowのへようこそ。あなたの投稿を編集して、コードブロックを見やすく見えるようにしました。すべての行頭に '> '文字がありますので、質問を投稿する前にコードの書式を確認してください。それで、あなたはこれまでに何を試しましたか?これは、このサイトの誰でもあなたの問題を把握するために読む必要があるため、コード内の特定の場所に絞って、問題が起こっている可能性が高いと考えられる場合は、より良い回答を得るためのコードです。 – akousmata
BTW: 'pygame.init()'の前にすべての定数とクラスを置くと読みやすくなります。クラス間で 'showStats = True'を作成しないでください。そして、定数値に対してのみ 'UPPER_CASE'という名前を使います。 'self.PLAYER_VELOCITY_X'は定数ではありません。 – furas
'print()'を使って、変数の中にあるものと実行されているコードの部分を確認します。問題を見つけるのに役立ちます。 ) – furas