我对python一般都是新手(大约一周的知识),我正在制作一个相当基本的pygame,并考虑到更大的项目。我写的pygame是如何应用的,除了一件我似乎无法弄清楚为什么会发生的事情,那就是当我开始游戏时,角色有时是看不见的。这从瓦片变为瓦片,每次游戏开始时都是不同的瓦片。现在我为我的生活无法弄清楚为什么会这样,我希望有人在这里看到我不能做的事。
先谢谢,这里有一些图片。
我的主要人物:
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)
我希望这里的任何人都可以看到我不能理解的东西,因为此时我已经陷入困境中。
答案 0 :(得分:4)
你的问题是画出精灵的顺序。
使用LayeredUpdates
组,而不是常规List<ObservableList<PieChart.Data>>
。
然后给你的精灵一个Group
属性(*)。这样,您就可以控制在屏幕上绘制精灵的顺序。
Here's一个例子。
对_layer
班级的更改:
Game
对...
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()
...
班级的更改:
Player
修改强>
由于您实际上没有使用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
或Python 3:
for sprite in sorted(self.all_sprites, lambda i, s: s._layer):
...
*文档说for sprite in sorted(self.all_sprites, key=lambda s: s._layer):
...
,但实际上是layer