2017-09-12 2 views
3

私は一般的に(約1週間の知識の)一般的なpythonには新しく、もっと大きなプロジェクトを考えてかなり基本的なパイゲームを作っています。私が書いたパイゲームは、なぜそれが起こるのかわからない、それがゲームを始めるとキャラクターが見えないことがあるということを除いて、どうすればよいのですか?これはタイルごとに変化し、ゲームが始まるたびに異なるタイルになります。今私は私の人生のために、なぜこれが起こっているのか理解できず、ここで誰かが私ができないものを見るかもしれないことを望んでいました。なぜパイゲームのプレイヤーキャラクターはタイルの後ろに消えても、まだ動きますか?

ありがとうございます。ここにいくつかの画像があります。

The first start up, player invisible in top left

First tile found where player is visible

私の主:

import pygame as pg 
import sys 
from os import path 
from settings import * 
from sprites import * 
from tilemap import * 

class Game: 
def __init__(self): 
    pg.init() 
    self.screen = pg.display.set_mode((WIDTH, HEIGHT)) 
    pg.display.set_caption(TITLE) 
    self.clock = pg.time.Clock() 
    pg.key.set_repeat(500, 100) 
    self.load_data() 

def load_data(self): 
    game_folder = path.dirname(__file__) 
    img_folder = path.join(game_folder, 'img') 
    self.map = Map(path.join(game_folder, 'map.txt')) 
    self.player_img = pg.image.load(path.join(img_folder, PLAYER)).convert_alpha() 
    self.floor_img = pg.image.load(path.join(img_folder, FLOOR)).convert() 
    self.wall_img = pg.image.load(path.join(img_folder, WALL)).convert() 
    self.water_img = pg.image.load(path.join(img_folder, WATER)).convert() 
    self.goal_img = pg.image.load(path.join(img_folder, GOAL)).convert() 

def new(self): 
    # initialize all variables and do all the setup for a new game 
    self.all_sprites = pg.sprite.Group() 
    self.walls = pg.sprite.Group() 
    self.floors = pg.sprite.Group() 
    self.water = pg.sprite.Group() 
    self.goal = pg.sprite.Group() 
    for row, tiles in enumerate(self.map.data): 
     for col, tile in enumerate(tiles): 
      if tile == 'X': 
       Wall(self, col, row) 
      if tile == 'W': 
       Water(self, col, row) 
      if tile == '.': 
       Floor(self, col, row) 
      if tile == 'G': 
       Goal(self, col, row) 
      if tile == 'P': 
       self.player = Player(self, col, row) 
       Floor(self, col, row) 

    self.camera = Camera(self.map.width, self.map.height) 

def run(self): 
    # game loop - set self.playing = False to end the game 
    self.playing = True 
    while self.playing: 
     self.dt = self.clock.tick(FPS)/1000 
     self.events() 
     self.draw() 
     self.update() 

def quit(self): 
    pg.quit() 
    sys.exit() 

def update(self): 
    # update portion of the game loop 
    self.all_sprites.update() 
    self.camera.update(self.player) 

def draw(self): 
    for sprite in self.all_sprites: 
     self.screen.blit(sprite.image, self.camera.apply(sprite)) 
    pg.display.flip() 

def events(self): 
    # catch all events here 
    for event in pg.event.get(): 
     if event.type == pg.QUIT: 
      self.quit() 
     if event.type == pg.KEYDOWN: 
      if event.key == pg.K_ESCAPE: 
       self.quit() 
      if event.key == pg.K_LEFT: 
       self.player.move(dx=-1) 
      if event.key == pg.K_RIGHT: 
       self.player.move(dx=1) 
      if event.key == pg.K_UP: 
       self.player.move(dy=-1) 
      if event.key == pg.K_DOWN: 
       self.player.move(dy=1) 

# create the game object 
g = Game() 
while True: 
g.new() 
g.run() 

マイセッティング:

DARKGREY = (40, 40, 40) 

# game settings 
WIDTH = 1280 # 16 * 64 or 32 * 32 or 64 * 16 
HEIGHT = 720 # 16 * 48 or 32 * 24 or 64 * 12 
FPS = 60 
TITLE = "Code Avontuur" 
BGCOLOR = DARKGREY 

TILESIZE = 100 
GRIDWIDTH = WIDTH/TILESIZE 
GRIDHEIGHT = HEIGHT/TILESIZE 

PLAYER = 'player.png' 
WALL = 'wall.jpg' 
FLOOR = 'floor.jpg' 
WATER = 'water.jpg' 
GOAL = 'goal.jpg' 

マイマップ:

XXXXXXXXXXXXXXXX 
XP.....X.....XWX 
XXX.XX.XXX.XXXXX 
XXX..X.XX..XXXXX 
XXXX...X..XXXXXX 
XWWWX.XX.XXWWWWX 
XXXXX....XXXXXXX 
XXXXXXXX......GX 
XXXXXXXXXXXXXXXX 
個の

マイスプライト:

import pygame as pg 
from PIL import Image 
from settings import * 

class Player(pg.sprite.Sprite): 
def __init__(self, game, x, y): 
    self.groups = game.all_sprites 
    pg.sprite.Sprite.__init__(self, self.groups) 
    self.game = game 
    self.image = game.player_img 
    self.rect = self.image.get_rect() 
    self.x = x 
    self.y = y 

def move(self, dx=0, dy=0): 
    if not self.collide(dx, dy): 
     self.x += dx 
     self.y += dy 

def collide(self, dx=0, dy=0): 
    for wall in self.game.walls: 
     if wall.x == self.x + dx and wall.y == self.y + dy: 
      return True 
    for water in self.game.water: 
     if water.x == self.x +dx and water.y == self.y +dy: 
      return True 
    return False 

def update(self): 
    self.rect.x = self.x * TILESIZE 
    self.rect.y = self.y * TILESIZE 

class Wall(pg.sprite.Sprite): 
def __init__(self, game, x, y): 
    self.groups = game.all_sprites, game.walls 
    pg.sprite.Sprite.__init__(self, self.groups) 
    self.game = game 
    self.image = game.wall_img 
    self.rect = self.image.get_rect() 
    self.x = x 
    self.y = y 
    self.rect.x = x * TILESIZE 
    self.rect.y = y * TILESIZE 

class Water(pg.sprite.Sprite): 
def __init__(self, game, x, y): 
    self.groups = game.all_sprites, game.water 
    pg.sprite.Sprite.__init__(self, self.groups) 
    self.game = game 
    self.image = game.water_img 
    self.rect = self.image.get_rect() 
    self.x = x 
    self.y = y 
    self.rect.x = x * TILESIZE 
    self.rect.y = y * TILESIZE 

class Floor(pg.sprite.Sprite): 
def __init__(self, game, x, y): 
    self.groups = game.all_sprites, game.floors 
    pg.sprite.Sprite.__init__(self, self.groups) 
    self.game = game 
    self.image = game.floor_img 
    self.rect = self.image.get_rect() 
    self.x = x 
    self.y = y 
    self.rect.x = x * TILESIZE 
    self.rect.y = y * TILESIZE 

class Goal(pg.sprite.Sprite): 
def __init__(self, game, x, y): 
    self.groups = game.all_sprites, game.goal 
    pg.sprite.Sprite.__init__(self, self.groups) 
    self.game = game 
    self.image = game.goal_img 
    self.rect = self.image.get_rect() 
    self.x = x 
    self.y = y 
    self.rect.x = x * TILESIZE 
    self.rect.y = y * TILESIZE 

マイマップハンドラ:

import pygame as pg 
from settings import * 

class Map: 
def __init__(self, filename): 
    self.data = [] 
    with open(filename, 'rt') as f: 
     for line in f: 
      self.data.append(line.strip()) 

    self.tilewidth = len(self.data[0]) 
    self.tileheight = len(self.data) 
    self.width = self.tilewidth * TILESIZE 
    self.height = self.tileheight * TILESIZE 

class Camera: 
def __init__(self, width, height): 
    self.camera = pg.Rect(0, 0, width, height) 
    self.width = width 
    self.height = height 

def apply(self, entity): 
    return entity.rect.move(self.camera.topleft) 

def update(self, target): 
    x = -target.rect.x + int(WIDTH/2) 
    y = -target.rect.y + int(HEIGHT/2) 

    #Limit scrolling off map 
    x = min(0, x) 
    y = min(0, y) 
    x = max(-(self.width - WIDTH), x) 
    y = max(-(self.height - HEIGHT), y) 
    self.camera = pg.Rect(x, y, self.width, self.height) 

私は立ち往生し、この時点で失わだから、ここで誰もが、私はカントものを見ることができると思います。

+2

だ - 多くのへの私のために。 [最小限で完全で検証可能なサンプルを作成する方法](http://stackoverflow.com/help/mcve)で説明されているように、問題を示すコードを最小限に抑えてください。これを行うことで問題が発生する可能性があります。 –

+1

私はpygameにはあまり慣れていませんが、あなたのスプライトがバッファー上に描画される順序を調べたいと思うかもしれません。または、スプライトに深さパラメータが添付されている場合はどうなりますか? (その場合、あなたはあなたのヒーローが常に上になるようにしたいと思うでしょう) –

答えて

4

あなたの問題は、スプライトが描画される順序です。

通常のGroupの代わりにLayeredUpdatesグループを使用してください。

スプライトに_layerプロパティ(*)を付けます。この方法で、スプライトが画面上に描画される順序を制御できます。

Here's例です。あなたのGameクラスに


変更:あなたのPlayerクラスに

... 
def new(self): 
    # initialize all variables and do all the setup for a new game 
    self.all_sprites = pg.sprite.LayeredUpdates() # <<--- change here 
    self.walls = pg.sprite.Group() 
    self.floors = pg.sprite.Group() 
    self.water = pg.sprite.Group() 
    self.goal = pg.sprite.Group() 
    ... 

変更:

class Player(pg.sprite.Sprite): 
    def __init__(self, game, x, y): 
     self.groups = game.all_sprites 
     pg.sprite.Sprite.__init__(self, self.groups) 
     self.game = game 
     self.image = game.player_img 
     self.rect = self.image.get_rect() 
     self.x = x 
     self.y = y 
     self._layer = 1 # <<--- add this line 

編集:

あなたが実際に描画のためのグループを使用していないので、あなたは、単純なGroupとしてそれを残して、ちょうど層によってスプライトをソートするために、あなたのドロー機能を変更することができます:

for sprite in sorted(self.all_sprites, lambda i, s: s._layer): 
    ... 

やPython 3:

for sprite in sorted(self.all_sprites, key=lambda s: s._layer): 
    ... 

は*ドキュメントはlayerを言いますが、それは実際に私たちが目を通すするために多くのコードがある_layer

+0

それは、それは今完璧に機能しました!本当にありがとう!私はこのため、壁と水に_layer = 0を追加しなければならなかったということを追加したいと思います。 クラスのようにクラス 'water(pg.sprite.Sprite): def __init __(self、game、x、 Y): self.groups = game.all_sprites、game.water pg.sprite.Sprite .__のinit __(自己、self.groups) self.game =ゲーム self.image = game.water_img self.rect =自己.image.get_rect() self.x = X self.y = Y self._layer = 0 < - THIS self.rect.x = X *タイルサイズ self.rect.y = Y * TILESIZE' –

+0

うれしいです私は助けることができた。コードをgithubまたはbitbucketに保存していますか?誰かがランニングゲームをダウンロードできるだけなら、そのような質問に答える方が簡単です。 – sloth

+0

Haventはそれらを前に使った、私は未来のためにそれを調べるだろう!もう一度ありがとう、私は今これに付随するはずのハードウェア部分に焦点を当てることができます! (これはこれまでの私の最初の記事でした。 –

関連する問題