Copied Code works, written code does not? - python

New Python programmer here. I'm trying to write Snake in python without the use of tutorials. I'm now working on key binds, but I'm running into a problem
#Move snake to the left
def move_right():
right = snake.xcor()
right += 20
snake.setx(right)
#Key bind "d"
wn.listen
wn.onkeypress(move_right(), "d")
The above code is supposed to move the snake to the right when the "d" key is pressed, but it does not work. However, when copying code from a fully functioning Pong program from a tutorial on YouTube, it does work. The copied code is this:
#Function for paddle_b_up
def paddle_b_up():
y = paddle_b.ycor()
y += 20
paddle_b.sety(y)
#key bind to the up arrow key
wn.onkeypress(paddle_b_up, "Up")
I then proceeded to write out the copied code, exactly as it was written in the Pong program, into the Snake program and it does not work. I am very confused. The indenting is the same, the code is the same (save a few different, but consistent variables), and only the movement and key binding code from the Pong program was copied into the Snake program. Without changing anything else, the Pong code works, but only when I copy and paste the code into the Snake program. Any advice? Thank you.

Notice the difference between the two calls to wn.onkeypress(). In the copied code there's no () after paddle_b_up, but in your code you have move_right().
When you put () after a function name it calls it immediately. But you want the function to be called later, when the key is pressed. You need to pass a reference to the function, not the result of calling the function.
wn.onkeypress(move_right, "d")
You also need () after wn.listen so you call the function.

Related

Clearing the screen for text based rpg in python

I am trying to make a text based rpg game in python. I just started and this is what my code looks so far:
class Game:
def __init__(self):
self.map = [[" " for i in range(50)]for i in range(30)]
def draw_map(self):
for i in range(len(self.map)):
print(self.map[i])
def add_stuff(self, thing, x, y):
self.map[y][x] = thing
game = Game()
class Player:
def __init__(self):
self.x = 1
self.y = 1
self.player = "ME"
def draw(self):
game.add_stuff(self.player, self.x, self.y)
def move(self):
pass
player = Player()
player.draw()
game.draw_map()
I was trying to find a way to implement a game loop in some way. To do this i was thinking of running the draw_map() and clearing the screen right away and printing the map again, a bit like real game loops. However i am having problems doing this. Based on other answers to other similar questions, i managed to produce the following code(it just shows the main loop and subprocess is imported as sp).
while True:
game.draw_map()
sp.call("cls", shell = True)
However this is not working for me. It simply dosent do anything. I also tried using clear function from clear_screen` module in a similar way and i cant figure out why this wouldnt work. Thanks for any help
so based on your previous comments you want to clear the screen in a Python interpreter. There is no "command" to clear the screen just like this. But you can use a loop to print some new lines until your screen is blank again.
def clear(lines):
for l in range(lines):
print()
while True:
game.draw_map()
clear(35)
time.sleep(0.05)
You may need to increase or decrease the amount of lines cleared. I hope this works for you. P.S.: I would use a normal console.
https://en.wikipedia.org/wiki/Interpreter_(computing)#Efficiency:
Efficiency:
The main disadvantage of interpreters is that an interpreted program typically runs slower than if it had been compiled. The difference in speeds could be tiny or great; often an order of magnitude and sometimes more. It generally takes longer to run a program under an interpreter than to run the compiled code but it can take less time to interpret it than the total time required to compile and run it. This is especially important when prototyping and testing code when an edit-interpret-debug cycle can often be much shorter than an edit-compile-run-debug cycle.
If your problem is clearing the console window, you can just use
import os
os.system('cls')
in place of
sp.call("cls", shell = True)
(Assuming you are working on windows)
EDIT for clarity:
This is the new loop after the change:
while True:
game.draw_map()
os.system('cls')

Problem with using keyboard module and turtle together

I am writing a script to read my keystrokes and draw simple shapes in turtle.
To record keystrokes, I am using the keyboard module and I am using turtle for drawing.
I am getting struck due to the use of threading in the keyboard module.
What I am currently doing is-
I added hotkeys using keyboard.add_hotkey method.
If I am pressing a certain key, that letter is added to a list (named data) for later use.
When I press the combination of Ctrl+Shift+S, the save function is called. In the save function, a turtle window is instantiated, and the list data is popped one letter at a time. The shape is drawn according to the letter popped.
When the list gets empty, I save the drawing and close the turtle window.
The problem that I am facing is that once the save function is called, the program stops listening to other calls. It is perhaps due to the use of threads in keyboard module.
The code is attached here-
def start():
#turtle.mainloop()
s=turtle.Screen().setup( width = WIDTH, height = HEIGHT, startx = 0, starty = 0)
global t
t=turtle.Turtle()
turtle.ht()
t.ht()
def save():
start()
global t
global data
t.speed(0)
while data:
fun = data.pop()
if fun=='c':
draw_circle()
elif fun=='r':
draw_rectangle()
elif fun=='p':
draw_polygon()
elif fun=='h':
draw_hexagon()
elif fun=='t':
draw_triangle()
elif fun=='m':
draw_pentagon()
ts = turtle.getscreen()
ts.getcanvas().postscript(file="drawing.eps")
img = Image.open('drawing.eps')
img.save('drawing.png')
turtle.bye()
def push_fun(fun):
data.append(fun)
if __name__=='__main__':
keyboard.add_hotkey('ctrl+shift+s', save)
keyboard.add_hotkey('ctrl+shift+e', exit)
keyboard.add_hotkey('ctrl+shift+p', send_to_server)
# keyboard.add_hotkey('ctrl+shift+s', save, args=(data))
keyboard.add_hotkey('c', push_fun, args=('c',))
keyboard.add_hotkey('s', push_fun, args=('t',))
keyboard.add_hotkey('h', push_fun, args=('h',))
keyboard.add_hotkey('p', push_fun, args=('p',))
keyboard.add_hotkey('r', push_fun, args=('r',))
keyboard.wait()
After the save function is called, the program remains in the keyboard.wait() part but does not listen to any other key press.
you can end the wait by setting a key to press like:
keyboard.wait('space')
but keyboard.wait() without any keys given blocks all keystrokes forever
I'm not sure why you even put it there, I'm not even sure why it picks anything up at all, but I think you can do this:
if __name__=='__main__':
'''your keystrokes'''
while True: #or set a timer or something
pass
you didn't give me the whole code so I can't make sure it works
you also need to global the list data in the push_fun function
I hope it helps :)

Sprite Sheets Pygame/Python

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

Issues running a code using Pygame

OKay, so i wrote a code to develop a game using pygame. this is the aim of the game :
there is a player (Mario) which can move only vertically. from the right side of the window, flames appear which the mario has to dodge. the game is very similar to dodger.py !
now, when i run the game, it gets stuck at "Press any key to Enter"
PLEASE HELP !
You are not doing anything in the waitforkey() function.
if event.type == KEYDOWN:
# if key exit blah blah
else:
runGame()
You could put your game in a function called runGame and that would probabaly be the easiest way of doing this. Just remember that the variables will then be local to the scope of that function and any changes won't affect the rest of the program.
Having checked the code on a PC, I have found 3 errors. Two of which are typing errors. First one is on Line 77:
playerrect.topleft = (50,window_hight/2)
Needs to be:
playerrect.topleft = (50,window_height/2)
and the second is on line 126:
WindowSurface.fill(bgcolour)
You haven't defined bgcolour (as far as I could see) so by adding the following to the variables at the top of the file:
bgcolour(255,255,255) #change to what colour you want
The third error I found was in your waitForKey() function. I don't know whether this is important to the running of the program, but you have your if event.type == "QUIT" in speech marks. Like I said, this may not matter but I thought I'd point it out. You have also done this for the other conditions in this function.
By making these changes, you get running code. However, flames do not appear and I don't have time to figure this one out. By fiddling though, I'm sure you'll figure it out!

Moving a sprite when mouse is pressed in Python

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

Categories