我正试图吸引一个叫做fudd_img的敌人来追随以bear_img身份扮演的玩家。 fudd_img应该比播放器本身慢。
我尝试使用以下行:
if bear_rect_x > fudd_rect_x:
fudd_rect_x = fudd_rect_x + max(2, bear_rectx - fudd_rect_x)
elif bear_rect_x < fudd_rect_x:
fudd_rect_x = fudd_rect_x - max(2, fudd_rect_x - bear_rect_x)
但是,fudd_img会完全充当bear_img,而不是查找bear_img的路径。每当我尝试将其转换为y时,它都将不起作用,并且fudd_img不会沿y轴移动。
import random
import pygame
import sys
import time
import math
# --- constants --- (UPPER_CASE_NAMES)
GREEN = (24, 255, 0)
WHITE = (255, 255, 255)
BLACK = (0,0,0)
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
SW2 = SCREEN_WIDTH/2
SH2 = SCREEN_HEIGHT/2
#---
camerax = 0
cameray = 0
# --- functions ---
def text_objects(text, font):
surface = font.render(text, True, BLACK)
return surface, surface.get_rect()
def message_display(text):
surface, rect = text_objects(text, CLOCKTXT)
rect.center = (58, 15)
screen.blit(surface, rect)
#pygame.display.update() # use update() only in one place
#generate random pos for fish and grass
def getRandomOffCameraPos(camerax, cameray, objWidth, objHeight):
camera_rect = pygame.Rect(camerax, cameray, SCREEN_WIDTH, SCREEN_HEIGHT)
x1 = camerax - SCREEN_WIDTH
x2 = camerax + (2*SCREEN_WIDTH)
y1 = cameray - SCREEN_HEIGHT
y2 = cameray + (2*SCREEN_HEIGHT)
while True:
x = random.randint(x1, x2)
y = random.randint(y1, y2)
obj_rect = pygame.Rect(x, y, objWidth, objHeight)
if not obj_rect.colliderect(camera_rect):
return x, y
def makeNewGrass(camerax, cameray):
w, h = 80, 80
x, y = getRandomOffCameraPos(camerax, cameray, w, h)
images = grasspic
item = {
'image': random.choice(images),
'rect': pygame.Rect(x, y, w, h),
}
return item
def makeNewFish(camerax, cameray):
w, h = 50, 50
x, y = getRandomOffCameraPos(camerax, cameray, w, h)
images = fishpic
item = {
'image': random.choice(images),
'rect': pygame.Rect(x, y, w, h),
}
return item
def makegrass(number=15):
for i in range(number):
item = makeNewGrass(camerax, cameray)
item['rect'].x = random.randint(0, SCREEN_WIDTH-item['rect'].width)
item['rect'].y = random.randint(0, SCREEN_HEIGHT-item['rect'].height)
allgrass.append(item)
def makefish(number=2):
for i in range(number):
item = makeNewFish(camerax, cameray)
item['rect'].x = random.randint(0, SCREEN_WIDTH-item['rect'].width)
item['rect'].y = random.randint(0, SCREEN_HEIGHT-item['rect'].height)
allfish.append(item)
def score_draw(score):
message_display("Score is: " + str(score))
#--- main ---
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Hungry Boi')
CLOCKTXT = pygame.font.Font('freesans.ttf', 20)
# ---
bear_img = pygame.image.load('bear.png')
bear_img = pygame.transform.scale(bear_img, (150, 150))
bear_rect = bear_img.get_rect()
bear_rect.x = SCREEN_WIDTH * 0.4
bear_rect.y = SCREEN_HEIGHT * 0.4
bear_vel = 5
fudd_img = pygame.image.load('fudd.png')
fudd_img = pygame.transform.scale(fudd_img, (150,150))
fudd_rect = fudd_img.get_rect()
fudd_rect.x = SCREEN_WIDTH * 0.4
fudd_rect.y = SCREEN_HEIGHT * 0.4
fudd_vel = 2
grasspic = []
for i in range(1, 5):
image = pygame.image.load('grass%s.png' % i)
grasspic.append(image)
fishpic = []
for i in range(1, 3):
image = pygame.image.load('fish%s.png' % i)
image = pygame.transform.scale(image, (50, 50))
fishpic.append(image)
# ---
allgrass = []
makegrass()
allfish = []
makefish()
x_change = 0
y_change = 0
score = 0
time = 60
# --- mainloop ---
gameExit = False
clock = pygame.time.Clock()
while not gameExit:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change -= bear_vel
elif event.key == pygame.K_RIGHT:
x_change += bear_vel
elif event.key == pygame.K_UP:
y_change -= bear_vel
elif event.key == pygame.K_DOWN:
y_change += bear_vel
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_change += bear_vel
elif event.key == pygame.K_RIGHT:
x_change -= bear_vel
elif event.key == pygame.K_UP:
y_change += bear_vel
elif event.key == pygame.K_DOWN:
y_change -= bear_vel
# --- updates ---
bear_rect.x += x_change
bear_rect.y += y_change
keep_fish = []
for fish in allfish:
if not bear_rect.colliderect(fish['rect']):
keep_fish.append(fish)
else:
makefish(1)
#makegrass()
score += 1
allfish = keep_fish
# --- time down ---
for i in range(60):
time -= 1
# --- draws ---
screen.fill(GREEN)
for grass in allgrass:
screen.blit(grass['image'], grass['rect'].move(camerax, cameray))
for fish in allfish:
screen.blit(fish['image'], fish['rect'].move(camerax, cameray))
screen.blit(bear_img, bear_rect.move(camerax, cameray))
screen.blit(fudd_img, fudd_rect.move(camerax, cameray))
score_draw(score)
pygame.display.update()
# --- FPS ---
clock.tick(30) #fps//may not be safe to run really fast
# --- end ---
pygame.quit()
如何让fudd_img跟随玩家,bear_img而不是跟随玩家顶部并在游戏的左上角生成?我希望以后,这将使碰撞系统更容易工作。
谢谢
答案 0 :(得分:1)
如果必须沿直线行驶且没有任何障碍,则可以使用pygame.math.Vector2D进行所有计算。它具有使它变得更简单的所有必需功能,并且使用float
值,因此移动可以更平滑。
首先,我将职位从pygame.Rect
转换为pygame.math.Vector2D
player_vector = pygame.math.Vector2(player_rect.center)
enemy_vector = pygame.math.Vector2(enemy_rect.center)
接下来,我计算两个对象之间的差异(它仍然给出矢量)
diff = player_vector - enemy_vector
如果我将其添加到敌人的位置,那么它将获得玩家的位置-敌人将使玩家一步一步,但我需要具有相同方向的较短矢量来使敌人移动得更慢-使其逐步移动。
如果我对向量进行归一化,那么我得到的向量方向相同但较短。它的长度是1。
move = diff.normalize()
现在我可以将其添加到敌人的位置,以向玩家的方向迈出一步。
enemy_vector += move
现在我可以使用新位置将其转换回pygame.Rect中的位置
enemy_rect.center = enemy_vector
并在屏幕上绘制
pygame.draw.rect(screen, GREEN, player_rect)
pygame.draw.rect(screen, RED, enemy_rect)
如果我想更快地移动,可以乘以归一化向量
move = diff.normalize() * 2
player_vector = pygame.math.Vector2(player_rect.center)
enemy_vector = pygame.math.Vector2(enemy_rect.center)
diff = player_vector - enemy_vector
move = diff.normalize() * 2
enemy_vector += move
enemy_rect.center = enemy_vector
pygame.draw.rect(screen, GREEN, player_rect)
pygame.draw.rect(screen, RED, enemy_rect)
为了使移动更平滑,我将敌人的位置保留在Vector中(作为浮点值)并转换为pygame。Rect仅作画。
完整的示例。玩家处于中心位置,敌人从随机位置开始向玩家移动。它还显示对象之间的线。您可以使用箭头移动播放器。
import pygame
import random
# --- constants --- (UPPER_CASE_NAMES)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 600
SCREEN_WIDTH_HALF = SCREEN_WIDTH//2
SCREEN_HEIGHT_HALF = SCREEN_HEIGHT//2
#--- main ---
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
player_rect = pygame.Rect(0, 0, 16, 16)
player_rect.center = (SCREEN_WIDTH_HALF, SCREEN_HEIGHT_HALF)
player_speed = 2
enemy_rect = pygame.Rect(0, 0, 16, 16)
enemy_rect.centerx = random.randint(0, SCREEN_WIDTH)
enemy_rect.centery = random.randint(0, SCREEN_HEIGHT)
enemy_speed = 2
enemy_vector = pygame.math.Vector2(enemy_rect.center)
#old_rect = enemy_rect.copy()
clock = pygame.time.Clock()
run = True
while run:
clock.tick(15) # 120 FPS
#pygame.time.delay(5)
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# --- changes ---
keys = pygame.key.get_pressed()
# move player
if player_rect.top > 0 and keys[pygame.K_UP]:
player_rect.y -= player_speed
if player_rect.bottom < SCREEN_HEIGHT and keys[pygame.K_DOWN]:
player_rect.y += player_speed
if player_rect.left > 0 and keys[pygame.K_LEFT]:
player_rect.x -= player_speed
if player_rect.right < SCREEN_WIDTH and keys[pygame.K_RIGHT]:
player_rect.x += player_speed
# enemy follow player
player_vector = pygame.math.Vector2(player_rect.center)
diff = player_vector - enemy_vector
if diff.length() > 0.1:
move = diff.normalize() * enemy_speed
enemy_vector += move
enemy_rect.center = enemy_vector
# -- draws ---
screen.fill(BLACK)
pygame.draw.line(screen, WHITE, player_rect.center, enemy_rect.center)
pygame.draw.rect(screen, GREEN, player_rect)
pygame.draw.rect(screen, RED, enemy_rect)
#pygame.draw.rect(screen, WHITE, old_rect)
pygame.display.flip()
# --- end ---
pygame.quit()