This question already has answers here:
What would be the output of range(x, y) if x > y?
(3 answers)
Closed last year.
I'm trying to load images in PyGame based on a value, like when the value is 6 it sets the image to be image number 6.
def bar():
global ink
global screen
global barImg
ink = 0
for ink in range(0,100):
barImg = pygame.image.load(f'inkbar\load{ink}.png')
screen.blit(barImg,(100,100))
pygame.display.update()
The value of ink gets changed in another function and I know that part works. Each image is called load0.png, load1.png and so on until 100, but the image never appears on the screen. I have tested putting the image on the screen by commenting out the for loop and just setting barImg to a specific image and it did put the image on the screen.
px, py = pygame.mouse.get_pos()
if pygame.mouse.get_pressed() == (1,0,0):
pygame.draw.rect(screen, (255,255,255), (px,py,10,10))
ink+=0.5
math.ceil(ink)
print(ink)
this is part of a function that allows the user to draw. This part detects mouse click and increases the value of ink. I tried calling bar() underneath the ink increase, but that decreased the rate of drawing.
I have removed the function bar()
ink+=1
math.ceil(ink)
print(ink)
for ink in range(1,100):
barImg = pygame.image.load(f'inkbar\load{ink}.png')
screen.blit(barImg,(100,100))
This is what I have used as a replacement, but now ink does not increase by one, it goes from 1 to 100 immediately, and causes large amounts of lag.
Maybe the images having "load" in the name is messing with something?
I have some code for running through frames of an animation which I know works
The code:
frame_index += animation_speed
if frame_index >= len(animation):
self.frame_index = 0
image = pygame.image.load(f'Ink ({int(frame_index)}).png')
screen.blit(image, (0,0))
pygame.display.update()
Essentially you want to have two variables, a frame index and an animation speed. The index is the number of the first image you are loading. In this case Ink 0.png or whatever it's called. So your frame index will be 0. This will increment by your animation speed variable. The higher this is, the faster your animation will be. The lower, the slower. After it loops it will go back to 0 if thats what you want. If you don't want that then you can simply remove the if statement.
Also check that you aren't filling the screen AFTER doing this as whatever you're wanting to see will just be covered instantly. Let me know if this works.
Related
I'm working on a project where I want to move this text box that I made from the left to the right. I have multiple of these text boxes, and I wanted to do that right after one another.
text1_rect = text1.get_rect(center = (window_width/2, window_height*.25)) : This is the current location of the text, but I was looking at the rect.move method to do this.
window.blit(text1, text1_rect) : This is how I blit the text onto the screen when the program first starts up.
I don't require a direct answer, but maybe just some tips or a nudge in the right direction on how to add a little movement to my text box.
Create text1_rect before the application loop and change the position of the rectangle in the application loop
If you want to move the text form from the left to the center of the window, you need to set the start position outside the window and move the text until it is in the center.
Use pygame.time.Clock to control the frames per second and thus the game speed.
The method tick() of a pygame.time.Clock object, delays the game in that way, that every iteration of the loop consumes the same period of time. See pygame.time.Clock.tick():
This method should be called once per frame.
That means that the loop:
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
runs 60 times per second.
clock = pygame.time.Clock()
# initial position is outside the window
text1_rect = text1.get_rect(midright = (0, window_height*.25))
# [...]
while run:
clock.tick(60)
# [...]
window.blit(text1, text1_rect)
# move the text to the center
if text1_rect.centerx < window_width // 2:
text1_rect.x += 1
# [...]
I need to make a code in python that draws the output below using recursion and a function named drawpoly. drawpoly() will take 6 arguments which include a turtle, the length of a side, the number of sides, red, green & blue. While the number of sides is > 2, drawpoly() will recursively call itself decrementing the number of sides by 1 each call. Red will increment by 10, green by 25 & blue by 35 each call. I need to set fillcolor and begin and end fill. I will also need will need to set the screen colormode to be able to use integers to make your colors.
[![enter image description here][1]][1]
her's the code I have so far It doesn't print out anything but its a rough outline of what I need to use in the program
wn = trtl.Screen()
def drawpoly(trtl, num_sides, side_length,color):
numOfSides=8
num_sides=8
side_length=100
color="blue"
while (numOfSides >2):
trtl.drawpoly(trtl,num_sides,side_length,color)
numOfSides -=1
def main():
return drawpoly
main()
[1]: https://i.stack.imgur.com/65dS4.png
So, for the game I am working on I have found an error which I haven't been able to find an answer anywhere.
Here is a snippet of my code from my UI
if not self.game.rot_lim == 0:
pg.draw.rect(self.ui, (255,255,255), (730,16,32,32))
rotators = str(self.game.rot_rem)
self.draw_text("Prisms Remaining: " + rotators, 770)
rot_lim is an Integer which stores the value of how many total rotators the user can place for that level. Similarly, rot_rem is the amount remaining that can be placed.
My draw text function goes as follows:
def draw_text(self, text, x, y = 20):
# Renders text
draw = self.game.text.render(text, False, (0,0,0), (170, 170, 170))
# Draws on UI
self.ui.blit(draw, (x,y))
Now my issue comes with displaying this with 10 or more in total. When I go below 10, it displays with an extra 0 at the end (e.g. If I place 1 it goes to 90). For every one I place after it ignores the last 0, and it does not exist within the code (tested with print statements) so it only exists in the rendering side of it.
Thanks a lot!
Alright, I managed to recreate the issue and it has to do with re-drawing the screen (not with the code you posted). Since we can only see a portion of your code, I can't be exactly sure if my recreation matches your issue.
Make sure you are doing one of two things:
1) clearing the who screen by refilling the background color screen.fill((255, 255, 200))
2) clearing the portion where the text is by refilling it (maybe it is within a rectangle that needs to be redrawn)
This should happen in each pass of the game while loop. Basically, make sure you are refreshing the screen each time, because currently it is just drawing over
I want to keep the enemies (red rectangles in my case) inside the rectangle.What happens is that since it's a random function , the enemies keep on moving.But slowly some of my enemies moves outside , I don't want this to happen.I want them to be inside the screen only.
I have tried subtracting the screen width and screen height but was unsuccessful in my attempt to do so.So basically what I am asking is how do I check if rectangle is inside the screen.
EDIT :
This is not a possible duplicate as my enemies are moving randomly.In that the player is controlled by the user whereas my program , the movements of the enemy are totally random.
Here is my random movement for my enemies:
def evilMove(evilGuy):
evilCoords = []
#Returns either -1, 0 or 1
randomMovex=random.randrange(-1,2)
randomMovey=random.randrange(-1,2)
evilMake={'x':evilGuy[0]['x']+randomMovex,'y':evilGuy[0]['y']+randomMovey}
del evilGuy[-1] #Delete the previous spawn of enemy so there is no trail
evilCoords.append(evilMake['x']) #Adds x coordinate
evilCoords.append(evilMake['y']) #Adds y coordinate
deadZones.append(evilCoords) #Adds the enemy coordinates in the list
evilGuy.insert(0,evilMake)
Thanks in advance.
Well, you should really look at other questions similar to this, but you could make an if statement where you test if it is outside the screen.
Lets just say your screen is 500 by 500, you would do,
if coordinatesx < 500:
do this and that
if coordinatesy < 500:
do this and that.
This checks if the coordinates of your bad guy are being checked by the screen by saying if the bad guys coordinates are not larger than the screen, then do what you need to do.
EDIT _________________________________________
def evilMove(evilGuy):
evilCoords = []
#Returns either -1, 0 or 1
if x < 500 and y < 500:
randomMovex=random.randrange(-1,2)
randomMovey=random.randrange(-1,2)
evilMake={'x':evilGuy[0]['x']+randomMovex,'y':evilGuy[0]['y']+randomMovey}
Im not sure what your x and y variable is called, just replace it with that. And replace the 500 with your sreen width.
To create an abstract, scrolling city skyline for a prototype, I created a class that generates random rectangles. These rects are added to a list and items are pulled from that list to be drawn on the screen. The rects begin off screen to the right and scroll across to the left until they leave the view plane and are trashed. The movement of the buildings is oddly jerky and they also shift to the right a few pixels at a specific point on the screen.
This video of the prototype is fairly accurate with very little video capture lag. Pay attention to the gaps between the buildings, as they get within the right most 3rd of the display area, the gap will suddenly shrink as if the building to the left of the gap is suddenly shifting right a few pixels. The smaller the gap, the more noticeable it is. The other anomalies in the video are from the recorder and are not present in the app. Here's a very short video that clearly shows this phenomenon: https://www.youtube.com/watch?v=0cdhrezjcY8
At about 1 second in you'll notice a very narrow gap between buildings in the rear layer. At :04 seconds in the gap is even with the blue player object, the left rectangle shifts and the gap vanishes. There's a second, larger gap to the right of that one that does the same thing but since the gap is larger it doesn't completely vanish. I've looked over the code numerous times but can't see what could be causing this anomaly. I'm hoping someone can tell me if it's something I did or a limitation I'm encountering.
I originally wrote this program linearly, without classes or functions. I rewrote it using a class that generates layer objects and handles all the generating and scrolling. In both cases the problem exists. It's driving me crazy trying to figure out why the buildings do not move smoothly. I've even written a version of this using png images instead of randomly generated rectangles. In that version the pngs scroll smoothly and seamlessly: https://www.youtube.com/watch?v=Uiw_giAvbOo (The video is a bit jerky, but the actual program plays smooth) So the issue is limited to these random rectangles.
Here's the code for the program: https://www.refheap.com/73079
Here's the class code by itself:
class Scroller():
def __init__(self, speed, color, heightMax):
# Speed of the layer scroll, the color of the layer and the maximum height for buildings
# set up the building parameters
self.buildingHeightMax = heightMax
self.buildingHeightMin = 100
self.buildingWidthMax = 125
self.buildingWidthMin = 75
self.buildings = []
self.layerspeed = speed
self.buildTime = True
self.buildCountdown = 10
self.color = color
def update(self):
# Check if it's time to build. If not, decrement counter
if self.buildTime == False:
self.buildCountdown -= 1
# If time is 0, time to build, reset counter to a new random time
if self.buildCountdown <= 0:
self.buildTime = True
self.buildCountdown = random.randint(3, self.layerspeed)
# create building if it's time
if self.buildTime:
# generate random width and height of building
buildingHeight = random.randint(self.buildingHeightMin, self.buildingHeightMax)
buildingWidth = random.randint(self.buildingWidthMin, self.buildingWidthMax)
buildingTop = WINDOWHEIGHT - buildingHeight
# This generates the building object from the above parameters
building = pygame.Rect(WINDOWWIDTH, buildingTop, buildingWidth, WINDOWHEIGHT)
self.buildTime = False
self.buildCountdown = random.randint(3, self.layerspeed * 5)
# add building to buildings list
self.buildings.append(building)
# move all buildings on layer at set speed
for building in self.buildings:
# if the building is off the screen, trash it. If not, move it to the
# right at the objects speed.
if building.right < 0:
self.buildings.remove(building)
else:
building.left -= self.layerspeed
# draw the Front buildings
for i in range(len(self.buildings)):
pygame.draw.rect(windowSurface, self.color, self.buildings[i])
Your problem most likely lies in:
# move all buildings on layer at set speed
for building in self.buildings:
# if the building is off the screen, trash it. If not, move it to the
# right at the objects speed.
if building.right < 0:
self.buildings.remove(building)
else:
building.left -= self.layerspeed
You're using remove on the same list you're iterating from, and this will make it skip the next building. So it's not the building to the right that's moving faster, it's the one to the left that has skipped moving.
You can see it yourself with this simple example:
a = [2, 3, 4, 1.5, 6, 8, 3.2]
for element in a:
if element == 4:
a.remove(element)
else:
print element
Try it and you'll see that not only 4 won't be printed, but also 1.5 will be skipped.
Possibly a good way to do it is to first iterate through all the buildings to see which ones need to be removed, then remove then all, and finally move all the ones that are left.
You might want to check this link for some good suggestions.
You're also updating the countdown twice, first on line 47 and then on line 58. Is there any reason for this?