Я новичок в программировании, и недавно я пытался создать игру для 2d-платформы и столкнулся с проблемой, которую не могу решить, мой NPC не будет следовать за игроком по карте и не будетон реагирует на столкновения, любая помощь приветствуется.
Я также рассматривал вопрос о создании алгоритма, который будет процедурно генерировать мои уровни в блоке платформ, и размещать выходной блок где-нибудь еще на уровне, как мне это сделать?архив то?
import pygame #imports pygame
import time #imports the timer so I can use the tick function to make game 60fps
import math #imports maths
import sys #imports system
from pygame import * #imports all pygame files
from pygame.math import *
from pygame.mixer import *
win_height = 750 #height of window is 750 pixles
win_width = 1050 #height of window is 1050 pixels
half_win_width = int(win_width / 2) #will be used to centre camera
half_win_height = int(win_height / 2)
display = (win_width, win_height) #creates the window as 500*500 pixels
depth = 32 #prevents infinate recursion
flags = 0 #message to Les: I don't really know what this does, however I have seen it in many places being used, therefore I assumed that it was important
camera_slack = 30 #how many pixels the player can move before the camera moves with them
pygame.init()
pygame.mixer.music.load('Toby Fox - Megalovania [Electro Swing Remix].mp3')
pygame.mixer.music.play(-1)
def main(): #main game function
global cameraX, cameraY
pygame.init()
screen = pygame.display.set_mode(display, flags, depth)
pygame.display.set_caption("Super Castlevania Man")
timer = pygame.time.Clock()
move_cameraX = 0
move_cameraY = 0
up = down = left = right = running = False
background = Surface((32,32)) #the background takes up space on the screen
background.convert()
background.fill(Color("#000000")) #background is black
entities = pygame.sprite.Group()
player = Player_class(32, 32) #the player is 32*32 pixels large
platforms = []
x = y = 0
level = [
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
"P P",
"P E P",
"P P",
"P PPPPPPPPP P",
"P P",
"P P",
"P P",
"P PPPPPPPP P",
"P P",
"P PPPP P",
"P PPPPPP P",
"P PPPPPPP P",
"P P",
"P PPPPPP P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P PPPPPPPPPPP P",
"P P",
"P P",
"P P",
"P P",
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
]
#builds the level
for row in level:
for col in row:
if col == "P":
p = Platform(x, y) #makes P a solid object
platforms.append(p)
entities.add(p)
if col == "E":
e = Exit_block(x, y)
platforms.append(e)
entities.add(e)
x += 32
y += 32
x = 0
entities.add(player)
while 1:
timer.tick(60) #makes game run at 60 frames per second
for e in pygame.event.get(): #shortens event to e
if e.type == QUIT: raise SystemExit ("QUIT")
if e.type == KEYDOWN and e.key == K_ESCAPE:
pygame.quit()
sys.exit()
raise SystemExit ("ESCAPE")
if e.type == KEYDOWN and e.key == K_UP:
up = True
move_cameraY = -10
if e.type == KEYDOWN and e.key == K_DOWN:
down = True
move_cameraY = 10
if e.type == KEYDOWN and e.key == K_LEFT:
left = True
move_cameraX = -10
if e.type == KEYDOWN and e.key == K_RIGHT:
right = True
move_cameraX = 10
if e.type == KEYDOWN and e.key == K_SPACE:
running = True
if e.type == KEYUP and e.key == K_UP:
up = False
move_cameraY = 0
if e.type == KEYUP and e.key == K_DOWN:
down = False
move_cameraY = 0
if e.type == KEYUP and e.key == K_RIGHT:
right = False
move_cameraX = 0
if e.type == KEYUP and e.key == K_LEFT:
left = False
move_cameraX = 0
if e.type == KEYUP and e.key == K_RIGHT:
right = False
for y in range(32): #draws the background
for x in range(32):
screen.blit(background, (x * 32, y * 32))
#updates the player and draws everything else
player.update(up, down, left, right, running, platforms)
entities.draw(screen)
pygame.display.update()
enemy = Enemy(60, 200, player) #Spawns enemy
enemy_list = pygame.sprite.Group() #creates an enemy group
enemy_list.add(enemy) #Add an enemy to the group
enemy_list.draw(screen)
for e in enemy_list:
e.move()
pygame.display.flip()
"""
enemysprite.draw(screen)
enemysprite.update()
enemy.move_towards_player(player)
"""
class Entity(pygame.sprite.Sprite): #makes player a sprite
def __init__(self):
pygame.sprite.Sprite.__init__(self) #sets sprite to initiate
class Player_class(Entity): #defines player class
def __init__(self, x, y): #x is the player x coordinate, y is the player y coordinate
Entity.__init__(self) #the player is an entity
self.xvel = 0 #how fast the player is moving left and right
self.yvel = 0 #how fast the player is moving up and down
self.onGround = False #assumes the player is in the air
self.image = Surface((32,32)) #the player is 32*32 pixels
self.image.fill(Color("#0000FF")) #makes the player blue
self.image.convert()
self.rect = Rect(x, y, 32, 32)
self.x = x
self.y = y
def update(self, up, down, left, right, running, platforms):
if up:
if self.onGround: self.yvel -= 10 #only jump if player is on the ground
if down:
pass
if running:
self.xvel = 12
if left:
self.xvel = -8
if right:
self.xvel = 8
if not self.onGround:
self.yvel += 0.3 #only accelerate with gravity if in the air
if self.yvel > 100: self.yvel = 100 #terminal velocity = 100
if not(left or right):
self.xvel = 0
self.rect.left += self.xvel #falls or jumps
self.collide(self.xvel, 0, platforms) #creates collisions along the x axis
self.rect.top += self.yvel #creates collisions along the y axis
self.onGround = False; #assumes that the player is in the air
# do y-axis collisions
self.collide(0, self.yvel, platforms)
def collide(self, xvel, yvel, platforms):
for p in platforms:
if pygame.sprite.collide_rect(self, p):
if isinstance(p, Exit_block):
pygame.quit()
sys.exit()
if xvel > 0:
self.rect.right = p.rect.left
print ("collide right")
if xvel < 0:
self.rect.left = p.rect.right
print ("collide left")
if yvel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
self.yvel = 0
if yvel < 0:
self.rect.top = p.rect.bottom
class Platform(Entity): #defines the platform class
def __init__(self, x, y):
Entity.__init__(self) #platform is an entity
self.image = Surface((32, 32)) #platforms are 32*32 pixels
self.image.convert()
self.image.fill(Color("#FFFFFF")) #platforms are white
self.rect = Rect(x, y, 32, 32) #platforms, like many things in this game, are rectangles
def update(self):
pass
class Exit_block(Platform): #defines the exit block class
def __init__(self, x, y):
Platform.__init__(self, x, y)
self.image.fill(Color("#FF0000"))#exit block is red
"""
class Enemy(pygame.sprite.Sprite):
def __init__(self, image_file, pos=(0,0)):
super(Enemy, self).__init__()
self.image = (32, 32)
self.image.fill(color("00FF00"))
self.rect = Rect(x, y, 32, 32)
self.speed = 1
def move_towards_player(self, Player):
dx, dy = self.rect.x - Player.rect.x, self.rect.y - Player.rect.y
dist = math.hypot(dx, dy)
dx, dy = dx/dist, dy/dist
self.rect.x += dx * self.speed
self.rect.y += dy * self.speed
"""
class Enemy(Entity):
def __init__(self, x, y,player):
pygame.sprite.Sprite.__init__(self)
self.image = Surface((32, 32))
self.xvel = 0
self.yvel = 0
self.image.fill(Color("#00FF00")) #Enemy is green
self.onGorund = False
#Enemy is 32 * 32 pixels
self.image.convert()
self.rect = Rect(x, y, 32, 32)
self.counter = 0 #counter variable
self.player = player
def move(self, speed = 5): # chase movement
if self.rect.x > self.player.x: # Movement along x direction
self.rect.x -= speed
elif self.rect.x < self.player.x:
self.rect.x += speed
if self.rect.y < self.player.y: # Movement along y direction
self.rect.y += speed
elif self.rect.y > self.player.y:
self.rect.y -= speed
def collide(self, xvel, yvel, platforms):
for p in platforms:
if pygame.sprite.collide_rect(self, p):
if isinstance(p, Player_class):
pygame.quit()
sys.exit()
if xvel > 0:
self.rect.right = p.rect.left
print ("collide right")
if xvel < 0:
self.rect.left = p.rect.right
print ("collide left")
if yvel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
self.yvel = 0
if yvel < 0:
self.rect.top = p.rect.bottom
def update(self, platforms):
if up:
if self.onGround: self.yvel -= 10 #only jump if player is on the ground
if down:
pass
if running:
self.xvel = 12
if left:
self.xvel = -8
if right:
self.xvel = 8
if not self.onGround:
self.yvel += 0.3 #only accelerate with gravity if in the air
if self.yvel > 100: self.yvel = 100 #terminal velocity = 100
if not(left or right):
self.xvel = 0
self.rect.left += self.xvel #falls or jumps
self.collide(self.xvel, 0, platforms) #creates collisions along the x axis
self.rect.top += self.yvel #creates collisions along the y axis
self.onGround = False; #assumes that the player is in the air
# do y-axis collisions
self.collide(0, self.yvel, platforms)
"""
class Enemy(Entity):
def __init__(self,x,y): # initial position
self.x = x
self.y = y
def move(self, speed=5): # chase movement
# Movement along x direction
if self.x > px:
self.x -= speed
elif self.x < px:
self.x += speed
# Movement along y direction
if self.y < py:
self.y += speed
elif self.y > py:
self.y -= speed
"""
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + othery)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
def __div__(self, scalar):
return Vector(self.x / scalar, self.y / scalar)
def length(self):
return ((self.x ** x) + (self.y ** 2)) ** 0.5
def normal(self):
return self / self.length()
class Camera(object):
def __init__(self, Player_class):
self.left_viewbox = display_width/2 - display_width/8
self.right_viewbox = display_width/2 + display_width/10
def follow(self, shift_x):
virtualwindow.x += shift_x
print (virtualwindow.x)
for i in Player_class:
i.rect.x += shift_x
def viewbox(self):
if player.x <= self.left_viewbox:
view_difference = self.left_viewbox - player.x
player.x = self.left_viewbox
self.follow(view_difference)
if player.x >= self.right_viewbox:
view_difference = self.right_viewbox - player.x
player.x = self.right_viewbox
self.follow(view_difference)
"""
class Camera(object):
def __init__(self, camera_func, win_width, win_height):
self.camera_func = camera_func
self.state = rect(0, 0, win_width, win_height)
def apply(self, target):
self.state = self.camera_func(self.state, target.rect)
def simple_camera(camera, target_rect):
def __init__(self, Camera, camera_func, win_width, win_height):
pass
"""
if __name__ == "__main__":
main()