Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
292 views
in Technique[技术] by (71.8m points)

python - Trying to make a "solid" block in pygame but it doesnt work

Hopefully you can help me, i have been struggling with this problem for the last few days. I want to make a "solid" block for my 2d platformer game that i am working on but when i go into that "solid" block i teleport to the other side or to the bottom of the block, i dont know why, hopefully you know why So here is my code:

class Block(pygame.sprite.Sprite):

    def __init__(self, color = blue,widht = 64, height = 64):

        super(Block, self).__init__()

        self.image = pygame.Surface((widht, height))
        self.image.fill(color)
        self.rect = self.image.get_rect()

        self.sound = pygame.mixer.Sound("2dSounds/Walk.wav")

        self.hspeed = 0
        self.vspeed = 0
    def update(self, collidable):
        self.rect.x += self.hspeed

        collision_list = pygame.sprite.spritecollide(self, collidable, False)
        for collided_object in collision_list:
            if (self.hspeed > 0):
                # right direction
                self.rect.right = collided_object.rect.left

            elif (self.hspeed < 0):
                # left direction
                self.rect.left = collided_object.rect.right

        self.rect.y += self.vspeed

        collision_list = pygame.sprite.spritecollide(self, collidable, False)   
        for collided_object in collision_list:
            if (self.vspeed > 0):
             # down direction
                self.rect.bottom = collided_object.rect.top

            elif (self.vspeed < 0):
                # up direction
                self.rect.top = collided_object.rect.bottom
    def change_speed(self, hspeed, vspeed):
        self.hspeed += hspeed
        self.vspeed += vspeed
    def set_position(self, x, y):
        self.rect.x = x 
        self.rect.y = y 

Thanks alot! :)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Sorry about the fact that my code isn't based off your's, I literally just threw it together in the past 5 minutes so it isn't very pretty, but here it is:

from pygame.locals import *

import pygame
import sys

GRAVITY = 1.2

class Player:
    def __init__(self, x, y):
        self.rect = pygame.Rect(x, y, 25, 25)
        self.yvel = 0

    def tick(self):
        self.yvel += GRAVITY

        self.rect.y += int(self.yvel)

        if self.rect.y >= 475:
            self.rect.y = 475
            self.yvel = 0

    def set(self, y):
        if y:
            self.yvel = y

class Block:
    def __init__(self, x, y, w, h):
        self.rect = pygame.Rect(x, y, w, h)

class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((500, 500))
        self.player = Player(0, 0)
        self.block = Block(225, 400, 50, 50)

    def main(self):
        right = left = False
        while True:
            self.screen.fill((230, 230, 230))
            pygame.draw.rect(self.screen, (40, 40, 40), self.block.rect)
            pygame.draw.rect(self.screen, (100, 200, 100), self.player.rect)

            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit(0)
                elif event.type == KEYDOWN:
                    if event.key == K_SPACE:
                        self.player.set(-20)
                    elif event.key == K_RIGHT:
                        right = True
                    elif event.key == K_LEFT:
                        left = True
                elif event.type == KEYUP:
                    if event.key == K_RIGHT:
                        right = False
                    elif event.key == K_LEFT:
                        left = False

            if right:
                self.player.rect.x += 5
                while self.player.rect.colliderect(self.block.rect):
                    self.player.rect.x -= 1
            if left:
                self.player.rect.x -= 5
                while self.player.rect.colliderect(self.block.rect):
                    self.player.rect.x += 1
            self.player.tick()
            if self.player.yvel > 0:
                while self.player.rect.colliderect(self.block.rect):
                    self.player.rect.y -= 1
                    self.player.yvel = 0
            elif self.player.yvel < 0:
                while self.player.rect.colliderect(self.block.rect):
                    self.player.rect.y += 1
                    self.player.yvel = 0

game = Game()
game.main()

The player speed is quite fast, but that can be changed at the lines:

self.player.rect.x -= 5

and

self.player.rect.x += 5

near the bottom.

The way it works is whenever you go to move, it moves the player, then looks to see if if collided with the block. If it did, the player moves in the opposite direction until is is satisfied that it isn't colliding any more. Jumping is accomplished using velocity, hence Player.yvel and GRAVITY. GRAVITY can be changed but if it it higher, jumps will be shorter and vice-versa.

Have a play around with the code and experiment with things like the blocks position (self.block = Block(225, 400, 50, 50)) and the player's staring position (self.player = Player(0, 0))

If you do find any errors in the code, just let me know and I'll try to fix them.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...