2017-01-15 2 views
-4

私はthisに基づいてPygameプラットフォームに取り組んでいます。 Linux特有の機能を持たないLinuxマシンに書きましたが、MacやWindowsでは動作しません。次のようにLinux以外の指向のpygame platformerは、Linux以外のもので正しくレベルを生成していません

コードは次のとおり

from pygame import * 
from threading import * 
from time import sleep 
from Tkinter import * 
import tkFileDialog 
import tkMessageBox 

tk = Tk() 
tk.withdraw() 

# Function to set intervals 
def set_interval(func, sec): 
    def wrapper(): 
     set_interval(func, sec) 
     func() 
    t = Timer(sec, wrapper) 
    t.start() 
    return t 

def stopwatch_increase(): 
    global stopwatch 
    stopwatch += 1 

def main(): 
    global cameraX, cameraY 
    global WIN_WIDTH, WIN_HEIGHT 
    global HALF_WIDTH, HALF_HEIGHT 
    global DISPLAY, DEPTH, FLAGS, CAMERA_SLACK 
    global entities 
    global money, deaths, stopwatch 

    fullscreen = False 

    # Initalize 
    init() 

    # Set up system info and the font 
    info = display.Info() 
    text_font = font.SysFont("monospace", 16) 

    WIN_WIDTH = int(info.current_w/1.3) 
    WIN_HEIGHT = int(info.current_h/1.5) 
    HALF_WIDTH = int(WIN_WIDTH/2) 
    HALF_HEIGHT = int(WIN_HEIGHT/2) 

    DISPLAY = (WIN_WIDTH, WIN_HEIGHT) 
    DEPTH = 32 
    FLAGS = 0 
    CAMERA_SLACK = 30 

    # Set up the window 
    screen = display.set_mode(DISPLAY, FLAGS, DEPTH) 
    display.set_caption("Player") 
    timer = time.Clock() 
    stopwatch = 0 

    up = down = left = right = running = False 
    bg = Surface((32, 32)) 
    bg.convert() 
    bg.fill(Color("#FFFFFF")) 
    entities = sprite.Group() 
    platforms = [] 

    x = y = 0 

    # Build the level 
    try: 
     # Load a .lvl file 
     levelFile = tkFileDialog.askopenfile(mode='r', defaultextension='.lvl', filetypes=[('Level File', '*.lvl')], parent=tk) 
     level = levelFile.read().split("\n") 
     del level[len(level) - 1] 
     for row in level: 
      for col in row: 
       if col == "P": 
        p = Platform(x, y) 
        platforms.append(p) 
        entities.add(p) 
       if col == "E": 
        e = ExitBlock(x, y) 
        platforms.append(e) 
        entities.add(e) 
       if col == "D": 
        d = DeathBlock(x, y) 
        platforms.append(d) 
        entities.add(d) 
       if col == "B": 
        b = BounceBlock(x, y) 
        platforms.append(b) 
        entities.add(b) 
       if col == "C": 
        c = CheckBlock(x, y) 
        platforms.append(c) 
        entities.add(c) 
       if col == "M": 
        m = MoneyBlock(x, y) 
        platforms.append(m) 
        entities.add(m) 
       if col == "S": 
        player = Player(x, y) 
       x += 32 
      y += 32 
      x = 0 
     total_level_width = len(level[0])*32 
     total_level_height = len(level)*32 
     camera = Camera(complex_camera, total_level_width, total_level_height) 
     entities.add(player) 
    except: 
     tkMessageBox.showwarning("Error", "File incompatible") 

    set_interval(stopwatch_increase, 1) 

    stat_text = "Money: %s Deaths: %s Time: %s" % (money, deaths, stopwatch) 

    while 1: 
     timer.tick(60) 

     stat_text = "Money: %s Deaths: %s Time: %s" % (money, deaths, stopwatch) 
     text_width, text_height = text_font.size(stat_text) 
     hud_rect = draw.rect(screen, (0, 0, 0), Rect(32, 32, text_width, text_height)) 
     textobj = text_font.render(stat_text, 1, (255, 255, 255)) 
     textrect = textobj.get_rect() 
     textrect.topleft = (32, 32) 
     screen.blit(textobj, textrect) 
     display.update() 

     for e in event.get(): 
      if e.type == QUIT: 
       quit() 
       raise SystemExit, "ESCAPE" 
      if e.type == KEYDOWN and e.key == K_ESCAPE: 
       quit() 
       raise SystemExit, "ESCAPE" 
      if e.type == KEYDOWN and e.key == K_F11: 
       if not fullscreen: 
        screen = display.set_mode(DISPLAY, FULLSCREEN, DEPTH) 
        fullscreen = True 
       else: 
        screen = display.set_mode(DISPLAY, FLAGS, DEPTH) 
        fullscreen = False 

      if e.type == KEYDOWN and e.key == K_UP: 
       up = True 
      if e.type == KEYDOWN and e.key == K_DOWN: 
       down = True 
      if e.type == KEYDOWN and e.key == K_LEFT: 
       left = True 
      if e.type == KEYDOWN and e.key == K_RIGHT: 
       right = True 
      if e.type == KEYDOWN and e.key == K_SPACE: 
       running = True 

      if e.type == KEYUP and e.key == K_UP: 
       up = False 
      if e.type == KEYUP and e.key == K_DOWN: 
       down = False 
      if e.type == KEYUP and e.key == K_RIGHT: 
       right = False 
      if e.type == KEYUP and e.key == K_LEFT: 
       left = False 

     # Draw background 
     for y in range(32): 
      for x in range(32): 
       screen.blit(bg, (x * 32, y * 32)) 

     camera.update(player) 

     # Update player, draw everything else 
     player.update(up, down, left, right, running, platforms) 
     for e in entities: 
      screen.blit(e.image, camera.apply(e)) 

class Camera(object): 
    def __init__(self, camera_func, width, height): 
     self.camera_func = camera_func 
     self.state = Rect(0, 0, width, height) 

    def apply(self, target): 
     return target.rect.move(self.state.topleft) 

    def update(self, target): 
     self.state = self.camera_func(self.state, target.rect) 

def simple_camera(camera, target_rect): 
    l, t, _, _ = target_rect 
    _, _, w, h = camera 
    return Rect(-l + HALF_WIDTH, -t + HALF_HEIGHT, w, h) 

def complex_camera(camera, target_rect): 
    l, t, _, _ = target_rect 
    _, _, w, h = camera 
    l, t, _, _ = -l + HALF_WIDTH, -t + HALF_HEIGHT, w, h 

    l = min(0, l)       # Stop scrolling at the left edge 
    l = max(-(camera.width - WIN_WIDTH), l) # Stop scrolling at the right edge 
    t = max(-(camera.height - WIN_HEIGHT), t) # Stop scrolling at the bottom 
    t = min(0, t)       # Stop scrolling at the top 
    return Rect(l, t, w, h) 

class Entity(sprite.Sprite): 
    def __init__(self): 
     sprite.Sprite.__init__(self) 

class Player(Entity): 
    def __init__(self, x, y): 
     global money, deaths 
     Entity.__init__(self) 
     self.xvel = 0 
     self.yvel = 0 
     self.x, self.y = x, y 
     money = 0 
     deaths = 0 
     self.onGround = False 
     self.bounce = False 
     self.image = Surface((32,32)) 
     self.image.fill(Color("#0000FF")) 
     self.image.convert() 
     self.rect = Rect(x, y, 32, 32) 

    def update(self, up, down, left, right, running, platforms): 
     if up: 
      # Only jump if on the ground and not bouncing 
      if self.onGround and not self.bounce: self.yvel -= 10 
     if self.bounce: 
      # Bounce 
      self.yvel -= 15 
      self.bounce = False 
     if down: 
      pass 
     if running: 
      self.xvel = 12 
     if left: 
      self.xvel = -5 
     if right: 
      self.xvel = 5 
     if not self.onGround: 
      # Only accelerate with gravity if in the air 
      self.yvel += 0.3 
      # Max falling speed 
      if self.yvel > 100: self.yvel = 100 
     if not(left or right): 
      self.xvel = 0 
     # Increment in x direction 
     self.rect.left += self.xvel 
     # Do x-axis collisions 
     self.collide(self.xvel, 0, platforms) 
     # Increment in y direction 
     self.rect.top += self.yvel 
     # Assuming we're in the air 
     self.onGround = False; 
     # Do y-axis collisions 
     self.collide(0, self.yvel, platforms) 

    def collide(self, xvel, yvel, platforms): 
     global entities 
     global money, deaths 
     for p in platforms: 
      # If the player collides with a platform 
      if sprite.collide_rect(self, p): 
       # If exit block, exit game 
       if isinstance(p, ExitBlock): 
        quit() 
        raise SystemExit, "ESCAPE" 
       # If death block, reset coords 
       if isinstance(p, DeathBlock): 
        self.rect = Rect(self.x, self.y, 32, 32) 
        self.yvel = 0 
        self.xvel = 0 
        deaths += 1 
        return 
       # If bounce block bounce 
       if isinstance(p, BounceBlock): 
        if yvel > 0: 
         self.bounce = True 
       # If checkpoint block set spawn point 
       if isinstance(p, CheckBlock): 
        self.x = p.rect.left 
        self.y = p.rect.top - 32 
       # If money block get money 
       if isinstance(p, MoneyBlock): 
        p.kill() 
        platforms.remove(p) 
        entities.remove(p) 
        money += 1 
        return 
       if xvel > 0: 
        self.rect.right = p.rect.left 
       if xvel < 0: 
        self.rect.left = p.rect.right 
       if yvel > 0: 
        self.rect.bottom = p.rect.top 
        self.onGround = True 
        self.yvel = 0 
       if yvel < 0: 
        self.rect.top = p.rect.bottom 

# Classes for the platforms 
class Platform(Entity): 
    def __init__(self, x, y): 
     Entity.__init__(self) 
     self.image = Surface((32, 32)) 
     self.image.convert() 
     self.image.fill(Color("#000000")) 
     self.rect = Rect(x, y, 32, 32) 

    def update(self): 
     pass 

class ExitBlock(Platform): 
    def __init__(self, x, y): 
     Platform.__init__(self, x, y) 
     self.image.fill(Color("#17950A")) 

class DeathBlock(Platform): 
    def __init__(self, x, y): 
     Platform.__init__(self, x, y) 
     self.image.fill(Color("#E31111")) 

class BounceBlock(Platform): 
    def __init__(self, x, y): 
     Platform.__init__(self, x, y) 
     self.image.fill(Color("#E91EE3")) 

class CheckBlock(Platform): 
    def __init__(self, x, y): 
     Platform.__init__(self, x, y) 
     self.image.fill(Color("#00FBFF")) 

class MoneyBlock(Platform): 
    def __init__(self, x, y): 
     Platform.__init__(self, x, y) 
     self.image.fill(Color("#E8E209")) 

if __name__ == "__main__": 
    main() 

ワウ。

S: Player's start point.

D: Death block.

B: Bounce block.

C: Checkpoint block.

:別の長いスクリプト...

とにかく、私はこのチャートを使用して、テキストエディタでLinux上のレベルを作りましたM: Money block.

E: Exit block.

私のスクリプトはtkFileDialogを使用して上記の形式で.lvlファイルを要求して、レベルを構築します。私のLinuxマシン(解像度1280x1024)ではうまく動作しますが、MacBook AirとVAIOラップトップで動作する場合は動作しません。レベルは正しく生成されません(レベルレイアウトは期待通りにロードされません)。

誰が何が起こっているのか、それを修正する方法はありますか?私は自分のゲームがクロスプラットフォームであることを本当に願っています。誰かがうまく動作する解決策を持っていれば幸いです...

+2

「レベルが正しく生成されない」とはどういう意味ですか?より具体的にする必要があります。 – BrenBarn

+0

デバッグのヘルプを求める質問(** "なぜこのコードは機能していないのですか?")は、質問自体に*必要な動作、*特定の問題またはエラー*、* *を再現するのに必要な最短コード* **。 **明確な問題文**のない質問は他の読者には役に立たない。参照:[最小限で完全で検証可能な例を作成する方法](http://stackoverflow.com/help/mcve)つまり、335行のコードを削除せずに、私たちがあなたのためにデバッグすることを期待してください。 – MattDMo

答えて

1

ファイルをLinuxで作成すると、レベルファイルの行区切り文字はウィンドウ "\ r \ n"の下で "\ n"を使いますそれがうまくいかない理由かもしれません。私はあなたがファイルを行に分割するために "\ n"の代わりにos.linesepを使うべきだと思います。

level = levelFile.read().split(os.linesep) 
関連する問題