T3 - QB - Chapter 7 - QB - Solution
T3 - QB - Chapter 7 - QB - Solution
Create a canvas of size 96×96, and draw the letter "X" with
font size 48 in the upper left portion of the canvas. Review the
syntax for the SimpleGUI method draw_text and the layout of
canvas coordinates.
In [ ]: import SimpleGUICS2Pygame.simpleguics2pygame as simplegui
def draw_3(canvas):
canvas.draw_text('X', [0,30], 48, 'white')
# Create frame and assign callbacks to event handlers
frame = simplegui.create_frame("Draw X", 96, 96)
frame.set_draw_handler(draw_3)
# Start the frame animation
frame.start()
image.png
Q. 26. Prepare the program and add two buttons that control the
radius of a white ball centered in the middle of the canvas. Clicking
the “Increase radius” button should increase the radius of the ball.
Clicking the “Decrease radius” button should decrease the radius
of the ball, except that the ball radius should always be positive.
In [ ]: # Define globals - Constants are capitalized in Python
import SimpleGUICS2Pygame.simpleguics2pygame as simplegui
HEIGHT = 400
WIDTH = 400
RADIUS_INCREMENT = 5
ball_radius = 20
# Draw handler
def draw_4(canvas):
canvas.draw_circle([WIDTH/2, HEIGHT/2], ball_radius, 1, "white")
# Event handlers for buttons
def increase_radius():
global ball_radius
ball_radius = ball_radius + RADIUS_INCREMENT
def decrease_radius():
global ball_radius
ball_radius = ball_radius - RADIUS_INCREMENT
# Create frame and assign callbacks to event handlers
frame = simplegui.create_frame("Ball control", WIDTH, HEIGHT)
frame.set_draw_handler(draw_4)
frame.add_button("Increase radius", increase_radius)
frame.add_button("Decrease radius", decrease_radius)
# Start the frame animation
frame.start()
After running
image.png
Q. 28. Use a timer to toggle the canvas background back and forth
between red and blue every 3 seconds. To locate the appropriate
call to change the background color of the canvas.
In [ ]: import SimpleGUICS2Pygame.simpleguics2pygame as simplegui
# Global variables
canvas_width = 400
canvas_height = 200
background_color = "red"
def toggle_background():
global background_color
if background_color == "red":
background_color = "blue"
else:
background_color = "red"
def draw_handler(canvas):
canvas.draw_text("Canvas Background", (30, 100), 36, "White")
canvas.draw_polygon([(0, 0), (canvas_width, 0), (canvas_width, canvas_height), (0, canvas_height)], 1, "Wh
# Create a frame
frame = simplegui.create_frame("Toggle Background", canvas_width, canvas_height)
# Register the draw handler
frame.set_draw_handler(draw_handler)
# Create a timer that calls toggle_background() every 3000 milliseconds (3 seconds)
timer = simplegui.create_timer(3000, toggle_background)
# Start the timer
timer.start()
# Start the frame
frame.start()
image.png
Q. 30. Use a timer to measure how fast you can press a button
twice. Create a button that starts a timer that ticks every hundredth
of a second. The first button press starts the measurement. The
second button press ends the measurement. Print to the console
the time elapsed between button presses. The next two button
presses should repeat this process, making a new measurement.
Hint: We suggest that you keep track of whether the program is on
the first or second button press using a global Boolean variable
In [ ]: import SimpleGUICS2Pygame.simpleguics2pygame as simplegui
total_ticks = 0
first_click = True
# Timer handler
def tick_5():
global total_ticks
total_ticks += 1
# Button handler
def click_6():
global first_click
global total_ticks
if first_click == True:
timer.start()
print('Timer started!')
# set first_click to the opposite boolean
first_click = not first_click
else:
timer.stop()
print('Timer stopped!')
print('Total ticks: ' + str(total_ticks))
# reset the game state
total_ticks = 0
first_click = True
print('Game state reset. Click to play again.')
# Create frame and timer
frame = simplegui.create_frame("Counter with buttons", 200, 200)
frame.add_button("Click me", click_6, 200)
timer = simplegui.create_timer(10, tick_5)
# Start timer
frame.start()
Timer started!
Timer stopped!
Total ticks: 112
Game state reset. Click to play again.
Timer started!
Timer stopped!
Total ticks: 220
Game state reset. Click to play again.
image.png
By pressing key up
image-2.png
By pressing up key
image.png
By pressing down down
image-2.png
By default
image.png
By pressing space bar
image-2.png
For keyup
image.png
For keydown
image-2 png
image.png
image.png
Adding two numbers the output will be: (Note: while adding numbers one have to add the number and press enter each time) The
output will be:
image-2.png
image.png
After guessing
image-2.png
Q. 38. Create a GUI which can create a screen saver for the screen
and the text can also be moved in the entire position randomly.
In [ ]: import random
import SimpleGUICS2Pygame.simpleguics2pygame as simplegui
message=''
positionx=0
positiony=0
def draw_handler(canvas):
global message,positionx,positiony
canvas.draw_text(message,(positionx,positiony),50,'Magenta')
def timer_handler():
global message,positionx,positiony
positionx=random.randint(0,800)
positiony=random.randint(0,500)
def input_handler(user_message):
global message
message=user_message
frame=simplegui.create_frame('Testing',800,500)
frame.set_draw_handler(draw_handler)
inp=frame.add_input('Enter your message',input_handler,50)
timer=simplegui.create_timer(1000,timer_handler)
timer.start()
frame.start()
#to control within the screen and should not be cut
image.png
[300.0, 200.0]
[282.0, 200.0]
[252.0, 200.0]
[48.0, 200.0]
[26.0, 200.0]
[108.0, 200.0]
[122.0, 186.0]
[134.0, 162.0]
[145.0, 129.0]
[155.0, 89.0]
[182.0, 84.0]
[196.0, 168.0]
[209.0, 259.0]
image.png
The game will have three layers of bricks, and each layer of brick will have a different hit capacity, which means some bricks will break
in a single hit, some will require a double hit and some will require three hits.
"
In [ ]:
import SimpleGUICS2Pygame.simpleguics2pygame as simplegui
# Constants
CANVAS_WIDTH = 600
CANVAS_HEIGHT = 400
PADDLE_WIDTH = 100
PADDLE_HEIGHT = 10
PADDLE_COLOR = "White"
BALL_RADIUS = 10
BALL_COLOR = "Red"
BALL_SPEED = 3
# Bricks
BRICK_WIDTH = 80
BRICK_HEIGHT = 20
BRICK_PADDING = 5
BRICK_COLOR = {"Green": "Green", "Pink": "Pink", "Purple": "Purple"}
BRICK_HIT_CAPACITY = {"Green": 3, "Pink": 2, "Purple": 3}
BRICK_ROWS = 3
BRICK_COLS = 8
# Game variables
paddle_pos = CANVAS_WIDTH // 2
ball_pos = [CANVAS_WIDTH // 2, CANVAS_HEIGHT // 2]
ball_vel = [BALL_SPEED, -BALL_SPEED]
bricks = []
# Initialize bricks
for row in range(BRICK_ROWS):
for col in range(BRICK_COLS):
brick_color = list(BRICK_COLOR.keys())[row]
bricks.append((BRICK_WIDTH * col, BRICK_HEIGHT * row, brick_color))
def draw(canvas):
global ball_pos, ball_vel, paddle_pos
# Update ball position
ball_pos[0] += ball_vel[0]
ball_pos[1] += ball_vel[1]
# Bounce ball off walls
if ball_pos[0] <= BALL_RADIUS or ball_pos[0] >= CANVAS_WIDTH - BALL_RADIUS:
ball_vel[0] = -ball_vel[0]
if ball_pos[1] <= BALL_RADIUS:
ball_vel[1] = -ball_vel[1]
# Check collision with paddle
if ball_pos[1] + BALL_RADIUS >= CANVAS_HEIGHT - PADDLE_HEIGHT and (
paddle_pos <= ball_pos[0] <= paddle_pos + PADDLE_WIDTH
):
ball_vel[1] = -ball_vel[1]
# Check collision with bricks
for brick in bricks:
if (
ball_pos[0] >= brick[0]
and ball_pos[0] <= brick[0] + BRICK_WIDTH
and ball_pos[1] >= brick[1]
and ball_pos[1] <= brick[1] + BRICK_HEIGHT
):
brick_color = brick[2]
if BRICK_HIT_CAPACITY[brick_color] > 1:
BRICK_HIT_CAPACITY[brick_color] -= 1
else:
bricks.remove(brick)
ball_vel[1] = -ball_vel[1]
# Draw bricks
for brick in bricks:
canvas.draw_polygon(
[
[brick[0], brick[1]],
[brick[0] + BRICK_WIDTH, brick[1]],
[brick[0] + BRICK_WIDTH, brick[1] + BRICK_HEIGHT],
[brick[0], brick[1] + BRICK_HEIGHT],
],
1,
"Black",
BRICK_COLOR[brick[2]],
)
# Draw paddle
canvas.draw_polygon(
[
[paddle_pos, CANVAS_HEIGHT - PADDLE_HEIGHT],
[paddle_pos + PADDLE_WIDTH, CANVAS_HEIGHT - PADDLE_HEIGHT],
[paddle_pos + PADDLE_WIDTH, CANVAS_HEIGHT],
[paddle_pos, CANVAS_HEIGHT],
],
1,
"Black",
PADDLE_COLOR,
)
# Draw ball
canvas.draw_circle(ball_pos, BALL_RADIUS, 1, "Black", BALL_COLOR)
def keydown(key):
global paddle_pos
if key == simplegui.KEY_MAP["left"]:
paddle_pos -= 20
elif key == simplegui.KEY_MAP["right"]:
paddle_pos += 20
def keyup(key):
pass
frame = simplegui.create_frame("Brick Breaker", CANVAS_WIDTH, CANVAS_HEIGHT)
frame.set_draw_handler(draw)
frame.set_keydown_handler(keydown)
frame.set_keyup_handler(keyup)
frame.start()
image-2.png
image.png
image.png
image.png
image.png
image.png
In [ ]: