2

I am making a simple Mario game. I simply just want to have a character, obviously Mario jump into set of collision boxes that will have a answer to a math question being displayed. So far I have managed to put together the gravity and the level collisions but I can't seem to be able solving how to get my character to give me an output when colliding with a simple box/rectangle. Here is my code so far:

import pygame
from block import *
from Player import *
pygame.mixer.pre_init(44100,  -16,  2,  2048)
pygame.init()
window = pygame.display.set_mode((800,  600))
pygame.display.set_caption("Super Mario Bros")
myfont = pygame.font.SysFont("Comic Sans MS", 100)
mariosound = pygame.mixer.music.load("data/sound.mp3")
pygame.mixer.music.play(-1)
gravity = -0.5
black = (0,  0,  0)
orange = (255,  174,  0)
blue = (11,  183,  217)
clock = pygame.time.Clock()
player = Player(0,  0)
label = myfont.render("9+10=", 1, black)

level1 = [
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]

def printText(txtText, Textfont, Textsize , Textx, Texty, Textcolor):
    myfont = pygame.font.SysFont(Textfont, Textsize)
    label = myfont.render(txtText, 1, Textcolor)
    window.blit(label, (Textx, Texty))
    pygame.display.flip()

blockList = []
for y in range(0,  len(level1)):
    for x in range(0,  len(level1[y])):
        if (level1[y][x]==1):
            blockList.append(Block(x*32,  y*32))

movex,  movey = 0, 0

gameLoop = True
while gameLoop:
    for event in pygame.event.get():
        if (event.type == pygame.QUIT):
            gameLoop = False
        if (event.type == pygame.KEYDOWN):
            if (event.key == pygame.K_RIGHT):
                movex = 5
            elif (event.key == pygame.K_LEFT):
                movex = -5
            elif (event.key == pygame.K_UP):
                player.jump()
        if (event.type == pygame.KEYUP):
             if (event.key == pygame.K_RIGHT):
                movex = 0
             elif (event.key == pygame.K_LEFT):
                movex = 0

    window.fill(blue)
    window.blit(label, (275, 100))
    for block in blockList:
        block.render(window)
    player.x += movex
    player.update(gravity,  blockList)
    player.render(window)
    clock.tick(60)
    pygame.display.flip()

pygame.quit()

I have a player and collision sub class in different python files, named: Block and Player which just does collisions and simple gravity etc.

Thanks for any help, as I said I'v very new so any explanation or help would be appreciated.

Here is my other pieces of code: My Player.py: import pygame

class Player:
    def __init__(self, x, y):
        self.x=x
        self.y=y
        self.width=32
        self.height=32
        self.velocity=0
        self.falling=True
        self.onGround=False

        self.images = pygame.image.load('resources/sprite.png')
        self.images = pygame.transform.scale(self.images, (35, 35))
    def jump(self):
        if (self.onGround == False):
            return
        self.velocity = 14
        self.onGround = False

    def detectCollisions(self, x1, y1, w1, h1, x2, y2, w2, h2):
        if (x2 + w2 > x1 >= x2 and y2 + h2 >= y1 >= y2):
            return True
        elif (x2 + w2 >= x1 + w1 > x2 and y2 + h2 >= y1 >= y2):
            return True
        elif (x2 + w2 >= x1 >= x2 and y2 + h2 >= y1 + h1 >= y2):
            return True
        elif (x2 + w2 >= x1 + w1 >= x2 and y2 + h2 >= y1 + h1 >= y2):
            return True
        else:
            return False

    def update(self, gravity, blockList):
        if (self.velocity < 0):
            self.falling = True
        collision = False
        blockX,blockY = 0,0
        for block in  blockList:
            collision = self.detectCollisions(self.x, self.y, self.width, self.height, block.x, block.y, block.width, block.height)
            if (collision == True):
                blockX=block.x
                blockY=block.y
                break
        if (collision == True):
            if (self.falling == True):
                self.falling = False
                self.onGround = True
                self.velocity = 0
                self.y = blockY - self.height

        if (self.onGround == False):
            self.velocity += gravity

        self.y-=self.velocity

    def render(self, window):
        window.blit(self.images, (self.x, self.y))

    def render1(self, collision):
        if (collision==True):
            pygame.draw.rect(window,red,(self.x,self.y,self.width,self.height))
        else:
            pygame.draw.rect(window,black,(self.x,self.y,self.width,self.height))

And block.py: import pygame

class Block:
    def __init__(self, x, y):
        self.x=x
        self.y=y
        self.width=32
        self.height=32

    def render(self, window):
        pygame.draw.rect(window, (255,174,0),(self.x, self.y, self.width, self.height))
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Doge
  • 21
  • 4
  • A good start would be to stop using the `x`, `y`, `height` and `width` fields and use a simple `pygame.Rect` instead, which offers convenient methods like `colliderect`, `collidelist` etc which you could use instead of your `detectCollisions` method. – sloth May 28 '15 at 07:24
  • Maybe also take a look at this [question/answer](http://stackoverflow.com/a/14357169/142637). It's another topic but the code in question uses a common technique for collision detection (first checking the vertical, then the horizontal axis). Maybe it's some help for you. – sloth May 28 '15 at 07:27
  • Thanks Ill take a look at it. – Doge May 28 '15 at 08:15

1 Answers1

0

I didn't know the size of the image and the box, so i wrote down some random size. hope it will help you. this is the code:

simplebox_width = 20 #pixels
simplebox_height = 20

image_width = 50
image_height = 250

image_x_coord = 100 #coords
image_y_coord = 200

simplebox_x_coord = 140
simplebox_y_coord = 250

image_x_side = range(image_x_coord, image_x_coord+image_width)
image_y_side = range(image_y_coord, image_y_coord+image_height)

simplebox_x_side = range(simplebox_x_coord, simplebox_x_coord+simplebox_width)
simplebox_y_side = range(simplebox_y_coord, simplebox_y_coord+simplebox_height)

for x in image_x_side:
    if x in simplebox_x_side:
        for y in image_y_side:
            if y in simplebox_y_side:
                collision = True
    else:
        collision = False

print collision
Liam
  • 6,009
  • 4
  • 39
  • 53
  • Hey Liam , thanks for the answer. I'm still fairly new to all this. Should i rewrite a collision class in response to your code? I'm just getting confused in what I'm doing at the moment, if possible could you explain very simply :) Cheers. – Doge May 27 '15 at 21:22
  • can you tell me exactly what confuses you? @Doge – Liam May 28 '15 at 09:56
  • Firstly, I have a collision class and function already which is used to stop the sprite/player falling off the screen. Secondly, I don't really understand what I am doing here, am I assigning a rectangle to the existing sprite or just changing the properties of the sprite. As well as that I'm a little confused how to tie all this together. – Doge May 28 '15 at 11:31
  • just over write your "detectcollision" function with my code – Liam May 28 '15 at 15:46
  • I am so sorry, I've restarted multiple times and still cant seem to figure it out. Whenever i set two sprites , 1 being the player and the other as a pygame.draw.rect (rectangle) it always crashes or gives an error. I'm so confused :/ – Doge May 31 '15 at 10:31