Python(2.7):Bug class program error of indentation - python-2.7

Whenever I compile my code
import pygame,sys
from classes import *
pygame.init()
SCREENWIDTH,SCREENHEIGHT = 640, 360
screen = pygame.display.set_mode ((SCREENWIDTH, SCREENHEIGHT))
clock = pygame.time.Clock()
FPS = 24
bug = Bug(0,100,40,40,"bug.png")
while True:
# PROCESSING
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#LOGIC
bug.motion()
#LOGIC
#DRAW
screen.fill((0,0,0))
BaseClass.allsprites.draw(screen)
pygame.display.flip()
#DRAW
clock.tick(FPS)
It shows the following error:
File "practice.py", line 16
bug.motion()
^
IndentationError: unindent does not match any outer indentation level

Every line after sys.exit() has five spaces, when they should have four.
import pygame,sys
from classes import *
pygame.init()
SCREENWIDTH,SCREENHEIGHT = 640, 360
screen = pygame.display.set_mode ((SCREENWIDTH, SCREENHEIGHT))
clock = pygame.time.Clock()
FPS = 24
bug = Bug(0,100,40,40,"bug.png")
while True:
# PROCESSING
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#LOGIC
bug.motion()
#LOGIC
#DRAW
screen.fill((0,0,0))
BaseClass.allsprites.draw(screen)
pygame.display.flip()
#DRAW
clock.tick(FPS)

Related

argument 1 must be pygame.Surface, not Window

Not sure if what I am trying to do is wrong or impossible. Here is my code:
import pygame
class Window(object):
def __init__(self, (width, height), color, cap=' '):
self.width = width
self.height = height
self.color = color
self.cap = cap
self.screen = pygame.display.set_mode((self.width, self.height))
def display(self):
self.screen
#screen =
pygame.display.set_caption(self.cap)
self.screen.fill(self.color)
class Ball(object):
def __init__(self, window, (x, y), color, size, thick=None):
self.window = window
self.x = x
self.y = y
self.color = color
self.size = size
self.thick = thick
def draw(self):
pygame.draw.circle(self.window, self.color, (self.x, self.y),
self.size, self.thick)
def main():
black = (0, 0, 0)
white = (255, 255, 255)
screen = Window((600, 600), black, 'Pong')
screen.display()
ball = Ball(screen, (300, 300), white, 5)
ball.draw()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
pygame.quit()
main()
This is the error I get:
Traceback (most recent call last):
File "C:\Users\acmil\Desktop\Team 7\newPongLib.py", line 47, in <module>
main()
File "C:\Users\acmil\Desktop\Team 7\newPongLib.py", line 36, in main
ball.draw()
File "C:\Users\acmil\Desktop\Team 7\newPongLib.py", line 28, in draw
self.size, self.thick)
TypeError: argument 1 must be pygame.Surface, not Window
I don't understand if i make a Window object why it won't draw a ball to the screen. Any help is appreciated.
Change your Ball class to the following:
class Ball(object):
def __init__(self, window, (x, y), color, size, thick=0):
self.window = window
self.x = x
self.y = y
self.color = color
self.size = size
self.thick = thick
def draw(self):
pygame.draw.circle(self.window.screen, self.color, (self.x, self.y),
self.size, self.thick)
I made two modifications to your code.
First, as for the error you were getting, you were passing in a custom Window object that you had defined instead of the pygame's Screen object that pygame was expecting. Check out the documentation on this function here.
Second, your original constructor defined thick=None by default, but that pygame function expects an int, so I changed it to thick=0.
It should work after these two changes. Let me know if you still are having issues!

Adding a play again option to python game

I'm working on making a game for my programming class using python. I don't know how to give the option to the player again when they lose, or quit the game. I am using python 2.7. This is the code for my game:
import pygame, sys, time, random
from pygame.locals import *
# set up pygame
pygame.init()
mainClock = pygame.time.Clock()
# set up the window
WINDOWWIDTH = 1000
WINDOWHEIGHT = 500
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Dankest Memes')
# set up the colors
PINK = (223, 61, 163)
TEXTCOLOR = (223, 61, 163)
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE: # pressing escape quits
terminate()
return
def terminate():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE: # pressing escape quits
terminate()
return
def drawText(text, font, surface, x, y):
textobj = font.render(text, 1, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
font = pygame.font.SysFont(None, 48)
TEXTCOLOR = (255,250,250)
Score=4
# set up fonts
font = pygame.font.SysFont(None, 48)
myscore=4
# set up the block data structure
file = 'score.txt'
player = pygame.Rect(300, 100, 40, 40)
playerImage = pygame.image.load('player.png')
playerStretchedImage = pygame.transform.scale(playerImage, (40, 40))
foodImage = pygame.image.load('meme.png')
foods = []
for i in range(20):
foods.append(pygame.Rect(random.randint(0, WINDOWWIDTH - 20), random.randint(0, WINDOWHEIGHT - 20), 20, 20))
foodCounter = 0
NEWFOOD = 40
baddie = pygame.Rect(300, 100, 40, 40)
baddieImage = pygame.image.load('baddie.png')
baddieStretchedImage = pygame.transform.scale(baddieImage, (40, 40))
baddies = []
for i in range(20):
baddies.append(pygame.Rect(random.randint(0, WINDOWWIDTH - 20), random.randint(0, WINDOWHEIGHT - 20), 20, 20))
baddieCounter = 0
NEWBADDIE = 120
# set up keyboard variables
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
MOVESPEED = 6
# set up music
pickUpSound = pygame.mixer.Sound('pickup.wav')
pygame.mixer.music.load('background.mp3')
pygame.mixer.music.play(-1, 0.0)
musicPlaying = True
# show the "Start" screen
drawText('Dankest Memes', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press any key to start.', font, windowSurface, (WINDOWWIDTH / 3) - 50, (WINDOWHEIGHT / 3) + 50)
drawText('Move with WASD or the arrow keys.', font, windowSurface, (WINDOWWIDTH / 3) - 50, (WINDOWHEIGHT / 3) + 100)
drawText('Collect green Pepes to get points.', font, windowSurface, (WINDOWWIDTH / 3) - 50, (WINDOWHEIGHT / 3) + 150)
drawText('Avoid the chickens.', font, windowSurface, (WINDOWWIDTH / 3) - 50, (WINDOWHEIGHT / 3) + 200)
pygame.display.update()
waitForPlayerToPressKey()
# run the game loop
while True:
# check for the QUIT event
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
# change the keyboard variables
if event.key == K_LEFT or event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == ord('s'):
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_LEFT or event.key == ord('a'):
moveLeft = False
if event.key == K_RIGHT or event.key == ord('d'):
moveRight = False
if event.key == K_UP or event.key == ord('w'):
moveUp = False
if event.key == K_DOWN or event.key == ord('s'):
moveDown = False
if event.key == ord('x'):
player.top = random.randint(0, WINDOWHEIGHT - player.height)
player.left = random.randint(0, WINDOWWIDTH - player.width)
if event.key == ord('m'):
if musicPlaying:
pygame.mixer.music.stop()
else:
pygame.mixer.music.play(-1, 0.0)
musicPlaying = not musicPlaying
if event.type == MOUSEBUTTONUP:
foods.append(pygame.Rect(event.pos[0] - 10, event.pos[1] - 10, 20, 20))
foodCounter += 1
if foodCounter >= NEWFOOD:
# add new food
foodCounter = 0
foods.append(pygame.Rect(random.randint(0, WINDOWWIDTH - 20), random.randint(0, WINDOWHEIGHT - 20), 20, 20))
baddieCounter += 1
if baddieCounter >= NEWBADDIE:
baddieCounter = 0
baddies.append(pygame.Rect(random.randint(0, WINDOWWIDTH - 20), random.randint(0, WINDOWHEIGHT - 20), 20, 20))
# draw the pink background onto the surface
windowSurface.fill(PINK)
# move the player
if moveDown and player.bottom < WINDOWHEIGHT:
player.top += MOVESPEED
if moveUp and player.top > 0:
player.top -= MOVESPEED
if moveLeft and player.left > 0:
player.left -= MOVESPEED
if moveRight and player.right < WINDOWWIDTH:
player.right += MOVESPEED
drawText('Score: %s' % (Score), font, windowSurface, 10,0)
# draw the block onto the surface
windowSurface.blit(playerStretchedImage, player)
# check if the block has intersected with any food squares.
for food in foods[:]:
if player.colliderect(food):
foods.remove(food)
Score+=2
if musicPlaying:
pickUpSound.play()
for baddie in baddies[:]:
if player.colliderect(baddie):
baddies.remove(baddie)
Score-=4
if musicPlaying:
pickUpSound.play()
if Score < 0:
drawText('You have lost', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press escape to quit the game', font, windowSurface, (WINDOWWIDTH / 3) - 50, (WINDOWHEIGHT / 3) + 50)
drawText('Press any other key to play again', font, windowSurface, (WINDOWWIDTH / 3) - 50, (WINDOWHEIGHT / 3) + 100)
pygame.display.update()
waitForPlayerToPressKey()
# draw the food
for food in foods:
windowSurface.blit(foodImage, food)
# draw the baddie
for baddie in baddies:
windowSurface.blit(baddieImage, baddie)
# draw the window onto the screen
pygame.display.update()
mainClock.tick(40)
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
The game is simple. The player moves around, collects food to get points and avoids baddies so they don't lose points. When the score drops below 0, the player loses. I managed to get and end game screen, but I can't make it play again or quit the game after this point.
First of, one suggestion. People will be more likely to help you if you show them what you've tried.
anyhow.
What I would do is wrap your entire game loop in a function. Like so:
def game_loop():
while True:
# check for the QUIT event
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
....
next when ever your game ends(I'm assuming it does have a condition that makes it end), call a game over screen function. In your game over screen function, you could first fill the window with a color, then blit any text to the screen you wan to show the user, such as "Press any key to play again". Then you would check if any key was pressed and if so call the game loop function. You also need to check if the user is trying to close the window.
Then call the game over screen function like so:
#pseudo code
if game_has_ended == True:
game_over_screen()

pygame only updates when mouse active over game window?

Just getting started with pygame (python 2.7, win7, i3) and looking at the tutorial here: http://www.pygame.org/docs/tut/intro/intro.html
When I run the code example:
import sys, pygame
pygame.init()
size = width, height = 320, 240
speed = [2, 2]
black = 0, 0, 0
screen = pygame.display.set_mode(size)
ball = pygame.image.load('ball.bmp')
ballrect = ball.get_rect()
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
ballrect = ballrect.move(speed)
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[1]
screen.fill(black)
screen.blit(ball, ballrect)
pygame.display.flip()
...from IDLE or powershell, the game window only updates when the mouse is actively moving over the game window. I was expecting that the ball would simply bounce around on its own. Is this mouse--position related performance due to the way pygame/SDL deal with graphics modes? Is it related to the hardware? Is there a way to improve the performance through the code? I'd like to get the proverbial ball rolling with pygame and this seems... odd. Thank you.
edit:
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
ballrect = ballrect.move(speed)
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[1]
screen.fill(black)
screen.blit(ball, ballrect)
pygame.display.flip()
You have the update code INSIDE the function! Move it out like this and it will work.
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
ballrect = ballrect.move(speed)
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[1]
screen.fill(black)
screen.blit(ball, ballrect)
pygame.display.flip()

Attaching snake-tail in snake game (Python:pygame)

I'm stumped after tying to attach a snake tail img, can someone explain a possible way to attach it so after each block is added it stays at the end.
The snake tail is variable tail under ##Snake Images
import pygame
import random
import time
pygame.init()
White = (255,255,255)
Black = (0,0,0)
Green = (0,155,0)
Lgreen = (219,255,219)
Red = (255,0,0)
Dwidth = 800
Dheight = 600
GameDisplay = pygame.display.set_mode((Dwidth,Dheight))
pygame.display.set_caption("Snake")
##Other Images
icon = pygame.image.load('apple.png')
pygame.display.set_icon(icon)
Logo = pygame.image.load('Snakelogo.png')
##Apple Images
appleimg = pygame.image.load('apple.png')
##Snake Images
img = pygame.image.load('snake.png')
tail = pygame.image.load('snakebot.png')
Clock = pygame.time.Clock()
blockS = 20
AppleThickness = 30
FPS = 17.5
direction = "right"
smallfont = pygame.font.SysFont("comicsansms", 25)
medfont = pygame.font.SysFont("comicsansms", 50)
largefont = pygame.font.SysFont("comicsansms", 80)
def pause():
paused = True
message("Paused",
Black,
-100,
size="large")
message("Press SPACE again to continue or Q to quit.",
Black,
25)
pygame.display.update()
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
paused = False
elif event.key == pygame.K_q:
pygame.quit()
quit()
Clock.tick(5)
def score(score):
text = smallfont.render("Score: "+str(score), True, Black)
GameDisplay.blit(text,[0,0])
def randAppleGen():
randAppleX = round(random.randrange(0,Dwidth-AppleThickness))#/10.0)*10.0
randAppleY = round(random.randrange(0,Dheight-AppleThickness))#/10.0)*10.0
return randAppleX,randAppleY
randAppleX,randAppleY = randAppleGen()
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
intro = False
if event.key == pygame.K_q:
pygame.quit()
quit()
GameDisplay.fill(Lgreen)
GameDisplay.blit(Logo,[0,100,800,170])
message("The objective of the game is to eat red apples,",
Black,
-30)
message("the more apples you eat the longer you get and",
Black,
10)
message("if you run into yourself or the edges you die.",
Black,
50)
message("Press C to play, SPACE to pause, or Q to quit.",
Black,
180)
pygame.display.update()
Clock.tick(15)
def snake(blockS,snakeList):
if direction == "right":
head = pygame.transform.rotate(img, 270)
if direction == "left":
head = pygame.transform.rotate(img, 90)
if direction == "up":
head = img
if direction == "down":
head = pygame.transform.rotate(img, 180)
GameDisplay.blit(head,(snakeList[-1][0],snakeList[-1][1]))
for XnY in snakeList[:-1]:
pygame.draw.rect(GameDisplay,Green,[XnY[0],XnY[1],blockS, blockS])
def text_objects(text,color,size):
if size == "small":
textSurface = smallfont.render(text,True,color)
elif size == "medium":
textSurface = medfont.render(text,True,color)
elif size == "large":
textSurface = largefont.render(text,True,color)
return textSurface, textSurface.get_rect()
def message(msg,color,y_displace=0, size = "small"):
textSurf, textRect = text_objects(msg,color,size)
textRect.center = (Dwidth/2),(Dheight/2) +y_displace
GameDisplay.blit(textSurf,textRect)
def gameloop():
global direction
direction = "right"
GameEX = False
GameOver = False
Hor_X = Dwidth/2
Ver_Y = Dheight/2
MoveS = 10
MoveDU = 0
snakeList = []
snakeLength = 1
randAppleX,randAppleY = randAppleGen()
while not GameEX:
if GameOver == True:
message("Game Over",
Red,
y_displace=-50,
size="large")
message("Press C to play again or Q to Quit", Black,50, size = "medium")
pygame.display.update()
while GameOver == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
GameEX = True
GameOver = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
GameEX = True
GameOver = False
if event.key == pygame.K_c:
gameloop()
for event in pygame.event.get():
if event.type == pygame.QUIT:
GameEX = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
MoveS = -blockS
MoveDU = 0
direction = "left"
elif event.key == pygame.K_RIGHT:
MoveS = blockS
MoveDU = 0
direction = "right"
elif event.key == pygame.K_UP:
MoveDU = -blockS
MoveS = 0
direction = "up"
elif event.key == pygame.K_DOWN:
MoveDU = blockS
MoveS = 0
direction = "down"
elif event.key == pygame.K_SPACE:
pause()
if Hor_X >= Dwidth or Hor_X < 0 or Ver_Y >= Dheight or Ver_Y < 0:
GameOver = True
Hor_X += MoveS
Ver_Y += MoveDU
GameDisplay.fill(Lgreen)
GameDisplay.blit(appleimg,(randAppleX, randAppleY))
snakeHead = []
snakeHead.append(Hor_X)
snakeHead.append(Ver_Y)
snakeList.append(snakeHead)
if len(snakeList) > snakeLength:
del snakeList[0]
for eachSegment in snakeList[:-1]:
if eachSegment == snakeHead:
GameOver = True
snake(blockS,snakeList)
score(snakeLength-1)
pygame.display.update()
if Hor_X > randAppleX and Hor_X < randAppleX + AppleThickness or Hor_X + blockS > randAppleX and Hor_X + blockS < randAppleX + AppleThickness:
if Ver_Y > randAppleY and Ver_Y < randAppleY + AppleThickness:
randAppleX,randAppleY = randAppleGen()
snakeLength += 1
elif Ver_Y + blockS > randAppleY and Ver_Y + blockS < randAppleY + AppleThickness:
randAppleX,randAppleY = randAppleGen()
snakeLength += 1
Clock.tick(FPS)
pygame.quit()
quit()
game_intro()
gameloop()
inserting this into the snake function is as close as Ive gotten to attaching it to the end~
for XnY in snakeList[0]:
GameDisplay.blit(tail,(snakeList[0][0],snakeList[0][1]))
I just increased my snakeLength to 2 and it solved my problem after adding
for XnY in snakeList[0]:
GameDisplay.blit(tail,(snakeList[0][0],snakeList[0][1]))
into the snake function.

When I run the program and click on my_rect nothing happens and eventualy it stops working

while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
elif event.type == pygame.MOUSEBUTTONDOWN:
is_inside = my_rect.collidepoint(pygame.mouse.get_pos())
print is_inside
if is_inside == 1:
myfont = pygame.font.SysFont("monospace", 15)
label = myfont.render("The Penrose Triangle by Roman Formicola", 5, (black))
gameDisplay.blit(label, (300,150))
I had it my goal is that once you click on my_rect the message will stay there indefinately
Just create a variable holding your Rect (actually using the Rect class):
my_rect = pygame.Rect(400, 300, 100, 100)
Then you can use the collidepoint() method of Rect to check if the mouse position is inside my_rect:
...
elif event.type == pygame.MOUSEBUTTONDOWN:
is_inside = my_rect.collidepoint(pygame.mouse.get_pos())
pygame.draw.rect(gameDisplay, cyan, my_rect, 0)
...