Mar-05-2020, 08:39 PM
So I have this test environment that I use whenever I'm trying to learn new stuff, lately it's been going on into alot of pygame. I'm currently trying to figure out how to use/define spritecollisions and I'm just really confused and stuck, therefore coming here to ask for help as a newb.
Now, I don't want to just dump some code and ask for help just like that, i want to try to explain what I've tried so far and what I'm trying to do specifically.
So what I want to do is create a function that detects collisions between the player (controlled by me) and the mob (enemy non moving object) and i want my pygame to automatically shut of if it detects a collision between the two. So, initially, since it's a static object I just could define an if statement, say something like "if player.x == mob.x pygame.quit(). However, that's not the solution that I want, because I've done that in previous projects and it's just really bad code, especially if i figure out later i want to move it somewhere...
So what have I tried? well, the two first functions in the codesheet below, are my two attemps at creating this detection. I'm not sure if i'm thinking wrong about this but I figured i couldn't define those functions inside the player or mob class because then it wont detect the other class definitions because they're separated. Therefore I went for the solution below, and defined the functions outside a class.
According to the examples i have searched up, there are different ways to do this, but those two below seemed to be accurate for my type of game so hence I went for those funcs as definitions, but they are clearly wrong. I'm just not sure if calling the player and mob in the func without further specification is the wrong way to approach this?
I could explain further, but I'm creating so much text from just this one problem
that I want to save everyones time...
Now, I don't want to just dump some code and ask for help just like that, i want to try to explain what I've tried so far and what I'm trying to do specifically.
So what I want to do is create a function that detects collisions between the player (controlled by me) and the mob (enemy non moving object) and i want my pygame to automatically shut of if it detects a collision between the two. So, initially, since it's a static object I just could define an if statement, say something like "if player.x == mob.x pygame.quit(). However, that's not the solution that I want, because I've done that in previous projects and it's just really bad code, especially if i figure out later i want to move it somewhere...
So what have I tried? well, the two first functions in the codesheet below, are my two attemps at creating this detection. I'm not sure if i'm thinking wrong about this but I figured i couldn't define those functions inside the player or mob class because then it wont detect the other class definitions because they're separated. Therefore I went for the solution below, and defined the functions outside a class.
According to the examples i have searched up, there are different ways to do this, but those two below seemed to be accurate for my type of game so hence I went for those funcs as definitions, but they are clearly wrong. I'm just not sure if calling the player and mob in the func without further specification is the wrong way to approach this?
I could explain further, but I'm creating so much text from just this one problem

import pygame import tkinter as tk from tkinter import messagebox import os '''Color definitions''' BLACK = (0,0,0) BLUE = (10,10,128) GREEN = (5,200,0) RED = (255,100,100) #Screen width SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 def checkCollision(self,Player,mobs): col = pygame.sprite.collide_rect(Player, mobs) if col == True: pygame.quit() def col(self): super.__init__() collision = pygame.sprite.spritecollide_mask(Player, mobs) if collision: pygame.quit() #player class/main class class Player(pygame.sprite.Sprite): def __init__(self,x,y): super().__init__() #surface decides how big my player is self.image = pygame.Surface([50,45]) #fill decides the color of my player self.image.fill(BLUE) #Player definitions, went for rect object and turning on x and y functions self.rect = self.image.get_rect() self.rect.y = y self.rect.x = x #self.player = Player #self.mobs = mobs self.change_x = 0 self.change_y = 0 self.walls = None ''' Doesn't work def checkCollision(self,Player,Mobs): col = pygame.sprite.collide_rect(Player, Mobs) if col == True: pygame.quit() ''' def changespeed(self,x,y): self.change_x += x self.change_y += y def update(self): self.rect.x += self.change_x #bad code #if self.rect.x >= 270 and self.rect.y > 160 < 165 and self.rect.x <275: #pygame.quit() #collision = pygame.sprite.spritecollideany(Player, mobs) #if collision: #pygame.quit() #hits = pygame.sprite.spritecollide(self.player, self.mobs, False) block_hit_list = pygame.sprite.spritecollide(self,self.walls, False) for block in block_hit_list: if self.change_x > 0: self.rect.right = block.rect.left else: self.rect.left = block.rect.right self.rect.y += self.change_y block_hit_list = pygame.sprite.spritecollide(self,self.walls,False) for block in block_hit_list: if self.change_y > 0: self.rect.bottom = block.rect.top else: self.rect.top = block.rect.bottom #wall class class Wall(pygame.sprite.Sprite): def __init__(self,x,y,width,height): super().__init__() self.image = pygame.Surface([width, height]) self.image.fill(GREEN) self.rect = self.image.get_rect() self.rect.y = y self.rect.x = x class Mob(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((30, 40)) self.image.fill(RED) self.rect = self.image.get_rect() self.rect.x = 270 self.rect.y = 150 self.speedy = 0 self.mob = mobs def update(self): self.rect.y += self.speedy if self.rect.top > SCREEN_HEIGHT: self.rect.x = 150 self.rect.y = 150 self.speedy = 0 #Definitions pygame.init() screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) pygame.display.set_caption('Sandbox') all_sprite_list = pygame.sprite.Group() #walls wall_list = pygame.sprite.Group() '''Very important to remember this... first coord = x, second Y third, length fourth, height''' #Left wall wall = Wall(0,0,10,600) wall_list.add(wall) all_sprite_list.add(wall) #top wall wall = Wall(10,0,790,10) wall_list.add(wall) all_sprite_list.add(wall) #Right wall wall = Wall (790,0,10,600) wall_list.add(wall) all_sprite_list.add(wall) #Bottom wall wall = Wall (0,590,1000,300) wall_list.add(wall) all_sprite_list.add(wall) #Create the player player = Player(50,50) player.walls = wall_list all_sprite_list.add(player) clock = pygame.time.Clock() mobs = pygame.sprite.Group() wall_list.add(mobs) all_sprite_list.add(mobs) for i in range(1): m = Mob() all_sprite_list.add(m) mobs.add(m) done = False #Keybindings + run statement while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True elif event.type == pygame.KEYDOWN: if event.key == pygame.K_a: player.changespeed(-3, 0) elif event.key == pygame.K_d: player.changespeed(3, 0) elif event.key == pygame.K_w: player.changespeed(0, -3) elif event.key == pygame.K_s: player.changespeed(0, 3) elif event.type == pygame.KEYUP: if event.key == pygame.K_a: player.changespeed(3, 0) elif event.key == pygame.K_d: player.changespeed(-3, 0) elif event.key == pygame.K_w: player.changespeed(0, 3) elif event.key == pygame.K_s: player.changespeed(0, -3) '''these updates needs to be indented like this in order to actually work''' all_sprite_list.update() screen.fill(BLACK) all_sprite_list.draw(screen) pygame.display.flip() clock.tick(60) pygame.quit()