Nebula
Nebula

Reputation: 33

How do I use a function to draw a line in pyglet?

I am a novice to pyglet and python in general, I want to create a function to draw a line. Here is my code:

import pyglet
from pyglet import shapes


title = "Tic Tac Toe"

window = pyglet.window.Window(600, 600, title)
batch = pyglet.graphics.Batch()


def drawBoard(batch=None):
    line = shapes.Line(600, 0, 300, 600, width=2, color=(0, 230, 0), batch=batch)
    line.opacity = 250


drawBoard(batch=batch)


@window.event
def on_draw():
    
    window.clear()
    batch.draw()
    

pyglet.app.run()

When I move the code inside the function out of the function it creates the line as desired but when I place it in the function the code only creates a blank background.

Upvotes: 3

Views: 991

Answers (2)

mmore500
mmore500

Reputation: 91

You can attach the shapes to an attribute on the batch to keep them from being garbage collected as long as the batch object persists.

def makeBatch() -> pyglet.graphics.Batch:
    batch = pyglet.graphics.Batch()
    assert not hasattr(batch, "_handles")
    batch._handles = []

    line = shapes.Line(600, 0, 300, 600, width=2, color=(0, 230, 0), batch=batch)
    line.opacity = 250
    batch._handles.append(line)
    return batch

Upvotes: 0

Rabbid76
Rabbid76

Reputation: 210876

The shape line is a local variable in the drawBoard function. The batch just stores a weak pointer to the shape. Therefor the line is destroyed when the function is terminated.

An option is to store the line global namespace:

def drawBoard(batch=None):
    global line
    line = shapes.Line(600, 0, 300, 600, width=2, color=(0, 230, 0), batch=batch)
    line.opacity = 250

If you want to draw more sahpes, I recommend to manage the shapes in a list:

import pyglet
from pyglet import shapes

title = "Tic Tac Toe"

window = pyglet.window.Window(600, 600, title)
batch = pyglet.graphics.Batch()

def drawBoard(shape_list, batch=None):
    for i in range(100, 600, 100):
        linex = shapes.Line(i, 0, i, 600, width=2, color=(0, 230, 0), batch=batch)
        linex.opacity = 250
        shape_list.append(linex)
        liney = shapes.Line(0, i, 600, i, width=2, color=(0, 230, 0), batch=batch)
        liney.opacity = 250
        shape_list.append(liney)

shape_list = []
drawBoard(shape_list, batch=batch)

@window.event
def on_draw():
    window.clear()
    batch.draw()

pyglet.app.run()

Upvotes: 3

Related Questions