So I am making a simple "Dodge the Meteor Game" with Python 27 and Pygame. So everything ran smoothly, until I wanted to make classes, so I could make multiple meteors without retyping the same code. After I did this, when I run it, it stops responding with no error message. Here is my code:
import pygame
from pygame.locals import *
import sys
import random
pygame.init()
width,height = 800,600
gameDisplay = pygame.display.set_mode((width,height))
pygame.display.set_caption("Fifteen Minute Game ")
gameStart = False
bg = pygame.image.load("C:\Users\DEREK\Desktop\Python\\space.jpg")
bg = pygame.transform.scale(bg,(900,600))
x = 300
y = 300
move_x = 0
move_y = 0
playerspeed = 3
pellet_x = random.randint(0,800)
pellet_y = random.randint(0,550)
player = pygame.draw.rect( gameDisplay, (255,255,255), (x,y,30,30) )
pellet = pygame.draw.rect( gameDisplay, (255,255,255), (pellet_x,pellet_y,15,15) )
count = 0
#Functions
def pelletxy():
global pellet_x, pellet_y
pellet_x = random.randint(0,770)
pellet_y = random.randint(0,570)
def collision(rect1,rect2):
global player, count, pellet
if rect1.colliderect(rect2):
if rect2 == pellet:
pelletxy()
count +=1
class Meteor():
def __init__(self):
self.meteor_x = random.randint(0,800)
self.meteor_y = 0
self.meteorfall = 3
self.meteor = pygame.draw.rect( gameDisplay, (255,255,255), (self.meteor_x,self.meteor_y,35,35) )
def collision(self,rect1,rect2):
if rect1.colliderect(rect2):
if rect2 == self.meteor:
print "Good Game"
print "MUA HAHAHAHA"
print ""
print "Your score:" + str(count)
pygame.quit()
sys.exit()
def meteorxy(self):
self.meteor_x = random.randint(0,800)
self.meteor_y = 0
def render(self):
self.meteor_y += self.meteorfall
self.meteor
if meteor_y > 600:
meteorxy()
m1 = Meteor()
#Game Loop
while gameStart:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Keyboard Movement
if event.type == pygame.KEYDOWN:
if event.key == K_UP:
move_y -= playerspeed
if event.key == K_DOWN:
move_y += playerspeed
if event.key == K_LEFT:
move_x -= playerspeed
if event.key == K_RIGHT:
move_x += playerspeed
if event.type == pygame.KEYUP:
if event.key == K_UP:
move_y = 0
if event.key == K_DOWN:
move_y = 0
if event.key == K_LEFT:
move_x = 0
if event.key == K_RIGHT:
move_x = 0
#Calculate new position
x = x + move_x
y = y + move_y
#Stop Movement on boundaries
if x > 830:
x = -30
elif x < -30:
x = 830
elif y < -30:
y = 630
elif y > 630:
y = -30
#Check Different Collision Scenarios
collision(player, pellet)
m1.collision(player, m1.meteor)
#Draw the things onto the screen
gameDisplay.blit(bg,(0,0))
player = pygame.draw.rect( gameDisplay, (255,255,255), (x,y,30,30) )
pellet_outline = pygame.draw.rect( gameDisplay, (255,255,255), ((pellet_x - 1), (pellet_y - 1), 17,17))
pellet = pygame.draw.rect( gameDisplay, (0,0,255), (pellet_x,pellet_y,15,15) )
m1.render
pygame.display.update()
I don't know what I'm doing wrong, but I know it is with the classes. Thanks in advance
Hobby Programmer, Derek
Well, it's probably because gameStart is always False. So you're never getting into the game loop.
You should get to know debugging. You can use pdb or any IDE like Eclipse. The important thing is that it can help you understand what code is being running.
if event.key == K_RIGHT:
move_x = 0
#Calculate new position
x = x + move_x
y = y + move_y
See how the indentation changes? In Python, indentation is very important. Because all of your code after the line 'move_x = 0' is not indented adequately, it is not part of your while loop; therefore, it does not get executed in the loop. Fix your indentation.
Related
I can't collide rect whit rectangles, should I give up or try using x and y positions?
I don't get any errors from it but it closes right after i run it.
can you please suggest me what to do.
import pygame,sys,time,random
pygame.init()
x = 425
y = 750
player_x = x/2-25
player_y = 600
player_speed = 0
timer = 0
score = 0
screen = pygame.display.set_mode((x,y))
clock = pygame.time.Clock()
enemy_x = random.randint(0,425)
enemy_y = -(random.randint(0,500))
enemy2_x = random.randint(0,425)
enemy2_y = -(random.randint(0,500))
police_x = random.randint(0,425)
police_y = random.randint(750,1400)
police2_x = random.randint(0,425)
police2_y = random.randint(750,1400)
enemy_speed = 16
police_speed = 3
font = pygame.font.SysFont("comicsansms",50)
player = pygame.image.load("macchina.png").convert_alpha()
pygame.display.set_caption("NapoliSimulator (schiva le buche e non farti prendere dalla pula)")
def player_a():
global player_x,player_y,player_speed
player_x+=player_speed
player = pygame.image.load("macchina.png").convert_alpha()
screen.blit(player,(player_x,player_y))
def enemy_a():
global enemy_x,enemy_y,enemy_speed,enemy2_x,enemy2_y,enemy3_x,enemy3_y,enemy4_x,enemy4_y,enemy5_x,enemy5_y
enemy_y += enemy_speed
enemy2_y += enemy_speed
enemy = pygame.image.load("crepa.png").convert_alpha()
enemy_2 = pygame.image.load("crepa.png").convert_alpha()
screen.blit(enemy,(enemy_x,enemy_y))
screen.blit(enemy,(enemy2_x,enemy2_y))
def enemy_b():
global police_x,police_y,police_speed,police2_x,police2_y
police_y -= police_speed
police = pygame.image.load("polizia.png").convert_alpha()
screen.blit(police,(police_x,police_y))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
player_speed -= 5
if event.key == pygame.K_d:
player_speed += 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player_speed += 5
if event.key == pygame.K_d:
player_speed -= 5
screen.fill((200,200,200))
player_a()
if enemy_y >= 700:
enemy_y = -(random.randint(500,1200))
enemy_x = random.randint(0,425)
score += 1
if enemy2_y >= 700:
enemy2_y = -(random.randint(0,750))
enemy2_x = random.randint(0,425)
score += 1
if police_y <= 40:
police_y = random.randint(750,1900)
police_x = random.randint(0,425)
score += 1
enemy_a()
if score >= 7:
enemy_b()
if score >= 15:
police_speed += 0.0001
enemy = pygame.image.load("crepa.png").convert_alpha()
enemy_2 = pygame.image.load("crepa.png").convert_alpha()
police = pygame.image.load("polizia.png").convert_alpha()
playerr = player.get_rect()
enemyr = enemy.get_rect()
policer = police.get_rect()
enemyr2 = enemy_2.get_rect()
if enemyr.colliderect(playerr):
pygame.quit()
sys.exit()
if enemyr2.colliderect(playerr):
pygame.quit()
sys.exit()
if crepar.colliderect(policer):
enemy_b()
if player.colliderect(policer):
pygame.quit()
ys.exit()
pygame.display.flip()
clock.tick(60)
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. A Surface is blit at a position on the screen. The position of the rectangle can be specified by a keyword argument. For example, the top left of the rectangle can be specified with the keyword argument topleft:
playerr = player.get_rect(topleft = (player_x, player_y))
enemyr = enemy.get_rect(topleft = (enemy_x, enemy_y))
policer = police.get_rect(topleft = (police_x, police_y))
enemyr2 = enemy_2.get_rect(topleft = (enemy2_x, enemy2_y))
if enemyr.colliderect(playerr):
pygame.quit()
sys.exit()
if enemyr2.colliderect(playerr):
pygame.quit()
sys.exit()
if player.colliderect(policer):
pygame.quit()
sys.exit()
I'm new to pygame so my code is a bit messy but I hope you can help me. When I make a sprite move it works fine, but if I switch keys really fast, or if I press the jump button and let go, my sprite stops moving.
import shelve
import sys, pygame, pygame.mixer
import time
from pygame.locals import *
import random
pygame.init()
shelfFile = shelve.open('save_game')
#screen
sise = width, hight = 700, 600
red = 30,30,30
screen = pygame.display.set_mode(sise)
pygame.display.set_caption('Thing')
#varuables
background = pygame.image.load('background.png')
player = pygame.image.load('you.png')
enemy1 = pygame.image.load('enemy1.png')
clock = pygame.time.Clock()
px = shelfFile['px']
py = shelfFile['py']
health = shelfFile['health']
x2 = 0
x = 0
y = 0
u = 0
d = 0
t = 0
r = 0
ex = 0
ey = 0
cutseane = shelfFile ['cutseane']
black = 255,255,255
Punch = False
color = 255,0,0
radius = 5
room = shelfFile['room']
ehealth = shelfFile['ehealth']
while True:
pygame.event.get()
if jump == 1:
y = -20
if py <= 200:
jump = 2
if jump == 2:
y = +20
if py >= 480:
py = 480
#The Wall
if px <= 0:
px = 0
if px >= 630:
px = 630
pygame.display.flip()
screen.blit(background,(1,1))
screen.blit(player,(px,py))
#if ehealth >= 1:
#screen.blit(enemy1,(ex,ey))
#else:
#ex = 0
#ey = 0
px = px + x
py = py + y
clock.tick(30)
for event in pygame.event.get():
keys = pygame.key.get_pressed()
if event.type == KEYDOWN and event.key == pygame.K_ESCAPE:
shelfFile['px'] = px
shelfFile['py'] = py
shelfFile['health'] = health
shelfFile['ehealth'] = ehealth
shelfFile['cutseane'] = cutseane
shelfFile['room'] = room
shelfFile.close()
pygame.quit(); sys.exit();
#Player Movement
elif event.type == pygame.KEYDOWN:
if keys [pygame.K_0]:
health -= 1
text = 1
shelfFile['text'] = text
elif event.key == pygame.K_RIGHT:
x = -15
elif event.key == pygame.K_LEFT:
x = +15
elif event.key == pygame.K_UP:
y = +15
elif event.key == pygame.K_DOWN:
y = -15
elif event.type == KEYUP:
if event.key == pygame.K_LEFT and x > 0:
x = 0
elif event.key == pygame.K_RIGHT and x < 0:
x = 0
elif event.key == pygame.K_UP and x > 0:
y = 0
elif event.key == pygame.K_DOWN and x < 0:
y = 0
I think the problem is that in some places, you wrote y = +20 instead of y += 20. If you want y to increase by 20 units, do y += 20, if you want y to be set to the value 20, do y = 20 (does the same thing as y = +20). I don't know what you are trying to do because I don't have your png files and I can't run the program to see what happens. Also, if it even is an unintentional mistake, you did the same thing for negatives and in other parts of the code.
This isn't really a mistake, it will work if not corrected but you also spelled some things wrong (if it was intentional, ignore this.)
sise should be size,
hight should be height,
cutseane should be cutscene...
There are other mistakes. If all of this works and they are not just typos, then you might be using some version of python that I am not aware of.
Your event loop is really messed up and should be restructured. keys = pygame.key.get_pressed() shouldn't be called in the event loop, but in the outer while loop. I've got a minimal example to show you one way to do the movement and event handling (only with the event loop and without key.get_pressed).
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((700, 600))
clock = pygame.time.Clock()
player = pygame.Surface((30, 30))
player.fill((120, 240, 90))
px = 100
py = 200
x_speed = 0
y_speed = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
# If player is on the ground, jump (in more advanced
# games you need collision detection instead >= 480).
if event.key == pygame.K_UP and py >= 480:
y_speed = -20
elif event.key == pygame.K_RIGHT:
x_speed = 10
elif event.key == pygame.K_LEFT:
x_speed = -10
elif event.type == pygame.KEYUP:
# If player is moving right, stop him.
if event.key == pygame.K_RIGHT and x_speed > 0:
x_speed = 0
# If player is moving left, stop him.
elif event.key == pygame.K_LEFT and x_speed < 0:
x_speed = 0
# Don't jump too high.
if py <= 200:
y_speed = 20
# Don't go below y = 480.
if py >= 480:
py = 480
# Move the player.
px += x_speed
py += y_speed
# The Wall.
if px <= 0:
px = 0
if px >= 630:
px = 630
screen.fill((50, 50, 50))
screen.blit(player, (px, py))
pygame.display.flip()
clock.tick(30)
I'm trying to create a little game as a training, but I'm blocked because I don't know how I can collide 2 moving cubes.
The game is simple, there is a red box that you can move and if this box touches a green cube, then you lost. (the green cubes are always moving)
I tried to read some documentations but it's not really easy to understand as a beginner.
Here is the code:
import pygame
import random
from threading import Timer
pygame.init()
screenWidth = 1100
screenHeight = 600
white = (255,255,255)
red = (255, 0, 0)
yellow = (50, 250, 20)
FPS = 60
gameDisplay = pygame.display.set_mode((screenWidth, screenHeight))
pygame.display.set_caption('Tekken')
pygame.display.update()
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 28)
class Players:
def __init__(self, playerName, playerAttribute, cubeheight, cubewidth, missilesHeight, missilesWidth):
self.playerName = playerName
self.playerAttribute = playerAttribute
self.playerLife = 100
self.droite_x = 300
self.droite_y = 600
self.cubeheight = cubeheight
self.cubewidth = cubewidth
self.missiles = True
self.missilesHeight = missilesHeight
self.missilesWidth = missilesWidth
self.missiles_droite_x = 0
self.missiles_droite_y = round(random.randrange(50, screenHeight-50))
self.missiles_droite_x_inverse = screenWidth-50
self.missiles_droite_y_inverse = round(random.randrange(50, screenHeight-50))
self.vitesse_missiles = 10
print(self.playerName, self.playerAttribute, self.playerLife)
def environment_un(self):
gameExit = False
gameOver = False
droite_x_change = 0
droite_y_change = 0
missiles_droite_x_change = 0
missiles_droite_x_change_inverse = 0
while not gameExit:
while gameOver:
gameDisplay.fill(red)
screen_text = font.render("Game Over, do you want to play again? [Q] to quit", True, white)
gameDisplay.blit(screen_text, [100, 300])
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameOver = False
gameExit = True
break
if event.type == pygame.QUIT:
gameOver = False
gameExit = True
break
for event in pygame.event.get(): #va chercher les events
if event.type == pygame.QUIT: #Si j'appuie sur X
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
droite_x_change = -3
if event.key == pygame.K_RIGHT:
droite_x_change = +3
if event.key == pygame.K_UP:
droite_y_change = -3
if event.key == pygame.K_DOWN:
droite_y_change = +3
if event.key == pygame.K_SPACE:
missiles_droite_x_change = self.vitesse_missiles
missiles_droite_x_change_inverse = -self.vitesse_missiles
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
droite_x_change = 0
if event.key == pygame.K_RIGHT:
droite_x_change = 0
if event.key == pygame.K_UP:
droite_y_change = 0
if event.key == pygame.K_DOWN:
droite_y_change = 0
self.missiles_droite_x_inverse += missiles_droite_x_change_inverse
self.missiles_droite_x += missiles_droite_x_change
self.droite_x += droite_x_change
self.droite_y += droite_y_change
if self.droite_y + self.cubeheight <= 0:
self.droite_y = 0
elif self.droite_y + self.cubeheight >= screenHeight:
self.droite_y = screenHeight-self.cubeheight
elif self.droite_x + self.cubewidth <= 0:
self.droite_x = 0
elif self.droite_x + self.cubewidth >= screenWidth:
self.droite_x = screenWidth-self.cubewidth
gameDisplay.fill(white)
gameDisplay.fill(red, rect=[self.droite_x, self.droite_y, self.cubewidth, self.cubeheight])
gameDisplay.fill(yellow, rect=[self.missiles_droite_x, self.missiles_droite_y, self.missilesWidth, self.missilesHeight])
gameDisplay.fill(yellow, rect=[self.missiles_droite_x_inverse, self.missiles_droite_y_inverse, self.missilesWidth, self.missilesHeight])
pygame.display.update()
if self.missiles_droite_x + self.missilesWidth >= screenWidth:
missiles_droite_x_change = 0
if missiles_droite_x_change == 0:
self.missiles_droite_x = 0
self.missiles_droite_y = round(random.randrange(50, screenHeight-50))
missiles_droite_x_change = self.vitesse_missiles
if self.missiles_droite_x_inverse <= 0:
missiles_droite_x_change_inverse = 0
if missiles_droite_x_change >= 0:
self.missiles_droite_x_inverse = screenWidth-50
self.missiles_droite_y_inverse = round(random.randrange(50, screenHeight-50))
missiles_droite_x_change_inverse = -12
clock.tick(FPS)
pygame.quit()
Player_1 = Players('John', 'sometext', 50, 50, 100, 100)
Player_1.environment_un()
What should do I in order to detect the collision?
I can not run your code at the moment as I dont have pygame installed. However, you can use the pygame.sprite.collide_rect() if you declare your objects to have in their class an pygame.sprite.Sprite-object or inherit from that class (as suggested below). The code below may note work as I can not test it but it should be close to a functioning code snippet. In the case you would like to test collision of a sprite against multiple other sprites - consider looking at pygame.sprite.Group(). I believe that something like this should work:
class SpriteObject(pygame.sprite.Sprite):
def __init__(self,pos_x, pos_y):
pygame.sprite.Sprite.__init__(self)
self.rect = self.original.get_rect()
self.rect.center = (pos_x, pos_y)
class Players:
def __init__(self, playerName, playerAttribute, cubeheight, cubewidth, missilesHeight, missilesWidth):
sprite1 = SpriteObject(1,2)
sprite2 = SpriteObject(1,2)
sprite1.rect.collide_rect(sprite2)
If you are looking for a conceptual answer:
Since you are considering just cubes and if they are of the same size, two cubes will occupy the same space 'if and only if' a corner of one cube is between (inclusive) two parallel planes of another. There are many ways to do this in practice.
I would check if between by evaluating an inward normal vector of cube 1 dotted with a vector to a corner (of cube 2) from any corner (of cube 1) . Do so for both parallel sides. If both are positive, its inside.
It's slightly more complicated for different shapes and varying sizes.
Use pygame.Rect() to keep cube position and size - and then you can use pygame.Rect.colliderect() to check collision between two cubes.
cube1 = pygame.Rect((x1, y1), (width, height))
cube2 = pygame.Rect((x2, y2), (width, height))
if cube1.colliderect(cube2):
print("Collision !")
PyGame has other usefull classes - pygame.sprite.Sprite and pygame.sprite.Group - which use Rect and collision detection functions.
I would like to know how to create a border in Pygame to stop the user controlled object from exiting the screen. Right now, I only have it so python prints some text when the user controlled object has come near one of the 4 sides.
Here is my code so far.
import pygame
from pygame.locals import *
pygame.init()
#Display Stuff
screenx = 1000
screeny = 900
screen = pygame.display.set_mode((screenx,screeny))
pygame.display.set_caption('Block Runner')
clock = pygame.time.Clock()
image = pygame.image.load('square.png')
#Color Stuff
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
white = (255,255,255)
black = (0,0,0)
#Variables
x_blocky = 50
y_blocky = 750
blocky_y_move = 0
blocky_x_move = 0
#Animations
def Blocky(x_blocky, y_blocky, image):
screen.blit(image,(x_blocky,y_blocky))
#Game Loop
game_over = False
while not game_over:
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:
blocky_y_move = -3
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
blocky_y_move = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
blocky_y_move = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
blocky_y_move = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
blocky_x_move = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
blocky_x_move = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
blocky_x_move = -3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
blocky_x_move = 0
if x_blocky > 870 or x_blocky < 0:
print(' X Border')
if y_blocky > 750 or y_blocky < 2:
print(' Y Border')
y_blocky += blocky_y_move
x_blocky += blocky_x_move
screen.fill(white)
Blocky(x_blocky, y_blocky, image)
pygame.display.update()
clock.tick(60)
Don't use integers to store your position. Use a Rect.
So instead of
x_blocky = 50
y_blocky = 750
use
blocky_pos = pygame.rect.Rect(50, 750)
Now you can simply use
blocky_pos.move_ip(blocky_x_move, blocky_y_move)
to move your object.
After moving, you can simply call clamp/clamp_ip to ensure the blocky_pos Rect is always inside the screen.
blocky_pos.clamp_ip(screen.get_rect())
Also, you don't need to define basic colors yourself, you could simply use pygame.color.Color('Red') for example.
I also suggest you use pygame.key.get_pressed() to get all pressed keys to see how to move your object instead of creating 1000 lines of event handling code.
Well, simply don't increase your move variable any further, if you detect that the user object is near or at the border. Or reverse the move direction, depending on your general intent.
if x_blocky > 870 or x_blocky < 0:
print(' X Border')
blocky_x_move = 0
if y_blocky > 750 or y_blocky < 2:
print(' Y Border')
blocky_y_move = 0
Also, you have some redundant code with your keyboard movement. Instead of writing
if event.type == KEYDOWN:
over and over again, group the KEYUP if statements and KEYDOWN if statements.
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
blocky_y_move = -3
elif event.key == pygame.K_DOWN:
blocky_y_move = +3
etc, and:
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
blocky_y_move = 0
elif event.type == pygame.K_DOWN:
blocky_y_move = 0
etc
You can set the boundaries using the min and max functions.
Here is the concept:
We have a pygame object that moves in all four directions; lets say the user holds down the LEFT arrow key, so that the object reaches the top of the screen. The y-coordinate of the top of the screen will always be 0, so we want the object to come to a stop at y-coordinate 0.
This may seem as simple as:
if char.rect.y > 0:
char.rect.y -= char.speed
But this will result in a bug ig char.speed is greater than 1. Like when the object is at y-coordinate 5,
and its speed is 10; the condition still allows for one more step for the object, resulting in the object
coming 5 pixels out of the pygame window. What we want to do is more like:
if char.rect.y > 0:
char.rect.y -= char.speed
if char.rect.y < 0:
char.rect.y = 0
to push the object back into the boundaries. The above block of code can be simplified with the max function:
self.rect.y = max([self.rect.y - self.speed, 0])
For the object moving down:
if char.rect.y < HEIGHT - char.height:
char.rect.y += char.speed
if char.rect.y > HEIGHT - char.height:
char.rect.y = HEIGHT - char.height
or, the more efficient and clean method:
self.rect.y = min([self.rect.y + self.speed, HEIGHT - self.height])
For going left and right, simply replace the ys and height (and HEIGHT) from two lines above with xs and widths (and WIDTH).
All together:
import pygame
pygame.init()
WIDTH = 600
HEIGHT = 600
wn = pygame.display.set_mode((WIDTH, HEIGHT))
class Player:
def __init__(self):
self.speed = 1
self.width = 20
self.height = 20
self.color = (255, 255, 0)
self.rect = pygame.Rect((WIDTH - self.width) / 2, (HEIGHT - self.height) / 2, 20, 20)
def up(self):
self.rect.y = max([self.rect.y - self.speed, 0])
def down(self):
self.rect.y = min([self.rect.y + self.speed, HEIGHT - self.height])
def left(self):
self.rect.x = max([self.rect.x - self.speed, 0])
def right(self):
self.rect.x = min([self.rect.x + self.speed, WIDTH - self.width])
def draw(self):
pygame.draw.rect(wn, self.color, self.rect)
char = Player()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
char.up()
if keys[pygame.K_DOWN]:
char.down()
if keys[pygame.K_LEFT]:
char.left()
if keys[pygame.K_RIGHT]:
char.right()
wn.fill((0, 0, 0))
char.draw()
pygame.display.update()
Good luck!
I need to make the player move continuously when I press a certain key.The problem that I have is that the image of the player is moving once (when I press one of the defined keys) and then it stops.
enter code here
import pygame
import sys
import os
import random
import time
from pygame.locals import *
pygame.init()
white = ( 255, 255, 255 )
black = ( 0, 0, 0 )
screenw = 800
screenh = 600
screen = pygame.display.set_mode( ( screenw, screenh ) )
pygame.display.set_caption( "Game" ) # Here I create a display.
clock = pygame.time.Clock()
class Car(pygame.sprite.Sprite): # Here I create a class.
def __init__( self, color = black, width = 100, height = 100 ):
pygame.sprite.Sprite.__init__( self )
self.image = pygame.Surface( ( width, height ) )
self.image.fill( color )
self.rect = self.image.get_rect()
def set_pos(self, x, y):
self.rect.x = x
self.rect.y = y
def set_img( self, filename = None):
if filename != None:
self.image = pygame.image.load( filename )
self.rect = self.image.get_rect()
def main():*I create a game loop
x_change = 0
y_change = 0
x = 0
y = 0
car_group = pygame.sprite.Group() # Make a group
player = Car()
player.set_img( "images.jpg" )
car_group.add( player )
exit = False
FPS = 60
while not exit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -10
elif event.key == pygame.K_RIGHT:
x_change = 10
elif event.key == pygame.K_UP:
y_change = -10
elif event.key == pygame.K_DOWN:
y_change = 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.type == pygame.K_DOWN:
x_change = 0
y_change = 0
x += x_change
y += y_change
screen.fill( white )
player.set_pos( x, y ) # Blit the player to the screen
car_group.draw( screen )
clock.tick( FPS )
pygame.display.update()
main()
pygame.quit()
quit()
Well the problem is that you are only allowing the sprite to move once. For example, take this piece of your code:
if event.key == pygame.K_LEFT:
x_change = -10
This will allow the x position to be smaller by 10. Then it stops. You maybe want to make a update function. A variable will also be made to allow the function to be used or not to be used. Another one will be used to control the direction it goes. Here is the update function. Feel free to change it to be able to fit your needs:
def update():
global direction
if direction == 'LEFT':
x -= 10
elif direction == 'RIGHT':
x += 10
elif direction == 'UP'
y -= 10
elif direction == 'DOWN':
y += 10
Now we will need the variable to control whether the function will run or not. Add these two lines for our new two variables:
run = 0
direction = 'NONE'
They should be before the code for the class. You absolutely change the lines from your event.key lines, it should be (in proper indention):
if event.key == pygame.K_LEFT:
direction = 'LEFT'
run = 1
elif event.key == pygame.K_RIGHT:
direction = 'RIGHT'
run = 1
elif event.key == pygame.K_UP:
direction = 'UP'
run = 1
elif event.key == pygame.K_DOWN:
direction = 'DOWN'
run = 1
Of course, there must be something to stop the car from repeatedly moving infinitely right? Add these lines with the lines above:
elif event.key == pygame.K_SPACE:
direction = 'NONE'
run = 0
Now put these two lines in the while loop but before you for loop:
if run == 1:
Car.update()
else:
pass
This should work because as long run is equal to 1, the car will continue its movement in the given direction until stopped by pressing the spacebar. I hope this helps you!