import pygame
import snake
pygame.init()
# Set the height and width of the screen
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption("Snake")
quit = False
clock = pygame.time.Clock()
snake = snake.Snake()
while not quit:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit = True # Flag that we are done so we exit this loop
# rectangle = pygame.Rect(400, 150, 100, 60) #first two = x and y coords
# pygame.draw.rect(screen, [0, 0, 255], rectangle)
snake.draw(screen)
pygame.display.update()
# Be IDLE friendly
pygame.quit()
import pygame
BODY_DIM = 50 #dimension for each part of the snake's body
RED = [255, 0, 0]
class Snake:
#represent the snake as a list of squares
class BodyNode:
def __init__(self, coords):
self.body = pygame.Rect(coords, (BODY_DIM, BODY_DIM))
def __init__(self):
self.snake_body = [Snake.BodyNode((50, 50))]
def draw(self, screen):
for s in self.snake_body:
pygame.draw().rect(screen, RED, s.body)
These are two separate files the bottom one with the import pygame statement is in a file called Snake.py. This line seems to be the issue: pygame.draw().rect(screen, RED, s.body), I can't seem to find out why though. the pygame was imported so it should work.
you need to remove the brackets
pygame.draw().rect(screen,RED,s.body)
# ^^ HERE
that way you are not calling a module
Related
I wrote a python game using pygame and pymunk, but the playground() section doesnt work. It supposed to show a static object, but it doesnt. I asked and it was supposed to interact with balls being dropped.
heres the code:
import pygame, sys
import pymunk
import pymunk.pygame_util
from pymunk.vec2d import Vec2d
size = (800, 600)
FPS = 120
space = pymunk.Space()
space.gravity = (0,250)
pygame.init()
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
class Ball:
global space
def __init__(self, pos):
self.body = pymunk.Body(1,1, body_type = pymunk.Body.DYNAMIC)
self.body.position = pos
self.radius = 60
self.shape = pymunk.Circle(self.body, self.radius)
space.add(self.body, self.shape)
# INDENTATION
#<--|
def draw(self):
x = int(self.body.position.x)
y = int(self.body.position.y)
pygame.draw.circle(screen, (255,0,0), (x,y), self.radius)
def playground():
body = pymunk.Body(1,1, body_type = pymunk.Body.STATIC)
balls = []
balls.append(Ball((400,0)))
balls.append(Ball((100,0)))
balls.append(Ball((600,100)))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
balls.append(Ball(event.pos))
# INDENTATION
#<------|
screen.fill((217,217,217))
for ball in balls:
ball.draw()
playground()
space.step(1/50)
pygame.display.update()
clock.tick(FPS)
Any solution?
Its for a school project so any help will greated.
Thanks.
You forgot to add the body into the space, that's why the balls kept on falling.
You also need to define the shape of the body which is a required argument in adding to space. Lastly, you need to draw into pygame screen the shape as previously defined.
def playground():
body = pymunk.Body(1,1, body_type = pymunk.Body.STATIC)
polygon_points = [(0,580),(800,580),(800,600),(0,600)]
shape = pymunk.Poly(space.static_body, polygon_points)
space.add(body, shape)
pygame.draw.polygon(screen, (0, 0, 0), polygon_points)
I am learning pygame by making a simple game.
Here is the code:
Main script:
import pygame
from gracz2 import SpriteGenerator
BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
GREEN = ( 0, 255, 0)
RED = ( 255, 0, 0)
BLUE = ( 0, 0, 255)
pygame.init()
pygame.display.set_caption("Super Gra!")
screen_height = 720
screen_width = 1280
screen = pygame.display.set_mode((screen_width, screen_height))
all_sprites_list = pygame.sprite.Group()
playerSprite = SpriteGenerator(1,150,150)
playerSprite.rect.x = (screen_width/2 - 75)
playerSprite.rect.y = 550
all_sprites_list.add(playerSprite)
clock = pygame.time.Clock()
mainloop = True
playtime = 0
while mainloop:
for event in pygame.event.get():
# User presses QUIT-button.
if event.type == pygame.QUIT:
mainloop = False
elif event.type == pygame.KEYDOWN:
# User presses ESCAPE-Key
if event.key == pygame.K_ESCAPE:
mainloop = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
playerSprite.moveLeft(8)
if keys[pygame.K_RIGHT]:
playerSprite.moveRight(8)
milliseconds = clock.tick(60)
playtime += milliseconds / 1000.0
all_sprites_list.update()
pygame.display.set_caption("Czas gry: " + str(round(playtime,1)) + " sekund")
# Refresh the screen
screen.fill(BLACK)
all_sprites_list.draw(screen)
screen.blit(playerSprite.image, (playerSprite.rect.x,playerSprite.rect.y))
pygame.display.flip()
print(all_sprites_list.sprites())
print(all_sprites_list)
print(playerSprite.rect.x)
print(playerSprite.rect.y)
pygame.quit()
and another file called "gracz2.py":
import pygame
WHITE = (255, 255, 255)
BLACK = ( 0, 0, 0)
class SpriteGenerator(pygame.sprite.Sprite):
#This class represents a player. It derives from the "Sprite" class in Pygame.
def __init__(self, type, width, height):
# Call the parent class (Sprite) constructor
super().__init__()
# Pass in the color of the player, and its x and y position, width and height.
# Set the background color and set it to be transparent
self.image = pygame.Surface([width, height])
self.image.fill(WHITE)
self.image.set_colorkey(WHITE)
if type == 1:
self.image = pygame.image.load("sprite-ufo.gif").convert_alpha()
elif type == 2:
self.image = pygame.image.load("sprite-bomb.jpg").convert_alpha()
# Fetch the rectangle object that has the dimensions of the image.
self.rect = self.image.get_rect()
def moveRight(self, pixels):
self.rect.x += pixels
def moveLeft(self, pixels):
self.rect.x -= pixels
It could be done in one file but the code is more readable for me this way.
around line 50 i call all_sprites_list.draw(screen)
which to my understanding should blit all the sprites contained in all_sprites_list but it does nothing.
I have to use screen.blit(playerSprite.image, (playerSprite.rect.x,playerSprite.rect.y))
to manually blit the sprite.
As i am going to add generate lots of sprites later i can't blit them all manually.
Why doesn't all_sprites_list.draw(screen) work as intended?
It's probably a stupid mistake in the code but I am trying to find for over an hour now and I am unable to locate it.
Turns out that when i restart my PC the draw() function works fine.
I don't know what caused it first, sorry for asking without following the first rule of IT troubleshooting first (restart and try again)
PS: thank you furas for your answers
I am new to python and pygame and I'm trying to move a image over drawed rectangles with changing colors. Whenever I run this code the image moves but it creates a track of the image.
I know that I need to blit the background of the image in the game loop but how can I blit the background if the background is not an image?
Or do I need to draw my rectangles in a different way?
Full code:
import pygame
pygame.init()
screen = pygame.display.set_mode((600,200))
pygame.draw.rect(screen, (175,171,171), [0, 0, 600, 200])
pygame.draw.rect(screen, (255,192,0), [200, 0, 200, 200])
clock = pygame.time.Clock()
# load your own image here (preferably not wider than 30px)
truck = pygame.image.load('your_image.png').convert_alpha()
class Truck:
def __init__(self, image, x, y, speed):
self.speed = speed
self.image = image
self.pos = image.get_rect().move(x, y)
def move(self):
self.pos = self.pos.move(self.speed, 0)
def game_loop():
newTruck = Truck(truck, 0, 50, 1)
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
newTruck.move()
screen.blit(newTruck.image, newTruck.pos)
clock.tick(60)
pygame.display.update()
game_loop()
You have to somehow redraw all the objects (rectangles) in your background at every update.
The simplest way to do this is just to call all the drawing code again, before updating your foreground object. Another way, if the background does not change after created, is to blit these background objects into a separate Surface object, and blit that one to the screen on every update.
More sophisticated ways would be to save the background under your foreground objects are prior to drawing them, and then, on the next redraw, first redraw the background and then save the background again and draw the foreground objects on the new position. It is easier to do one of the former methods.
Your code could be written like this:
import pygame
pygame.init()
SIZE = (600,200)
screen = pygame.display.set_mode(SIZE)
bg_image = None
def draw_background(screen):
global bg_image
if not bg_image:
bg_image = pygame.Surface((SIZE))
pygame.draw.rect(bg_image, (175,171,171), [0, 0, 600, 200])
pygame.draw.rect(bg_image, (255,192,0), [200, 0, 200, 200])
...
# Draw whatever you want inside this if body
screen.blit(bg_image, (0, 0))
...
class Truck:
...
def game_loop():
newTruck = Truck(truck, 0, 50, 1)
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
newTruck.move()
draw_background()
screen.blit(newTruck.image, newTruck.pos)
clock.tick(60)
pygame.display.update()
game_loop()
You can just move the two lines that draw your rects into the main while loop:
def game_loop():
newTruck = Truck(truck, 0, 50, 1)
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
newTruck.move()
# Draw the background items first, then the foreground images.
# If the rects don't cover the whole screen, you can use
# `screen.fill(some_color)` to clear it.
pygame.draw.rect(screen, (175,171,171), [0, 0, 600, 200])
pygame.draw.rect(screen, (255,192,0), [200, 0, 200, 200])
screen.blit(newTruck.image, newTruck.pos)
clock.tick(60)
pygame.display.update()
If the background should be static, you could also draw the rects onto a background surface once and then blit this surf onto the screen in the main loop as jsbueno suggests.
I have written simple code to get a green block which is my sprite to scroll across the screen. When the game starts the sprite is meant to appear in the centre of the screen, however when I run my code the screen is just black and the green block does not appear unless I click on the x cross on the window to exit the screen, then it appears for a second when the window is closing. Any ideas how I can resolve this.
import pygame, random
WIDTH = 800 #Size of window
HEIGHT = 600 #size of window
FPS = 30
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
class Player(pygame.sprite.Sprite):
#sprite for the player
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH/2, HEIGHT/2)
def update(self):
self.rect.x += 5
#initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Game")
clock = pygame.time.Clock()
all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
#Game loop
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
#check for closing window
if event.type == pygame.QUIT:
running = False
#update
all_sprites.update()
#Render/Draw
screen.fill(BLACK)
all_sprites.draw(screen)
pygame.display.flip()
pygame.quit()
All your code to updat the sprites, fill the screens and draw the sprites is outside your main loop (while running)
You must have in mind that identation Python's syntax: your commands are just outside your mainloop.
Moreover, I'd strongly advise to put that mainloop inside a proper function, instead of just leaving it on the module root.
...
#Game loop
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
#check for closing window
if event.type == pygame.QUIT:
running = False
#update
all_sprites.update()
#Render/Draw
screen.fill(BLACK)
all_sprites.draw(screen)
pygame.display.flip()
pygame.quit()
I made a class called Player that has an image called player.img that is not being displayed on the screen. When I run the code, it just displays a black screen with nothing on it. I'm trying to learn how to make classes so sorry if this is really messed up.
import pygame
import sys
from pygame.locals import *
#starts the program
pygame.init()
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
blue = (0, 0, 255)
green = (0, 255, 0)
yellow = (255, 255, 153)
#creates a window of 800x600
setDisplay = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Menu')
img = pygame.image.load('C:\\Users\\Ben\\Documents\\sprite.png')
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.img = pygame.image.load('C:\\Users\\Ben\\Documents\\sprite.png').convert()
self.imgx = 10
self.imgy = 10
self.screen = pygame.display.get_surface()
def draw(self):
self.screen.blit(self.img)
def load(self, filename):
self.img = pygame.image.load('C:\\Users\\Ben\\Documents\\sprite.png').convert_alpha()
player = Player()
def gameLoop():
imgx = 10
imgy = 10
lead_x_change = 0
lead_y_change = 0
move_variable = 5
while True:
screen.blit(player.img, [player.imgx,player.imgy])
for event in pygame.event.get():
#print (event)
if event.type == QUIT:
pygame.quit()
sys.exit()
gameLoop()
I can see two issues with your current code.
You never flip your display. This is generally performed after all blitting is complete for a given frame. For example your while loop would look like this:
while True:
screen.blit(player.img, [player.imgx,player.imgy])
pygame.display.flip()
for event in pygame.event.get():
#print (event)
if event.type == QUIT:
pygame.quit()
sys.exit()
Your gameLoop() function doesn't know what "screen" is. You will need to specify it somewhere. For example, right before your while loop starts would be fine.
screen = pygame.display.get_surface()
while True:
screen.blit....
You will definitely want to restructure some things. If I have some time later I will add to this answer my recommendations for how to restructure. But for now, these two adjustments should get your program running.