2017-01-15 4 views
-4

J'ai travaillé sur un jeu de plateforme pygame, basé sur this. Je l'ai écrit sur une machine Linux sans fonctionnalités spécifiques à Linux, mais il ne semble pas fonctionner sur Mac ou Windows.Plate-forme de pygame non orientée Linux ne générant pas des niveaux correctement sur autre chose que Linux

Le code est le suivant:

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() 

Wow. Un autre long script ...

Quoi qu'il en soit, je fait un niveau sur Linux dans un éditeur de texte en utilisant ce tableau:

S: Player's start point.

D: Death block.

B: Bounce block.

C: Checkpoint block.

M: Money block.

E: Exit block.

Mon script demande un fichier .lvl dans le format ci-dessus à l'aide d'un tkFileDialog et construit ensuite le niveau. Cela fonctionne très bien sur ma machine Linux (résolution 1280x1024), mais pas sur un MacBook Air et un ordinateur portable VAIO. Les niveaux ne sont pas générés correctement (la configuration de niveau ne se charge pas comme prévu).

Est-ce que quelqu'un a une idée de ce qui se passe et comment y remédier? J'aimerais vraiment que mon jeu soit multi-plateforme. Espérons que quelqu'un a une solution qui fonctionne ...

+2

Qu'entendez-vous par "les niveaux ne génèrent pas correctement"? Tu dois être plus précis. – BrenBarn

+0

Questions demandant l'aide au débogage (** "pourquoi ce code ne fonctionne-t-il pas?" **) doit inclure le comportement souhaité, * un problème ou une erreur spécifique * et * le plus petit code nécessaire * pour le reproduire ** dans la question même **. Les questions sans ** un énoncé de problème clair ** ne sont pas utiles aux autres lecteurs. Voir: [Comment créer un exemple minimal, complet et vérifiable] (http://stackoverflow.com/help/mcve). Cela signifie ne pas laisser tomber 335 lignes de code et attendez-vous à ce que nous le déboguons pour vous. – MattDMo

Répondre

1

Les séparateurs de ligne dans votre fichier de niveau dépendent du système d'exploitation si vous créez votre fichier sous Linux il utilisera "\ n" sous Windows "\ r \ n", donc ceci pourrait être une raison pour laquelle cela ne fonctionne pas. Je pense que vous devriez utiliser os.linesep au lieu de "\ n" pour diviser le fichier en lignes.

level = levelFile.read().split(os.linesep)