CS 151: Intro to Programming in Python

Problem Set 4: Graphics

Due: Monday, 14 October, 11:59 PM

Github Classroom Link: https://classroom.github.com/a/Bb83mHVX


This is a problem set of 3 problems, all involving graphics operations.


Files:

1. draw_image

  • Update (only) this file:
    • Prob1.py

2. draw_pyramid

  • Update (only) this file:
    • Prob2.py

3. clicky_box

  • Update (only) this file:
    • Prob3.py

All:

  • You will also need:
    • pgl.py

Resources on PGL (Portable Graphics Library):

Problems:

Problem 1: draw_image

Write a function that, when run, uses PGL to draw something you find beautiful, or at least as close as you can manage on short notice. You must use at least one each of:

  1. GRect
  2. GOval
  3. GLine
  4. GLabel

How I solved it.


def draw_image():

    # Creating the window
    gw = GWindow(WIDTH, HEIGHT)
    
    w = WIDTH # just to save typing
    
    #red box
    r = GRect(w//2,w)
    r.set_filled(True)
    r.set_fill_color("red")
    gw.add(r) 
    
    # green circle
    o = GOval(w//2,w//2)
    o.set_filled(True)
    o.set_fill_color("green")
    gw.add(o)
    
    # line for left side middle to rightside middle
    gw.add(GLine(0,w//2,w,w//2))
    
    # that's half height, half width - the middle.
    gw.add(GLabel("hello world", w//2, w//2)) 

Problems:

Problem 1: draw_image

Write a function that, when run, uses PGL to draw something you find beautiful, or at least as close as you can manage on short notice. You must use at least one each of:

  1. GRect
  2. GOval
  3. GLine
  4. GLabel

How I solved it.


Problem 2: draw_pyramid

Write a function that, when run, uses PGL to display a pyramid of rectangles on the graphics window.

The pyramid consists of bricks arranged in horizontal rows, arranged so that the number of bricks decreases by one as you move upward, as shown in the demo. The pyramid should be centered perfectly in the window both horizontally and vertically. You should be able to change the following constants in your program and have it react appropriately by drawing the altered pyramid centered still within the window.

  1. BRICK_WIDTH The width of each brick
  2. BRICK_HEIGHT The height of each brick
  3. BRICKS_IN_BASE The number of bricks in the base (bottom) row

How I solved it. I wrote an "n_bricks" function that made a horizontal row of bricks and then used a similar loop to the '*' pyramid, but multipled "height" and "width" rather than spaces.

Demo

WIDTH          = 400 # for the demo, must be changeable in your code
HEIGHT         = 400 # for the demo, must be changeable in your code
BRICK_WIDTH    = 
BRICK_HEIGHT   = 
BRICKS_IN_BASE = 

Problem 3: clicky_box

The function clicky_box will

  • Display a randomly positioned square in a PGL graphics window
  • When the square is clicked, and only when the square is clicked, it will move to a different random part of the screen
  • Track the number of clicks in the lower left.

Firstly, add a colored and filled square of size SQUARE_SIZE to the center of the window. You can choose the color of the square. Ensure your square is displaying centered in the screen when you run your program before continuing.

Optionally, add a listener to your window which will listen for when the user presses down the mouse button, and calls the on_mouse_down function when that occurs. Run your program and ensure that, now, when you click the mouse anywhere in the window, a message prints to the terminal saying as much!

Next, add/update on_mouse_down function so that if (and only if) you click inside the colored square, the square moves to a new random position that causes it to be entirely within the window bounds, that is, fully visible within the graphic window. Make sure that nothing happens if you click outside the square: it should only move if you clicked within the square boundry.

There are several ways you can check to see if the mouse was clicked within the confines of the square, some easier and some harder. You may want to look here to refresh your memory about some functions/methods that may be useful.

Lastly maintain a "score" SCORE_DX from the left wall and SCORE_DY up from the bottom. Every time that you click inside the square, you want to add one to the score, and every time you click outside the square, set the score to 0.

There are a few ways you could handle this. One would be to keep track of the score purely inside a GLabel, getthing and setting the text of the label as necessary. Another would be to create a variable which you would increment or reset as needed, and then update the GLabel from the variable. Just be aware that if you go the variable route, you will need to add that variable as an attribute to the GWindow, or else you won’t be able to globally set its value within the callback function.

Problem 3: clicky_box

Here is demo. The label is a bit goofy looking due to web-embedding.


This code snippet defines how to calculate a random integer between 0 and SOME_VAL


import random # at top of file, by other imports

def get_r():
    return random.randint(0, SOME_VAL)

This code snippet defines how to configure a graphics window to perform a function after a click. Without this, 'on_mouse_down' will never run.


gw.add_event_listener("click", on_mouse_down)