pygame - How to make a circle move based on a dice roll? - python

I'm trying to get a circle to move based on a dice roll of 1-5.
Eg. if it rolls a 4, it will move the circle to a total of 580 - (55 * 4) pixels.
However I can't make it so the circle will basically clear the old version of itself dynamically, any ideas?
Also, I am trying to make it so the prompt message saying what number on the dice you have rolled clear itself after the user has seen it. so like pressing a button to make the program know that you have seen the dice number and wishes to proceed, however I can't do that without clearing the entire game window and when the game window clears, it will forget the old circle coordinates which makes the counters move back to the starting position again...
What I've attempted as requested -
while True:
for event in pygame.event.get():
if event.type==pygame.KEYDOWN and event.key==pygame.K_SPACE:
diceRoll = random.randint(1,5)
diceAlert = font.render("You rolled a: "+str(diceRoll), True, red)
moveCounter = font.render("Please click 1 or 2 to select the counter", True, red)
screen.blit(diceAlert, [665, 35])
screen.blit(moveCounter, [665, 70])
pygame.display.update()
if event.type==pygame.KEYDOWN and event.key==pygame.K_1:
if diceRoll == 1:
cover = int(0)
if diceRoll == 2:
cover = int(2)
if diceRoll == 3:
cover = int(2)
if diceRoll == 4:
cover = int(3)
counter1 = pygame.draw.circle(screen, white, (250, 580-(cover*55)), 15, 0)
counter1 = pygame.draw.circle(screen, red, (250, var[0]-55*diceRoll), 15, 0)
window()
pygame.display.update()

You seem to be bliting a circle only if a button has been pressed. This forces you to use your screen, as your only information of the state of your game. Instead you should separate those 2.
Here is a template of a pygame game:
init()
while not finished:
draw()
update()
input()
These 4 functions do different things. You should not do any drawing in the input method.
Let's go through these functions:
init() initializes pygame, screen, loads files, and creates any instances that are needed. In your case here you can create a variable that will store the current circle position.
draw() clears the screen with fill(), and draws all the sprites on screen. In your case, his will the the circle position, and draw it accordingly.
update() this updates sprites on the screen, checks collisions etc. You don't have anything that will use this function, since your game is static, it does not change in time.
input() takes input, and changes the state of objects. In your case, you would test to see if a button was pressed, and if so, change the circle position.
After tidying up your code it will look like this:
circle_pos = (0,0)
circle_pos2 = (0,0)
while True:
screen.blit(diceAlert, [665, 35])
screen.blit(moveCounter, [665, 70])
counter1 = pygame.draw.circle(screen, white, circle_pos, 15, 0)
counter1 = pygame.draw.circle(screen, red, circle_pos2, 15, 0)
pygame.display.update()
for event in pygame.event.get():
if event.type==pygame.KEYDOWN and event.key==pygame.K_SPACE:
diceRoll = random.randint(1,5)
diceAlert = font.render("You rolled a: "+str(diceRoll), True, red)
moveCounter = font.render("Please click 1 or 2 to select the counter", True, red)
if event.type==pygame.KEYDOWN and event.key==pygame.K_1:
if diceRoll == 1:
cover = int(0)
if diceRoll in (2,3):
cover = int(2)
if diceRoll == 4:
cover = int(3)
circle_pos = (250, 580-(cover*55))
The code is not fully functional, since I did not know what you are trying to accomplish. I hope this template will get you going.

Related

Why does my pygame screen go non responsive while waiting for user input? [duplicate]

This question already has answers here:
How can I create a text input box with Pygame?
(5 answers)
Why is my pygame display not responding while waiting for input?
(1 answer)
Closed 1 year ago.
I am new to python programming and am trying to create a game for class. Every time I run the program, before the user gets to put input in the surface screen goes non responsive. What am I doing wrong?
#import modules needed
import pygame, sys, time, random
from pygame.locals import *
def main():
#Assigns Colors
ORANGE = (255, 127, 80) #Background
BLACK = (0, 0, 0 ) #Mountains
WHITE = (255,255,255) #Snow & Trees
BROWN = (61, 16, 16) #moose & Mountains
GREEN = (0, 153, 0) #Trees
L_BROWN=(181, 101, 29) #Tree Trunks
YELLOW =(255, 255, 204) #Sky
BLUE = (67, 111, 181) #Lake
LIME = (57, 255, 20)
#initiate modules
pygame.init()
done=False
#assign screen values and display captions
screen = pygame.display.set_mode((1000,600))
pygame.display.set_caption("Welcome To Michelle Era's Final Project - Moose Scene")
#start clock
clock=pygame.time.Clock()
fps = (60)
#Assign Variables
drink = " "
name = " "
welcome = " "
water= " "
quit = " "
i = 0
Moose_img = pygame.image.load('moose.png')
Beer_img = pygame.image.load('beer.png')
mikey_img=pygame.image.load('Mikey.jpg')
Water_img = pygame.image.load('water.png')
font = pygame.font.SysFont('Calibri',25,False,False)
text=font.render("My text", True, YELLOW)
player_num = 0
moose_num = random.randrange(1,26)
while not done:
pygame.event.pump()
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(ORANGE) #fills background orange
#Draw Scene
def draw_mountains(screen, x,y):
pygame.draw.rect(screen, BLACK,(1,200,1000,100)) # Base of mountain
x_offset=0
while x_offset<1000:
pygame.draw.polygon(screen, WHITE, [[100+x_offset,100], [0+x_offset ,225], [200+x_offset, 225]], 0) # snow caps on mountain
pygame.draw.polygon(screen, BROWN, [[100+x_offset,120], [0+x_offset ,225], [200+x_offset, 230]], 0)
x_offset=x_offset+120#tells how many pixels to move over until you reached 1000
def draw_trees(screen, x,y):
x_offset=0
while x_offset<1000:
pygame.draw.ellipse(screen, GREEN, [27+x_offset,158,40,50], 0) #draws leaves starting at x27 to x 1000 every 50 pixels
x_offset=x_offset +50 #tells how many pixels to move over until you reached 1000
pygame.draw.line(screen,L_BROWN,[x_offset,200],[x_offset +10,250],8) #draws trunk starting at x0 to x 1000 every 50 pixels
pygame.draw.line(screen,WHITE,[x_offset,207],[x_offset +10,250],1) #draws snow starting at x0 to x 1000 every 50 pixels
x_offset=x_offset +50
def draw_lake(screen, x,y):
pygame.draw.rect(screen,BLUE, [0,300,1000,200],0)# draws the lake
pygame.draw.rect(screen,L_BROWN,[0,500,1000,100],0) #draws grass
def gameover():
screen.fill(BLACK) #fills play surface
pygame.display.flip() #updates the display
gameOverFont=pygame.font.Font('freesansbold.ttf',17)
gameOversurf = gameOverFont.render("A Big thank you to my brother Michael Era who originally painted the mural that was the inspiration for this project",True, YELLOW)
gameOverRect = gameOversurf.get_rect()
gameOverRect.midtop = (500,40)
screen.blit(gameOversurf, gameOverRect)
screen.blit(mikey_img, (200,100))
pygame.display.flip()
time.sleep(30)
draw_mountains(screen, 0,0)
draw_trees(screen,0,0)
draw_lake(screen,300,400)
screen.blit(Moose_img, (600,400))
welcome = font.render("WELCOME TO MOOSEVILLE", True, YELLOW)
screen.blit(welcome, [300,50])
pygame.display.update()
#
#GET user input
name=(input('What is your Moose named ? '))
name=font.render("I like The Name " + str(name), True, YELLOW)
draw_mountains(screen, 0,0)
draw_trees(screen,0,0)
draw_lake(screen,300,400)
screen.blit(Moose_img, (600,400))
screen.blit(name, (550, 355))
pygame.display.update()
num_game=font.render("I am thinking of a number between 1 and 25, can you guess it? ", True, LIME)
screen.blit(num_game,(25,325))
player_num=(input(" What is your guess 1 to 10: "))
player_num = font.render('You Choose The Number: ' +str(player_num), True, LIME)
screen.blit(player_num,(25,350))
pygame.display.update()
moose_num = random.randrange(1,11)
moose_num=font.render('My number choice was : ' + str(moose_num), True, LIME)
screen.blit(moose_num,(25,376))
pygame.display.update()
if player_num == moose_num:
won=font.render('You Won!!!', True, YELLOW)
screen.blit(won,(25,400))
pygame.display.update()
else:
lose=font.render('You Lose!' , True, YELLOW)
screen.blit(lose,(25,400))
pygame.display.update()
quit = input('Do you want to try again? y or n ')
if quit == "n":
gameover()
else:
done=False
pygame.quit()
main()
Firstly, you don't need both event.pump() and event.get(), just use event.get in the loop as now. Also, you don't usually define functions inside a while loop. They would be outside the loop and called from inside it. You are also calling both event.pump and event.get and getting input via "input."
You also call pygame.quit() inside the while loop. Break this up into a bunch of functions.
main() - this calls all the others
get_input()
draw_screen()
etc
Also the numbers game says:
num_game=font.render("I am thinking of a number between 1 and 25, can you guess it? "
and then asks for:
player_num=(input(" What is your guess 1 to 10: "))
You cannot use input in the application loop. input waits for an input. While the system is waiting for input, the application loop will halt and the game will not respond. Use the KEYDOWN event instead of input:
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
# [...]
Either implement a textbox (see How to create a text input box with pygame?)
or get the input in a separate thread (see Why is my display not responding while waiting for input?).

Can somebady help me why errors exist in my pygame code about `ball moving`?

I will show my code below. I think when I def moveDot, something wrong I can feel it. However, I just code as my instructor's presentation. She's code can work and mine cannot. I don't know the reason. I think the order of moveDot's variances may have some problems. Is that right? I will appreciate anyone who can help me! Thanks a lot!
# Poke The Dots
# There are two dots that are moving on a 500 by 400 window
# There is a score board that displays the time in seconds
# since the game started
# If the player clicks inside the window, the dots disappear
# and reappear at some random location
# If the dots collide, the dots stop moving, the score stops
# changing and Game Over is displayed.
# Version 1
import pygame, sys, time
from pygame.locals import *
# User-defined classes
# User-defined functions
def main():
# Initialize pygame
pygame.init()
# Set window size and title, and frame delay
surfaceSize = (500, 400) # window size
windowTitle = 'Poke The Dots' #window title
frameDelay = 0.02 # smaller is faster game
# Create the window
surface = pygame.display.set_mode(surfaceSize, 0, 0)
pygame.display.set_caption(windowTitle)
# create and initialize red dot and blue dot
gameOver = False
color1=pygame.Color('red')
center1 = [50, 75]
radius1=30
speed1=[1,2]
color2=pygame.Color('blue')
center2=[200,100]
radius2=40
speed2=[2,1]
# Draw objects
pygame.draw.circle(surface, color1, center1, radius1, 0)
pygame.draw.circle(surface, color2,center2,radius2,0)
gameOver = update(surface, color1, center1, radius1, speed1, color2, center2, radius2, speed2)
# Refresh the display
pygame.display.update()
# Loop forever
while True:
# Handle events
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# Handle additional events
# Update and draw objects for the next frame
#gameOver = update(center, surface)
# Refresh the display
pygame.display.update()
# Set the frame speed by pausing between frames
time.sleep(frameDelay)
def update(surface, color1, center1, radius1, speed1, color2, center2, radius2, speed2):
#Check if the game is over. If so, end the game and
#returnTrue. Otherwise, update the game objects, draw
#them, and return False.
#This is an example update function - replace it.
#- center is a list containing the x and y int coords
#of the center of a circle
#- surface is the pygame.Surface object for the window
erasecolor=pygame.Color('black')
if False: # check if the game is over
return True
else: # continue the game
surface.fill(erasecolor)
moveDot(surface, color1, center1, radius1)
moveDot(surface, color2, center2, radius2)
pygame.draw.circle(surface,color1,center1,radius1,0,0)
pygame.draw.circle(surface,color2,center2,radius2,0,0)
return False
def moveDot(surface,center,radius,speed):
size=surface.get_size()
for coord in range(0,2):
center[coord]=center[coord]+speed[coord]
if center [coord]<radius:
speed[coord]=-speed[coord]
if center[coord]+radius>size(coord):
speed[coord]=-speed[coord]
main()
The order of your arguments being passed when you call moveDot is incorrect. It should be
moveDot(surface, center1, radius1, speed)
For both statements. Speed should be the speed of movement of the circle.

Redrawing image isn't working?

So, i have a pygame.circle that i would like to move. I have it moving etc, but it just duplicated the image and doesn't remove the previous. I understand the concept of "Blit" and understand it copies an array of pixels over. So i thought i would try redrawing my whole game, here's what i have:
if event.type == pygame.KEYDOWN and event.key == pygame.K_a:
diceRoll = random.randint(1, 4)
diceRollLabel = myFont.render(str(diceRoll), 1, black)
window.blit(diceRollLabel, (750, 40))
window.fill(black)
game()
count1 = pygame.draw.circle(window, (black),(150, countY - 72 * diceRoll), 25, 0)
game = False
game2 = True
print("Test")
player1Text = myFont.render(("Player twos turn!"), 1, black)
window.blit(player1Text, (650, 750))
pygame.display.update()
break
When it calls "game()" it should recall the function that contains all of the game screen, so the texture etc. but for some reason, it doesn't do anything? The screen just goes black?
it says "Bool object not callable" but my function isn't a boolean?
Fill the screen at the start of the loop.
def draw():
screen.fill(Color('black'))
# draw
pygame.display.flip()
You've set game as a Boolean
game = False
So when you call "game()" it's the same as "False()" which is the reason for your error.
You also fill the screen black after blitting the diceRollLabel (in black), and you then seem to draw a black circle on a black screen.
Full code would be helpful.

Pygame: Drawing Lines

In my previous question For Loop Functions in Python,
I had trouble with putting functions that contained a command to draw a line for a hangman game. It didn't exactly draw the line, and I first suspected it was a problem with the for loop or the functions. Now I realize there is somewhat a glitch with Pygame.
I have tried solving the problem by using this code in the country, CANADA:
b2 = font.render(str(letters[1]), True, (red))
screen.blit(b2, (bPosition))
if hangman1x == -500 and hangman1y == -500:
hangman1x = (775, 250)
hangman1y = (775, 50)
pygame.draw.line(screen, black, (hangman1x), (hangman1y), (5))
pygame.display.flip()
time.sleep(0.5)
bPosition = -500, -500
b1.x, b1.y = -500, -500
if hangman1x == (775, 250) and hangman1y == (775, 50):
print 'hi'
width = 6
pygame.draw.line(screen, black, (hangman1x), (hangman1y), (5))
print 'yay'
pygame.display.flip()
Now here's the weird thing.
When you press the B blitted onto the screen, it turns red, like its meant to, draws the line perfectly fine, but disappears, when the B disappears, and I understand why. After that, I added that extra if code. (Notice that both pygame.draw.line(s) are the same), It prints hi and yay in the shell, but it does not keep the line. Anyway to solve this?
After you are calling pygame.draw.line() you are probably redrawing your screen completely white, this will draw over the line and hide it. Instead of drawing lines like you are, I would build a hangman class draw from that
class Hangman():
def __init__(self):
self.lines = 0 #Number of lines to be drawn
def draw(self,screen):
#TODO draw to screen based on self.lines
#More code setting up pygame
drawlist = []
myMan = Hangman()
drawlist.append(myMan)
#mainloop
while 1:
screen.fill('#000000')
for item in drawlist:
item.draw(screen)
This way you are redrawing you hangman every frame, and thus he is always being showed
EDIT Added a running example
#!/usr/bin/python
import pygame
pygame.init()
class Hangman():
def __init__(self):
self.lines = 0 #Number of lines to be drawn
def hang(self):
self.lines += 1
def draw(self,screen):
for x in range(self.lines):
coord1 = (x*10,20)
coord2 = (x*10,50)
pygame.draw.line(screen,(0,0,0),coord1,coord2)
size = screenWidth,screenHeight = 200,70
screen = pygame.display.set_mode(size)
pygame.display.flip()
myman = Hangman()
drawlist = []
drawlist.append(myman)
#mainloop
running = True
while running:
#EVENT HANDLING#
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == 32: #Spacebar
myman.hang()
#DRAWING#
screen.fill((255,255,255))
for item in drawlist:
item.draw(screen)
pygame.display.flip()

Different colors for shapes through iterations in Python / Pygame?

I'm new to stackoverflow, but was hoping for a little insight from more advanced programmers. I am switching majors to Computer Science next semester and am taking an intro class learning some beginner's Python programming. I have already finished the program below (the assignment was to make a program that draws ovals on the window surface by filling in some of the professor's code, not too bad at all) but I wanted to add a little something extra: As you can see, I have the color of the ovals set to be random, but it stays the same until the program is restarted entirely i.e. all of the ovals are that particular color for the length of the program. With the code written the way it is, I can't figure out a way to get the color to change for each oval. Keep in mind, this is all for kicks, but if anyone's feeling especially helpful or creative, I'm curious to see what you have to say. Let me know if I can expound on anything. Thanks!
import pygame, random, sys
WINDOWWIDTH = 700
WINDOWHEIGHT = 700
BACKGROUNDCOLOR = (150,160,100)
#A different color every run
OVAL_COLOR = (random.randint (0,255),random.randint (0,255),
random.randint (0,255))
pygame.init()
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption("Mobile Ovals")
#The draw variable is used later to indicate the mouse is still pressed
ovals = []
completedOvals = []
finished = False
draw = False
startXY = (-1, -1)
while not finished:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYUP and
event.key == pygame.K_ESCAPE):
finished = True
elif event.type == pygame.KEYDOWN:
pressed = pygame.key.get_pressed()
if pressed[pygame.K_F4] and (pressed[pygame.K_LALT] or
pressed[pygame.K_RALT]):
finished = True
elif event.type == pygame.MOUSEBUTTONDOWN:
startXY = event.pos
draw = True
elif event.type == pygame.MOUSEBUTTONUP:
draw = False
for oval in ovals:
completedOvals.append (oval)
if draw == True:
del ovals [:]
#The above function ensures only one oval is onscreen at any given time
endXY = event.pos
width = (abs(endXY[0]-startXY[0]))
height = (abs(endXY[1]-startXY[1]))
#The code below allows the user to drag any direction
if endXY[0] < startXY[0]:
left = endXY[0]
else:
left = startXY[0]
if endXY[1] < startXY[1]:
top = endXY[1]
else:
top = startXY[1]
ovals.append (pygame.Rect (left, top, width, height))
windowSurface.fill(BACKGROUNDCOLOR)
for oval in ovals:
pygame.draw.ellipse(windowSurface, OVAL_COLOR, oval)
for completedOval in completedOvals:
pygame.draw.ellipse(windowSurface, OVAL_COLOR, completedOval)
pygame.display.update()
pygame.quit()
Your problem is quite simple. You set OVAL_COLOR once. But every time you make reference to the variable OVAL_COLOR, you're not creating a new random color, you're re-using the RGB color that was randomly generated when you created the variable.
Now, the way your program is structured, you maintain a list of all complete ovals that you're re-drawing every time the draw variable is set to true. If you place the OVAL_COLOR variable inside the for loop, you will update the color with every mouse movement, changing the color of the oval being drawn, as well as the color of all the old ovals being re-drawn.
The solution to have a new random oval color is to set the variable OVAL_COLOR when the mouse button goes down. That way, the oval color won't change as you drag the mouse to adjust the oval. But, given the current structure of the program, you'll need to save the oval colors assigned to completed ovals, or you'll still have the oval color change each time.
When the mouse button is pressed down, we want a new random color for our circle. Generate a random value, which will be used every time the circle is re-drawn.
elif event.type == pygame.MOUSEBUTTONDOWN:
startXY = event.pos
OVAL_COLOR = (random.randint (0,255),random.randint (0,255),
random.randint (0,255))
draw = True
When the mouse button is released, save the coordinates for the oval, along with the color that it was drawn with.
elif event.type == pygame.MOUSEBUTTONUP:
draw = False
# print len(ovals) # (always ==1)
completedOvals.append ((ovals[-1], OVAL_COLOR))
When we iterate through these completed ovals, draw them with the same color each time.
for (completedOval, color) in completedOvals:
pygame.draw.ellipse(windowSurface, color, completedOval)
Create a simple Oval() class, that contains it's color, and size.
import pygame
from pygame.locals import *
class Oval(object):
"""handle, and draw basic ovals. stores Rect() and Color()"""
def __init__(self, startXY, endXY):
self.color = Color(random.randint(0,255), random.randint(0,255), random.randint(0,255))
self.rect = Rect(0,0,1,1)
self.coord_to_oval(startXY, endXY)
def draw(self):
pygame.draw.ellipse(windowSurface, self.color, self.rect)
def coord_to_oval(self, startXY, endXY):
width = (abs(endXY[0]-startXY[0]))
height = (abs(endXY[1]-startXY[1]))
#The code below allows the user to drag any direction
if endXY[0] < startXY[0]:
left = endXY[0]
else:
left = startXY[0]
if endXY[1] < startXY[1]:
top = endXY[1]
else:
top = startXY[1]
self.rect = Rect(left, top, width, height)
# main loop
while not finished:
for event in pygame.event.get():
# events, and creation:
# ... your other events here ...
elif event.type == MOUSEBUTTONDOWN:
startXY = event.pos
draw = True
elif event.type ==MOUSEBUTTONUP:
# on mouseup, create instance.
endXY = event.pos
oval_new = Oval(startXY, endXY)
completedOvals.append(oval_new)
# draw them:
for oval in ovals:
oval.draw()
for oval in completedOvals:
oval.draw()
I mostly left out your non-completed ovals. Was that to show the size before clicking?

Categories

Resources