2017-01-26 19 views
-1

私は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() 
+0

はStackOverflowのへようこそ。あなたの投稿を編集して、コードブロックを見やすく見えるようにしました。すべての行頭に '> '文字がありますので、質問を投稿する前にコードの書式を確認してください。それで、あなたはこれまでに何を試しましたか?これは、このサイトの誰でもあなたの問題を把握するために読む必要があるため、コード内の特定の場所に絞って、問題が起こっている可能性が高いと考えられる場合は、より良い回答を得るためのコードです。 – akousmata

+0

BTW: 'pygame.init()'の前にすべての定数とクラスを置くと読みやすくなります。クラス間で 'showStats = True'を作成しないでください。そして、定数値に対してのみ 'UPPER_CASE'という名前を使います。 'self.PLAYER_VELOCITY_X'は定数ではありません。 – furas

+0

'print()'を使って、変数の中にあるものと実行されているコードの部分を確認します。問題を見つけるのに役立ちます。 ) – furas

答えて

1

問題はfloat値です。

あなたはfloat値の計算を行うが、それはintegerにすべてfloat計算を丸めるようにのみinteger値をrect.x保つ - しかし、それは間違った方法でそれをしないと、それは間違った結果が得られます。

すべての計算をfloatとすることができます。

おそらくrect.xラウンドそれは-1代わりのから-0.1に変換floorに値を追加:可変self.x

self.x += self.PLAYER_VELOCITY_X + 0.5 * self.PLAYER_ACCELERATION_X 

、すべての計算がself.rect.x

self.rect.x = self.x 

EDITを設定した後にその後、rect.x += -0.1はまた、あなたはそれを

を追加する前に、手動でfloatを変換するround()を使用することができます。しかしfloat値を維持するためにself.xを使用すると、より良い結果を与えることができrect.x += -1の代わりに、rect.x += 0

を与えます。

floatは、すべて実際の値を維持することはできませんが、それは問題になることはありません。それともdecimalモジュールを使用することができます)

+0

ありがとうございました! – d3cka2d3pwood