So I am making a game in pygame and really need to get sprite sheets working. Every sprite sheet example I've seen however, is either terrible and I have no idea how to use it or is not a class. I thought that by pressing in the direction of the arrow keys(which is the movement in my game) I could just draw it to the player objects x and y values. This works for the first arrow key and if you press another after that it errors with
TypeError: argument 1 must be pygame.Surface, not bool
My code is:
posi=[player.rect.x,player.rect.y]
if left1:
posi=[player.rect.x,player.rect.y]
screen.blit(left,posi)
if right1:
posi=[player.rect.x,player.rect.y]
screen.blit(right,posi)
if down1:
posi=[player.rect.x,player.rect.y]
screen.blit(down,posi)
if up1:
posi=[player.rect.x,player.rect.y]
screen.blit(up,posi)
and I pretty much set left1,down1,right1 or up1 equal to true if you press an arrow key
It looks like you are not using screen.blit correctly. The first argument should be the image you are blitting (in other words, the picture of the sprite) and the second argument should be a tuple coordinate.
Go into your code and check what left is: I bet that it is not an image, so substitute it with the sprite's image. The coordinates are fine, though.
Pygame docs (see for help with surfaces): pygame home
Related
I have a python program using turtle to make the game "Snake". It is fully functional. At this point I'm adding in .gif images to spruce it up.
The problem arises when I'm trying to use a custom shape as the head of the snake. If I use a basic shape from turtle like "triangle" or "arrow" it works fine. It turns correctly and is printed over the first body segment as intended. When I change it to my custom image, the problem is that it is printed out under the first body segment and cannot turn.
Sample of controls
if direction == "up":
if snake_direction != "down":
snake_direction = "up"
head_stamper.setheading(90)
Stampers used to make numerous sections, and a head over the first segment.
for segment in snake:
stamper.goto(segment[0], segment[1]) #These are the body segments, they work fine.
stamper.stamp()
head_stamper.goto(new_head)
Showing both stampers here.
# Stamper for each body section
stamper = turtle.Turtle()
stamper.shape(bod_segment)
stamper.shapesize(25 / 20)
stamper.penup()
# Special stamper just for the snake's head.
head_stamper = turtle.Turtle()
# head_stamper has no issues when I make the shape "arrow" or "triangle", etc.
head_stamper.shape(head_segment)
stamper.shapesize(25 / 20)
head_stamper.penup()
I think this is all the code relevant to the problem.
When I change it to my custom image, the problem is that it is printed
out under the first body segment and cannot turn.
As far as not turning, this is addressed in the Python turtle documentation of register_shape() aka addshape():
Note: Image shapes do not rotate when turning the turtle, so they do
not display the heading of the turtle!
As far as the overlap problem, I can only guess. Generally the rule in turtle is the last thing that moved is on top. So turning your generic head shape lands it on top, but since your image shape doesn't actually turn, it winds up on the bottom. Again, just a guess.
def death_en():
death = pygame.Surface.blit(pygame.image.load('tombstone.png'))
if x + (WarriorSize_x * .8) == x_en:
screenDisplay.blit(death, (x_en, y_en))
I'm new to Python and over all programing. I have started learning about pygame and I'm trying to create a game. What I want this function to do is to put another image on top of the enemy that was killed, though nothing happens when I get close enough to it with the main character. I now I haven't assigned a y-axis, but want to make sure this works first. I could send the whole code if it's necessary.
Thanks in advance.
To check for collisions use the PyGame Rect Class. Keep a rectangle for your player, and a rectangle for each enemy, updating the position of the rect whenever the item it tracks changes position. Also, when an enemy or the player moves, use the function Rect.colliderect() to determine if the two items have intersected on-screen.
This might be something like:
tombstone_image = pygame.image.load('tombstone.png')
...
# Inside main loop
# Have there been any collisions?
for e_rect in all_enemy_rects:
if ( e_rect.colliderect( player_rect ) ):
screenDisplay.blit( tombstone_image, e_rect )
# TODO: remove enemy from game
Is there a way in pygame for sprites, when dragged, to snap to an invisible (or visible) grid? Kinda like drag 'n drop? If so, how? I've been trying to do some sprite overlap, but it's too tedious to make an if-statement for each of the grid-lines. So how can I make a snap-to-grid drag-n-drop sprite? This is for a chess program. I'll appreciate your help.
Make an array of corners of the chess board using for loops.
corners = []
for x in range(edgeRight, edgeLeft, interval):
for y in range(edgeTop, edgeBottom, interval):
corners.append((x,y))
Then, make an event listener. When the piece is being dragged around, insert this code into whatever while statement you have:
px, py = Piece.Rect.topleft //using tuples to assign multiple vars
for cx, cy in corners:
if math.hypot(cx-px, cy-py) < distToSnap:
Piece.setPos((cx,cy))
break
I have no idea what your actual code is, but this should give you an idea. Again, pygame has no snap-to-grid functionality.
So this can be done quite simply by using the round function in python.
sprite.rect.x = ((round(sprite.rect.x/gridSquareSize))*gridSquareSize)
sprite.rect.y = ((round(sprite.rect.y/gridSquareSize))*gridSquareSize)
This manipulates the round function, by rounding your sprite's coordinates to the nearest grid square.
This is just my second day at pygame, and I am not much aware about many functions. The following is a sample of what I am doing on my surface(window)
for c in nStations:
pygame.time.wait( 20 )
pygame.draw.circle( window, c.tColor, c.tPosition, c.iRadius )
pygame.display.update()
This is looped for n number of circles(in a tuple) to be displayed. Now, this will be repeated a total of 5-6 times. I wish to store/save the surface window as an image(or sub-surface) and put it as a thumbnail/link at the top-right-corner of my window.
Is it possible? Or is pygame not a good library for this? I tried working on cocos2d too, but it's documentation is very poor as compared to pygame.
In case my question didn't make any-sense anywhere, please reply. I'll keep updating it.
P.S. I've seen python.surface library functions. and surface.copy seems to be what I am looking for, but can I store the surface as a thumbnail/image before copying and editing it further?
EDIT->After reading jsbueno's reply, what I did:
tThumbs.append( pygame.transform.smoothscale( window, (32, 32) ) )
# the above statement inside drawing-circle loop
i = 1
for thumb in tThumbs:
window.blit( thumb, (1050, 36*i) )
pygame.display.update()
i += 1
pygame.time.wait( 200 )
The above seems to work perfectly for me. Thanks. :)
Indeed - all drawing and transofmr functions in Pygame accept a "surface" as the first parameter. Actually, in pygame, a "surface" is an image.
The display window is just a surface as well - although a specialized one, whose contents are reflected on screen. But you can use pygame.transform.smoothscale to get a thumbnail copy of your screen surface, and then, the blit method of your screen object itself to paste it on screen.
If this is going to be done continuoulsy, the pasted corner ould also be replicated, like a video camera pointing to its own output - so the "right way" to do it is: keep yoru drawing ina separate, in memory surface, blit it to the screen surface, and then blit the thumbnail above it.
I'm making a Pong clone for learning purposes, and need to get the ball moving from the middle of the screen (it's sent there when it goes past a paddle) when the mouse is pressed. I've tried the following code, but it does nothing, so I probably don't understand the syntax. Try to keep it as simple as possible please, and explain it, I'd rather not have 50 lines of code for this (I want to understand everything I'm using here). I think this is all the relevant code, sorry if it isn't. Thanks.
def middle(self):
"""Restart the ball in the centre, waiting for mouse click. """
# puts ball stationary in the middle of the screen
self.x = games.screen.width/2
self.y = games.screen.height/2
self.dy = 0
self.dx = 0
# moves the ball if mouse is pressed
if games.mouse.is_pressed(1):
self.dx = -3
It's impossible to know exactly what's happening based on that code fragment, but it looks like you are using the wrong function to detect whether or not the mouse button is pressed.
Screen.is_pressed from the games module wraps pygame.key.get_pressed, which only detects the state of keyboard keys, not mouse buttons. You probably want the function Screen.mouse_buttons, which wraps pygame.mouse.get_pressed. You could use it within a loop like this (I'll pretend you have an instance of games.Screen called 'screen'):
left, middle, right = screen.mouse_buttons()
# value will be True if button is pressed
if left:
self.dx = -3
I am looking at the same issue as a beginner Python coder - Games.py (revision 1.7) includes several is_pressed methods in various classes, including both keyboard and mouse.
class Mouse(object):
#other stuff then
def is_pressed(self, button_number):
return pygame.mouse.get_pressed()[button_number] == 1
since pygame is a compiled module (I have 1.9.1) referring to the documentation rather than source code, I find here that there is a pygame.mouse.get_pressed():
the will get the state of the mouse buttons
get_pressed() -> (button1, button2, button3)
So I think the issue is the use of this in (y)our code rather than the use of the wrong function.....
OK GOT THIS TO WORK - MY FIX:
class myClass(games.Sprite):
def update(self):
if games.mouse.is_pressed(0)==1:
self.x=games.mouse.x
self.y=games.mouse.y
invoking the in Main() causes the selected sprite to move to the mouse location. HTH