Pygame Scrolling

我们两清 提交于 2020-01-11 14:02:25

问题


I am currently taking an A level computer science course in which I have to create a game for a project. I know this code is probably not efficient but I am trying to keep it to my own work and would like a hand with one bit that I am confused on.

I am trying to scroll the screen right and left which i know is done by moving every object on the screen in the relevant direction. I have created boundaries for which the screen should start to move when the robot is within them. But for the code i have written the platforms move without them being updated on the screen and the speed of the robot changes when it is within these boundaries

Any ideas or help would be appreciated.

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()

回答1:


So here we go. Here you are updating the platforms if the robot reached the limit:

for plat in platforms:
    plat.rect.x = plat.rect.x - abs(Robot.vel.x)

But when you draw the platforms you draw from the original PLATFORM_LIST list:

def draw():
    for plat in PLATFORM_LIST:
        p = Platform(*plat)
        pg.draw.rect(gameDisplay, blue, (p))

So what ends up happening is even though you are updating the platforms properly, you are drawing from the original list, so you are not drawing the updated the list. You should draw from the platform list you are updating:

def draw():
    for plat in platforms:
        pg.draw.rect(gameDisplay, blue, plat)

Second, I discovered once you hit the left scroll limit, the movement back to the right direction moved the robot the wrong way. replace this:

if Robot.rect.left < display_width/4:
    Robot.RobotPos.x = Robot.RobotPos.x - abs(Robot.vel.x)

with this (the minus sign switched over to the plus sign):

if Robot.rect.left < display_width/4:
    Robot.RobotPos.x = Robot.RobotPos.x + abs(Robot.vel.x)

Just a couple things I found while playing around with the game.

Update

There is also an issue with rounding. Pygame rectangles take integers. Your calculation of velocity yields a float and you are trying to add that to the x of the rectangle here:

for plat in platforms:
    plat.rect.x = plat.rect.x - abs(Robot.vel.x)

This causes issues with rounding that show up in the display (platforms) moving in peculiar ways. You can make them ints:

for plat in platforms:
    plat.rect.x = plat.rect.x - int(abs(Robot.vel.x))

Otherwise you will have to make the platforms like you do the Robot and deal in vec()



来源:https://stackoverflow.com/questions/43077272/pygame-scrolling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!