【发布时间】:2021-01-06 08:22:55
【问题描述】:
我正在使用 pygame 制作 2D 游戏。我对 python 面向对象编程很陌生,不太了解类和对象,所以我的编码方法可能有点奇怪。我有一个播放器和实体类,以及一个键监听器来更改播放器 x 和 y(实际上是背景图片的 x/y 坐标)相对于按下的键。目前,我只有一个名为 Monster 的实体对象,因为为了正确移动玩家,我需要同时移动每个实体,否则实体将与玩家一起移动。 如何引用我同时创建的每一个实体,以便更改它们的 x 和 y 值,从而不必在关键侦听器函数中一一引用它们? 有一些 entity.objects.all() 之类的东西吗?如果有人可以提供帮助,谢谢,这是我的代码。
import os
import time
import threading
p.init()
c = p.time.Clock()
SCREEN_W = 800
SCREEN_H = 600
w = p.display.set_mode((SCREEN_W, SCREEN_H))
p.display.set_caption("Mason's Game")
walkRight = [p.image.load('game/r1.png'), p.image.load('game/r2.png'), p.image.load('game/r3.png'), p.image.load('game/r4.png'), p.image.load('game/r5.png'), p.image.load('game/r6.png'), p.image.load('game/r7.png'), p.image.load('game/r8.png'), p.image.load('game/r9.png')]
walkLeft = [p.image.load('game/l1.png'), p.image.load('game/l2.png'), p.image.load('game/l3.png'), p.image.load('game/l4.png'), p.image.load('game/l5.png'), p.image.load('game/l6.png'), p.image.load('game/l7.png'), p.image.load('game/l8.png'), p.image.load('game/l9.png')]
bg = p.image.load('game/bg.jpg')
char = p.image.load('game/standing.png')
mob = p.image.load('game/mob.png')
health = [p.image.load('game/h0.png'), p.image.load('game/h1.png'), p.image.load('game/h2.png'), p.image.load('game/h3.png'), p.image.load('game/h4.png'), p.image.load('game/h5.png'), p.image.load('game/h6.png'), p.image.load('game/h7.png'), p.image.load('game/h8.png'), p.image.load('game/h9.png'), p.image.load('game/h10.png'),]
def delay(x):
later = p.time.get_ticks() + x
if p.time.get_ticks() >= later:
pass
class entity(object):
def __init__(self, spawnx, spawny, x,y, level, health):
self.x=x
self.y=y
self.spawnx = spawnx
self.spawny= spawny
self.velocity=14
self.level = level
self.health = health
self.dead = False
def draw(self, w):
w.blit(mob, (self.x,self.y))
def printCoords(self):
print('x: ' , (-1*(m.x - monster.x) - 3600) - 300, " y: ", ((-1*(m.y - monster.y) - 3700) - 300)*-1)
def pace(self):
reachedRight = False
reachedLeft = False
if not reachedRight:
self.x += self.velocity/10
if self.x >= (self.spawnx + 100):
reachedRight = True
if reachedRight:
self.velocity *= -1
if self.x <= (self.spawnx - 100):
reachedLeft = True
if reachedLeft:
self.velocity*=-1
def stop(self):
self.velocity = 0
def followPlayer(self, player):
#if (abs(ogre.x - monster.x)) < 160 or (abs(ogre.y - monster.y)) < 160:
# monster.attackPlayer()
#if monster is left of player, close enough, but not too close
if self.x < player.x - 128 and self.x > player.x - 400:
self.velocity = 5
self.x += self.velocity
#if monster is right of player, close enough, but not too close
elif self.x > player.x + 128 and self.x < player.x + 400:
self.velocity = -5
self.x += self.velocity
#if monster is south of player, close enough, but not too close
if self.y < player.y - 128 and self.y > player.y - 400:
self.velocity = 5
self.y += self.velocity
#if monster is north of player, close enough, but not too close
elif self.y > player.y + 128 and self.y < player.y + 400:
self.velocity = -5
self.y += self.velocity
def attackPlayer(self, player):
def hitPlayer():
if player.health > 0:
player.sethealth(player.health - 1)
else:
player.death()
t=threading.Timer(5.0,hitPlayer)
t.start()
class mapp(object):
def __init__(self,x,y):
self.x= -3600
self.y= -3700
self.velocity = 14
self.left = False
self.right = False
self.standing = True
def draw(self, w):
w.blit(bg, (self.x,self.y))
class player(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 14
self.j = False
self.jc = 10
self.right = False
self.left = False
self.walk = 0
self.standing = True
self.health = 10
self.travX = (-3600 - m.x)
self.travY = (-3700 - m.y)
def respawn(self):
time.sleep(0.4)
monster.x = (-1*(m.x - monster.x) - 3600)
monster.y = (-1*(m.y - monster.y) - 3700)
m.x += (-3600 - m.x)
m.y += (-3700 - m.y)
#monster.y += (-1*(m.y - monster.y) - 3700)
def death(self):
self.sethealth(10)
self.respawn()
def sethealth(self, x):
self.health = x
def draw(self,w):
w.blit(health[self.health], (730, 20))
if self.walk + 1 >= 27:
self.walk = 0
if not(self.standing):
if self.left:
w.blit(walkLeft[self.walk//3], (self.x,self.y))
self.walk += 1
elif self.right:
w.blit(walkRight[self.walk//3], (self.x,self.y))
self.walk += 1
else:
if self.left:
w.blit(walkLeft[0], (self.x,self.y))
else:
w.blit(walkRight[0], (self.x,self.y))
def drawGame():
m.draw(w)
ogre.draw(w)
monster.draw(w)
monster.followPlayer(ogre)
p.display.update()
####### main ############
m = mapp(-3600,-3700)
ogre = player(400, 300, 64, 64)
monster = entity(-200, 600, -200, 600, 5, 100)
monster2 = entity(-300, 630, -300, 630, 5, 100)
####### main ############
run = True
while run:
c.tick(27)
for event in p.event.get():
if event.type == p.QUIT:
run = False
k = p.key.get_pressed()
#monster.printCoords()
### left right up down player ####
if k[p.K_a]:
monster.x +=m.velocity
monster.spawnx+=m.velocity
m.x+=m.velocity
ogre.left = True
ogre.right = False
ogre.standing = False
elif k[p.K_d]:
monster.x -=m.velocity
monster.spawnx-=m.velocity
m.x-=m.velocity
ogre.right = True
ogre.left = False
ogre.standing = False
elif k[p.K_w]:
monster.y +=m.velocity
monster.spawny+=m.velocity
m.y+=m.velocity
ogre.right = False
ogre.left = False
ogre.standing = True
elif k[p.K_s]:
monster.y -=m.velocity
monster.spawny-=m.velocity
m.y-=m.velocity
ogre.right = False
ogre.left = False
ogre.standing = True
elif k[p.K_j]:
#monster.attackPlayer()
ogre.death()
else:
ogre.standing = True
ogre.walk = 0
drawGame()
p.quit()```
【问题讨论】:
-
"我如何引用我同时创建的每一个实体,以便我可以更改它们的 x 和 y 值,这样我就不必在关键侦听器函数中一一引用它们? " - 创建实体列表并在
for-loop 中移动它们