I'm making a version of http://agar.io and i'm trying to make the circle shape for the player. I have been trying to use pygame.draw.circle to draw it, however it keeps showing a square. Thanks for help!
import pygame, sys, random
from pygame.locals import *
# set up pygame
pygame.init()
mainClock = pygame.time.Clock()
# set up the window
width = 600
height = 800
screen = pygame.display.set_mode((width, height), 0, 32)
pygame.display.set_caption('Agar.io')
# set up the colors
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)
# set up the player and food data structure
foodCounter = 0
NEWFOOD = 0
FOODSIZE = 20
player = pygame.draw.circle(screen, WHITE, (60, 250), 40)
foods = []
for i in range(20):
foods.append(pygame.Rect(random.randint(0, width - FOODSIZE), random.randint(0, height - FOODSIZE), FOODSIZE, FOODSIZE))
# set up movement variables
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
MOVESPEED = 10
# run the game loop
while True:
# check for events
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, height - player.height)
player.left = random.randint(0, width - player.width)
if event.type == MOUSEBUTTONUP:
foods.append(pygame.Rect(event.pos[0], event.pos[1], FOODSIZE, FOODSIZE))
foodCounter += 1
if foodCounter >= NEWFOOD:
# add new food
foodCounter = 0
foods.append(pygame.Rect(random.randint(0, width - FOODSIZE), random.randint(0, height - FOODSIZE), FOODSIZE, FOODSIZE))
# draw the black background onto the surface
screen.fill(BLACK)
# move the player
if moveDown and player.bottom < height:
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 < width:
player.right += MOVESPEED
# draw the player onto the surface
pygame.draw.rect(screen, WHITE, player)
# check if the player has intersected with any food squares.
for food in foods[:]:
if player.colliderect(food):
foods.remove(food)
player.width+=1
player.height+=1
# draw the food
for i in range(len(foods)):
pygame.draw.rect(screen, GREEN, foods[i])
# draw the window onto the screen
pygame.display.update()
mainClock.tick(40)
Your immediate problem can be solved by using pygame.draw.circle instead of pygame.draw.rect:
# draw the player onto the surface
pygame.draw.circle(screen, WHITE, player.center, 40)
You are creating your player object with:
player = pygame.draw.circle(screen, WHITE, (60, 250), 40)
pygame.draw.circle returns a Rect object (not a circle object, which you might have expected), and you can use its .center attribute as the center of the circle.
here is my agar.io code:
import pygame,random,math
pygame.init()
place_10 = 500
place_9 = random.randint(501, 550)
place_8 = random.randint(551, 600)
place_7 = random.randint(601, 650)
place_6 = random.randint(651, 700)
place_5 = random.randint(701, 750)
place_4 = random.randint(751, 800)
place_3 = random.randint(801, 850)
place_2 = random.randint(851, 900)
place_1 = 950
colors_players = [(37,7,255),(35,183,253),(48,254,241),(19,79,251),(255,7,230),(255,7,23),(6,254,13)]
colors_cells = [(80,252,54),(36,244,255),(243,31,46),(4,39,243),(254,6,178),(255,211,7),(216,6,254),(145,255,7),(7,255,182),(255,6,86),(147,7,255)]
colors_viruses = [(66,254,71)]
screen_width, screen_height = (800,500)
surface = pygame.display.set_mode((screen_width,screen_height))
t_surface = pygame.Surface((95,25),pygame.SRCALPHA) #transparent rect for score
t_lb_surface = pygame.Surface((155,278),pygame.SRCALPHA) #transparent rect for leaderboard
t_surface.fill((50,50,50,80))
t_lb_surface.fill((50,50,50,80))
pygame.display.set_caption("Agar.io")
cell_list = list()
clock = pygame.time.Clock()
try:
font = pygame.font.Font("Ubuntu-B.ttf",20)
big_font = pygame.font.Font("Ubuntu-B.ttf",24)
except:
print("Font file not found: Ubuntu-B.ttf")
font = pygame.font.SysFont('Ubuntu',20,True)
big_font = pygame.font.SysFont('Ubuntu',24,True)
def drawText(message,pos,color=(255,255,255)):
surface.blit(font.render(message,1,color),pos)
def getDistance(pos1,pos2):
px,py = pos1
p2x,p2y = pos2
diffX = math.fabs(px-p2x)
diffY = math.fabs(py-p2y)
return ((diffX**2)+(diffY**2))**(0.5)
class Camera:
def __init__(self):
self.x = 0
self.y = 0
self.width = screen_width
self.height = screen_height
self.zoom = 0.5
def centre(self,blobOrPos):
if(isinstance(blobOrPos,Player)):
p = blobOrPos
self.x = (p.startX-(p.x*self.zoom))-p.startX+((screen_width/2))
self.y = (p.startY-(p.y*self.zoom))-p.startY+((screen_height/2))
elif(type(blobOrPos) == tuple):
self.x,self.y = blobOrPos
class Player:
def __init__(self,surface,name = ""):
self.startX = self.x = random.randint(100,400)
self.startY = self.y = random.randint(100,400)
self.mass = 20
self.surface = surface
self.color = colors_players[random.randint(0,len(colors_players)-1)]
self.name = name
self.pieces = list()
piece = Piece(surface,(self.x,self.y),self.color,self.mass,self.name)
def update(self):
self.move()
self.collisionDetection()
def collisionDetection(self):
for cell in cell_list:
if(getDistance((cell.x,cell.y),(self.x,self.y)) <= self.mass/2):
self.mass+=0.5
cell_list.remove(cell)
cell = Cell(surface)
cell_list.append(cell)
def move(self):
dX,dY = pygame.mouse.get_pos()
rotation = math.atan2(dY-(float(screen_height)/2),dX-(float(screen_width)/2))*180/math.pi
speed = 5-1
vx = speed * (90-math.fabs(rotation))/90
vy = 0
if(rotation < 0):
vy = -speed + math.fabs(vx)
else:
vy = speed - math.fabs(vx)
self.x += vx
self.y += vy
def feed(self):
pass
def split(self):
pass
def draw(self,cam):
col = self.color
zoom = cam.zoom
x = cam.x
y = cam.y
pygame.draw.circle(self.surface,(col[0]-int(col[0]/3),int(col[1]-col[1]/3),int(col[2]-col[2]/3)),(int(self.x*zoom+x),int(self.y*zoom+y)),int((self.mass/2+3)*zoom))
pygame.draw.circle(self.surface,col,(int(self.x*cam.zoom+cam.x),int(self.y*cam.zoom+cam.y)),int(self.mass/2*zoom))
if(len(self.name) > 0):
fw, fh = font.size(self.name)
drawText(self.name, (self.x*cam.zoom+cam.x-int(fw/2),self.y*cam.zoom+cam.y-int(fh/2)),(50,50,50))
class Piece:
def __init__(self,surface,pos,color,mass,name,transition=False):
self.x,self.y = pos
self.mass = mass
self.splitting = transition
self.surface = surface
self.name = name
def draw(self):
pass
def update(self):
if(self.splitting):
pass
class Cell:
def __init__(self,surface):
self.x = random.randint(20,1980)
self.y = random.randint(20,1980)
self.mass = random.randint(6, 8)
self.surface = surface
self.color = colors_cells[random.randint(0,len(colors_cells)-1)]
def draw(self,cam):
pygame.draw.circle(self.surface,self.color,(int((self.x*cam.zoom+cam.x)),int(self.y*cam.zoom+cam.y)),int(self.mass*cam.zoom))
def spawn_cells(numOfCells):
for i in range(numOfCells):
cell = Cell(surface)
cell_list.append(cell)
def draw_grid():
for i in range(0,2001,25):
pygame.draw.line(surface,(230,240,240),(0+camera.x,i*camera.zoom+camera.y),(2001*camera.zoom+camera.x,i*camera.zoom+camera.y),3)
pygame.draw.line(surface,(230,240,240),(i*camera.zoom+camera.x,0+camera.y),(i*camera.zoom+camera.x,2001*camera.zoom+camera.y),3)
camera = Camera()
blob = Player(surface,"person x")
spawn_cells(2000)
def draw_HUD():
w,h = font.size("Score: "+str(int(blob.mass*2))+" ")
surface.blit(pygame.transform.scale(t_surface,(w,h)),(8,screen_height-30))
surface.blit(t_lb_surface,(screen_width-160,15))
drawText("Score: " + str(int(blob.mass*2)),(10,screen_height-30))
surface.blit(big_font.render("Leaderboard",0,(255,255,255)),(screen_width-157,20))
if blob.mass >= place_1:
drawText("1. person x", (screen_width-157,20+25))
else:
drawText("1. team",(screen_width-157,20+25))
if blob.mass >= place_2 and blob.mass < place_1:
drawText("2. person x", (screen_width-157,20+25*2))
else:
drawText("2. help",(screen_width-157,20+25*2))
if blob.mass >= place_3 and blob.mass < place_2:
drawText("3. person x", (screen_width-157,20+25*3))
else:
drawText("3. ISIS",(screen_width-157,20+25*3))
if blob.mass >= place_4 and blob.mass < place_3:
drawText("4. person x", (screen_width-157,20+25*4))
else:
drawText("4. ur mom",(screen_width-157,20+25*4))
if blob.mass >= place_5 and blob.mass < place_4:
drawText("5. person x", (screen_width-157,20+25*5))
else:
drawText("5. w = pro team",(screen_width-157,20+25*5))
if blob.mass >= place_6 and blob.mass < place_5:
drawText("6. person x", (screen_width-157,20+25*6))
else:
drawText("6. jumbo",(screen_width-157,20+25*6))
if blob.mass >= place_7 and blob.mass < place_6:
drawText("7. person x", (screen_width-157,20+25*7))
else:
drawText("7. [cg]team",(screen_width-157,20+25*7))
if blob.mass >= place_8 and blob.mass < place_7:
drawText("8. person x", (screen_width-157,20+25*8))
else:
drawText("8. jack",(screen_width-157,20+25*8))
if blob.mass >= place_9 and blob.mass < place_8:
drawText("9. person x", (screen_width-157,20+25*9))
else:
drawText("9. doge",(screen_width-157,20+25*9))
if blob.mass >= place_10 and blob.mass < place_9:
drawText("10. person x",(screen_width-157,20+25*10))
else:
drawText("10. happy",(screen_width-157,20+25*10),(210,0,0))
while(True):
clock.tick(70)
for e in pygame.event.get():
if(e.type == pygame.KEYDOWN):
if(e.key == pygame.K_ESCAPE):
pygame.quit()
quit()
if(e.key == pygame.K_SPACE):
blob.split()
if(e.key == pygame.K_w):
blob.feed()
if(e.type == pygame.QUIT):
pygame.quit()
quit()
blob.update()
camera.zoom = 100/(blob.mass)+0.3
camera.centre(blob)
surface.fill((242,251,255))
#surface.fill((0,0,0))
draw_grid()
for c in cell_list:
c.draw(camera)
blob.draw(camera)
draw_HUD()
pygame.display.flip()
Related
This question already has an answer here:
How do I get the snake to grow and chain the movement of the snake's body?
(1 answer)
Closed 1 year ago.
I'm new to python and only now the basics, I'm trying to make a snake game but I can't seem to figure out how to make my snake grow 1 extra square each time it eats an apple. My reasoning is that I keep a list of all the old positions but only show the last one on the screen, and each time the snakes eats another apple it shows 1 extra old positions making the snake 1 square longer.
This is my code:
import pygame
from random import randint
WIDTH = 400
HEIGHT = 300
dis = pygame.display.set_mode((WIDTH,HEIGHT))
white = (255,255,255)
BACKGROUND = white
blue = [0,0,255]
red = [255,0,0]
class Snake:
def __init__(self):
self.image = pygame.image.load("snake.bmp")
self.rect = self.image.get_rect()
self.position = (10,10)
self.direction = [0,0]
self.positionslist = [self.position]
self.length = 1
pygame.display.set_caption('Snake ')
def draw_snake(self,screen):
screen.blit(self.image, self.position)
def update(self):
self.position = (self.position[0] + self.direction[0],self.position[1] + self.direction[1])
self.rect = (self.position[0],self.position[1],5, 5 )
self.positionslist.append(self.position)
if self.position[0]< 0 :
self.position = (WIDTH,self.position[1])
elif self.position[0] > WIDTH:
self.position = (0,self.position[1])
elif self.position[1] > HEIGHT:
self.position = (self.position[0],0)
elif self.position[1] < 0 :
self.position = (self.position[0],HEIGHT)
class Food:
def __init__(self):
self.image = pygame.image.load("appel.png")
self.rect = self.image.get_rect()
apple_width = -self.image.get_width()
apple_height = -self.image.get_height()
self.position = (randint(0,WIDTH+apple_width-50),randint(0,HEIGHT+apple_height-50))
self.rect.x = self.position[0]
self.rect.y = self.position[1]
def draw_appel(self,screen):
screen.blit(self.image, self.position)
def eat_appel (self, snake):
if self.rect.colliderect(snake.rect) == True:
self.position = (randint(0,WIDTH),randint(0,HEIGHT))
self.rect.x = self.position[0]
self.rect.y = self.position[1]
snake.length += 1
def main():
game_over = False
while not game_over:
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
snake = Snake()
food = Food()
while True:
screen.fill(BACKGROUND)
font = pygame.font.Font('freesansbold.ttf', 12)
text = font.render(str(snake.length), True, red, white)
textRect = text.get_rect()
textRect.center = (387, 292)
screen.blit(text,textRect)
snake.update()
#snake.update_list()
snake.draw_snake(screen)
food.draw_appel(screen)
food.eat_appel(snake)
pygame.display.flip()
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
snake.direction = [0,1]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
snake.direction = [1,0]
if event.key == pygame.K_LEFT:
snake.direction = [-1,0]
if event.key == pygame.K_UP:
snake.direction = [0,-1]
if event.key == pygame.K_DOWN:
snake.direction = [0,1]
if __name__ == "__main__":
main()
This can have multiple reasons. Firstly, I saw you tried to increase the length of the snake by typing snake.length += 1, which may work (probably won't because the module pygame allows the snake to hover around, but not like the loop or conditional statements). One of my tips would be, to increase the length of the snake by using the idea of adding the score with your present snake.length every time (because once your score is 1 by eating an apple, your snake.length would be 2. And it increases with the score). This is my code (a few modifications might be needed):
import pygame
import time
import random
pygame.init()
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
orange = (255, 165, 0)
width, height = 600, 400
game_display = pygame.display.set_mode((width, height))
pygame.display.set_caption("Snake Mania")
clock = pygame.time.Clock()
snake_size = 10
snake_speed = 15
message_font = pygame.font.SysFont('ubuntu', 30)
score_font = pygame.font.SysFont('ubuntu', 25)
def print_score(score):
text = score_font.render("Score: " + str(score), True, orange)
game_display.blit(text, [0,0])
def draw_snake(snake_size, snake_pixels):
for pixel in snake_pixels:
pygame.draw.rect(game_display, white, [pixel[0], pixel[1], snake_size, snake_size])
def run_game():
game_over = False
game_close = False
x = width / 2
y = height / 2
x_speed = 0
y_speed = 0
snake_pixels = []
snake_length = 1
target_x = round(random.randrange(0, width - snake_size) / 10.0) * 10.0
target_y = round(random.randrange(0, height - snake_size) / 10.0) * 10.0
while not game_over:
while game_close:
game_display.fill(black)
game_over_message = message_font.render("Game Over!", True, red)
game_display.blit(game_over_message, [width / 3, height / 3])
print_score(snake_length - 1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
game_over = True
game_close = False
if event.key == pygame.K_2:
run_game()
if event.type == pygame.QUIT:
game_over = True
game_close = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_speed = -snake_size
y_speed = 0
if event.key == pygame.K_RIGHT:
x_speed = snake_size
y_speed = 0
if event.key == pygame.K_UP:
x_speed = 0
y_speed = -snake_size
if event.key == pygame.K_DOWN:
x_speed = 0
y_speed = snake_size
if x >= width or x < 0 or y >= height or y < 0:
game_close = True
x += x_speed
y += y_speed
game_display.fill(black)
pygame.draw.rect(game_display, orange, [target_x, target_y, snake_size, snake_size])
snake_pixels.append([x, y])
if len(snake_pixels) > snake_length:
del snake_pixels[0]
for pixel in snake_pixels[:-1]:
if pixel == [x, y]:
game_close = True
draw_snake(snake_size, snake_pixels)
print_score(snake_length - 1)
pygame.display.update()
if x == target_x and y == target_y:
target_x = round(random.randrange(0, width - snake_size) / 10.0) * 10.0
target_y = round(random.randrange(0, height - snake_size) / 10.0) * 10.0
snake_length += 1
clock.tick(snake_speed)
pygame.quit()
quit()
run_game()
Creating a game where a maze is randomly generated and the player must navigate from the top left to the bottom right of the maze.
I have tried many things to stop my character going off-screen but it still doesn't work.
When already on the boundary of the screen the code works as intended and the character cannot continue moving off screen. However, if already moving then the character continues moving off the screen until the movement key is released where the character is then teleported back on to the screen where it should be. Additionally, I need to add boundaries to the maze walls as well but this is my current problem.
import pygame
import numpy
import sys
import csv
import random
from datetime import date
pygame.init()
done = False
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
cols = 10
rows = 10
width = 600
height = 600
wr = width/cols
hr = height/rows
screen = pygame.display.set_mode([width, height])
screen_rect = screen.get_rect()
pygame.display.set_caption("Maze Generator")
clock = pygame.time.Clock()
class Spot:
def __init__(self, x, y):
self.x = x
self.y = y
self.f = 0
self.g = 0
self.h = 0
self.neighbors = []
self.visited = False
self.walls = [True, True, True, True]
def show(self, color=BLACK):
if self.walls[0]:
pygame.draw.line(screen, color, [self.x*hr, self.y*wr], [self.x*hr+hr, self.y*wr], 2)
if self.walls[1]:
pygame.draw.line(screen, color, [self.x*hr+hr, self.y*wr], [self.x*hr+hr, self.y*wr + wr], 2)
if self.walls[2]:
pygame.draw.line(screen, color, [self.x*hr+hr, self.y*wr+wr], [self.x*hr, self.y*wr+wr], 2)
if self.walls[3]:
pygame.draw.line(screen, color, [self.x*hr, self.y*wr+wr], [self.x*hr, self.y*wr], 2)
def show_block(self, color):
if self.visited:
pygame.draw.rect(screen, color, [self.x*hr+2, self.y*wr+2, hr-2, wr-2])
def add_neighbors(self):
if self.x > 0:
self.neighbors.append(grid[self.x - 1][self.y])
if self.y > 0:
self.neighbors.append(grid[self.x][self.y - 1])
if self.x < rows - 1:
self.neighbors.append(grid[self.x + 1][self.y])
if self.y < cols - 1:
self.neighbors.append(grid[self.x][self.y + 1])
grid = [[Spot(i, j) for j in range(cols)] for i in range(rows)]
for i in range(rows):
for j in range(cols):
grid[i][j].add_neighbors()
current = grid[0][0]
visited = [current]
completed = False
def breakwalls(a, b):
if a.y == b.y and a.x > b.x:
grid[b.x][b.y].walls[1] = False
grid[a.x][a.y].walls[3] = False
if a.y == b.y and a.x < b.x:
grid[a.x][a.y].walls[1] = False
grid[b.x][b.y].walls[3] = False
if a.x == b.x and a.y < b.y:
grid[b.x][b.y].walls[0] = False
grid[a.x][a.y].walls[2] = False
if a.x == b.x and a.y > b.y:
grid[a.x][a.y].walls[0] = False
grid[b.x][b.y].walls[2] = False
class Player:
def __init__(self, x, y):
self.rect = pygame.Rect(x, y, hr-2, wr-2)
self.x = int(x)
self.y = int(y)
self.colour = (255, 0, 0)
self.velX = 0
self.velY = 0
self.left_pressed = False
self.right_pressed = False
self.up_pressed = False
self.down_pressed = False
self.speed = 5
def draw(self, win):
pygame.draw.rect(win, self.colour, self.rect)
def update(self):
self.velX = 0
self.velY = 0
if self.left_pressed and not self.right_pressed:
self.velX = -self.speed
if self.right_pressed and not self.left_pressed:
self.velX = self.speed
if self.up_pressed and not self.down_pressed:
self.velY = -self.speed
if self.down_pressed and not self.up_pressed:
self.velY = self.speed
self.x += self.velX
self.y += self.velY
self.rect = pygame.Rect(self.x, self.y, hr-2, wr-2)
def readMyFiles():
questionsAndAnswers = []
correctAnswers = []
with open('questions.txt', newline='') as f:
reader = csv.reader(f, delimiter='\t')
for row in reader:
questionsAndAnswers.append(row)
return questionsAndAnswers
def game(questions, answers, correctAnswers):
score = 0
counter = 0
numberOfQuestions = len(questions)
while not counter == numberOfQuestions:
print(questions[counter])
print(answers[counter])
userAnswer = input('\nWhat is the correct answer?\n')
if userAnswer == correctAnswers[counter]:
print('Well done! That is correct.')
score += 1
else:
print('Better luck next time, that is not correct.')
counter += 1
return score
def shuffleSplit(qna):
random.shuffle(qna)
questions = []
answers = []
correctAnswers = []
for q in qna:
questions.append(q[0])
correctAnswers.append(q[1])
del q[0]
random.shuffle(q)
answers.append(q)
return (questions, answers, correctAnswers)
def exportScores(score, ):
with open('scores.txt', mode='a') as scores:
scores = csv.writer(scores, delimiter='\t')
today = date.today()
dateFormat = today.strftime("%d/%m/%Y")
scores.writerow([dateFormat, score])
player = Player(2, 2)
while not done:
clock.tick(60)
screen.fill(BLACK)
if not completed:
grid[current.x][current.y].visited = True
got_new = False
temp = 10
while not got_new and not completed:
r = random.randint(0, len(current.neighbors)-1)
Tempcurrent = current.neighbors[r]
if not Tempcurrent.visited:
visited.append(current)
current = Tempcurrent
got_new = True
if temp == 0:
temp = 10
if len(visited) == 0:
completed = True
break
else:
current = visited.pop()
temp = temp - 1
if not completed:
breakwalls(current, visited[len(visited)-1])
current.visited = True
current.show_block(WHITE)
for i in range(rows):
for j in range(cols):
grid[i][j].show(WHITE)
# grid[i][j].show_block(BLUE)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
questionsAndAnswers = readMyFiles()
questions, answers, correctAnswers = shuffleSplit(questionsAndAnswers)
score = game(questions, answers, correctAnswers)
exportScores(score)
print('\nYour score is', str(score))
sys.exit()
if event.type == pygame.KEYDOWN and completed:
if event.key == pygame.K_LEFT:
player.left_pressed = True
if event.key == pygame.K_RIGHT:
player.right_pressed = True
if event.key == pygame.K_UP:
player.up_pressed = True
if event.key == pygame.K_DOWN:
player.down_pressed = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.left_pressed = False
if event.key == pygame.K_RIGHT:
player.right_pressed = False
if event.key == pygame.K_UP:
player.up_pressed = False
if event.key == pygame.K_DOWN:
player.down_pressed = False
player.rect.clamp_ip(screen_rect)
if player.x <= 2:
player.left_pressed = False
player.x = 2
if player.y <= 2:
player.up_pressed = False
player.y = 2
if player.x >= width-(wr-2):
player.right_pressed = False
player.x = width-(wr-2)
if player.y >= height-(wr-2):
player.down_pressed = False
player.y = height-(wr-2)
player.draw(screen)
player.update()
pygame.display.flip()
I have tried using player.clamp_ip(screen_rect) and creating a screen rectangle but this also doesn't work. I have tried checking for going off-screen using player.rect.x rather than player.x but still doesn't work.
Please help.
It is a matter of Indentation. The player moves even if the key is held down, but the keyboard events only occur once when a key is pressed or released. You need to do the collision test in the application loop and not in the event loop:
while not done:
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
# [...]
#<--| INDENTATION
player.rect.clamp_ip(screen_rect)
if player.x <= 2:
player.left_pressed = False
player.x = 2
if player.y <= 2:
player.up_pressed = False
player.y = 2
if player.x >= width-(wr-2):
player.right_pressed = False
player.x = width-(wr-2)
if player.y >= height-(wr-2):
player.down_pressed = False
player.y = height-(wr-2)
player.draw(screen)
player.update()
pygame.display.flip()
Commands screen.fill() or screen.blit(), doesnt refresh my object on the screen. My player's object or biedronka's objects stays in the same position even then my program reset the whole screen. My game runs perfectly and i have only problem with this refreshing screen. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
…
import os
import random
import pygame
pygame.init()
pygame.display.set_caption('Biedronkaaa')
screen = pygame.display.set_mode((500, 500))
background_menu = pygame.image.load("tlo-menu.png")
background_game = pygame.image.load("tlo-gra.png")
def write(text, x, y, size):
cz = pygame.font.SysFont("Arial", size)
text = cz.render(text, 1, (204, 0, 0))
screen.blit(text, (x, y))
class Biedronki():
def __init__(self):
self.x = random.randint(10, 100)
self.y = random.randint(10, 100)
self.vx = random.randint(-4, 4)
self.vy = random.randint(-4, 4)
self.graphic = pygame.image.load(os.path.join('biedrona.png'))
self.size = 24
def draw(self):
screen.blit(self.graphic, (self.x, self.y))
def moves(self):
self.x += self.vx
self.y += self.vy
if self.x <= 0 or self.x >= 500 - self.size:
self.vx = self.vx * -1
if self.y <= 0 or self.y >= 500 - self.size:
self.vy = self.vy * -1
def collision(self, player):
x_srodek = self.x + self.size / 2
y_srodek = self.y + self.size / 2
if player.collidepoint(x_srodek, y_srodek):
return True
else:
return False
enemies = []
for i in range(20):
enemies.append(Biedronki())
# player cords
x_player = 450
y_player = 450
v = 20
player = pygame.Rect(x_player, y_player, 32, 32)
graphic_player = pygame.image.load(os.path.join('gracz.png'))
game = "menu"
points = 0
# mainloop
while True:
screen.fill((255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
if y_player - v > 0:
y_player -= v
if event.key == pygame.K_DOWN:
if y_player + v < 500 - 32:
y_player += v
if event.key == pygame.K_RIGHT:
if x_player + v < 500 - 32:
x_player += v
if event.key == pygame.K_LEFT:
if x_player - v > 0:
x_player -= v
if event.key == pygame.K_SPACE:
if game != "contest":
screen.blit(graphic_player, (x_player, y_player))
game = 'contest'
points = 0
player = pygame.Rect(x_player, y_player, 32, 32)
if game == "menu":
screen.blit(background_menu, (0, 0))
write("Press space to run", 140, 250, 20)
elif game == "contest":
points += 1
screen.blit(background_game, (0, 0))
for biedroneczka in enemies:
biedroneczka.moves()
biedroneczka.draw()
if biedroneczka.collision(player):
game = "end"
screen.blit(graphic_player, (x_player, y_player))
write(str(points), 30, 30, 20)
pygame.time.wait(15)
elif game == "end":
write("Niestety przegrywasz", 50, 290, 20)
write("Nacisnij spację, aby zagrać jeszcze raz", 50, 350, 20)
write("Twój wynik to: " + str(points), 50, 320, 20)
pygame.display.update()
Finally fixed it by added to the space key reseting objects and player position
if event.key == pygame.K_SPACE:
if game != "contest":
screen.blit(graphic_player, (x_player, y_player))
game = 'contest'
points = 0
x_player = 450
y_player = 450
for _ in range(20):
enemies.pop(0)
for _ in range(20):
enemies.append(Biedronki())
You need to do pygame.display.update() at the end of the main loop.
So I'm just learning how to work with classes and getting them to work between each different class. I'm trying to design a game where the user moves around and picks up food and each time the user picks up a piece of food the size of the character increases. I've done something similar before but now that there are classes involved I seem to have a hard time finding which class this should be part of. I added within the sprite update method that if it collides with a cherry then the size of the player should increase by 5 pixels each time. using the code :
self.Player.surface = pygame.transform.scale(self.Player.surface, (pwidth+5, pheight+5))
self.rect = self.Player.surface.get_rect()
Each time the game runs the player size doesn't change and for some reason the game no longer ends after the player has eaten a certain amount of cherries so I was just wondering if I was using a wrong method of changing the size of the player perhaps there may be an easier way to do so? Heres the rest of the code incase it helps at all.
import pygame, glob, random, time
from pygame.locals import *
from LabelClass import *
# CONSTANTS
WIDTH = 400 # Window width
HEIGHT = 400 # Window height
BLACK = (0,0,0) # Colors
WHITE = (255,255,255)
BACKGR = BLACK # Background Color
FOREGR = WHITE # Foreground Color
FPS = 40 # Frames per second
pwidth = 40
pheight = 40
class Food:
def __init__(self,screen,centerx,centery):
self.screen = screen
self.surface = pygame.image.load('cherry.png')
self.rect = self.surface.get_rect()
self.rect.centerx = centerx
self.rect.centery = centery
def draw(self):
self.screen.blit(self.surface,self.rect)
#pygame.display.update([self.rect])
class Player:
def __init__(self, screen, centerx,
centery, speed, backcolor):
self.surface = pygame.image.load('player.png')
self.rect = self.surface.get_rect()
self.rect.centerx = centerx
self.rect.centery = centery
self.speed = speed
self.screen = screen
self.backcolor = backcolor
self.dir = ''
def draw(self):
self.screen.blit(self.surface,self.rect)
#pygame.display.update([self.rect])
def move(self):
if self.dir != '':
if self.dir == 'd' and self.rect.bottom < HEIGHT:
self.rect.top += self.speed
if self.dir == 'u' and self.rect.top > 0:
self.rect.top -= self.speed
if self.dir == 'l' and self.rect.left > 0:
self.rect.left -= self.speed
if self.dir == 'r' and self.rect.right < WIDTH:
self.rect.right += self.speed
def jump(self,top,left):
self.rect.top = top
self.rect.left = left
class SpritesGame:
def __init__(self,screen):
self.screen = screen
screen.fill(BLACK)
pygame.display.update()
music_file = getRandomMusic()
pygame.mixer.music.load(music_file)
pygame.mixer.music.play(-1,0.0)
self.music = True
self.Foods = [ ]
self.Eaten = 0
for i in range(20):
self.Foods.append(
Food(self.screen,
WIDTH*random.randint(1,9)//10,
HEIGHT*random.randint(1,9)//10))
for f in self.Foods:
f.draw()
self.Player = Player(screen,WIDTH//2,HEIGHT//2,6,BLACK)
self.PickUpSound = pygame.mixer.Sound('pickup.wav')
self.PlaySound = True
self.startTime = time.clock()
self.endTime = -1
self.Won = False
def update(self):
self.screen.fill(BLACK)
pickedUp = False
for f in self.Foods[:]:
if self.Player.rect.colliderect(f.rect):
self.Foods.remove(f)
self.Foods.append(Food(self.screen,WIDTH*random.randint(1,9)//10,HEIGHT*random.randint(1,9)//10))
pickedUp = True
self.Eaten += 1
self.Player.surface = pygame.transform.scale(self.Player.surface, (pwidth+5, pheight+5))
self.rect = self.Player.surface.get_rect()
#self.rect.center = center
print self.Eaten
if pickedUp and self.PlaySound:
self.PickUpSound.play()
for f in self.Foods:
f.draw()
if self.Eaten == 40:
self.Won = True
self.endTime = time.clock()
self.Player.move()
self.Player.draw()
pygame.display.update()
def toggleMusic(self):
self.music = not self.music
if self.music:
pygame.mixer.music.play(-1,0.0)
else:
pygame.mixer.music.stop()
def run(self):
stop = False
while not stop:
for event in pygame.event.get():
if event.type == QUIT:
stop = True
if event.type == KEYDOWN: # Keeps moving as long as key down
if event.key == K_LEFT or event.key == ord('a'):
self.Player.dir = 'l'
if event.key == K_RIGHT or event.key == ord('d'):
self.Player.dir = 'r'
if event.key == K_UP or event.key == ord('w'):
self.Player.dir = 'u'
if event.key == K_DOWN or event.key == ord('s'):
self.Player.dir = 'd'
if event.type == KEYUP:
if event.key == ord('q'):
stop = True
if event.key == K_ESCAPE:
stop = True
if event.key == K_LEFT or event.key == ord('a'): # End repetition.
self.Player.dir = ''
if event.key == K_RIGHT or event.key == ord('d'):
self.Player.dir = ''
if event.key == K_UP or event.key == ord('w'):
self.Player.dir = ''
if event.key == K_DOWN or event.key == ord('s'):
self.Player.dir = ''
if event.key == ord('x'):
top = random.randint(0,
HEIGHT - self.Player.rect.height)
left = random.randint(0,
WIDTH - self.Player.rect.width)
self.Player.jump(top,left)
if event.key == ord('m'):
self.toggleMusic()
if event.key == ord('p'):
self.PlaySound = not self.PlaySound
mainClock.tick(FPS)
self.update()
if self.Won:
stop = True # END OF WHILE
if self.Won:
self.screen.fill(BLACK)
pygame.display.update()
msg = (str((int(self.endTime)
-int(self.startTime)))
+" seconds to finish. Hit Q.")
L2 = Label(display,WIDTH//2,HEIGHT*7//8,26,msg,WHITE,BLACK)
L2.draw()
stop = False
while not stop:
for event in pygame.event.get():
if event.type == KEYUP:
if event.key == ord('q'):
stop = True
pygame.event.get()
pygame.mixer.music.stop()
def getRandomMusic():
mfiles = glob.glob("*.wav")
mfiles.append(glob.glob("*.mid"))
r = random.randint(0,len(mfiles)-1)
return mfiles[r]
def OpeningScreen(screen):
screen.fill(BLACK)
pygame.display.update()
L1 = Label(display,WIDTH//2,HEIGHT*7//8,26,"Hit Q to Quit, P to Play.",WHITE, BLACK)
L1.draw()
# Properly initiate pygame
pygame.init()
# pygame.key.set_repeat(INT,INT)
# Set the clock up
mainClock = pygame.time.Clock()
# Initialize Display
display = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption('Sprites and Sounds V06')
OpeningScreen(display)
stop = False
while not stop:
for event in pygame.event.get():
if event.type == QUIT:
stop = True
if event.type == KEYUP:
if event.key == ord('p'):
game = SpritesGame(display)
game.run()
OpeningScreen(display)
if event.key == ord('q'):
stop = True
pygame.quit()
Surface.get_rect() will always return a rect starting at (0,0), and you also are modifying SpritesGame.rect. I think you should change
self.rect = self.Player.surface.get_rect()
to
self.Player.rect.inflate_ip(5, 5)
I am making a platformer type game but I have run into two problems.
My Sprite is confined to a small box in the centered in the window. How do I make it so he can cover the entire window?
When I move the old sprite is not removed. It make it appear that there is a tail following the sprite.
Help for either would be appreciated!
import random, sys, copy, os, pygame, time, math
from pygame.locals import *
TILESIZE = 20
WINDOWWIDTH = 1280
WINDOWHEIGHT = 720
FPS = 30
floorx = (WINDOWHEIGHT - (TILESIZE))
floory = (WINDOWWIDTH / TILESIZE)
TileOffset = 20
tilesNeeded = (WINDOWWIDTH / TILESIZE)
floorSize = TILESIZE * 2
OUTSIDE_DECORATION_PCT = 20
HALF_WINDOWHEIGHT = (WINDOWHEIGHT / 2)
HALF_WINDOWWIDTH = (WINDOWWIDTH / 2)
CAMERASLACK = 25
MOVERATE = 9
BOUNCERATE = 6
BOUNCEHEIGHT = 30
INVULTIME = 2
GAMEOVERTIME = 4
MAXHEALTH = 3
STARTSIZE = 30
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
LIGHTGRAY = (174, 174, 174)
DARKGRAY = ( 41, 41, 41)
MEDGRAY = (101, 101, 101)
SKYBLUE = (200, 210, 255)
DARKTURQUOISE = ( 3, 54, 73)
GREEN = ( 0, 92, 7)
LIGHTGREEN = ( 0, 135, 15)
BGCOLOR = LIGHTGRAY
TEXTCOLOR = BLACK
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
def main():
global FPSCLOCK, DISPLAYSURF, BASICFONT, TILESIZE, floorx, floory, floorCovered, tilesNeeded, OUTSIDEDECOMAPPING, L_Monster, R_Monster, BGIMAGE
pygame.init()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
FPSCLOCK = pygame.time.Clock()
pygame.display.set_caption('Alpha One')
# Set up the background image.
boardImage = pygame.image.load('bg.png')
# Use smoothscale() to stretch the board image to fit the entire board:
boardImageRect = boardImage.get_rect()
boardImageRect.topleft = (0, 0)
BGIMAGE = pygame.image.load('bg.png')
# Use smoothscale() to stretch the background image to fit the entire window:
BGIMAGE = pygame.transform.smoothscale(BGIMAGE, (WINDOWWIDTH, WINDOWHEIGHT))
BGIMAGE.blit(boardImage, boardImageRect)
#Draw the background
DISPLAYSURF.blit(BGIMAGE, BGIMAGE.get_rect())
#Draw the Floor
drawFloor()
L_Monster = pygame.image.load('monster.png')
L_Monster = pygame.transform.scale(L_Monster, (1000, 600))
R_Monster = pygame.transform.flip(L_Monster, True, False)
pygame.display.flip()
#Main Game Loop
while True:
runGame()
#pygame.display.update()
def runGame():
invulnerableMode = False
invulnerableStartTime = 0
gameOverMode = False
gameOverStartTime = 0
winMode = False
camerax = 0
cameray = 0
playerObj = {'surface': pygame.transform.scale(L_Monster,(STARTSIZE, STARTSIZE)),
'facing': LEFT,
'size': STARTSIZE,
'x': HALF_WINDOWWIDTH,
'y': HALF_WINDOWHEIGHT,
'bounce':0,
'health': MAXHEALTH}
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
while True:
DISPLAYSURF.blit(BGIMAGE, BGIMAGE.get_rect())
drawFloor()
#DISPLAYSURF.fill(WHITE)
if invulnerableMode and time.time() - invulnerableStartTime > INVULNTIME:
invulnerableMode = False
playerCenterx = playerObj['x'] + int(playerObj['size'] / 2)
playerCentery = playerObj['y'] + int(playerObj['size'] / 2)
if (camerax + HALF_WINDOWWIDTH) - playerCenterx > CAMERASLACK:
camerax = playerCenterx + CAMERASLACK - HALF_WINDOWWIDTH
elif playerCenterx - (camerax +HALF_WINDOWWIDTH) > CAMERASLACK:
camerax = playerCenterx - CAMERASLACK - HALF_WINDOWWIDTH
if (cameray + HALF_WINDOWHEIGHT) - playerCentery > CAMERASLACK:
cameray = playerCentery + CAMERASLACK - HALF_WINDOWHEIGHT
elif playerCentery - (cameray +HALF_WINDOWHEIGHT) > CAMERASLACK:
cameray = playerCentery - CAMERASLACK - HALF_WINDOWHEIGHT
flashIsOn = round(time.time(), 1) * 10 % 2 == 1
if not gameOverMode and not (invulnerableMode and flashIsOn):
playerObj['rect'] = pygame.Rect((playerObj['x'] - camerax,
playerObj['y'] - cameray - getBounceAmount(playerObj['bounce'], BOUNCERATE, BOUNCEHEIGHT),
playerObj['size'],
playerObj['size']))
DISPLAYSURF.blit(playerObj['surface'], playerObj['rect'])
for event in pygame.event.get():
if event.type == QUIT:
terminate()
elif event.type == KEYDOWN:
if event.key in (K_UP, K_w):
moveDown = False
moveUp = True
elif event.key in (K_DOWN, K_s):
moveUp = False
moveDown = True
elif event.key in (K_LEFT, K_a):
moveRight = False
moveLeft = True
if playerObj['facing'] == RIGHT:
playerObj['surface'] = pygame.transform.scale(L_Monster, (playerObj['size'], playerObj['size']))
playerObj['facing'] == LEFT
elif event.key in (K_RIGHT, K_d):
moveLeft = False
moveRight = True
if playerObj['facing'] == LEFT:
playerObj['surface'] = pygame.transform.scale(R_Monster, (playerObj['size'], playerObj['size']))
playerObj['facing'] = RIGHT
elif winMode and event.key == K_r:
return
elif event.type == KEYUP:
if event.key in (K_LEFT, K_a):
moveLeft = False
elif event.key in (K_RIGHT, K_d):
moveRight = False
elif event.key in (K_UP, K_w):
moveUp = False
elif event.key in (K_DOWN, K_s):
moveDown = False
elif event.key == K_ESCAPE:
terminate()
if not gameOverMode:
if moveLeft:
playerObj['x'] -= MOVERATE
if moveRight:
playerObj['x'] += MOVERATE
if moveUp:
playerObj['y'] -= MOVERATE
if moveDown:
playerObj['y'] += MOVERATE
if (moveLeft or moveRight or moveUp or moveDown) or playerObj['bounce'] != 0:
playerObj['bounce'] += 1
if playerObj['bounce'] > BOUNCERATE:
playerObj['bounce'] = 0
else:
# game is over, show "game over" text
DISPLAYSURF.blit(gameOverSurf, gameOverRect)
if time.time() - gameOverStartTime > GAMEOVERTIME:
return
if winMode:
DISPLAYSURF.blit(winSurf, winRect)
DISPLAYSURF.blit(winSurf2, winRect2)
pygame.display.update()
FPSCLOCK.tick(FPS)
def getBounceAmount(currentBounce, bounceRate, bounceHeight):
return int(math.sin( (math.pi / float(bounceRate)) * currentBounce ) * bounceHeight)
def getRandomOffCameraPos(camerax, cameray, objWidth, objHeight):
# create a Rect of the camera view
cameraRect = pygame.Rect(camerax, cameray, WINDOWWIDTH, WINDOWHEIGHT)
while True:
x = random.randint(camerax - WINDOWWIDTH, camerax + (2 * WINDOWWIDTH))
y = random.randint(cameray - WINDOWHEIGHT, cameray + (2 * WINDOWHEIGHT))
# create a Rect object with the random coordinates and use colliderect()
# to make sure the right edge isn't in the camera view.
objRect = pygame.Rect(x, y, objWidth, objHeight)
if not objRect.colliderect(cameraRect):
return x, y
def isOutsideActiveArea(camerax, cameray, obj):
boundsLeftEdge = camerax - WINDOWWIDTH
boundsTopEdge = cameray - WINDOWHEIGHT
boundsRect = pygame.Rect(boundsLeftEdge, boundsTopEdge, WINDOWWIDTH * 3, WINDOWHEIGHT * 3)
objRect = pygame.Rect(obj['x'], obj['y'], obj['width'], obj['height'])
return not boundsRect.colliderect(objRect)
def checkForQuit():
for event in pygame.event.get(QUIT): # get all the QUIT events
terminate() # terminate if any QUIT events are present
for event in pygame.event.get(KEYUP): # get all the KEYUP events
if event.key == K_ESCAPE:
terminate() # terminate if the KEYUP event was for the Esc key
pygame.event.post(event)
def drawFloor():
#Open the image used for tiles and initialize N
floorTile = pygame.image.load('tile.png')
N = 0
while (N < tilesNeeded):
DISPLAYSURF.blit(floorTile,((20 * N, (floorx + (TILESIZE/4)) - TILESIZE)), )
DISPLAYSURF.blit(floorTile,(20 * N, (floorx + (TILESIZE/4))))
N = N + 1
#Updates the display
pygame.display.flip()
def checkCollide():
FLOOR_SURF = pygame.Rect( 0, (WINDOWHEIGHT - (TILESIZE * 2)), WINDOWWIDTH, WINDOWHEIGHT)
def terminate():
pygame.quit()
sys.exit()
if __name__ == '__main__':
main()
The reason you're getting the "tail" of your sprite is because you're not clearing the screen before you begin drawing a new frame. One way to handle this would be to enter something like the following at the beginning of runGame():
DISPLAYSURF.fill(white)
This will "clear" the surface by covering everything in white. When you begin drawing images for that frame, they will be drawn over a blank white surface. The caveat to this is that you will need to redraw every sprite on the screen, not just the ones that have moved in the last frame.
For the first question, if you're asking how to scale the size of the image, you would use the scale function from pygame.transform
L_monster = pygame.transform.scale(L_monster, (500, 500))
This creates a new surface by transforming the given surface to the new size given by the tuple.
http://www.pygame.org/docs/ref/transform.html#pygame.transform.scale