I'm beginner at pygame development, when I update my spritesheet image, the old image persists in the surface.
How do I clear the surface?
main.py
FPS = 10
try:
import sys
import random
import math
import os
import getopt
import pygame
from socket import *
from pygame.locals import *
from player import *
except ImportError as err:
print("Couldn't load module. {}".format( err ) )
sys.exit(2)
pygame.init()
fps_clock = pygame.time.Clock()
screen = pygame.display.set_mode((600, 600))
game_surface = pygame.Surface(screen.get_size())
game_surface.fill((250,250,250))
game_surface_image = pygame.image.load("data/landscape.jpg").convert()
game_surface.convert()
p = Player()
player_surface = pygame.Surface((p.SPRITE_WIDTH, p.SPRITE_HEIGHT), pygame.SRCALPHA)
# ---------------------------------------------------------------
# MAIN LOOP -----------------------------------------------------
# ---------------------------------------------------------------
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
screen.fill((250,250,250))
pygame.display.set_caption("FPS: {:.2f}".format(fps_clock.get_fps()))
p.animation()
player_surface.blit(p.image, (0,0), p.rect)
game_surface.blit(game_surface_image, (0,0))
game_surface.blit(player_surface, (screen.get_rect().centerx - p.SPRITE_WIDTH/2, screen.get_rect().centery - p.SPRITE_HEIGHT/2))
screen.blit(game_surface, (0,0))
pygame.display.update()
fps_clock.tick(FPS)
player.py
import pygame
from pygame.locals import *
class Player(pygame.sprite.Sprite):
SPRITE_HEIGHT = 110
SPRITE_WIDTH = 60
SPRITE_QTY = 8
SPRITE_NAME = "data/player_sprite.png"
__ANIMATION_INTERVAL = 12
__ANIMATION_COUNT = 0
__SPRITE_POSITION = 0
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(self.SPRITE_NAME).convert_alpha()
self.rect = (0, 0, self.SPRITE_WIDTH, self.SPRITE_HEIGHT)
def animation(self):
if self.__ANIMATION_COUNT == self.__ANIMATION_INTERVAL:
self.__ANIMATION_COUNT = 0
if self.__SPRITE_POSITION < self.SPRITE_QTY - 1:
self.__SPRITE_POSITION += 1
else:
self.__SPRITE_POSITION = 0
self.rect = Rect(self.SPRITE_WIDTH * self.__SPRITE_POSITION, 0, self.SPRITE_WIDTH * self.__SPRITE_POSITION + self.SPRITE_WIDTH, self.SPRITE_HEIGHT)
else:
self.__ANIMATION_COUNT += 1
The problem lies in this line:
player_surface.blit(p.image, (0,0), p.rect)
The player image is blit again on top of the old image. The player_surface needs to be cleared first.
Adding player_surface.fill(BLANK_ALPHA) with BLANK_ALHPA = (0, 0, 0, 0) should do the trick.
player_surface.fill(BLANK_ALPHA)
player_surface.blit(p.image, (0,0), p.rect)
Related
I have 3 python files: main.py, settings.py and classes.py
main.py:
import pygame as pg
from classes import *
from settings import *
pg.font.init()
HEALTH_FONT = pg.font.SysFont('comicsans', 20)
pg.display.set_caption("Testa Game")
ground_surface = pg.image.load('graphics/ground.png').convert()
BG_COLOR = (0, 255, 255)
BLACK = (0, 0, 0)
run = True
while run == True:
clock = pg.time.Clock()
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
exit()
clock.tick(FPS)
keys_pressed = pg.key.get_pressed()
health_text = HEALTH_FONT.render("Health: " + str(class_type.health), 1, BLACK)
WIN.fill(BG_COLOR)
WIN.blit(class_type.karakter_surface, (class_type.karakter.x, class_type.karakter.y))
WIN.blit(ground_surface, (0, 350))
WIN.blit(health_text, (10, 10))
karakter_moving(keys_pressed, class_type.karakter)
pg.display.flip()
settings.py:
import pygame as pg
from classes import *
WIDTH, HEIGHT = 900, 500
WIN = pg.display.set_mode((WIDTH, HEIGHT))
class_type = death_mage
FPS = 60
def karakter_moving(keys_pressed, karakter):
if keys_pressed[pg.K_w] and karakter.y - class_type.speed > 0:
karakter.y -= class_type.speed
if keys_pressed[pg.K_s] and karakter.y + class_type.speed + karakter.height < HEIGHT - 5:
karakter.y += class_type.speed
if keys_pressed[pg.K_a] and karakter.x - class_type.speed > 0: #LEFT
karakter.x -= class_type.speed
if keys_pressed[pg.K_d] and karakter.x + class_type.speed + karakter.width < WIDTH:
karakter.x += class_type.speed
classes.py:
import pygame as pg
from settings import WIN
pg.init()
def fire_ball():
fireball = []
maxFireBall = 3
manacost = 1
color = 'ORANGE'
for event in pg.event.get():
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE and len(fireball) < maxFireBall:
dmFireBall = pg.Rect(
death_mage.karakter.x + death_mage.karakter.width, death_mage.karakter.y + death_mage.karakter.height//2 - 2, 10, 5)
fireball.append(dmFireBall)
death_mage.mana -= manacost
pg.draw.rect(WIN, color, fireball)
class death_mage:
KARAKTER_WIDTH, KARAKTER_HEIGHT = 60, 85
karakter = pg.Rect(400, 200, KARAKTER_WIDTH, KARAKTER_HEIGHT)
karakter_surface = pg.transform.scale(pg.image.load('Assets/death_mage.png'), (KARAKTER_WIDTH, KARAKTER_HEIGHT))
health = 10
mana = 5
attack = 1
speed = 2
attack_speed = 1
crit_rate = 0
crit_damage = 0
Error message:
"settings.py", line 12, in <module>
class_type = death_mage
NameError: name 'death_mage' is not defined
or if settings.py: from classes import death_mage
"settings.py", line 3, in <module>
from classes import death_mage
ImportError: cannot import name 'death_mage' from partially initialized module 'classes' (most likely due to a circular import)
How can I remedy this?
Thanks to helping me
One of your modules has got no urls.py
Here's the code, i'm working on Atom. I've been using pygame for a lot of time, and that rarely happens. I never knew what the problem was, but i never needed to, until now.
import pygame
from random import randint as rnd
from colorama import Cursor
import math
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (600,90)
pygame.init()
xsize, ysize = 700, 700
screen = pygame.display.set_mode((xsize, ysize))
screen.fill((0, 0, 0))
def dis(p1, a1):
return math.sqrt((p1[0] - a1[0])**2 + (p1[1] - a1[1])**2)
inner = 0
tot = 0
pygame.draw.circle(screen, (255, 255, 255), (350, 350), 350, 2)
while True:
pos = (rnd(0, xsize), rnd(0, ysize))
if dis((350, 350), pos) < 350:
color = (50, 255, 50)
inner += 1
else:
color = (50, 50, 250)
tot += 1
pygame.draw.circle(screen, color, pos, 2)
print(" pi = " + str(4 * inner / tot) + "\nnÂș dots: " + str(tot), Cursor.UP(2))
pygame.display.flip()
The window freeze, because you do not handle the events. You have to handle the events by either pygame.event.pump() or pygame.event.get(), to keep the window responding.
Add an event loop, for instance:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# [...]
I am starting to write a game but whenever I run my code it takes 2 minutes to boot up and even then some methods are not working. The main ones that's not working are quitting pygame and drawGameScene().
My code is:
import os, random
from pygame import *
init()
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" %(0, 20)
scalefactor = 2
FPS = 60
screenWidth = round(224 * scalefactor)
screenHeight = round(298 * scalefactor)
size = screenWidth, screenHeight
screen = display.set_mode(size)
button = 0
RED = (255, 0, 0)
BLUE = (0,0,255)
STATEGAME = 1
STATEQUIT = 3
curState = STATEGAME
titleFont = font.SysFont("Times New Roman",45)
def drawText(words, screen,position, color, font):
text = font.render(words, False, color)
textSize = text.get_size()
position[0] = position[0] - textSize[0]//2
position[1] = position[1] - textSize[1]//2
#centers the text
screen.blit(text,position)
def gameRun():
while curState != STATEQUIT:
if curState == STATEGAME:
drawGameScene()
eventCheck()
updater()
def eventCheck():
for evnt in event.get():
if evnt.type == QUIT:
curState == STATEQUIT
def updater():
pass
def drawGameScene():
draw.rect(screen,RED,(0,0,screenWidth,screenHeight))
drawText("High Score", screen, [0,0], BLUE, titleFont)
display.update
gameRun()
display.flip()
no error messages are given
Please Help, It's for a project
For the quitting pygame:
You should use the code as below:
for events in event.get():
if events.type == QUIT:
pygame.quit()
exit() #this is from sys module
This way, your pygame is quitted at the first place. So, you don't need anything about curstate, etc.
Also, you need to use while True statement to repeat the blitting process.
Full code:
import os, random
from pygame import *
from sys import exit
init()
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" %(0, 20)
scalefactor = 2
FPS = 60
screenWidth = round(224 * scalefactor)
screenHeight = round(298 * scalefactor)
size = screenWidth, screenHeight
screen = display.set_mode(size)
button = 0
RED = (255, 0, 0)
BLUE = (0,0,255)
titleFont = font.SysFont("Times New Roman",45)
def drawText(words,screen,position,color,font):
text = font.render(words, False, color)
textSize = text.get_size()
position[0] = position[0] - textSize[0]//2
position[1] = position[1] - textSize[1]//2
#centers the text
screen.blit(text,position)
def gameRun():
drawGameScene()
eventCheck()
updater()
def eventCheck():
for events in event.get():
if events.type == QUIT:
quit()
exit()
def updater():
pass
def drawGameScene():
draw.rect(screen,RED,(0,0,screenWidth,screenHeight))
drawText("High Score", screen, [0,0], BLUE, titleFont)
#display.update()
while True:
gameRun()
display.flip()
I would like to implement a code which has non colliding pairs with colliding objects. My pairs are 2 balls which are connected to each other. I want those 2 pair ball to collide. However I don't want those 2 balls to collide with other pairs.
How can I implement a mask with this much of categories in pymunk ShapeFilter? Should I use bitwise operators? As you can see in my shape filter I tried to ignore values which is out of their category except their pairwise catergory, BUT it doesnt work for 4 + number of balls?
My code cannot handle those states of balls with each other.
import pygame
from pygame.locals import *
from pygame.color import *
import pymunk
import pymunk.pygame_util
from pymunk import Vec2d
import sys
#import tensorflow as tf
from time import sleep
import time
import numpy as np
from math import exp
from random import seed
from random import random
import datetime
import operator
class Game:
def __init__(self):
# initialize game window
pygame.init()
self.screen_x= 1500
self.screen_y= 200
# Pool Hyper Parameters
# BE CAREFULL CHANGING THESE VARIABLES
self.pool_size = 2
self.pool_time = 15
#########################################################################
# NN lists
#Pygame fonts
self.font = pygame.font.SysFont("Arial", 16)
self.screen = pygame.display.set_mode((self.screen_x,self.screen_y+200)) #screen display
self.clock = pygame.time.Clock() ## init clock
self.running = True
# pymunk init
self.space = pymunk.Space()
self.space.gravity = (0.0, -1200.0) #gravity setup
self.draw_options = pymunk.pygame_util.DrawOptions(self.screen)#adds add physics to the screen
def new(self):
# start a new game
## Balls
self.balls = []
## creating walls
self.static_body = self.space.static_body
self.static_lines = [pymunk.Segment(self.static_body, (0.0,50.0), (1500.0, 50.0), 0.0) ## road
,pymunk.Segment(self.static_body, (1499.0, 150.0), (1499.0, 700.0), 0.0)
,pymunk.Segment(self.static_body, (1800, 50.0), (1800, 170.0), 0.0)
,pymunk.Segment(self.static_body, (0.0,50.0), (0.0, 700.0), 0.0) ## wall 1
]
## set walls
for line in self.static_lines:
line.elasticity = 0.95
line.friction = 01.5
#line.filter = pymunk.ShapeFilter(categories=np.uint8(0))
self.space.add(self.static_lines)
# Go to run
self.run()
def run(self):
# Game Loop
self.playing = True
self.no_ball = True
while self.running:
self.events()
if self.no_ball == True:
self.unit(self.pool_size)
self.update()
def update(self):
self.screen.fill(THECOLORS["white"])
### Draw stuff
self.balls_to_remove = []
for ball in self.balls:
if ball.body.position.y < 0: self.balls_to_remove.append(ball)
for ball in self.balls_to_remove:
self.space.remove(ball, ball.body)
self.balls.remove(ball)
self.space.debug_draw(self.draw_options)
### Update physics
self.dt = 1.0/60.0
for k in range(1):
self.space.step(self.dt)
### Flip screen
pygame.display.flip()
self.clock.tick(50)
pygame.display.set_caption("fps: " + str(self.clock.get_fps()))
def events(self):
for event in pygame.event.get():
if event.type == QUIT:
self.running = False
if event.type == KEYDOWN:
if event.key == K_y: ## Creates a ball
self.running = False
pass
elif event.type == pygame.MOUSEMOTION:
(self.mouse_x, self.mouse_y) = pymunk.pygame_util.get_mouse_pos(self.screen)
def unit (self, number_balls=None):
#Mass And Radius units
self.mass = 20
self.radius = 10
#Mass and Radius for joint
self.mass_joint = 2
self.radius_joint = 2
#for n in number_balls
self.objs = list()
for i in range(number_balls):
self.objs.append(pymunk.Body())
self.objs.append(pymunk.Body())
self.objs.append(pymunk.Body())
#Inertia
self.inertia = pymunk.moment_for_circle(self.mass, 0, self.radius, (0,0))
self.inertia_joint = pymunk.moment_for_circle(self.mass_joint , 0, self.radius_joint, (0,0))
#Body
self.objs[i], self.objs[i+1] = pymunk.Body(self.mass, self.inertia), pymunk.Body(self.mass, self.inertia)
self.objs[i+2] = pymunk.Body(self.mass_joint, self.inertia_joint)
#Position
x = 100
self.objs[i].position = x , 90
self.objs[i+1].position = x+24, 90
self.objs[i+2].position = x+12, 90
#Links
self.link_1 = pymunk.PinJoint(self.objs[i], self.objs[i+2], (0, 0), (0, 0))
self.link_2 = pymunk.PinJoint(self.objs[i+1], self.objs[i+2], (0, 0), (0, 0))
# Adding Body links
self.space.add(self.link_1)
self.space.add(self.link_2)
#First ball shape
self.shape_first = pymunk.Circle(self.objs[i], self.radius, (0,0))
self.shape_first.elasticity = 0.4
self.shape_first.friction = 0.9
self.space.add(self.objs[i], self.shape_first)
#Fsecond ball shape
self.shape_second = pymunk.Circle(self.objs[i+1], self.radius, (0,0))
self.shape_second.elasticity = 0.4
self.shape_second.friction = 0.9
self.space.add(self.objs[i+1], self.shape_second)
#Joint shape
self.shape_joint = pymunk.Circle(self.objs[i+2], self.radius_joint, (0,0))
self.shape_joint.elasticity = 0.4
self.shape_joint.friction = 0.9
#self.shape_joint.sensor == True
self.space.add(self.objs[i+2], self.shape_joint)
body_first_category = (i*3)+1#"{0:b}".format(int(i+1))
body_second_category = (i*3)+2
body_joint_category = (i*3)+3
print (body_first_category )
print(body_second_category )
print(body_joint_category )
#"{0:b}".format(int(i+2))
self.shape_first.filter = pymunk.ShapeFilter(categories=body_first_category, mask=(body_joint_category and body_second_category) )
self.shape_second.filter = pymunk.ShapeFilter(categories=body_second_category, mask=(body_first_category and body_joint_category) )
self.shape_joint.filter = pymunk.ShapeFilter(categories=body_joint_category, mask=(body_first_category and body_second_category))
self.balls.append(self.shape_first)
self.balls.append(self.shape_second)
self.balls.append(self.shape_joint)
self.no_ball = False
g = Game()
while g.running:
g.new()
##pg.quit()
Please help :)
P.S: Example Library shape filter class:
http://www.pymunk.org/en/latest/pymunk.html#pymunk.ShapeFilter
You can solve this with collision callbacks, I think begin callback is a good option for you. On each pair of shapes you want to collide you set a common identifier, and then check that in the callback, and return True only when the two objects colliding belong to the same pair.
Something like this:
def only_collide_same(arbiter, space, data):
a, b = arbiter.shapes
return a.pair_index == b.pair_index
h = space.add_collision_handler(1,1)
h.begin = only_collide_same
for i in range(10):
# create shapes and bodies ...
# then for each pair of shapes:
shape1.pair_index = i
shape1.collision_type = 1
shape2.pair_index = i
shape2.collision_type = 1
I'm new to Pygame and I'm trying to move my sprite on my background image.
My sprite is not re appearing after it moves? Any ideas?
This is most of the program without some screens.
I have been trying to get this to work for many hours,
#dependencies
import pygame as P
import random as R
def welcome(screen):
#load background
bg = P.image.load("space-wallpaper.jpg")
screen.blit(bg,[0,0])
#set fonts etc
font = P.font.Font("Space_Age.ttf",60)
width, height = screen.get_size()
#play button
message = "PLAY "
text = font.render(message,1,[255 , 0, 0])
rect = text.get_rect()
x, y = text.get_size()
rect = rect.move((width - x)/2, (height - y)/2)
screen.blit(text,rect)
#high_score button
message = "HIGH SCORE "
text = font.render(message,1,[255 , 0, 0])
rect = text.get_rect()
x, y = text.get_size()
rect = rect.move((width - x)/2, (height - y)/2 +100)
screen.blit(text,rect)
def play_button(screen):
"""launch welcome screen.
"""
#welcome screen play button
font = P.font.Font("Space_Age.ttf",60)
message = "PLAY "
play_x,play_y = font.size(message)
play_text = font.render(message,1,[255 , 0, 0])
width, height = 800,600
screen.blit(play_text,[(width - play_x)/2, (height - play_y)/2])
play_rect = play_text.get_rect().move((width - play_x)/2, (height - play_y)/2)
P.display.flip()
return(play_rect)
def welcome_background(screen):
# Welcome screen background
bg = P.image.load("space-wallpaper.jpg")
screen.blit(bg,[0,0])
P.display.update()
def high_score_screen(screen):
"""opens the highscore screen"""
high_score_bg = P.image.load("bg_game.jpg")
screen.blit(high_score_bg,[0,0])
P.display.update()
def splash_screen(screen):
"""loads the first screen in the game with a 3 sec wait"""
splash_image = P.image.load('splash.jpg')
screen.blit(splash_image,[0,0])
P.display.update()
P.time.wait(2001)
def play_game(screen):
"""loads the play game screen"""
game_bg = P.image.load("bg_game.jpg")
screen.blit(game_bg,[0,0])
P.display.update()
def move_right(screen,x_cord,flagship):
dist = 20
play_game(screen)
x_cord = x_cord + dist
print(x_cord)
screen.blit(flagship,[x_cord])
P.display.update()
def key_detection(screen,flagship,x_cord):
key = P.key.get_pressed()
if key[P.K_RIGHT]:
move_right(screen,x_cord,flagship)
#move_right()
elif key[P.K_LEFT]:
print("left")
class Sprite():
def __init__(self,screen):
""" The constructor of the class """
self.flagship = P.image.load("sprite2.png")
self.x = 0
self.y = 0
def display(self,screen):
#screen.blit(self.sprite,[self.x,self.y]) changed by geoff
screen.blit(self.flagship,[self.x,self.y])
P.display.update()
_init_
# dependencies
from mods import *
import pygame as P
#initialise pygame
P.init()
def main():
# parameters to control pygame basics
screen_size = width, height = 800,600 #sixe of playing screen
P.display.set_caption('Space Smasher!')
screen = P.display.set_mode(screen_size)
clock = P.time.Clock() # timer used to control rate of looping
loop_rate = 20 #number of times per second does loop
play = True #control the playing of the actual game
splash_screen(screen)
welcome(screen)
P.display.flip()
rect_play = play_button(screen)
flagship = Sprite(screen)
while play:
key_detection(screen,flagship.image,flagship.x)
# for event in P.event.poll(): changed by geoff
event = P.event.poll() #did the player do something?
if event.type == P.QUIT:
play = False
if event.type == P.MOUSEBUTTONDOWN:
player_position = P.mouse.get_pos()
if rect_play.collidepoint(player_position):
play_game(screen)
flagship.display(screen)
P.quit()
if __name__ == '__main__':
main()
You are not calling either of your functions or your classes anywhere. You need a while loop that is similarly structured to this:
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
#Do your movements
With the following imports at the top:
import pygame, sys
from pygame.locals import *
Here is an example of moving an object with the keys:
import pygame, sys
from pygame.locals import *
pygame.init()
WIDTH=1439
HEIGHT=791
DISPLAYSURF = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Hello Pygame World!')
pygame.key.set_repeat(1, 10)
circx, circy = 200, 150
CIRWIDTH=20
while True: # main game loop
if pygame.key.get_pressed()[pygame.K_UP]:
circy-=5
if pygame.key.get_pressed()[pygame.K_DOWN]:
circy+=5
if pygame.key.get_pressed()[pygame.K_RIGHT]:
circx+=5
if pygame.key.get_pressed()[pygame.K_LEFT]:
circx-=5
try:
for event in pygame.event.get():
if event.type == QUIT or event.key == pygame.K_ESCAPE or event.key == pygame.K_q:
pygame.quit()
sys.exit()
except AttributeError:
pass
DISPLAYSURF.fill((0, 0, 0))
pygame.draw.circle(DISPLAYSURF, (158, 219, 222), (circx, circy), CIRWIDTH)
pygame.display.flip()
Main loop should be similar to:
while True:
# events - check keyboad and mouse and change player direction or speed
# move - move sprite with speed and direction
# check collison
# draw background, all objects and all sprites
# clock - to keep constant speed - FPS (Frames Per Seconds)
So you have to move sprites in every loop and draw them.