DIPÉPTIDOS AZETIDÍNICOS COMO INHIBIDORES DE CMVH
H- L Ala-NHChx TFA (1.39d)
1.6.3.2. Protocolos generales de síntesis en fase sólida Aspectos generales
A game that has the ball starting in the same position is going to be pretty boring, so let’s add some randomness to the start position and direction. We can do that by using the random module. Here is tk move circle2.pywhere I’ve shown only the modified lines.
from Tkinter import * import random ... x = 10 y = random.randint(10,190) dx = 2 dy = random.randint(-5,5)
Now we have a ball that’s a bit more interesting — it starts on the left hand side of the window, and heads off in a random direction. Unfortunately, it often quickly disappears from the window, never to return. What we really need is to have the ball bounce off the top and bottom of the window. This is another situation where it’s worth spending some time thinking about how to make the ball bounce. So before you look on ahead, see if you can come up with a reasonable scheme.
The solution is actually quite simple. A perfect bounce that loses no energy in the collision should leave the bounce at the same angle as it entered. If the ball is bouncing off a horizontal surface, its velocity in the x direction will stay the same, and it’s velocity in the y direction will be opposite to what it was before. This can be achieved fairly easily with an if-elif statement. The move function becomes:
from Tkinter import * import random def move(): global ball global gameCanvas global x, y, dx, dy x = x+dx y = y+dy if y<0: y = 0 dy = -dy elif y>180: y = 180 dy = -dy gameCanvas.coords(ball, x, y, x+20, y+20) gameCanvas.after(100, move) root = Tk()
gameCanvas = Canvas(root, width=200, height=200) gameCanvas.grid(column=0,row=0)
x=10
y=random.randint(10,190) dx=2
dy=random.randint(-5,5)
ball = gameCanvas.create_oval(x, y, x+20, y+20, fill="blue") gameCanvas.after(100, move)
root.mainloop()
The ball should now bounce off the top and the bottom of the screen. I’m a little concerned though that there are a lot of magic numbers (0, 180, 100, 20 etc) creeping into the code. All these numbers make the code a bit hard to read, and can make code hard to modify. Generally, if you find that you use the same number in more than one place, it is good practice to put it in a constant variable — that way you can modify the constants in your program at a later date by just changing one number and not several. Also, with GUI widgets, we can often discover their state (such as their width and height), by using the widget’s query method. To discover the width of a widget in Tkinter, we can use the winfo width() method. Why do you think that’s preferable than specifying a program constant? If we make those changes, our bouncing ball program eventually looks like bounce.py:
from Tkinter import * import random def move(): global ball global gameCanvas global x, y, dx, dy global BALL_SIZE global WAIT_TIME x = x+dx y = y+dy if y<0: y = 0 dy = -dy elif y>gameCanvas.winfo_height()-BALL_SIZE: y = gameCanvas.winfo_height()-BALL_SIZE dy = -dy
gameCanvas.coords(ball, x, y, x+BALL_SIZE, y+BALL_SIZE) gameCanvas.after(WAIT_TIME, move)
# constants are usually written all in upper case
BALL_SIZE = 20 WAIT_TIME = 100 root = Tk()
gameCanvas = Canvas(root, width=400, height=400) gameCanvas.grid(column=0,row=0) gameCanvas.wait_visibility() x=0 y=random.randint(0,gameCanvas.winfo_height()-BALL_SIZE) dx=2 dy=random.randint(-5,5)
ball = gameCanvas.create_oval(x, y, x+BALL_SIZE, y+BALL_SIZE, fill="blue") gameCanvas.after(WAIT_TIME, move)
root.mainloop()
I added one extra function call to the above program: gameCanvas.wait visibility(). This was because I wanted to make sure the canvas was created before asking for its size when generating a random y position.
14.4
Glossary
random: Having no specific pattern. Unpredictable. Computers are designed to be predictable, and it is not possible to get a truly random value from a computer. Certain functions produce sequences of values that appear as if they are random, and it is these pseudo-random values that we get from Python.
14.5
Laboratory exercises
1. The following Tkinter script draws a simple house on a Tkinter canvas:
from Tkinter import *
root = Tk()
houseCanvas = Canvas(root, width=400, height=400) houseCanvas.grid(row=0, column=0)
houseCanvas.create_rectangle(20, 380, 120, 280) # the house
houseCanvas.create_rectangle(55, 380, 85, 330) # the door
houseCanvas.create_rectangle(40, 320, 60, 300) # left window
houseCanvas.create_rectangle(80, 320, 100, 300) # right window
houseCanvas.create_line(20, 280, 70, 240, 120, 280) # the roof
root.mainloop()
• Create a file called, house.py, and type in the above code. Run this script and confirm that you get a window that looks like this:
• Wrap the house code in a function named draw house(). • Run the script now. Do you see a house? Why not?
• Add a call to draw house() at the bottom of the script so that the house returns to the screen.
• Parameterize the function with x and y parameters — the header should then become def draw house(x, y):, so that you can pass in the location of the house on the canvas.
• Use draw house to place five houses on the canvas in different locations. 2. Modify the code in bounce.py, to make the ball go faster.
3. Modify the code in bounce.py so that the bounce is a little bit random. This should make the catch game we develop in the next lecture a bit more interesting.
Lecture 15
Case study: Catch continued
15.1
Keyboard input
To be able to respond to input from the user, Tkinter and most GUI toolkits use the notion of an event. To get a program to respond to events, we need to bind an event to a callback function. Here is how we can implement a mitt for the catch game that moves the mitt up or down depending on the key pressed:
from Tkinter import * def move_mitt(event):
global mitt
global gameCanvas
global mittx, mitty
global MITT_SIZE
if event.char=="j": mitty = mitty+10
elif event.char=="k": mitty = mitty-10
gameCanvas.coords(mitt, mittx, mitty, mittx+MITT_SIZE, mitty+MITT_SIZE) MITT_SIZE = 20
root = Tk()
gameCanvas = Canvas(root, width=400, height=400) gameCanvas.grid(column=0,row=0)
gameCanvas.wait_visibility()
mittx = gameCanvas.winfo_width()-30 mitty = gameCanvas.winfo_height()/2
mitt = gameCanvas.create_oval(mittx, mitty,
mittx+MITT_SIZE, mitty+MITT_SIZE, fill="blue")
root.bind("k", move_mitt) root.bind("j", move_mitt) root.mainloop()
The callback function, move mitt takes the variable event as a parameter. This variable is of type Event. Each event we want the program to respond to must be bound with a bind call. You can bind as many events as you like, and they can also be bound to different callbacks if desired. In move mitt, the particular event is checked by testing the char attribute of the Event type. Type in help(Event) at the python prompt to find out what other attributes an Event variable has.