您好,我正在使用pygame进行图形冒险/角色扮演。 有没有办法用pygame制作NPC,并能够与它们进行交互,就像对话一样? 我一直在互联网上搜索,但没有有用的结果。如果有人可以帮助我,那就太好了。
这是主要代码。
import pygame as pg
import sys
from os import path
from settings import *
from sprites import *
from tiledmap import *
from pgu import gui
from pygame.draw import circle
import pygame_ai as pai
import time
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()
self.load_data()
def load_data(self):
game_folder = path.dirname(__file__)
img_folder = path.join(game_folder, 'img')
map_folder = path.join(game_folder, 'maps')
self.map = TiledMap(path.join(map_folder, 'mapa_inici.tmx'))
self.map_img = self.map.make_map()
self.map_rect = self.map_img.get_rect()
self.player_img = pg.image.load(path.join(img_folder, PLAYER_IMG)).convert_alpha()
def new(self):
# iniciar totes les variables i fer tota la preparació per a una nova partida
self.all_sprites = pg.sprite.Group()
self.walls = pg.sprite.Group()
#for row, tiles in enumerate(self.map.data):
#for col, tile in enumerate(tiles):
#if tile == '1':
#Wall(self, col, row)
#if tile == 's':
#self.player = Player(self, col, row)
for tile_object in self.map.tmxdata.objects:
if tile_object.name == 'Jugador':
self.player = Player(self, tile_object.x, tile_object.y)
if tile_object.name == 'Muro':
Obstacle(self, tile_object.x, tile_object.y, tile_object.width, tile_object.height)
self.camera = Camera(self.map.width, self.map.height)
def run(self):
# bucle del joc - s'iguala self.playing = False per finalitzar el joc
self.playing = True
while self.playing:
self.dt = self.clock.tick(FPS) / 1000
self.events()
self.update()
self.draw()
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_grid(self):
for x in range(0, WIDTH, TILESIZE):
pg.draw.line(self.screen, LIGHTGREY, (x, 0), (x, HEIGHT))
for y in range(0, HEIGHT, TILESIZE):
pg.draw.line(self.screen, LIGHTGREY, (0, y), (WIDTH, y))
def draw(self):
self.screen.blit(self.map_img, self.camera.apply_rect(self.map_rect))
for sprite in self.all_sprites:
self.screen.blit(sprite.image, self.camera.apply(sprite))
pg.display.flip()
def events(self):
# tots els events
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()
g = Game()
while True:
g.new()
g.run()
精灵代码
import pygame as pg
from os import path
import sys
from settings import *
import pygame_ai as pai
from tiledmap import TiledMap
vec = pg.math.Vector2
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.vel = vec(0,0)
self.pos = vec(x, y)
self.rot = 0
def get_keys(self):
self.vel = vec(0,0)
keys = pg.key.get_pressed()
if keys[pg.K_LEFT] or keys[pg.K_a]:
self.vel.x = -PLAYER_SPEED
if keys[pg.K_RIGHT] or keys[pg.K_d]:
self.vel.x = PLAYER_SPEED
if keys[pg.K_UP] or keys[pg.K_w]:
self.vel.y = -PLAYER_SPEED
if keys[pg.K_DOWN] or keys[pg.K_s]:
self.vel.y = PLAYER_SPEED
if self.vel.x != 0 and self.vel.y != 0:
self.vel *= 0.7071
def collide_walls(self,dir):
if dir == 'x':
hits = pg.sprite.spritecollide(self, self.game.walls, False)
if hits:
if self.vel.x > 0:
self.pos.x = hits[0].rect.left - self.rect.width
if self.vel.x < 0:
self.pos.x = hits[0].rect.right
self.vel.x = 0
self.rect.x = self.pos.x
if dir == 'y':
hits = pg.sprite.spritecollide(self, self.game.walls, False)
if hits:
if self.vel.y > 0:
self.pos.y = hits[0].rect.top - self.rect.height
if self.vel.y < 0:
self.pos.y = hits[0].rect.bottom
self.vel.y = 0
self.rect.y = self.pos.y
def update(self):
self.get_keys()
self.pos += self.vel * self.game.dt
self.rect.x = self.pos.x
self.collide_walls('x')
self.rect.y = self.pos.y
self.collide_walls('y')
class Obstacle(pg.sprite.Sprite):
def __init__(self, game, x, y, w, h):
self.groups = game.walls
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.rect = pg.Rect(x, y, w, h)
self.x = x
self.y = y
self.rect.x = x
self.rect.y = y
The tile map code
import pygame as pg
import pytmx
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 TiledMap:
def __init__(self, filename):
tm = pytmx.load_pygame(filename, pixelalpha=True)
self.width = tm.width * tm.tilewidth
self.height = tm.height * tm.tileheight
self.tmxdata = tm
def render(self, surface):
ti = self.tmxdata.get_tile_image_by_gid
for layer in self.tmxdata.visible_layers:
if isinstance(layer, pytmx.TiledTileLayer):
for x, y, gid, in layer:
tile = ti(gid)
if tile:
surface.blit(tile, (x * self.tmxdata.tilewidth, y * self.tmxdata.tileheight))
def make_map(self):
temp_surface = pg.Surface((self.width, self.height))
self.render(temp_surface)
return temp_surface
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 apply_rect(self, rect):
return rect.move(self.camera.topleft)
def update(self, target):
x = -target.rect.centerx + int(WIDTH / 2)
y = -target.rect.centery + int(HEIGHT / 2)
# limit al seguiment del personatge
x = min(0,x) # esquerra
y = min(0,y) # part de dalt
x = max(-(self.width - WIDTH), x) # dreta
y = max(-(self.height - HEIGHT), y) # part de baix
self.camera = pg.Rect(x, y, self.width, self.height)
答案 0 :(得分:1)
在1960年代,有一个简单的类似对话的处理程序,名为Eliza。从那时起,发生了许多变化和变体,它们被称为“聊天机器人”。也许您的NPC可以与玩家进行类似Eliza的对话?可能需要对这类自然文本处理器进行一些研究。
但是,如果您的意思是仅从[(a),(b),(c)]类型列表中选择对话主题,则通常将这些对话映射到选择图中。您读过制作choices to change the narrative的故事吗?这些是简单的选择图。您可以将它们绘制在一张纸上,然后将它们编码为数据结构,例如python字典。每个选项将移动到图中的另一个节点。也许他们也回过头来。