如何制作一个物体'模仿'另外在python / pygame中?

时间:2016-01-26 16:34:08

标签: python pygame

好吧,我试图用pygame创建一个pacman,但我无法弄清楚如何对鬼魂和pacman进行迫害。我试过这个:

if keyup == True:
    y_position_pacman -= 1
    pygame.time.wait(50)
    y_position_ghost -= 1

它没有按照我想要的方式工作,只是落后于游戏。我想要的是幽灵跟随玩家。一个重要的观察是鬼需要找到玩家,而不仅仅是模仿他。我试图这么做很多时间,但我无法弄清楚如何做到这一点,帮助?

更新:我不知道是否有任何问题,但我是巴西人。所以我的代码是葡萄牙语。 Fanstasma是葡萄牙语中的幽灵,如果有帮助的话。 Paracima是键盘的变量,parabaixo,direita和esquerda分别用于向下,向右和向左。这是我的全部代码:

import pygame
# -*- coding: UTF-8 -*-
from random import randint
from pygame.locals import *
while True:
  reiniciar = True
  tamanho_da_tela = (600, 600)
  x = 0
  y = 240
  y_2 = y + 46
  x_2 = x + 46
  pygame.init()

  #cores
  branco = (255, 255, 255)
  preto = (0, 0, 0)
  pygame.display.set_caption("PacMan por: Jean (^J^)")
  surface = pygame.display.set_mode(tamanho_da_tela)

  #declaracao de todos os elementos
  pacman_aberto_direita = pygame.image.load ("pacman_aberto.png")
  pacman_fechado = pygame.image.load ("pacman_fechado.png")
  pacman_aberto_cima = pygame.image.load ("pacman_aberto_cima.png")
  pacman_aberto_esquerda = pygame.image.load ("pacman_aberto_esquerda.png")
  pacman_aberto_baixo = pygame.image.load ("pacman_aberto_baixo.png")
  fantasma = pygame.image.load ("fantasma.png")
  fantasma1 = pygame.image.load ("fantasma1.png")
  morte = pygame.mixer.Sound("pacman_death.wav")
  som = pygame.mixer.Sound("pacman_chomp.wav")
  muro = pygame.sprite.Sprite()
  muro.image = pygame.image.load("muro.png")
  pacman = pacman_aberto_direita
  movimentar = True

  #variaveis das posicoes dos fantasmas
  fx = 500
  fy = 100
  fx1 = 450
  fy1 = 100

  #mapa
  m = 1
  v = 0
  cores = {
    m : preto,
    v : branco
    }
  mapa = [ 
    [v,v,v,v,m,v,v,v,v,v,v,m],
    [v,v,v,m,m,v,m,m,m,m,m,v],
    [v,m,v,v,v,v,m,v,v,v,v,v],
    [v,m,v,m,m,v,m,v,v,v,m,v],
    [v,m,v,m,v,v,m,m,m,m,m,v],
    [v,m,v,m,v,v,v,v,v,v,v,v],
    [v,v,v,m,v,m,v,m,v,m,v,v],
    [v,m,v,m,v,m,v,m,v,m,v,m],
    [v,m,m,m,v,m,v,m,v,v,v,v],
    [v,v,v,v,v,m,v,m,v,m,m,v],
    [m,m,m,m,m,m,v,m,v,m,v,v],
    [v,v,v,v,v,v,v,v,v,v,v,m]
  ]
  tamanho_tile = 50
  altura_mapa = 12
  largura_mapa = 12

  def colided(column, row):
    if mapa[int(row/50)][int(column/50)] == m:
      return True
    else:  
      return False
  def colidec(column, row):
    if mapa[int(row/50)][int(column/50)] == m:
      return True
    else:  
      return False
  def colideb(column, row):
    if mapa[int(row/50)][int(column/50)] == m:
      return True
    else:  
      return False
  def colidee(column, row):
    if mapa[int(row/50)][int(column/50)] == m:
      return True
    else:  
      return False
  pacman = pacman_aberto_direita
  tamanho_tile_detect = 46

  def detectacolisao(x,y,tamanho_tile_detect,fx,fy,fx1,fy1):
    if (fx+tamanho_tile_detect>=x>=fx and fy+tamanho_tile_detect>=y>=fy):
        return True

elif (fx+tamanho_tile_detect>=x+tamanho_tile_detect>=fx and fy+tamanho_tile_detect>=y>=fy):
    return True

elif (fx+tamanho_tile_detect>=x>=fx and fy+tamanho_tile_detect>=y+tamanho_tile_detect>=fy):
    return True

elif (fx+tamanho_tile_detect>=x+tamanho_tile_detect>=fx and fy+tamanho_tile_detect>=y>=fy):
    return True

elif (fx1+tamanho_tile_detect>=x>=fx1 and fy1+tamanho_tile_detect>=y>=fy1):
    return True

elif (fx1+tamanho_tile_detect>=x+tamanho_tile_detect>=fx1 and fy1+tamanho_tile_detect>=y>=fy1):
    return True

elif (fx1+tamanho_tile_detect>=x>=fx1 and fy1+tamanho_tile_detect>=y+tamanho_tile_detect>=fy1):
    return True

elif (fx1+tamanho_tile_detect>=x+tamanho_tile_detect>=fx1 and fy1+tamanho_tile_detect>=y>=fy1):
    return True

else:
    return False

#loop para manter o jogo aberto

while reiniciar:

#limpeza da tela para nao bugar o grafico do pacman e outros elementos. cria um novo fundo todo fim de while
pygame.draw.rect( surface, (255, 255, 255),   (0, 0, 600, 600) )

#introducao do mapa (tiles)
for row in range(0, 12):
  for column in range(0, 12):
    pygame.draw.rect( surface, (255, 255, 255),   (row*tamanho_tile, column*tamanho_tile, 50, 50) )

clock = pygame.time.Clock()
clock.tick(60)

#facilitar o uso das teclas de direcao
paracima = pygame.key.get_pressed() [pygame.K_UP]
parabaixo = pygame.key.get_pressed() [pygame.K_DOWN]
direita = pygame.key.get_pressed() [pygame.K_RIGHT]
esquerda = pygame.key.get_pressed() [pygame.K_LEFT]

#introducao dos pontos
for row in range(0, 12):
  for column in range(0, 12):
    pygame.draw.rect( surface, cores[mapa[row][column]], (column*tamanho_tile, row*tamanho_tile, 50, 50) )

#introducao dos elementos na interface
surface.blit ( pacman, (x, y) )
surface.blit ( fantasma, (fx, fy) )
surface.blit ( fantasma1, (fx1, fy1) )

#era pra ser a inteligencia dos fantasmas


#movimentos do pacman
if paracima == True:
  pacman = pacman_aberto_cima
  if colidec(x, y - 2):
    pass
  else:
    y -= 2.5
    pygame.time.wait(50)
    fy -= 2.5
    fy1 -= 2.5

if parabaixo == True:
  pacman = pacman_aberto_baixo
  if colideb(x, y + 48):
    pass
  else:
    y += 2.5
    pygame.time.wait(50)
    fy += 2.5
    fy1 += 2.5

if direita == True:
  pacman = pacman_aberto_direita
  if colided(x + 48, y):
    pass
  else:
    x += 2.5
    pygame.time.wait(50)
    fx += 2.5
    fx1 += 2.5

if esquerda == True:
  pacman = pacman_aberto_esquerda
  if colidee(x - 2, y):
    pass
  else:
    x -= 2.5
    pygame.time.wait(50)
    fx -= 2.5
    fx1 -= 2.5

#colisao com os pontos
#for x in range(int(x, x + 50)) and y in range(int(y, y + 50)) == p1 or p2:"
  #p1 = v
  #p2 = v

#colisao do pacman com fantasma e fantasma1
if detectacolisao(x,y,tamanho_tile,fx,fy,fx1,fy1) == True:
  morte.play()
  pygame.time.wait(1800)
  reiniciar = False

#colisao do pacman e fantasmas
if x < 1:
  x += 2.5
if x > 553:
  x -= 2.5
if y < 1:
  y += 2.5
if y > 553:
  y -= 2.5

if fx < 0:
  fx += 2.5
if fx > 550:
  fx -= 2.5
if fy < 0:
  fy += 2.5
if fy > 550:
  fy -= 2.5

if fx1 < 0:
  fx1 += 2.5
if fx1 > 550:
  fx1 -= 2.5
if fy1 < 0:
  fy1 += 2.5
if fy1 > 550:
  fy1 -= 2.5

#evento de saida
for event in pygame.event.get():
  if event.type == pygame.QUIT:
      pygame.quit()

#nem lembro. atualizar a tela?
pygame.display.flip()

&#34; #movimentos do pacman&#34;是运动的一部分。 &#34; X&#34;是pacman的x坐标,fx是ghost的x坐标,fx1是ghost2&x 39的坐标。

3 个答案:

答案 0 :(得分:1)

time.wait(50)将整个程序停止50毫秒,这样就无法工作了。如果你的程序有一个主循环,那么在每个第10或第n个循环中如何执行ghost跟随运动?

答案 1 :(得分:1)

我首先想到的是,这里提出的问题是为什么比赛落后,因此另一个帖子。这篇文章包含了关于敌人幽灵寻找pacman玩家的信息。


解决方案1(非常无效)

<小时/> 你可以朝着pacman的方向移动幽灵。 (与答案中的解决方案不同,它将鬼魂移动到pacman给出的相同运动)。 通过这个,我的意思是如果pacman在幽灵的右边,鬼魂每一帧向右移动,直到它在pacman之上。编码示例如下:

def pathfindToPlayer():
    # X and Y are the ghost's location attributes
    pac_x, pac_y = pacman.x, pacman.y # Pacman's location attributes

    tomove_x = pac_x-self.x # Get difference between x locations
    tomove_x = cmp(abs(tomove_x), tomove_x) # Normalize to positive/negative 1

    # repeat with y values
    tomove_y = pac_y-self.y
    tomove_y = cmp(abs(tomove_y), tomove_y)

    # apply location offsets to ghost
    if tomove_x != 0: # try to move x before y, diagonal moves not allowed
        self.x += tomove_x
    else:
        self.y += tomove_y


解决方案2

<小时/> 这个解决方案涉及使用实际地图来确定它可以和不能移动的位置,同时仍然朝着pacman方向移动。

gamemap = [
    [0,   0, 0, 0, 0  ],
    ['p', 0, 0, 0, 0  ],
    [0,   1, 1, 1, 0  ],
    [0,   0, 0, 1, 0  ],
    [0,   0, 0, 1,'g' ]
]
def pathfindToPlayer():
    '''
    Same stuff here as the above function, without applying the offsets yet
    '''
    if gamemap[self.x+tomove_x][self.y] != 1: # If there isn't a wall
        self.x += tomove_x
    elif gamemap[self.x][self.y+tomove_y] != 1: # If there isn't a wall
        self.y += tomove_y
    else:
        print "Can't move closer to Pacman"


解决方案3 - 使用寻路算法

<小时/> 如果上述两种解决方案不够强大,无法满足您的需求,那么您可以使用众多寻路算法中的一种。我之所以选择上述两种解决方案的原因是因为它们很简单,很容易适应答案而不需要太多解释。

这里有一些链接可以帮助你找到寻路算法:

https://en.wikipedia.org/wiki/Pathfinding#Algorithms_used_in_pathfinding
https://gamedev.stackexchange.com/questions/28041/path-finding-algorithms
https://cstheory.stackexchange.com/questions/11855/how-do-the-state-of-the-art-pathfinding-algorithms-for-changing-graphs-d-d-l

答案 2 :(得分:0)

视觉游戏的事情是有一个叫做游戏循环的主要块。没有不同的线程或进程处理游戏逻辑,比如你提出的幽灵运动,那么你就不应该做任何阻止代码的事情。你想要做的是每隔更新幽灵的位置,而不是等待一定的时间。例如:

def gameLogic(keysPressed):
    if keysPressed["up"]: # Only one case for the movement, the rest is common sense
        y_position_pacman -= 1
    ghost.pathfindTo(id="player") # You'll have to implement this method yourself

# Main game loop
while gameRunning:
    keysPressed = handleInput()
    gameLogic(keysPressed)
    render()
    fpsClock.tick(60) # Tick the created fpsClock object to limit the game to 60 fps