I am creating a space type game for a school competition. Im going to use stars (white dots) moving outwards to give an effect of moving in space. Next I would check to see if a star's x cords are less than the centre or the screen (move the star to the left) and if the x coordinate is larger (Move to the right). However, I can't seem to make more than one instance of the stars class.Here is an image of the kind of thing I want . Help is very appreciated.
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((1200, 800))
caption = pygame.display.set_caption("sapce game")
screen.fill((56, 56, 56))
white = (255, 255, 255)
class Stars:
def __init__(self):
self.x = random.randint(0, 600)
self.y = random.randint(0, 400)
self.pos = (self.x, self.y)
def move(self):
pygame.draw.circle(screen, white, (self.x, self.y), 4)
self.y -= 1
self.x -= 2
screen.fill((56, 56, 56))
pygame.draw.circle(screen, white, (self.x, self.y), 4)
pygame.display.update()
s = Stars()
run = True
while run:
s.move()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
quit()
First of all you have to put scrre.fill and pygame.display.update() in the main application loop. Remove this calls from Stars.move:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
quit()
screen.fill((56, 56, 56))
s.move()
pygame.display.update()
Note, you want to clear the display once, then draw all the stars and finally update the display.
Create a list of stars:
star_list = []
for i in range(10):
star_list.append(Stars())
Move and draw the stars in a loop:
run = True
while run:
# [...]
screen.fill((56, 56, 56))
for s in star_list:
s.move()
pygame.display.update()
Example code:
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((1200, 800))
caption = pygame.display.set_caption("sapce game")
screen.fill((56, 56, 56))
white = (255, 255, 255)
class Stars:
def __init__(self):
self.x = random.randint(0, 600)
self.y = random.randint(0, 400)
self.dx, self.dy = 0, 0
while self.dx == 0:
self.dx = random.randint(-2, 2)
while self.dy == 0:
self.dy = random.randint(-2, 2)
self.pos = (self.x, self.y)
def move(self):
self.x += self.dx
self.y += self.dy
if self.x <= 0 or self.x >= 1200:
self.dx = -self.dx
if self.y <= 0 or self.y >= 800:
self.dy = -self.dy
pygame.draw.circle(screen, white, (self.x, self.y), 4)
star_list = []
for i in range(10):
star_list.append(Stars())
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
quit()
screen.fill((56, 56, 56))
for s in star_list:
s.move()
pygame.display.update()
Related
This question already has answers here:
How do I detect collision in pygame?
(5 answers)
Closed 7 months ago.
I'm working in pygame & python and trying to make a zombie shooting game. It all worked smoothly until I tried to add the collision system. If you also know how to add a collision system for this game please leave a comment with a full code.
The error:
type object 'bullet' has no attribute 'rect'
File "C:\Users\*\Desktop\Zombie!\main.py", line 172, in game
collide = pygame.sprite.spritecollide(bullet, enemiesList, False)
File "C:\Users\*\Desktop\Zombie!\main.py", line 44, in menu
game()
File "C:\Users\*\Desktop\Zombie!\main.py", line 211, in <module>
menu()
The code:
import pygame, sys, math, random, time
pygame.init()
#var
screen = pygame.display.set_mode([800, 500])
font = pygame.font.SysFont(None, 20)
playerX = 200
playerY = 200
player = pygame.Rect((playerX, playerY), (10,10))
bullets = pygame.sprite.Group()
clock = pygame.time.Clock()
previous_time = pygame.time.get_ticks()
waveCount = 1
#Remaining enemy count
enemiesList = pygame.sprite.Group()
normalEnemy = 0
speedyEnemy = 0
tankEnemy = 0
def draw_text(text, font, color, surface, x, y):
textobj = font.render(text, 1, color)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
click = False
def menu():
while True:
global click
screen.fill((0,0,0))
draw_text('main menu', font, (255, 255, 255), screen, 20, 20)
mx, my = pygame.mouse.get_pos()
button_1 = pygame.Rect(50, 100, 200, 50)
button_2 = pygame.Rect(50, 200, 200, 50)
if button_1.collidepoint((mx, my)):
if click:
game()
if button_2.collidepoint((mx, my)):
if click:
options()
pygame.draw.rect(screen, (255, 0, 0), button_1)
pygame.draw.rect(screen, (255, 0, 0), button_2)
click = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
click = True
pygame.display.update()
clock.tick(60)
def game():
run = True
class bullet(pygame.sprite.Sprite):
def __init__(self, x, y, mx, my):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.mx = mx
self.my = my
self.speed = 10
self.angle = math.atan2(my-self.y, mx-self.x)
self.x_vel = math.cos(self.angle) * self.speed
self.y_vel = math.sin(self.angle) * self.speed
self.radius = 4
self.mask = pygame.mask.Mask((self.radius, self.radius), True)
self.rect = pygame.Rect(self.x, self.y, self.radius, self.radius)
def update(self):
self.x += int(self.x_vel)
self.y += int(self.y_vel)
pygame.draw.circle(screen, (0, 255, 255), (self.x + 5, self.y + 5), self.radius)
if self.x > 800 or self.x < 0 or self.y > 500 or self.y < 0:
#Remove Bullet Class from list(bullets)
self.kill()
class enemy(pygame.sprite.Sprite):
def __init__(self, enemyType, x, y):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
if enemyType == "normal":
self.speed = 1
self.hp = 1
self.color = (255, 28, 28)
self.radius = 10
if enemyType == "speedy":
self.speed = 3
self.hp = 1
if enemyType == "tank":
self.speed = 3
self.hp = 3
self.mask = pygame.mask.Mask((self.radius, self.radius), True)
self.rect = pygame.Rect(self.x, self.y, self.radius, self.radius)
def update(self):
global playerX, playerY, enemiesList, bullets
# Find direction vector (dx, dy) between enemy and player.
dx, dy = playerX - self.x, playerY - self.y
dist = math.hypot(dx, dy)
dx, dy = dx / dist, dy / dist # Normalize.
# Move along this normalized vector towards the player at current speed.
self.x += dx * self.speed
self.y += dy * self.speed
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius)
#Wave system
def waves(waveNumber):
global normalEnemy,speedyEnemy, tankEnemy, enemiesList, waveCount
if waveNumber == 1:
normalEnemy = 5
speedyEnemy = 0
tankEnemy = 0
for i in range(5):
enemiesList.add(enemy("normal", random.randint(0, 800), random.randint(0, 600)))
if waveNumber == 2:
normalEnemy = 7
speedyEnemy = 0
tankEnemy = 0
while run:
clock.tick(60)
screen.fill([255, 255, 255])
mx, my= pygame.mouse.get_pos()
#movements
def movement():
global playerX, playerY, previous_time
key = pygame.key.get_pressed()
mouse = pygame.mouse.get_pressed()
if key[pygame.K_w]:
playerY -= 5
if key[pygame.K_s]:
playerY += 5
if key[pygame.K_d]:
playerX += 5
if key[pygame.K_a]:
playerX -= 5
if mouse[0]:
current_time = pygame.time.get_ticks()
if current_time - previous_time > 500:
previous_time = current_time
bullets.add(bullet(playerX, playerY, mx, my))
for bullets_ in bullets:
bullets_.update()
for enemies_ in enemiesList:
enemies_.update()
if normalEnemy == 0 and speedyEnemy == 0 and tankEnemy == 0:
waves(waveCount)
collide = pygame.sprite.spritecollide(bullet, enemiesList, False)
def draw():
global player, waveCount
player = pygame.Rect((playerX, playerY), (10,10))
pygame.draw.rect(screen, (0, 255, 0), player)
draw_text('wave:' + str(waveCount), font, (0, 0, 0), screen, 20, 20)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
movement()
draw()
pygame.display.flip()
def options():
running = True
while running:
screen.fill((0,0,0))
draw_text('options', font, (255, 255, 255), screen, 20, 20)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
pygame.display.update()
clock.tick(60)
menu()
I am pretty sure I assigned self.rect at the bullet class, I checked the indents and the spelling but I can't to seem to find the error.
You have a Group bullets and a Group enemiesList. Use pygame.sprite.groupcollide() to detect collisions between Sprites in Groups:
collide = pygame.sprite.groupcollide(bullets, enemiesList, False, False)
Look at the error: type error bullet ... . Somewhere, you're using the bullet class name instead of using an instance of that class.
pygame.sprite.spritecollide - assumes that first parameter is an instance of a class which has 'rect' attribute. But you put the class itself there.
I believe the code must looks like this:
for bullets_ in bullets:
collide = pygame.sprite.spritecollide(bullets_, enemiesList, False)
I am creating a game with pygame & python 3.10.0 using VSCode everything is working fine but this if statement stops working after sometime and the font doesn't draw but I can't pinpoint the problem for that , for the if statement it usually runs till 10 or 11 score but it can be quicker like 2:
if player.rect.colliderect(food):
pygame.sprite.Sprite.kill(food)
food.rect.x = random.randrange(20, 1700)
food.rect.y = random.randrange(20, 860)
all_sprites_list.add(food)
score += 1
print(score)
whole code:
import pygame
import sys
import time
import random
import ctypes
from ctypes import wintypes
from pygame import sprite
from pygame.draw import rect
from pygame.event import pump, wait
from pygame import font
pygame.font.init()
myappid = 'elementalstudios.snake.Alpha 0_1' # arbitrary string
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
#------ Initialize Variables------#
# Player
player_width = 20
player_height = 20
# Food
food_width = 10
food_height = 10
# Colours
seafoam_gr = (159, 226, 191)
black = (0, 0, 0)
blue = (0, 0, 255)
red = (255, 0, 0)
green = (0, 255, 0)
white = (255, 255, 255)
# Score
score = 0
#------ Score Font Initialize ------#
font = pygame.font.Font(None, 50)
text = font.render("Score:", False, white, None)
#------Sprites Class------#
class Sprite(pygame.sprite.Sprite):
def __init__(self, color, height, width):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(seafoam_gr)
self.image.set_colorkey(black)
pygame.draw.rect(self.image,
color,
pygame.Rect(0, 0, width, height))
self.rect = self.image.get_rect()
def moveRight(self, pixels):
self.rect.x += pixels
def moveLeft(self, pixels):
self.rect.x -= pixels
def moveUp(self, speed):
self.rect.y -= speed * speed / 5
def moveDown(self, speed):
self.rect.y += speed * speed / 5
#------ Font Class ------#
def create_font(t,s = 24, colour_font = white, bold = False, italic = False):
font = pygame.font.Font("prstart.ttf", s, bold, italic)
text = font.render(t, True, colour_font)
return text
#------ Initialize Pygame and Window------#
pygame.init()
icon = pygame.image.load('Icon.ico')
pygame.display.set_icon(icon)
gameDisplay = pygame.display.set_mode((1920,1080), pygame.FULLSCREEN)
#rect = pygame.Rect( * gameDisplay.get_rect().center, 0, 0).inflate(100, 100)
pygame.display.set_caption("Blocky")
gameDisplay.fill(black)
clock = pygame.time.Clock()
running = True
#------Initialize Sprites------#
all_sprites_list = pygame.sprite.Group()
player = Sprite(seafoam_gr, player_height, player_width)
food = Sprite(red, food_height, food_width)
player.rect.x = 960
player.rect.y = 540
food.rect.x = 20 #random.randrange(20, 1800)
food.rect.y = 30 #random.randrange(20, 1050)
#------Add Sprites to sprite list------#
all_sprites_list.add(player)
all_sprites_list.add(food)
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
#------Eating------#
if player.rect.colliderect(food):
pygame.sprite.Sprite.kill(food)
food.rect.x = random.randrange(20, 1700)
food.rect.y = random.randrange(20, 860)
all_sprites_list.add(food)
score += 1
print(score)
#------ Score Draw ------#
text_rect = text.get_rect()
text_rect.center = (100, 150)
gameDisplay.blit(text, text_rect)
#------Key Movement------#
keys = pygame.key.get_pressed()
# Move Left
if keys[pygame.K_a]:
player.moveLeft(3)
if keys[pygame.K_LCTRL]:
player.moveLeft(5)
if keys[pygame.K_LEFT]:
player.moveLeft(3)
if keys[pygame.K_LCTRL]:
player.moveLeft(5)
# Move Right
if keys[pygame.K_d]:
player.moveRight(5)
if keys[pygame.K_LCTRL]:
player.moveRight(5)
if keys[pygame.K_RIGHT]:
player.moveRight(3)
if keys[pygame.K_LCTRL]:
player.moveRight(5)
# Move Down
if keys[pygame.K_s]:
player.moveDown(3)
if keys[pygame.K_LCTRL]:
player.moveDown(5)
if keys[pygame.K_DOWN]:
player.moveDown(3)
if keys[pygame.K_LCTRL]:
player.moveDown(5)
# Move Up
if keys[pygame.K_w]:
player.moveUp(3)
if keys[pygame.K_LCTRL]:
player.moveUp(5)
if keys[pygame.K_UP]:
player.moveUp(3)
if keys[pygame.K_LCTRL]:
player.moveUp(5)
all_sprites_list.update()
gameDisplay.fill(black)
all_sprites_list.draw(gameDisplay)
pygame.display.flip()
clock.tick(60)
pygame.quit()
quit()
It is not necessary to kill the food object. It is sufficient to change the position of the food. pygame.sprite.Sprite.kill just removes the Sprite object from all Gorups. So there is no point in calling kill and then adding the object back to the Group.
The text does not show up, because you draw it before you clear the display. pygame.Surface.fill fills the Surface with a solid color. Everything that was previously drawn will be cleared. blit the text after fill.
You will have to render the text Surface again if the score has changed.
I recommend simplifying the code that moves the player. See How can I make a sprite move when key is held down.
class Sprite(pygame.sprite.Sprite):
def __init__(self, color, x, y, height, width):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.image.set_colorkey(black)
self.rect = self.image.get_rect(topleft = (x, y))
self.x, self.y = self.rect.x, self.rect.y
def move(self, move_x, move_y, speed_up):
if move_x or move_y:
direction = pygame.math.Vector2(move_x, move_y)
direction.scale_to_length(5 if speed_up else 3)
self.x += direction.x
self.y += direction.y
self.rect.x, self.rect.y = round(self.x), round(self.y)
player = Sprite(seafoam_gr, 400, 300, player_height, player_width)
food = Sprite(red, 20, 30, food_height, food_width)
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if player.rect.colliderect(food):
food.rect.x = random.randrange(20, 780)
food.rect.y = random.randrange(20, 580)
score += 1
# render text
text = font.render("Score: " + str(score), False, white, None)
keys = pygame.key.get_pressed()
move_x = ((keys[pygame.K_d] or keys[pygame.K_RIGHT]) - (keys[pygame.K_a] or keys[pygame.K_LEFT]))
move_y = ((keys[pygame.K_s] or keys[pygame.K_DOWN]) - (keys[pygame.K_w] or keys[pygame.K_UP]))
player.move(move_x, move_y, keys[pygame.K_LCTRL])
all_sprites_list.update()
gameDisplay.fill(black)
# draw text
gameDisplay.blit(text, text.get_rect(center = (100, 150)))
all_sprites_list.draw(gameDisplay)
pygame.display.flip()
clock.tick(60)
pygame.quit()
quit()
This question already has answers here:
pygame 2 dimensional movement of an enemy towards the player, how to calculate x and y velocity?
(1 answer)
Pygame make sprite walk in given rotation
(1 answer)
How to make smooth movement in pygame
(2 answers)
Closed 1 year ago.
I created a circle in pygame. The circle moves to wherever you click, but instead of "walking" over there, it just appears. I tried some ways, but it doesn't work. If you could find out a way to do it, that would be great. The moving function is in the move function in the Player class.
# import
import pygame
# initialize pygame
pygame.init()
# frame rate variables
FPS = 120
clock = pygame.time.Clock()
# game variables
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 800
mouse_pos = ''
# colors
BLUE = (0, 0, 255)
# activate screen
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Bonker')
class Player(pygame.sprite.Sprite):
def __init__(self, x, y):
# init the sprite class
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.mouse_x = 0
self.mouse_y = 0
def move(self):
# delta x and delta y
dx = 0
dy = 0
# extract info from tuple
(x, y) = mouse_pos
self.mouse_x = x
self.mouse_y = y
# create tuple destination and current position tuple
destination = (self.mouse_x, self.mouse_y)
current_pos = [self.x, self.y]
# draw the rectangle
if current_pos[0] >= SCREEN_WIDTH // 2:
dx = 10
self.x += dx
if current_pos[0] < SCREEN_WIDTH // 2:
dx = -10
self.x += dx
if current_pos[1] >= SCREEN_HEIGHT // 2:
dy = 10
self.y += dy
if current_pos[1] < SCREEN_HEIGHT // 2:
dy = -10
self.y += dy
pygame.draw.circle(screen, BLUE, (self.x, self.y), 20)
def draw(self):
# draw the circle
pygame.draw.circle(screen, BLUE, (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2), 20)
# create instances
# player instance
player = Player(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
player.draw()
# main loop
run = True
while run:
# run frame rate
clock.tick(FPS)
# events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
screen.fill((0, 0, 0))
mouse_pos = pygame.mouse.get_pos()
player.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
pygame.display.update()
pygame.quit()
I think some code is not needed
Help would be appreciated
This will move the circle to the mouse position. It doesn't move in one diagonal, but that can be changed.
# import
import pygame
# initialize pygame
pygame.init()
# frame rate variables
FPS = 120
clock = pygame.time.Clock()
# game variables
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 800
# colors
BLUE = (0, 0, 255)
# activate screen
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Bonker')
class Player(pygame.sprite.Sprite):
def __init__(self, x, y):
# init the sprite class
pygame.sprite.Sprite.__init__(self)
self.rect = pygame.Rect(0, 0, 40, 40)
self.rect.x = x
self.rect.y = y
self.radius = 20
self.destination = None
self.moving = False
self.dx = 0
self.dy = 0
def set_destination(self, pos):
self.destination = pos
# delta x and delta y
self.dx = self.destination[0] - self.rect.centerx
self.dy = self.destination[1] - self.rect.centery
self.moving = True
def move(self):
if self.rect.centerx != self.destination[0]:
if self.dx > 0:
self.rect.centerx += 1
elif self.dx < 0:
self.rect.centerx -= 1
if self.rect.centery != self.destination[1]:
if self.dy > 0:
self.rect.centery += 1
elif self.dy < 0:
self.rect.centery -= 1
elif self.rect.center == self.destination:
self.moving = False
def draw(self):
# draw the circle
pygame.draw.circle(screen, BLUE, self.rect.center, self.radius)
# create instances
# player instance
player = Player(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
player.draw()
# main loop
run = True
movetime = 100
move = False
while run:
# run frame rate
dt = clock.tick(FPS)
movetime -= dt
if movetime <= 0:
move = True
movetime = 400
# events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
player.set_destination(mouse_pos)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if player.moving:
player.move()
screen.fill((0, 0, 0))
player.draw()
pygame.display.update()
pygame.quit()
I'm making a game in pygame and I'm trying to move the self.jetRect, which is the rectangular area of the Surface (jetSurface), but when I try updating the coordinates of the rectangle, I get a TypeError: 'tuple' object is not callable. I think this is related to the fact that a tuple is immutable, but I don't know how to fix this.
import pygame
pygame.init()
clock = pygame.time.Clock()
# Screen setup
screen_width = 600
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Jet Fighter Game")
# Colors
black = (0, 0, 0)
white = (255, 255, 255)
grey = (100, 100, 100)
# Classes
class PLAYER1:
def __init__(self):
self.jetSurface = pygame.image.load("player1 - blackJet.png")
self.x = 100
self.y = 100
self.speed = 5
self.jetRect = self.jetSurface.get_rect(center = (self.x, self.y))
self.angle = 0
self.rotatedJet = self.jetSurface
def rotateJet(self, surface, angle):
key = pygame.key.get_pressed()
if key[pygame.K_a]:
self.angle += 10
self.rotatedJet = pygame.transform.rotozoom(surface, angle, 1)
self.jetRect = self.rotatedJet.get_rect(center=(self.x, self.y))
if key[pygame.K_d]:
self.angle -= 10
self.rotatedJet = pygame.transform.rotozoom(surface, angle, 1)
self.jetRect = self.rotatedJet.get_rect(center=(self.x, self.y))
if self.angle >= 360:
self.angle = 0
screen.blit(self.rotatedJet, self.jetRect)
def moveJet(self):
key = pygame.key.get_pressed()
if key[pygame.K_w]:
self.y -= self.speed
self.jetRect.center(self.x, self.y)
class PLAYER2:
pass
class BULLET:
pass
class MAIN:
def __init__(self):
self.player1 = PLAYER1()
def rotateJets(self):
self.player1.rotateJet(self.player1.jetSurface, self.player1.angle)
def moveJets(self):
self.player1.moveJet()
main = MAIN()
# Main loop
run = True
while run:
# Checking for events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# Drawing on screen
screen.fill(grey)
# Movement and Collisions
main.rotateJets()
main.moveJets()
pygame.display.flip()
clock.tick(60)
pygame.quit()
Its a typo. self.jetRect.center is a tuple of (self.x, self.y), so when you do
self.jetRect.center(self.x, self.y), you are doing (self.x, self.y)(self.x, self.y), hence the error message of calling a tuple.
I think you meant to assign the tuple like self.jetRect.center = (self.x, self.y)
I'm starting to work with classes more and I was trying to translate my old classless code to this new format. Before, I defined my lists as global variables and could draw multiple enemies to the screen with no problem. This time, however, something about working with classes causes the enemies to be drawn and instantly disappear from their position.
Some help or workaround would be greatly appreciated. Here's the code:
import pygame
import sys
import random
import math
pygame.init()
class enemies(object):
enemies = []
def __init__(self, enemy_num, diff, enemy_size):
self.enemy_num = enemy_num
self.diff = diff
self.enemy_s = enemy_size
def add_enemies(self):
counter = 0
if len(self.enemies) < self.enemy_num:
for enemy in range(0, self.enemy_num):
if len(self.enemies) < 5:
self.enemies.append([counter * (self.enemy_s * 0.5), 200, (50, 168, 82)])
elif len(self.enemies) > 5 and len(self.enemies) <= 9:
self.enemies.append([counter * (self.enemy_s * 0.5), 250, (168, 160, 50)])
else:
self.enemies.append([counter * (self.enemy_s * 0.5), 300, (50, 52, 168)])
counter += 1
def move(self, surface):
for enemy in self.enemies:
surface.fill((0, 0, 0))
pygame.draw.rect(surface, enemy[2], (enemy[0], enemy[1], self.enemy_s, self.enemy_s))
pygame.display.update()
class ship(object):
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
def draw_all(self, surface, ship_size):
surface.fill((0, 0, 0))
pygame.draw.rect(surface, self.color, (self.x, self.y, ship_size, ship_size))
pygame.display.update()
def move(self):
keys = pygame.key.get_pressed()
for key in keys:
if keys[pygame.K_LEFT]:
self.x -= 0.2
if keys[pygame.K_RIGHT]:
self.x += 0.2
if keys[pygame.K_UP]:
self.y -= 0.2
if keys[pygame.K_DOWN]:
self.y += 0.2
def main():
width = 800
height = 1000
ship_size = 35
difficulty = 0
enemy_number = 12
enemy_size = 35
player = ship(width / 2, height - 100, (255, 0, 0))
aliens = enemies(enemy_number, difficulty, enemy_size)
screen = pygame.display.set_mode((width, height))
enemy_list = 12
run = True
clock = pygame.time.Clock()
aliens.add_enemies()
while run:
player.draw_all(screen, ship_size)
player.move()
aliens.move(screen)
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.quit()
main()
You've to do 1 clear display and 1 display update in the main loop of the application.
Remove .fill() respectively .pygame.display.update from the .move() and .draw_all method. Clear the display once, draw all the objects and then update the display:
while run:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.quit()
screen.fill((0, 0, 0))
player.draw_all(screen, ship_size)
player.move()
aliens.move(screen)
pygame.display.update()
Note, you didn't see the enemies, because the display is clear before drawing a single enemy in enemies.move() and it is clear again when drawing the ship in ship.draw_all()