List in object gets overwritten - python-3.x

After some work I finished my first algorithm for a maze generator and now I am trying to make it visual in Pygame. I first let the algorithm generate a maze and then I make a visual representation of it.
Here I get into multiple problems, but I think they are all linked to the same thing which is that the first cell of the maze gets overwritten in some way. Because of this, what I get is totally not a maze at all but just some lines everywhere.
I tried putting the removal of walls in a seperate method, but that does not seem to work also. I looked if the remove walls method gets called at the first cell and it says it is true, but in some way the values of that cell gets overwritten.
Code:
import pygame
import random
WIDTH = 300
HEIGHT = 300
CellSize = 30
Rows = int(WIDTH/30)
Columns = int(HEIGHT/30)
current = None
grid = []
visited = []
DISPLAY = pygame.display.set_mode((WIDTH, HEIGHT))
class Cell:
def __init__(self, r, c):
self.r = r
self.c = c
self.x = CellSize * c
self.y = CellSize * r
self.sides = [True, True, True, True] # Top, Bottom, Left, Right
self.visited = False
self.neighbours = []
self.NTop = None
self.NBottom = None
self.NRight = None
self.NLeft = None
self.NTopIndex = None
self.NBottomIndex = None
self.NRightIndex = None
self.NLeftIndex = None
self.nr = None
self.nc = None
self.random = None
self.neighbour = None
def index(self, nr, nc):
self.nr = nr
self.nc = nc
if self.nr < 0 or self.nc < 0 or self.nr > Rows-1 or self.nc > Columns-1:
return -1
return self.nr + self.nc * Columns
def neighbour_check(self):
# Get neighbour positions in Grid
self.NTopIndex = self.index(self.r, self.c - 1)
self.NBottomIndex = self.index(self.r, self.c + 1)
self.NRightIndex = self.index(self.r + 1, self.c)
self.NLeftIndex = self.index(self.r - 1, self.c)
# Look if they are truly neighbours and then append to neighbour list
if self.NTopIndex >= 0:
self.NTop = grid[self.NTopIndex]
if not self.NTop.visited:
self.neighbours.append(self.NTop)
if self.NBottomIndex >= 0:
self.NBottom = grid[self.NBottomIndex]
if not self.NBottom.visited:
self.neighbours.append(self.NBottom)
if self.NRightIndex >= 0:
self.NRight = grid[self.NRightIndex]
if not self.NRight.visited:
self.neighbours.append(self.NRight)
if self.NLeftIndex >= 0:
self.NLeft = grid[self.NLeftIndex]
if not self.NLeft.visited:
self.neighbours.append(self.NLeft)
# Choose random neighbour
if len(self.neighbours) > 0:
self.random = random.randint(0, len(self.neighbours) - 1)
self.neighbour = self.neighbours[self.random]
# Remove the wall between self and neighbour
if self.neighbour == self.NTop:
if self == grid[0]:
print('TOP')
self.sides[0] = False
self.NTop.sides[1] = False
elif self.neighbour == self.NBottom:
if self == grid[0]:
print('BOTTOM')
self.sides[1] = False
self.NBottom.sides[0] = False
elif self.neighbour == self.NLeft:
if self == grid[0]:
print('LEFT')
self.sides[2] = False
self.NLeft.sides[3] = False
elif self.neighbour == self.NRight:
if self == grid[0]:
print('RIGHT')
self.sides[3] = False
self.NRight.sides[2] = False
else:
print('SIDES ERROR')
return self.neighbours[self.random]
else:
return -1
def draw(self):
global DISPLAY, CellSize
# Top
if self.sides[0]:
pygame.draw.line(DISPLAY, (0, 0, 0), (self.x, self.y), (self.x + CellSize, self.y))
# Bottom
if self.sides[1]:
pygame.draw.line(DISPLAY, (0, 0, 0), (self.x, self.y + CellSize), (self.x + CellSize, self.y + CellSize))
# Left
if self.sides[2]:
pygame.draw.line(DISPLAY, (0, 0, 0), (self.x, self.y), (self.x, self.y + CellSize))
# Right
if self.sides[3]:
pygame.draw.line(DISPLAY, (0, 0, 0), (self.x + CellSize, self.y), (self.x + CellSize, self.y + CellSize))
class Maze:
def __init__(self):
global current
self.next = None
self.running = True
self.DISPLAY = None
self.display_running = True
def init_cells(self):
# Make grid and make cell 0 the begin of the algorithm
global current
for i in range(0, Columns):
for j in range(0, Rows):
cell = Cell(j, i)
grid.append(cell)
current = grid[0]
def init_maze(self):
global current, visited
print(grid[0].sides)
# Start Algorithm
while self.running:
# Check if the current cell is visited, if not make it visited and choose new neighbour
if not current.visited:
current.visited = True
visited.append(current)
self.next = current.neighbour_check()
if not self.next == -1:
# If it finds a neighbour then make it the new current cell
# self.next.visited = True
current = self.next
elif self.next == -1 and len(visited) > 0:
# If it doesn't then look trough the path and backtrack trough it to find a possible neighbour
if len(visited) > 1:
del visited[-1]
current = visited[-1]
# If the last cell of the visited list is Cell 0 then remove it
elif len(visited) <= 1:
del visited[-1]
elif len(visited) <= 0:
# Stop the Algorithm
self.running = False
print('Done')
def draw(self):
DISPLAY.fill((255, 255, 255))
# Get the maze made by the algorithm and draw it on the screen
for i in range(0, len(grid)):
grid[i].draw()
pygame.display.update()
while self.display_running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.display_running = False
maze = Maze()
maze.init_cells()
maze.init_maze()
maze.draw()
I put some print methods in it for debugging purposes.
And am still a beginner in programming, I know it could probably be way cleaner or that some naming of methods could be better.
What I want to happen is that in def init_maze the maze blueprints gets written out and that in def draw the blueprint gets drawn on the screen.

Related

A-star algorithm freezing seemlingly random after some time in Snake

I'm making an AI for the game Snake, here's my Code:
import math
class Node():
def __init__(self, parent=None, position=None):
self.parent = parent
self.position = position
self.g = 0
self.h = 0
self.f = 0
def __eq__(self, other):
return self.position == other.position
def astar(maze, start, end):
# Initialize the open list
open_list = []
start_node = Node(None, start)
start_node.g = start_node.h = start_node.f = 0
open_list.append(start_node)
# Initialize the closed list
closed_list = []
end_node = Node(None, end)
# While the open list is not empty
while len(open_list) > 0:
current_node = open_list[0]
current_index = 0
# Find the node with the least f on the open list
for index, item in enumerate(open_list):
if item.f < current_node.f:
current_node = item
current_index = index
# Pop current node off the open list
open_list.pop(current_index)
# Push current node on the closed list
closed_list.append(current_node)
# If current node is goal, then stop search
if current_node == end_node:
path = []
current = current_node
while current is not None:
path.append(current.position)
current = current.parent
return path[::-1]
# Find the 4 neighboring squares
children = []
for new_position in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])
# Make sure it's within the maze
if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0:
continue
# Make sure it's not a wall
if maze[node_position[0]][node_position[1]] != 0:
continue
new_node = Node(current_node, node_position)
children.append(new_node)
# For each child
flag = 0
for child in children:
if child in closed_list:
continue
child.g = current_node.g + 1
child.h = hueristic_estimate(child, end_node)
child.f = child.g + child.h
for open_node in open_list:
if child.position == open_node.position and child.f > open_node.f:
flag = 1
break
if flag == 1:
continue
open_list.append(child)
return None
def hueristic_estimate(start_node, end_node):
return ((start_node.position[0] - end_node.position[0]) ** 2 + (start_node.position[1] - end_node.position[1]) ** 2) * 4
I have no idea why, but after a bit, around when the snake get's about 15 in length, it will freeze. I don't know whether it's running very, very, very slow or if it's in an infinite loop. I'm pretty sure this should be all correct, yet the problem persists.

I keep getting "pygame.sprite.Sprite.add() argument after * must be an iterable, not int" error

I am trying to make a platforming game and I keep getting this error when I tried to add particles for when the character jumps, and I can't figure it out. Everytime I try and jump with the character the error pops up. I will need some help in order to fix this.
Code for the Level
import pygame
# Importing the necessary files
from tiles import Tile
from settings import tile_size, screen_width
from player import Player
from particles import ParticleEffect
class Level:
def __init__(self, level_data, surface):
# Level setup
self.display_surface = surface
self.setup_level(level_data)
self.world_shift = 0
self.current_x = 0
# Particles
self.dust_sprite = pygame.sprite.GroupSingle()
def setup_level(self, layout):
self.tiles = pygame.sprite.Group()
self.player = pygame.sprite.GroupSingle()
for row_index, row in enumerate(layout):
for column_index, cell in enumerate(row):
x = column_index * tile_size
y = row_index * tile_size
if cell == "X":
tile = Tile((x, y), tile_size)
self.tiles.add(tile)
if cell == "P":
player_sprite = Player((x, y), self.display_surface, self.jump_particles)
self.player.add(player_sprite)
def jump_particles(self, pos):
jump_particle_sprite = ParticleEffect(pos, 'Jump')
self.dust_sprite.add(jump_particle_sprite)
def scroll_x(self):
player = self.player.sprite
player_x = player.rect.centerx
direction_x = player.direction.x
if player_x < screen_width / 4 and direction_x < 0:
self.world_shift = 8
player.speed = 0
elif player_x > screen_width - (screen_width / 4) and direction_x > 0:
self.world_shift = -8
player.speed = 0
else:
self.world_shift = 0
player.speed = 8
# Checks for horizontal collisions with the tiles
def horizontal_collision(self):
player = self.player.sprite
player.rect.x += player.direction.x * player.speed
for sprite in self.tiles.sprites():
if sprite.rect.colliderect((player.rect)):
if player.direction.x < 0:
player.rect.left = sprite.rect.right
player.on_left = True
self.current_x = player.rect.left
elif player.direction.x > 0:
player.rect.right = sprite.rect.left
player.on_right = True
self.current_x = player.rect.right
if player.on_left == True and (player.rect.left < self.current_x or player.direction.x >= 0):
player.on_left = False
if player.on_right == True and (player.rect.left > self.current_x or player.direction.x <= 0):
player.on_right = False
def vertical_collision(self):
player = self.player.sprite
player.apply_gravity()
for sprite in self.tiles.sprites():
if sprite.rect.colliderect((player.rect)):
if player.direction.y > 0:
player.rect.bottom = sprite.rect.top
player.direction.y = 0
player.on_ground = True
elif player.direction.y < 0:
player.rect.top = sprite.rect.bottom
player.direction.y = 0
player.on_ceiling = True
if player.on_ground == True and player.direction.y < 0 or player.direction.y > 1:
player.on_ground = False
if player.on_ceiling == True and player.direction.y > 0:
player.on_ceiling = False
def run(self):
# Tiles for the level
self.tiles.update(self.world_shift)
self.tiles.draw(self.display_surface)
self.scroll_x()
# Dust Particles
self.dust_sprite.update(self.world_shift)
self.dust_sprite.draw(self.display_surface)
# Player for the level
self.player.update()
self.horizontal_collision()
self.vertical_collision()
self.player.draw(self.display_surface)
Code for the Class ParticleEffect
import pygame
from support import import_folder
class ParticleEffect(pygame.sprite.Sprite):
def _init__(self, pos, type):
super().__init__()
self.frame_index = 0
self.animation_speed = 0.5
if type == 'Jump':
self.frames = import_folder('Hero/Dust Particles/Jump')
if type == 'Land':
self.frames = import_folder('Hero/Dust Particles/Land')
self.image = self.frames[self.frame_index]
self.rect = self.image.get_rect(center = pos)
def animate(self):
self.frame_index += self.animation_speed
if self.frame_index >= len(self.frames):
self.kill()
else:
self.image = self.frames[int(self.frame_index)]
def update(self, x_shift):
self.animate()
self.rect.x += x_shift
import_folder is just a class used for loading images.
The full error is
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\player.py", line 109, in get_input
self.jump_particles(self.rect.midbottom)
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\level.py", line 35, in jump_particles
jump_particle_sprite = ParticleEffect(pos, 'Jump')
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\venv\lib\site-packages\pygame\sprite.py", line 115, in __init__
self.add(*groups)
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\venv\lib\site-packages\pygame\sprite.py", line 133, in add
self.add(*group)
File "C:\School\KS5\Computer Science\Project\Coding\pythonProject\venv\lib\site-packages\pygame\sprite.py", line 133, in add
self.add(*group)
TypeError: pygame.sprite.Sprite.add() argument after * must be an iterable, not int
You have a typo in the __init__() method in your ParticleEffect class that is causing this issue.
The def _init__(self, pos, type) is missing a underscore _ at the beginning.

Bug causes player to collide with the first two obstacles and nothing else [duplicate]

This question already has answers here:
How do I detect collision in pygame?
(5 answers)
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
I'm making a game environment for NEAT. The first two obstacles seem to collide with the players just fine, but none of the other obstacles do anything. The visuals won't work, but based on the size of the player list, yeah no it's not working. The collide class also wouldn't work before I started implementing NEAT, so there's that.
Anyway here's some (probably) irrelevant code:
import pygame
from pygame.locals import *
import random
import os
import neat
debugfun = 0
W = 300
H = 300
win = pygame.display.set_mode((W, H))
pygame.display.set_caption("bruv moment")
coords = [0, 60, 120, 180, 240]
class Player(object):
def __init__(self, x):
self.x = x
self.y = 600 - 60
self.width = 60
self.height = 60
self.pos = 0
self.left = False
self.right = False
def move(self):
if self.left:
self.pos -= 1
if self.right:
self.pos += 1
if self.pos < 0:
self.pos = 4
if self.pos > 4:
self.pos = 0
self.x = coords[self.pos]
class Block(object):
def __init__(self, pos, vel):
self.pos = pos
self.x = coords[self.pos]
self.y = -60
self.width = 60
self.height = 60
self.vel = vel
def move(self):
self.y += self.vel
def redraw_window():
pygame.draw.rect(win, (0, 0, 0), (0, 0, W, H))
for ob in obs:
pygame.draw.rect(win, (0, 255, 0), (ob.x, ob.y, ob.width, ob.height))
for ind in homies:
pygame.draw.rect(win, (255, 0, 0), (ind.x, ind.y, ind.width, ind.height))
pygame.display.update()
obs = []
homies = []
player_collision = False
ge = []
nets = []
And here's some relevant code:
def collide():
for ob in obs:
for x, ind in enumerate(homies):
if ind.y < ob.y + ob.height and ind.y + ind.height > ob.y and ind.x + ind.width > ob.x and ind.x < ob.x + ob.width:
ge[x].fitness -= 1
homies.pop(x)
nets.pop(x)
ge.pop(x)
def main(genomes, config):
speed = 30
pygame.time.set_timer(USEREVENT + 1, 550)
pygame.time.set_timer(USEREVENT + 2, 1000)
for _, g in genomes:
net = neat.nn.FeedForwardNetwork.create(g, config)
nets.append(net)
homies.append(Player(0))
g.fitness = 0
ge.append(g)
clock = pygame.time.Clock()
ran = True
while ran and len(homies) > 0:
clock.tick(27)
collide()
for x, ind in enumerate(homies):
ind.move()
ge[x].fitness += 0.1
try:
output = nets[x].activate((ind.x, abs(obs[0].x - ind.x)))
except IndexError:
output = 50
try:
if output in range(5, 25):
ind.left = True
else:
ind.left = False
if output > 25:
ind.right = True
else:
ind.right = False
except TypeError:
if output[0] in range(5, 25):
ind.left = True
else:
ind.left = False
if output[1] > 25:
ind.right = True
else:
ind.right = False
for ob in obs:
ob.move()
if ob.x > H:
obs.pop(obs.index(ob))
for event in pygame.event.get():
if event.type == pygame.QUIT:
ran = False
pygame.quit()
if event.type == USEREVENT+1:
if speed <= 200:
speed += 3
if event.type == USEREVENT+2:
for g in ge:
g.fitness += 0.5
if len(obs) == 0:
obs.append(Block(round(random.randint(0, 4)), speed))
print(len(homies))
print(len(obs))
redraw_window()
def run(config_file):
config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction, neat.DefaultSpeciesSet,
neat.DefaultStagnation, config_path)
p = neat.Population(config)
p.add_reporter(neat.StdOutReporter(True))
stats = neat.StatisticsReporter()
p.add_reporter(stats)
winner = p.run(main, 50)
if __name__ == "__main__":
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, "avoidpedofiles.txt")
run(config_path)

pygame sets position of all instances of class to the same value for some reason?

I'm making a snake game in pygame and i've run into a problem. Whenever the snake eats food, the player gains a point. From that point on a tail is created behind the snake whenever it moves. Only the tails the number of player points away from the snake head will be drawn while the rest are deleted. The problem arises when i'm creating the tails. Whenever i create an instance of the tail, i have to get the position of the snake head and subtract away a value equal to the snake size in the opposite direction. That's where the tail will be drawn. However the position of all the tails are set to the same value for some reason and i cant't figure out why that is. I'm using my own library so i cant post it in here but iv'e determined it's not the cause.
import pygame as pg
from random import randrange
import widget
# disp -> display properties
disp = widget.get_json("config", ["display"])
food = widget.Surface(image="../images/food.png", pos=[0, 0])
def set_food_pos(snake):
while True:
pos = [randrange(0, disp["size"][_], disp["cell"]) for _ in range(2)]
safe = 0
for tail in snake.tails:
if tail.pos != pos: safe += 1
if safe == len(snake.tails):
food.pos = pos
food.rect.topleft = food.pos
break
class Snake(widget.Sprite):
""" Snake: main playable sprite """
SIZE = [disp["cell"]] * 2
KEYS = [[276, 275], [273, 274]]
def __init__(self):
self.image = pg.image.load("../images/snake_head.png")
self.pos = widget.VEC(0, 0)
super().__init__(pg.sprite.GroupSingle)
self.axis, self.orient, self.do_move = 0, 1, False
self.past, self.delay = pg.time.get_ticks(), 150
self.speed, self.vel = disp["cell"], [-1, 1]
self.alive, self.points = True, 0
self.tails = [self]
def control(self, key):
axis = [0 if key in Snake.KEYS[0] else 1][0]
if axis != self.axis:
if self.do_move:
self.axis = axis
self.orient = Snake.KEYS[axis].index(key)
self.do_move = False
def time_base_movement(self):
now = pg.time.get_ticks()
if now - self.past >= self.delay:
self.do_move = True
self.pos[self.axis] += self.vel[self.orient] * self.speed
self.past = pg.time.get_ticks()
def eat_food(self):
if food.rect.contains(self.rect):
set_food_pos(self)
self.points += 1
def create_tail(self):
if self.points:
if self.do_move:
pos = [_ for _ in self.rect.topleft]
pos[self.axis] += self.vel[::-1][self.orient] * 20
tail = widget.Sprite(image="../images/snake_head.png", pos=pos)
self.tails.insert(0, tail)
def render_tails(self, surface):
if self.points > 0:
tails = self.tails[:-1]
for tail in tails[0:self.points]: tail.group.draw(surface)
[self.tails.remove(tail) for tail in tails[self.points:]]
def check_boundary_collision(self):
for _ in range(2):
if self.pos[_] > disp["size"][_] - Snake.SIZE[_]:self.alive = False
elif self.pos[_] < 0: self.alive = False
for tail in self.tails[:-1]:
if tail.rect.contains(self.rect): self.alive = False
def reset_properties(self):
if self.alive == False:
print([tail.pos for tail in self.tails[:-1]])
self.tails = [self]
self.do_move = False
self.pos = widget.VEC([0, 0])
self.rect.topleft = self.pos
self.axis, self.orient = 0, 1
self.points, self.alive = 0, True
set_food_pos(self)
def update(self):
if self.alive:
self.time_base_movement()
self.check_boundary_collision()
self.reset_properties()
self.rect.topleft = self.pos
I figured it out, it seems python doesn't create a new copy of an attribute each time it is assigned to a different attribue. Instead the new attribute points to the assigned attribute. The fix for this is the "deepcopy" method in the built in module "copy".
Exe: new_value = copy.deepcopy(old_value)

Collision between a rect and a circle

The problem is next, I have falling circles and I need them to be deleted if they will overlap with the player. I have tried to create a bunch of methods to get coordinates of the circles and the rectangle however when i try checking if they overlap i get an error.
TypeError: unorderable types: method() > method()
Here is the code:
# Colour
# Created by Niktia Kotter
#!/usr/bin/env python
import pygame, sys, random, time
from pygame.locals import*
# set up pygame
pygame.init()
FPS=60
fpsclock = pygame.time.Clock()
# colours R G B
WHITE = (255, 255, 255)
BLACK = (0 , 0 , 0 )
RED = (237, 28 , 36 )
# set up screen
SCREEN_W = 800
SCREEN_H = 480
SCREEN = pygame.display.set_mode((SCREEN_W,SCREEN_H),0,32)
snapMultX = SCREEN_W / 5
snapMultY = SCREEN_H / 5
basicFont = pygame.font.SysFont(None, 32)
# set up functions
def isPointInsideRect(Cx, Cy, rectX, rectY, rectW, rectH ):
if ((Cx > rectX) and \
(Cx < rectY) and \
(Cy > rectW) and \
(Cy < rectH)):
return True
else:
return False
"""
def doRectsOverlap(rect1, rect2):
for a,b in [(rect1, rect2), (rect2, rect1)]:
# check if a's corners are inside b
if ((isPointInsideRect(a.left, a.top, b)) or
(isPointInsideRect(a.left, a.bottom, b)) or
(isPointInsideRect(a.right, a.top, b)) or
(isPointInsideRect(a.right, a.bottom, b))):
return True
return False
"""
# set up calsses
class Actor:
def __init__ (self):
self._x = snapMultX*2
self._y = SCREEN_H - snapMultX/5 -(snapMultX/2)
self._w = snapMultX
self._h = snapMultX/2
self._colour = WHITE
self._Rect = pygame.Rect(self._x, self._y, self._w, self._h)
def moveRight(self):
self._x += snapMultX
def moveLeft(self):
self._x -= snapMultX
def draw(self):
pygame.draw.rect(SCREEN, self._colour, (self._x, self._y, self._w, self._h))
return
def rectX(self):
return self._x
def rectY(self):
return self._y
def rectW(self):
return self._w
def rectH(self):
return self._h
class Enemy:
def __init__ (self, location):
self._x = snapMultX*location+snapMultX/2
self._y = 0
self._r = snapMultX/10
self._colour = WHITE
def move(self, dy):
self._y += dy
def draw(self):
pygame.draw.circle(SCREEN, self._colour, (int(self._x),int(self._y)), int(self._r), 0)
return
def GetCircleX(self):
return self._x
def GetCircleY(self):
return self._y
class Capture(object):
def __init__(self):
self.caption = pygame.display.set_caption('Space Invaders')
self.screen = SCREEN
self.startGame = True
self.gameOver = False
self.enemyCount = 0
self.timer = 50
self.score = 0
def main(self):
clock = pygame.time.Clock()
enemy =[]
player = Actor()
while True:
if self.startGame:
SCREEN.fill(BLACK)
pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*1-snapMultX/5*2,0), (snapMultX*0+snapMultX/5*2,0), (snapMultX*0+snapMultX/2,snapMultY/4)])
pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*2-snapMultX/5*2,0), (snapMultX*1+snapMultX/5*2,0), (snapMultX*1+snapMultX/2,snapMultY/4)])
pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*3-snapMultX/5*2,0), (snapMultX*2+snapMultX/5*2,0), (snapMultX*2+snapMultX/2,snapMultY/4)])
pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*4-snapMultX/5*2,0), (snapMultX*3+snapMultX/5*2,0), (snapMultX*3+snapMultX/2,snapMultY/4)])
pygame.draw.polygon(SCREEN,WHITE, [(snapMultX*5-snapMultX/5*2,0), (snapMultX*4+snapMultX/5*2,0), (snapMultX*4+snapMultX/2,snapMultY/4)])
player.draw()
# enemy move/spawn timer
self.timer -= 1
# enemy spawner
if self.timer <= 0:
num = random.randint(0, 5)
if num == 0:
print (0)
enemy.append(Enemy(0))
if num == 1:
print (1)
enemy.append(Enemy(1))
if num == 2:
print (2)
enemy.append(Enemy(2))
if num == 3:
print (3)
enemy.append(Enemy(3))
if num == 4:
print (4)
enemy.append(Enemy(4))
# player mover
for event in pygame.event.get():
if player._x != snapMultX*4 and (event.type == KEYDOWN) and (event.key == K_d):
player.moveRight()
if player._x != 0 and(event.type == KEYDOWN) and (event.key == K_a):
player.moveLeft()
if event.type == QUIT:
pygame.quit()
sys.exit()
# enemy logic
if self.timer <= 0:
for e in enemy:
e.move(snapMultY)
if isPointInsideRect(e.GetCircleX, e.GetCircleY, player.rectX, player.rectY, player.rectW, player.rectH):
self.score += 1
enemy.remove(e)
if e._y > snapMultY*5:
enemy.remove(e)
# reste timer
self.timer = 50
for e in enemy:
e.draw()
# score
self.myScore = "Score = " + str(self.score)
text = basicFont.render(self.myScore, True, RED, WHITE)
textRect = text.get_rect()
textRect.centerx = SCREEN.get_rect().centerx
textRect.centery = SCREEN.get_rect().centery
SCREEN.blit(text, textRect)
pygame.display.update()
fpsclock.tick(FPS)
if __name__ == '__main__':
game = Capture()
game.main()
The cause of your error is actually a typo and the joys of Python Duck Typing. The key to debugging is understanding what the error means.
Your error "TypeError: unorderable types: method() > method()". What does this mean?
Obviously you have a type error, but what does that really mean. It means that Python is trying to complete an operation that has certain requirements. In this case in has do to with unorderable types - we are trying to do a comparison on two things that don't have an orderable property so that they can't be compared in that way. The next portion says "method() > method()". That means we are attempting to compare that one method is greater than another. That probably isn't what is intended.
So now we have to look at those comparisons in our ifs. Lets look at isPointInsideRect.
def isPointInsideRect(Cx, Cy, rectX, rectY, rectW, rectH ):
if ((Cx > rectX) and (Cx < rectY) and (Cy > rectW) and (Cy < rectH)):
return True
else:
return False
Here we are doing a whole bunch of comparisons on six values. Lets look at where this method gets called? This function gets called in one uncommented-out line (Line 175).
if isPointInsideRect(e.GetCircleX, e.GetCircleY, player.rectX, player.rectY, player.rectW, player.rectH):
Do you see the issue here? Each of those values that you are passing into the function aren't values, they are method definitions. Hence, everytime isPointInsideRect is doing those comparisons, they are comparing one method to another. And that isn't a valid comparison.
Trying changing line 175 to:
if isPointInsideRect(e.GetCircleX(), e.GetCircleY(), player.rectX(), player.rectY(), player.rectW(), player.rectH()):

Resources