敌人不在原地 [英] Enemy not staying at original spot
问题描述
因此,我一直在尝试让我的敌人在播放器移动相机但不起作用的同时向同一地点移动,当屏幕移动时,我的敌人将从其原先的位置缓慢移动,但一旦其离开原先的位置,它将开始小故障.另外,当我的玩家与平台的侧面碰撞时,我的敌人将以与我的玩家相同的方式移动,但速度更快,例如: https://gyazo.com/926207e82cd9849266decd68c08ea84d
So I been trying make my enemy move at the same spot while my player moves the camera but it's not working, when the screen moves my enemy will slowly move from its original spot but once its out of its original spot it will start glitching. Also when my player collides with a side of a platform my enemy will move the same way as my player but faster e.g.: https://gyazo.com/926207e82cd9849266decd68c08ea84d
相机运动的一部分(不起作用)
A part of my camera movement(Not working)
if keys[pygame.K_d]:
for Platform in platforms:
Platform.x -= playerman.speed
for Snake in snakes:
Snake.scroll(-playerman.speed,0)
for Rule in rules:
Rule.x -= playerman.speed
if not playerman.isJump:
playerman.direction = "right"
我的完整代码
import pygame
pygame.init()
window = pygame.display.set_mode((700,500))
pygame.display.set_caption("Noobs First Game")
move = pygame.image.load("WASD.png")
# Playerman
class Player:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.speed = 5
self.isJump = False
self.JumpCount = 10
self.idle =[pygame.image.load("player_idel_1.png"),
pygame.image.load("player_idel_2.png"),
pygame.image.load("player_idel_3.png"),
pygame.image.load("player_idel_4.png"),
pygame.image.load("player_idel_5.png"),
pygame.image.load("player_idel_6.png"),
pygame.image.load("player_idel_7.png"),
pygame.image.load("player_idel_8.png")
]
self.idlel = [pygame.image.load("Player_idel_left1.png"),
pygame.image.load("Player_idel_left2.png"),
pygame.image.load("Player_idel_left3.png"),
pygame.image.load("Player_idel_left4.png"),
pygame.image.load("Player_idel_left5.png"),
pygame.image.load("Player_idel_left6.png"),
pygame.image.load("Player_idel_left7.png"),
pygame.image.load("Player_idel_left8.png")
]
self.right = [pygame.image.load("Player_walk_right1.png"),
pygame.image.load("Player_walk_right2.png"),
pygame.image.load("Player_walk_right3.png")]
self.left = [pygame.image.load("Player_walk_left1.png"),
pygame.image.load("Player_walk_left2.png"),
pygame.image.load("Player_walk_left3.png")]
self.jump1 = [pygame.image.load("Player_jump5.png")]
self.jump2 = [
pygame.image.load("Player_rjump1.png")]
self.fall = 0
self.rect = pygame.Rect(x,y,height,width)
self.idle = [pygame.transform.scale(image,(image.get_width()*2,image.get_height()*2)) for image in self.idle]
self.idlel = [pygame.transform.scale(image,(image.get_width()*2,image.get_height()*2)) for image in self.idlel]
self.right = [pygame.transform.scale(image,(image.get_width()*2,image.get_height()*2)) for image in self.right]
self.left = [pygame.transform.scale(image,(image.get_width()*2, image.get_height()*2)) for image in self.left]
self.jump1 = [pygame.transform.scale(image,(image.get_width()*2,image.get_height()*2)) for image in self.jump1]
self.jump2 = [pygame.transform.scale(image,(image.get_width()*2,image.get_height()*2)) for image in self.jump2]
self.fps = 10
self.clock = pygame.time.Clock()
self.anim_index = 0
self.direction = "idle"
self.direction = "right"
self.direction = "left"
self.dierection = "idleleft"
self.dierection = "jump1"
self.dierection = "jump2"
self.next_frame_time = 0
def get_rect(self):
self.rect.topleft = (self.x,self.y)
return self.rect
pygame.draw.rect(self.color,self.rect)
def draw(self):
if self.direction == "idle":
image_list = self.idle
if self.direction == "right":
image_list = self.right
if self.direction == "left":
image_list = self.left
if self.direction == "idlel":
image_list = self.idlel
if self.direction == "jump1":
image_list = self.jump1
if self.direction == "jump2":
image_list = self.jump2
# Is it time to show the next animation frame?
time_now = pygame.time.get_ticks()
if ( time_now > self.next_frame_time ):
# set the time for the next animation-frame
inter_frame_delay = 1000 // self.fps
self.next_frame_time = time_now + inter_frame_delay # in the future
# move the current image to the next (with wrap-around)
self.anim_index += 1
if self.anim_index >= len( image_list ):
self.anim_index = 0
if self.anim_index >= len(image_list):
self.anim_index = 0
player_image = image_list[self.anim_index]
pygame.draw.rect( window, self.color, self.get_rect(), 2 )
player_image = image_list[self.anim_index]
player_rect = player_image.get_rect(center = self.get_rect().center)
player_rect.centerx += 3
player_rect.centery -= 13
window.blit(player_image, player_rect)
class Snake:
def __init__(self, x, y, width, height, end):
self.x = x
self.y = y
self.width = width
self.height = height
self.path = [x, end]
self.walkCount = 0
self.vel = 3
self.visible = True
self.no = pygame.image.load("Player_jump5.png")
self.rect = pygame.Rect(x,y,width,height)
def draw(self):
self.move()
self.rect.topleft = (self.x,self.y)
window.blit(self.no,self.rect)
def move(self):
if self.visible:
# turn around if the move would go out-of-bounds
proposed_move = self.x + self.vel
if ( proposed_move < self.path[0] or proposed_move > self.path[1] ):
# Move hits a boundary, so we need to turn around
self.vel = -self.vel
self.Walking_index = 0
# now make the correct move
self.x += self.vel # add +/- velocity
def scroll(self,sx,sy):
self.x += sx
self.y += sy
self.path[0] += sx
self.path[1] += sx
class Platform:
def __init__(self,x,y,width,height,color):
self.x = x
self.y =y
self. width = width
self.color = color
self.height = height
self.color = color
self.speed = 4
self.rect = pygame.Rect(x,y,width,height)
def get_rect(self):
self.rect.topleft = (self.x,self.y)
return self.rect
def draw(self):
pygame.draw.rect(window,self.color,self.get_rect())
class Rule:
def __init__(self,x,y,width,height,color):
self.x = x
self.y =y
self. width = width
self.color = color
self.height = height
self.color = color
self.speed = 4
self.rect = pygame.Rect(x,y,width,height)
def draw(self):
self.rect.topleft = (self.x,self.y)
# Colors for hitbox
white = (255,255,255)
green = (0,255,0)
# Drawing Player
playerman = Player(350,445,40,40,white)
#Drawing Platforms
platform1 = Platform(300,-9.1,40,500,green)
platform2 = Platform(330,451,2000,40,green)
platform3 = Platform(2300,-9.1,40,500,green)
# Drawing Rule
rule1 = Rule(340,-9.1,220,500,green)
rule2 = Rule(20000,-9,1,5,green)
snake1 = Snake(100, 110, 64, 64, 300)
# List
platforms = [platform1,platform2,platform3]
rules = [rule1,rule2]
snakes = [snake1]
# draws map
platformGroup = pygame.sprite.Group
Level = [
" 1 1",
" 1 ",
" 1 1 111 1 ",
" 1 1 1 1 ",
" 11 1 1 1 11 ",
" 1 1 1 1 ",
" 1 1 1 11 1 ",
" 1 1 111 1 11 1 1 ",
" 1 1 11111 1 1 ",]
for iy,row in enumerate(Level):
for ix, col in enumerate(row):
if col == "1":
new_platforms = Platform(ix*50,iy*50.2,50,50,(255,255,255))
platforms.append(new_platforms)
# Windows color
def redrawwindow():
window.fill((0,0,0))
# Drawing the player and other stuff to the screen
playerman.draw()
for Platform in platforms:
Platform.draw()
for Rule in rules:
Rule.draw()
for Snake in snakes:
Snake.draw()
x = 10
y = 10
x_change = 0
y_change = 0
old_x = x
old_y = y
fps = (30)
clock = pygame.time.Clock()
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# part of player screen movment
if playerman.y < 250:
playerman.y += 1
for Platform in platforms:
Platform.y += playerman.speed
for Snake in snakes:
Snake.scroll(0, +playerman.speed)
if playerman.y > 410:
playerman.y -= playerman.fall
for Platform in platforms:
Platform.y -= playerman.fall
for Snake in snakes:
Snake.scroll(0, -playerman.fall)
# part of side colliding
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
x_change = -7
for Snake in snakes:
Snake.scroll(playerman.speed,0)
if event.key == pygame.K_a:
x_change = 7
for Snake in snakes:
Snake.scroll(-playerman.speed,0)
if event.type == pygame.KEYUP:
if event.key == pygame.K_d or event.key == pygame.K_a:
x_change = 0
x += x_change
if x > 500 - playerman.width or x < 0:
x = old_x
# lets player move
keys = pygame.key.get_pressed()
px, py = playerman.x, playerman.y
for Platform in platforms:
if playerman.fall > 0 and keys[pygame.K_SPACE]:
if keys[pygame.K_d]:
playerman.direction = "jump1"
else:
if playerman.direction == "left":
if keys[pygame.K_SPACE]:
playerman.direction = "jump2"
# direction for player animation and screen movment
if keys[pygame.K_d]:
for Platform in platforms:
Platform.x -= playerman.speed
for Snake in snakes:
Snake.scroll(-playerman.speed,0)
for Rule in rules:
Rule.x -= playerman.speed
if not playerman.isJump:
playerman.direction = "right"
elif keys[pygame.K_a]:
for Platform in platforms:
Platform.x += playerman.speed
for Rule in rules:
Rule.x += playerman.speed
if not playerman.isJump:
playerman.direction = "left"
for Snake in snakes:
Snake.scroll(playerman.speed,0)
else:
if playerman.direction == "left" and playerman.direction == "idlel":
playerman.direction = "idlel"
else:
if playerman.direction == "right" and playerman.direction == "idle":
playerman.direction = "idle"
if playerman.direction == "right" and keys[pygame.K_SPACE]:
playerman.direction = "jump1"
if playerman.direction == "left":
if keys[pygame.K_SPACE]:
playerman.direction = "jump2"
# sides for player and player screen movment
platform_rect_list = [p.rect for p in platforms]
player_rect = playerman.get_rect()
player_rect.topleft = (px, py)
playerman.y = py
if player_rect.collidelist(platform_rect_list) < 0:
playerman.x = px
move_right = keys[pygame.K_d]
move_left = keys[pygame.K_a]
if move_right:
for Platform in platforms:
Platform.x -= playerman.speed
for Rule in rules:
Rule.x -= playerman.speed # <---
for Snake in snakes:
Snake.scroll(-playerman.speed,0)
if move_left:
for Platform in platforms:
Platform.x += playerman.speed
for Rule in rules:
Rule.x += playerman.speed # <---
for Snake in snakes:
Snake.scroll(playerman.speed,0)
platform_rect_list = [p.get_rect() for p in platforms] # get_rect()
player_rect = playerman.get_rect()
player_rect.topleft = (px, py)
playerman.y = py
cI = player_rect.collidelist(platform_rect_list)
if cI >= 0:
# undo movement of platforms dependent on the direction and intersection distance
dx = 0
if move_right:
dx = platform_rect_list[cI].left - player_rect.right
if move_left:
dx = platform_rect_list[cI].right - player_rect.left
for Platform in platforms:
Platform.x -= dx
Platform.get_rect() # update rectangle
for Rule in rules:
Rule.x -= dx # <---
for Snake in snakes:
Snake.x -= dx
##############
# About isJump
if not playerman.isJump:
playerman.y += playerman.fall
playerman.fall += 1
playerman.isJump = False
# this part lets you jump on platform only the top
collide = False
for Platform in platforms:
if playerman.get_rect().colliderect(Platform.rect):
collide = True
playerman.isJump = False
playerman.y = Platform.rect.top - playerman.height
if playerman.rect.right > Platform.rect.left and playerman.rect.left < Platform.rect.left - playerman.width:
playerman.x = Platform.rect.left - playerman.width
if playerman.rect.left < Platform.rect.right and playerman.rect.right > Platform.rect.right + playerman.width:
playerman.x = Platform.rect.right
# colliding with floor
if playerman.rect.bottom >= 500:
collide = True
playerman.isJump = False
playerman.Jumpcount = 10
playerman.y = 500 - playerman.height
# Jumping
if collide:
if keys[pygame.K_SPACE]:
playerman.isJump = True
py -= playerman.speed
playerman.fall = 0
# Jump Count
else:
if playerman.JumpCount >= 0:
playerman.y -= (playerman.JumpCount*abs(playerman.JumpCount))*0.3
playerman.JumpCount -= 1
else:
playerman.isJump = False
playerman.JumpCount = 10
redrawwindow()
if playerman.rect.colliderect(rule1.rect):
window.blit(move,(-40,-100))
pygame.display.update()
pygame.quit()
推荐答案
提高代码的健壮性.确保即使蛇的位置远离 path
,蛇的移动也仍然有效.如果 proposed_move
小于 self.path [0] -self.vel
或 self.path [1] + self.vel
,则 Snake
永远不会返回路径,因为 self.vel
会不断反转.如果 proposed_move<请确保始终将移动方向设置为正确的方向.self.path [0]
并确保如果 proposed_move>始终将移动方向设置为左侧.self.path [1]
:
Improve the robustness of your code. Make sure that the movement of a Snake
works even if the position of the snake is far out of the path
. If proposed_move
is less than self.path[0]-self.vel
or self.path[1]+self.vel
, then the Snake
will never return to the path, because self.vel
will be inverted continuously. Make sure that the direction of movement is always set to the right if proposed_move < self.path[0]
and make sure that the direction of movement is always set to the left if proposed_move > self.path[1]
:
class Snake:
# [...]
def move(self):
if self.visible:
# turn around if the move would go out-of-bounds
proposed_move = self.x + self.vel
# Move hits a boundary, so we need to turn around
if proposed_move < self.path[0]:
self.vel = abs(self.vel)
self.Walking_index = 0
if proposed_move > self.path[1]:
self.vel = -abs(self.vel)
self.Walking_index = 0
# now make the correct move
self.x += self.vel # add +/- velocity
对蝙蝠
执行相同操作:
class Bat:
# [...]
def move(self):
if self.visible:
# relizes when it hits bounds
proposed_move = self.x + self.vel
if proposed_move < self.path[0]:
self.vel = abs(self.vel)
self.Walking_index = 0
if proposed_move > self.path[1]:
self.vel = -abs(self.vel)
self.Walking_index = 0
# starting movment
self.x += self.vel
您必须简化代码.
You have to simplify your code.
将播放器的初始位置( start_x
, start_y
)和to方法存储到类播放器中,这些方法返回播放器相对于开始位置的当前位置位置( get_x
, get_y
):
Store the initial position of the player (start_x
, start_y
) and a to methods to the class player that return the current position of the player in relation to the start position (get_x
, get_y
):
class Player:
def __init__(self,x,y,width,height,color):
self.start_x = x
self.start_y = y
self.x = x
self.y = y
#[...]
def get_x(self):
return self.x - self.start_x
def get_y(self):
return self.y - self.start_y
计算相对于播放器的 Snake
, Bat
, Platform
和 Rule
的位置:>
Compute the positions of Snake
, Bat
, Platform
and Rule
in relation to the player:
class Snake:
# [...]
def draw(self):
self.move()
self.rect.topleft = (self.x-playerman.get_x(), self.y-playerman.get_y())
window.blit(self.no,self.rect)
class Bat:
# [...]
def draw(self):
self.move()
self.rect.topleft = (self.x-playerman.get_x(), self.y-playerman.get_y())
window.blit(self.no, self.rect)
class Platform:
# [...]
def get_rect(self):
self.rect.topleft = (self.x-playerman.get_x(), self.y-playerman.get_y())
return self.rect
def draw(self):
pygame.draw.rect(window,self.color,self.get_rect())
class Rule:
# [...]
def draw(self):
self.rect.topleft = (self.x-playerman.get_x(), self.y-playerman.get_y())
摆脱玩家的移动补偿( scroll
等).由于对象是相对于玩家绘制的,因此这不再是必需的.完成主循环:
Get rid of player movement compensation (scroll
etc.). This is no longer necessary as the objects are drawn in relation to the player. Complete main loop:
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# lets player move
keys = pygame.key.get_pressed()
if playerman.fall > 0 and keys[pygame.K_SPACE]:
if keys[pygame.K_d]:
playerman.direction = "jump1"
else:
if playerman.direction == "left":
if keys[pygame.K_SPACE]:
playerman.direction = "jump2"
# direction for player animation and screen movment x
if keys[pygame.K_d]:
if not playerman.isJump:
playerman.direction = "right"
elif keys[pygame.K_a]:
if not playerman.isJump:
playerman.direction = "left"
if playerman.direction == "right" and keys[pygame.K_SPACE]:
playerman.direction = "jump1"
if playerman.direction == "left" and keys[pygame.K_SPACE]:
playerman.direction = "jump2"
px, py = playerman.x, playerman.y
# sides for player and player screen movment
platform_rect_list = [p.rect for p in platforms]
player_rect = playerman.get_rect()
player_rect.topleft = (px, py)
playerman.y = py
if keys[pygame.K_d]:
playerman.x += playerman.speed
if keys[pygame.K_a]:
playerman.x -= playerman.speed
if player_rect.collidelist(platform_rect_list) > 0:
playerman.x = px
# About isJump
if not playerman.isJump:
playerman.y += playerman.fall
playerman.fall += 1
playerman.isJump = False
# this part lets you jump on platform only the top
collide = False
for Platform in platforms:
player_rect = playerman.get_rect()
player_rect.topleft = (playerman.x, playerman.y)
platform_rect = Platform.get_rect()
if playerman.get_rect().colliderect(platform_rect):
collide = True
playerman.isJump = False
if platform_rect.top > playerman.x:
playerman.y = platform_rect.top - playerman.height
if player_rect.right > platform_rect.left and player_rect.left < platform_rect.left:
playerman.x = platform_rect.left - playerman.width
if player_rect.left < platform_rect.right and player_rect.right > platform_rect.right:
playerman.x = platform_rect.right
# colliding with floor
if player_rect.bottom >= 500:
collide = True
playerman.isJump = False
playerman.Jumpcount = 10
playerman.y = 500 - playerman.height
# Jumping
if collide:
if keys[pygame.K_SPACE]:
playerman.isJump = True
playerman.y -= playerman.speed
playerman.fall = 0
# Jump Count
else:
if playerman.JumpCount >= 0:
playerman.y -= (playerman.JumpCount*abs(playerman.JumpCount))*0.3
playerman.JumpCount -= 1
else:
playerman.isJump = False
playerman.JumpCount = 10
redrawwindow()
if playerman.rect.colliderect(rule1.rect):
window.blit(move,(-40,-100))
pygame.display.update()
这篇关于敌人不在原地的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!