gpt4 book ai didi

python - 蛇将 "flow"而不是 "snap"分段到蛇的头部位置

转载 作者:太空宇宙 更新时间:2023-11-04 02:07:44 24 4
gpt4 key购买 nike

我正在尝试用 python 制作蛇游戏,我希望蛇的片段在用户按下 WASD 键时流动,而不是片段捕捉到用户所需的方向

import pygame
import random
import time
pygame.init()
win = pygame.display.set_mode((800,600))
pygame.display.set_caption("Pygame")
clock = pygame.time.Clock()
x = 30
y = 30
x2 = x
y2 = random.randrange(1,601-30)
vel = 2
run = True
facing = 0
direction = 0
text = pygame.font.SysFont('Times New Roman',30)
score = 0
segments = []
green = ((0,128,0))
white = ((255,255,255))
counting = 0
segmentTime = time.time()
class segmentClass():
def __init__(self,x,y,pos,color):
self.x = x
self.y = y
self.pos = pos
self.color = color
def draw(self,win):
pygame.draw.rect(win,(self.color),(self.x,self.y,30,30))
def gameOver():
global run
run = False
def segmentGrowth():
global x2
global y2
global score
global vel
global ammount
segments.append(segmentClass(x,y,len(segments)+1,green))
ammount = 0
x2 = random.randrange(1,801-30)
y2 = random.randrange(1,601-30)
score += 1
print(vel)
while run:
currentTime = time.time()
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
vel += (score*0.0001)
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
if direction != 1:
direction = 1
facing = -1
if keys[pygame.K_s]:
if direction != 1:
direction = 1
facing = 1
if keys[pygame.K_a]:
if direction != 0:
direction = 0
facing = -1
if keys[pygame.K_d]:
if direction != 0:
direction = 0
facing = 1
if direction == 1:
y += (vel*facing)
else:
x += (vel*facing)
if x > x2 and x < x2 + 30 or x + 30 > x2 and x + 30 < x2 + 30:
if y == y2:
segmentGrowth()
if y > y2 and y < y2 + 30 or y + 30 > y2 and y + 30 < y2 + 30:
segmentGrowth()
if y > y2 and y < y2 + 30 or y + 30 > y2 and y + 30 < y2 + 30:
if x == x2:
segmentGrowth()
if x > x2 and x < x2 + 30 or x + 30 > x2 and x + 30 < x2 + 30:
segmentGrowth()
if x > 800-30 or y > 600-30 or x < 0 or y < 0:
gameOver()
win.fill((0,0,0))
for segment in segments:
if direction == 0: #X value
if facing == 1: #Right
segment.x = x - (35 * segment.pos)
segment.y = y
else: #Left
segment.x = x + (35 * segment.pos)
segment.y = y
else: #Y value
if facing == -1: #Up
segment.y = y + (35 * segment.pos)
segment.x = x
else:#Down
segment.y = y - (35 * segment.pos)
segment.x = x
for segment in segments:
segment.draw(win)
scoreDisplay = text.render(str(score),1,(255,255,255))
win.blit(scoreDisplay,(760,0))
pygame.draw.rect(win,(0,128,0),(x,y,30,30))
pygame.draw.rect(win,(255,0,0),(x2,y2,30,30))
pygame.display.update()
pygame.quit()

它的工作原理是有一个段列表和每个段的信息类(即 x、y 等)。每当用户与红色立方体发生碰撞时,我都会在该列表中附加一个段类的实例。我有这段代码:

for segment in segments:
if direction == 0: #X value
if facing == 1: #Right
segment.x = x - (35 * segment.pos)
segment.y = y
else: #Left
segment.x = x + (35 * segment.pos)
segment.y = y
else: #Y value
if facing == -1: #Up
segment.y = y + (35 * segment.pos)
segment.x = x
else:#Down
segment.y = y - (35 * segment.pos)
segment.x = x

当玩家决定他们希望蛇移动的方向时,这将同时移动蛇的所有部分。但是,这些片段会立即捕捉到头部的 x 位置,而不是一次平滑地移动一个片段。如果有人可以帮助我解决这个问题,那就太好了。谢谢!

最佳答案

不错的游戏。我建议创建一个点列表,它是蛇头位置的元组列表 ((x, y))。将每个位置添加到列表中:

pts = []
while run:

# [...]

pts.append((x, y))

创建一个函数,通过从蛇的头部开始计算的索引 (i) 来计算蛇的一部分的位置。到头部的距离必须是 lenToI = i * 35
到点之间的距离可以通过 Euclidean distance 来计算(math.sqrt((px-pnx)*(px-pnx) + (py-pny)*(py-pny)),其中点为(px, py)(pnx, pny). 如果点之间的距离之和 (lenAct) 超过指向的长度 (lenToI ), 然后找到 i 部分的位置:

def getPos(i):
global pts
lenToI = i * 35
lenAct = 0
px, py = pts[-1]
for j in reversed(range(len(pts)-1)):
px, py = pts[j]
pnx, pny = pts[j+1]
lenAct += math.sqrt((px-pnx)*(px-pnx) + (py-pny)*(py-pny))
if lenAct >= lenToI:
break
return (px, py)

编写另一个函数cutPts,它从列表中删除不再需要的点:

def cutPts(i):
global pts
lenToI = i * 35
lenAct = 0
cut_i = 0
px, py = pts[0]
for j in reversed(range(len(pts)-1)):
px, py = pts[j]
pnx, pny = pts[j+1]
lenAct += math.sqrt((px-pnx)*(px-pnx) + (py-pny)*(py-pny))
if lenAct >= lenToI:
break
cut_i = j
del pts[:cut_i]

在循环中更新段的位置:

pts.append((x, y))
for i in range(len(segments)):
segments[i].x, segments[i].y = getPos(len(segments)-i)
cutPts(len(segments)+1)


关于评论:

how would I go about calling the gameOver() function if the head of the snake touches any of its segments? I tried using an if statement to check for collision (the same way I did for the apple) using segment.x and segment.y but this won't work since the second segment of the snake always overlaps the head when the snake moves.

请注意,头部永远不会“接触”第一段,除非方向更改为相反方向,但这种情况可以通过额外的测试轻松处理。
检查头部是否“击中”任何部分就足够了,除了第一个连接到头部的部分。
使用 pygame.Rect.colliderect检查矩形段的交集:

def selfCollide():    
for i in range(len(segments)-1):
s = segments[i]
if pygame.Rect(x, y, 30, 30).colliderect(pygame.Rect(s.x, s.y, 30, 30)):
return True
return False
if selfCollide():
gameOver()

关于python - 蛇将 "flow"而不是 "snap"分段到蛇的头部位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54273041/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com