Pygame 滚动
Pygame Scrolling
我目前正在上 A 级计算机科学课程,我必须在其中为项目创建游戏。我知道这段代码可能效率不高,但我正在努力将其保留在我自己的工作中,并希望得到我困惑的一点帮助。
我正在尝试左右滚动屏幕,我知道这是通过沿相关方向移动屏幕上的每个对象来完成的。我已经创建了边界,当机器人在边界内时屏幕应该开始移动。但是对于我编写的代码,平台在没有在屏幕上更新的情况下移动,并且机器人的速度在这些边界内时发生变化
如有任何想法或帮助,我们将不胜感激。
import pygame as pg
import time
import random
pg.init()#initiates pygame
display_height = 690#Creates width and height of screen
display_width = 1024
#Colours
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
sky = (73,71,65) # grey
Robot_height = 99#Height of robot
Robot_width = 112#Width of robot
lives = 3 #Robot Lives
Bullet_Fired = False
PowerUp_Active = False
Robot_acc = 0.3 #Robot Acceleration
vec = pg.math.Vector2
gameDisplay = pg.display.set_mode((display_width,display_height)) #Sets display properties of window
pg.display.set_caption ("Game") #Title on window
clock = pg.time.Clock()
robotImg = pg.image.load("robot1.png") #Loads robots image
#Class for platforms
class Platform(pg.sprite.Sprite):
def __init__(self, x,y,w,h):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((w,h))
self.image.fill(blue)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
#List of platforms
PLATFORM_LIST = [(0,display_height - 40,display_width,40),
(display_width /2 - 50,display_height * 3/4,100,20)]
#Platform group
platforms = pg.sprite.Group()
#class for robot
class RobotClass(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((Robot_width,Robot_height))
self.rect = self.image.get_rect()
self.rect.center = (display_width / 2, display_height / 2)
self.RobotPos = vec(display_width / 2, display_height / 2)
self.bottom = (0,0)
self.vel = vec(0, 0)
self.acc = vec(0, 0.3)
#Creates Robot
Robot = RobotClass()
for plat in PLATFORM_LIST:
p = Platform(*plat)
platforms.add(p)
def draw():
for plat in PLATFORM_LIST:
p = Platform(*plat)
pg.draw.rect(gameDisplay, blue, (p))
#Jump function
def jump():
#Checks pixel below robot to see if there is a collision
Robot.rect.x = Robot.rect.x +1
hits = pg.sprite.spritecollide(Robot , platforms, False)
Robot.rect.x = Robot.rect.x -1
if hits:
#Gives robot velocity of 5 upwards
Robot.vel.y = -10
#game loop
def game_loop():
pg.draw.rect(gameDisplay, red, Robot.rect, 2)
Robot_friction = -0.3 #Friction value
vec = pg.math.Vector2 #Setting vec as vector quantity
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit
quit()
#Starts acceleration when key is pressed
if event.type == pg.KEYDOWN:
if event.key == pg.K_LEFT:
Robot.acc.x = -Robot_acc
elif event.key == pg.K_RIGHT:
Robot.acc.x = Robot_acc
elif event.key == pg.K_UP:
jump()
#Adds friction to accleration to slow robot down when key is not being pressed
if event.type == pg.KEYUP:
if event.key == pg.K_LEFT or event.key == pg.K_RIGHT:
Robot.acc.x = Robot.acc.x * Robot_friction
#Adjusts velocity of robot by adding the acceleration on each cycle
Robot.vel = Robot.vel+ Robot.acc
#Fills background
gameDisplay.fill(sky)
#Draws the platforms to the screen and adds them to platform group
draw()
#Changes Robot position according to its velocity,acceleration and the friction
Robot.RobotPos = Robot.RobotPos + Robot.vel + 0.5 * Robot.acc
#Loads robot onto screen
gameDisplay.blit(robotImg,(Robot.rect))
pg.draw.rect(gameDisplay, red, Robot.rect, 2)
#Updates display
pg.display.update()
clock.tick(60)
#Sets bottom of robot to its position
Robot.rect.midbottom = Robot.RobotPos
#Collision detection
if Robot.vel.y > 0:
hits = pg.sprite.spritecollide(Robot , platforms, False)
if hits:
#Puts Robot on top of platform
Robot.RobotPos.y = hits[0].rect.top + 1
Robot.vel.y = 0
#Scrolling
if Robot.rect.left < display_width/4:
print("left")
Robot.RobotPos.x = Robot.RobotPos.x - abs(Robot.vel.x)
print(Robot.vel)
for plat in platforms:
plat.rect.x = plat.rect.x + abs(Robot.vel.x)
pg.draw.rect(gameDisplay, blue, (PLATFORM_LIST[0]))
if Robot.rect.right > (display_width-display_width/4):
print("right")
Robot.RobotPos.x = Robot.RobotPos.x + abs(Robot.vel.x)
print(Robot.vel)
for plat in platforms:
plat.rect.x = plat.rect.x - abs(Robot.vel.x)
#Sets top velocity of robot
if Robot.vel.x > 6:
Robot.vel.x = 6
if Robot.vel.x < -6:
Robot.vel.x = -6
#Makes robot velocity = 0 when it is close to 0
if Robot.vel.x < 0.05 and Robot.vel.x > -0.05:
Robot.acc.x = 0
Robot.vel.x = 0
game_loop()
pg.quit()
quit()
我们开始吧。如果机器人达到限制,您将在此处更新平台:
for plat in platforms:
plat.rect.x = plat.rect.x - abs(Robot.vel.x)
但是当您绘制平台时,您是从原始 PLATFORM_LIST 列表中绘制的:
def draw():
for plat in PLATFORM_LIST:
p = Platform(*plat)
pg.draw.rect(gameDisplay, blue, (p))
所以最终发生的事情是,即使您正确地更新了平台,您也是从原始列表中绘制的,所以您没有绘制更新后的列表。您应该从正在更新的平台列表中提取:
def draw():
for plat in platforms:
pg.draw.rect(gameDisplay, blue, plat)
其次,我发现一旦您达到左侧滚动限制,向右移动的方向就会将机器人移动到错误的方向。替换为:
if Robot.rect.left < display_width/4:
Robot.RobotPos.x = Robot.RobotPos.x - abs(Robot.vel.x)
这样(减号转为加号):
if Robot.rect.left < display_width/4:
Robot.RobotPos.x = Robot.RobotPos.x + abs(Robot.vel.x)
我在玩游戏时发现的几件事。
更新
四舍五入也有问题。 Pygame 矩形采用整数。您对速度的计算产生了一个浮点数,您正试图将其添加到此处矩形的 x 中:
for plat in platforms:
plat.rect.x = plat.rect.x - abs(Robot.vel.x)
这会导致显示(平台)以特殊方式移动时出现的舍入问题。您可以将它们设为整数:
for plat in platforms:
plat.rect.x = plat.rect.x - int(abs(Robot.vel.x))
否则你将不得不像做机器人一样制作平台并在 vec() 中处理
我目前正在上 A 级计算机科学课程,我必须在其中为项目创建游戏。我知道这段代码可能效率不高,但我正在努力将其保留在我自己的工作中,并希望得到我困惑的一点帮助。
我正在尝试左右滚动屏幕,我知道这是通过沿相关方向移动屏幕上的每个对象来完成的。我已经创建了边界,当机器人在边界内时屏幕应该开始移动。但是对于我编写的代码,平台在没有在屏幕上更新的情况下移动,并且机器人的速度在这些边界内时发生变化
如有任何想法或帮助,我们将不胜感激。
import pygame as pg
import time
import random
pg.init()#initiates pygame
display_height = 690#Creates width and height of screen
display_width = 1024
#Colours
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
sky = (73,71,65) # grey
Robot_height = 99#Height of robot
Robot_width = 112#Width of robot
lives = 3 #Robot Lives
Bullet_Fired = False
PowerUp_Active = False
Robot_acc = 0.3 #Robot Acceleration
vec = pg.math.Vector2
gameDisplay = pg.display.set_mode((display_width,display_height)) #Sets display properties of window
pg.display.set_caption ("Game") #Title on window
clock = pg.time.Clock()
robotImg = pg.image.load("robot1.png") #Loads robots image
#Class for platforms
class Platform(pg.sprite.Sprite):
def __init__(self, x,y,w,h):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((w,h))
self.image.fill(blue)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
#List of platforms
PLATFORM_LIST = [(0,display_height - 40,display_width,40),
(display_width /2 - 50,display_height * 3/4,100,20)]
#Platform group
platforms = pg.sprite.Group()
#class for robot
class RobotClass(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((Robot_width,Robot_height))
self.rect = self.image.get_rect()
self.rect.center = (display_width / 2, display_height / 2)
self.RobotPos = vec(display_width / 2, display_height / 2)
self.bottom = (0,0)
self.vel = vec(0, 0)
self.acc = vec(0, 0.3)
#Creates Robot
Robot = RobotClass()
for plat in PLATFORM_LIST:
p = Platform(*plat)
platforms.add(p)
def draw():
for plat in PLATFORM_LIST:
p = Platform(*plat)
pg.draw.rect(gameDisplay, blue, (p))
#Jump function
def jump():
#Checks pixel below robot to see if there is a collision
Robot.rect.x = Robot.rect.x +1
hits = pg.sprite.spritecollide(Robot , platforms, False)
Robot.rect.x = Robot.rect.x -1
if hits:
#Gives robot velocity of 5 upwards
Robot.vel.y = -10
#game loop
def game_loop():
pg.draw.rect(gameDisplay, red, Robot.rect, 2)
Robot_friction = -0.3 #Friction value
vec = pg.math.Vector2 #Setting vec as vector quantity
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit
quit()
#Starts acceleration when key is pressed
if event.type == pg.KEYDOWN:
if event.key == pg.K_LEFT:
Robot.acc.x = -Robot_acc
elif event.key == pg.K_RIGHT:
Robot.acc.x = Robot_acc
elif event.key == pg.K_UP:
jump()
#Adds friction to accleration to slow robot down when key is not being pressed
if event.type == pg.KEYUP:
if event.key == pg.K_LEFT or event.key == pg.K_RIGHT:
Robot.acc.x = Robot.acc.x * Robot_friction
#Adjusts velocity of robot by adding the acceleration on each cycle
Robot.vel = Robot.vel+ Robot.acc
#Fills background
gameDisplay.fill(sky)
#Draws the platforms to the screen and adds them to platform group
draw()
#Changes Robot position according to its velocity,acceleration and the friction
Robot.RobotPos = Robot.RobotPos + Robot.vel + 0.5 * Robot.acc
#Loads robot onto screen
gameDisplay.blit(robotImg,(Robot.rect))
pg.draw.rect(gameDisplay, red, Robot.rect, 2)
#Updates display
pg.display.update()
clock.tick(60)
#Sets bottom of robot to its position
Robot.rect.midbottom = Robot.RobotPos
#Collision detection
if Robot.vel.y > 0:
hits = pg.sprite.spritecollide(Robot , platforms, False)
if hits:
#Puts Robot on top of platform
Robot.RobotPos.y = hits[0].rect.top + 1
Robot.vel.y = 0
#Scrolling
if Robot.rect.left < display_width/4:
print("left")
Robot.RobotPos.x = Robot.RobotPos.x - abs(Robot.vel.x)
print(Robot.vel)
for plat in platforms:
plat.rect.x = plat.rect.x + abs(Robot.vel.x)
pg.draw.rect(gameDisplay, blue, (PLATFORM_LIST[0]))
if Robot.rect.right > (display_width-display_width/4):
print("right")
Robot.RobotPos.x = Robot.RobotPos.x + abs(Robot.vel.x)
print(Robot.vel)
for plat in platforms:
plat.rect.x = plat.rect.x - abs(Robot.vel.x)
#Sets top velocity of robot
if Robot.vel.x > 6:
Robot.vel.x = 6
if Robot.vel.x < -6:
Robot.vel.x = -6
#Makes robot velocity = 0 when it is close to 0
if Robot.vel.x < 0.05 and Robot.vel.x > -0.05:
Robot.acc.x = 0
Robot.vel.x = 0
game_loop()
pg.quit()
quit()
我们开始吧。如果机器人达到限制,您将在此处更新平台:
for plat in platforms:
plat.rect.x = plat.rect.x - abs(Robot.vel.x)
但是当您绘制平台时,您是从原始 PLATFORM_LIST 列表中绘制的:
def draw():
for plat in PLATFORM_LIST:
p = Platform(*plat)
pg.draw.rect(gameDisplay, blue, (p))
所以最终发生的事情是,即使您正确地更新了平台,您也是从原始列表中绘制的,所以您没有绘制更新后的列表。您应该从正在更新的平台列表中提取:
def draw():
for plat in platforms:
pg.draw.rect(gameDisplay, blue, plat)
其次,我发现一旦您达到左侧滚动限制,向右移动的方向就会将机器人移动到错误的方向。替换为:
if Robot.rect.left < display_width/4:
Robot.RobotPos.x = Robot.RobotPos.x - abs(Robot.vel.x)
这样(减号转为加号):
if Robot.rect.left < display_width/4:
Robot.RobotPos.x = Robot.RobotPos.x + abs(Robot.vel.x)
我在玩游戏时发现的几件事。
更新
四舍五入也有问题。 Pygame 矩形采用整数。您对速度的计算产生了一个浮点数,您正试图将其添加到此处矩形的 x 中:
for plat in platforms:
plat.rect.x = plat.rect.x - abs(Robot.vel.x)
这会导致显示(平台)以特殊方式移动时出现的舍入问题。您可以将它们设为整数:
for plat in platforms:
plat.rect.x = plat.rect.x - int(abs(Robot.vel.x))
否则你将不得不像做机器人一样制作平台并在 vec() 中处理