Please note: Friday June 18 is a holiday celebrating Juneteenth, please allow extra time for your order to arrive and plan accordingly.
0

Stage and Ugame on Clue
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Stage and Ugame on Clue

by codingCat on Wed May 20, 2020 8:34 am

Has anyone done the work to get the stage and ugame modules to work on the Clue?

I'm hoping to use Clue as part of my Intro to Programming and Intro to Game design courses. For the experience to be meaningful the students will want the ability to play games on the Clue as well as produce animations to go along with the Clue's tricorder like abilities. The Clue is my first dip into CircuitPython and Looking through the modules suggests that stage and ugame are the way to go.

Can anyone give a noob to the Clue some hints on getting the modules working?

Thanks, :-)

codingCat
 
Posts: 5
Joined: Wed May 20, 2020 8:05 am

Re: Stage and Ugame on Clue

by kevinjwalters on Thu May 21, 2020 10:11 am

Just to make things more complicated, I'll raise the issue of MakeCode Arcade and the alternate set of devices for it like the Adafruit PyGamer for MakeCode Arcade, CircuitPython or Arduino. The CLUE has a lot going for it but you should evaluate the MakeCode world (if you haven't already!) which I'd rate as one of the two interesting products that Microsoft produce.

The devices (there's lots of choice - at least one has the microbit edge connector if you have some investment there already) have all got input buttons/joysticks in the classic game controller style and a 160x120 resolution colour canvas for the games. There's a decent development environment for writing games with an easy learning curve with blocks style programming. There's JavaScript for more complex games too and you can mix JavaScript with blocks too in various ways. They've been working on a Python equivalent but I've not followed that more recent work.

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Stage and Ugame on Clue

by kevinjwalters on Fri May 22, 2020 1:20 pm

Another twist is the availability of game controller boards designed for the micro:bit. These are likely to be compatible with the CLUE. I've not used these but here's a quick search, there's probably more out there too in the large micro:bit edge connected world:


Those or similar would need testing with a CLUE and availability and easy of adding support in libraries would need investigating.

I'm not sure what the support is for the nRF52840 chip in MakeCode Arcade world, if that interests you? It was mentioned briefly at tail end of: MakeCode Forum: What is an ARCADE F4?

What sort of course are you working on? What's the age range?

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Stage and Ugame on Clue

by codingCat on Sun May 24, 2020 2:11 am

Nope. No interest in anything Microsoft.

I had been using Microsoft Small Basic for my Intro to programming course, and I had to abandon it mid semester because of the lockdown. From this point forward I need to use only languages and environments that work on any platform. I’m not about to chose something that is locked into windows, or requires a particular website. This is why I chose to go with a microcontroller and python.

The clue doesn’t have an operating system. And Python is universal. This means the students can work on projects from any platform as long aa it can access a USB device.

Can we stick to the topic please. Do you (or anyone else reading this) have any hints in getting Stage and Ugame working in the Clue?

codingCat
 
Posts: 5
Joined: Wed May 20, 2020 8:05 am

Re: Stage and Ugame on Clue

by kevinjwalters on Sun May 24, 2020 7:35 am

I've not used stage but I'll ask around. The import below fails on a CLUE so this suggests it's not compiled in for the CLUE and I'm not sure how it would or could adapt to a 2 button, 3 touch pad device.

Code: Select all | TOGGLE FULL SIZE
>>> import _stage
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: no module named '_stage'

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Stage and Ugame on Clue

by deshipu on Sun May 24, 2020 8:17 am

@kevinjwalters is right here, the stage library requires a small component that is written in C for performance reasons, and that has to be compiled into the CircuitPython firmware to work. While both PyGamer and PyBadge have it included by default, the CLUE does not, so you would need to compile your own version of the firmware, with _stage enabled, to use the stage library.

Another problem I can see is with the ugame library, which provides a consistent interface for the display, sound, and buttons (so that all ugame games work on all boards that have the ugame library). Since CLUE doesn't have console-style buttons, I don't see a good way of implementing button handling for that board.

But all is not lost, because CLUE has the displayio library, which is actually more flexible than the stage library. You can use that to make games for CLUE.

deshipu
 
Posts: 14
Joined: Mon Jun 27, 2016 5:40 pm

Re: Stage and Ugame on Clue

by kevinjwalters on Thu Jun 11, 2020 5:47 pm

I'm making a game at the moment that's got some basic movement with sprites - this is easy to do with displayio. Objects like TileGrid can be used to pick sprites out of a bmp sheet and those have an x,y position so it's easy to move them around. Auto refresh will update the screen as needed. Here's a preview of the not-quite-finished game in action: Rock paper scissors game on Circuit Playground Bluefruit + TFT Gizmo with audio leakage via fingers (YouTube). Same code runs on the CLUE.

My sprites are intentionally low-res. They are 16x16 scaled up by 3. I think it would work just as well with 48x48 sprites.

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Stage and Ugame on Clue

by codingCat on Sat Jun 13, 2020 12:52 pm

I'm new to the Adafruit hardware, Can clue me in on which of the displayio drivers to use with the Clue, and what settings to use in the python script to get it working?

Or, where I would go to find the information. The displayio page on adafruit doesn't talk much about setup.

codingCat
 
Posts: 5
Joined: Wed May 20, 2020 8:05 am

Re: Stage and Ugame on Clue

by kevinjwalters on Sat Jun 13, 2020 1:08 pm

The display is automatically initalised for you on the CLUE and can be found in board. The example on Adafruit Learn: CircuitPython Display Support Using displayio: Text should work as is on the CLUE. Here's more-or-less the same thing tapped in quickly on REPL over serial console on the board I'm currently using:

Code: Select all | TOGGLE FULL SIZE
Adafruit CircuitPython 5.3.0 on 2020-04-29; Adafruit CLUE nRF52840 Express with nRF52840
>>>
>>> import board, displayio, terminalio
>>> from adafruit_display_text import label
>>> display = board.DISPLAY
>>> text_area = label.Label(terminalio.FONT, text="Some text", color=0x0000FF, scale=4)
>>> display.show(text_area)
>>> text_area.y = 120

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Stage and Ugame on Clue

by codingCat on Sat Jun 13, 2020 1:18 pm

Thank you, that helps a lot.

I'm fluent in python so I understand what is going on with the imports. The rest of it, where you set up the display... not so much.

Can you take a moment to explain what is going on?

codingCat
 
Posts: 5
Joined: Wed May 20, 2020 8:05 am

Re: Stage and Ugame on Clue

by kevinjwalters on Sat Jun 13, 2020 1:47 pm

Using my example.

Code: Select all | TOGGLE FULL SIZE
001 import board, displayio, terminalio
002 from adafruit_display_text import label
003 display = board.DISPLAY
004 text_area = label.Label(terminalio.FONT, text="Some text", color=0x0000FF, scale=4)
005 display.show(text_area)
006 text_area.y = 120


  1. load the libraries - these are actually all built into the interpreter so will not appear in /lib folder/directory.
  2. load the label library which provides a convenient way to put text on the screen - this needs to be in the /lib directory.
  3. set a display variable to the "main display" - the Adafruit boards which have permanently attached screens have this and the interpreter initalises it at power on for you. This is partly done because the screen is useful for showing the serial console. Updating the serial console shown on the display slows down a program so you have to be aware of that.
  4. Create a label based on some specified text using the built-in standard font from terminalio library with a blue colour and with 4x scaling to make it bigger, I think default size is 6x14 including inter-glyph spacing. Font position will be (0,0) (top left) by default and its anchored at "west" so its initial position will be with the top half off the top of the screen. The text and color are properties which can be changed later but the text has a fixed maximum size, see the docs for how to explicitly set this. The default background is transparent.
  5. This actually puts the text on the screen. show() takes a displayio.Group object but the Label happens to be one of these so works here. If you wanted to show two bits of text you can do "line 1\nline 2" or you can make two Labels and append them into a Group. The position in a Group determine their stacking order so you can put things above each other with this. I think there's also a hidden property to make things invisible but I've not played with that. Doing display.show(None) would return the display to the serial console.
  6. This changes the y position of the text - it moves to a position half way down the screen. This command doesn't actually immediately move it. The default mode for the screen is to automatically refresh (see property display.auto_refresh) so the next refresh (I forget what it's set to but probably between 40-60Hz) will send the changes to the screen for display. This means you can make multiple changes and they will often coalesce into one group of updates to the screen. Huge updates will also make you code run in a slightly more stuttery way.

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Stage and Ugame on Clue

by codingCat on Mon Jun 15, 2020 8:21 am

This helps a lot. It has sent me down the path to understanding some of how displayio works, and explains the text_area / label code that I have been seeing in a lot of the examples for the Clue.

I am still feeling a little clueless (it is hard to resist the puns) when it comes to loading and displaying bitmaps for sprites. Could you provide a small, commented, example that shows how to display a couple of sprites on the display?

codingCat
 
Posts: 5
Joined: Wed May 20, 2020 8:05 am

Re: Stage and Ugame on Clue

by kevinjwalters on Mon Jun 15, 2020 8:43 am

Here's some snippets for now. I'll put more effort and detail into a Guide that I'm working on that'll be out a in week or two:

This is loading a 48x16 bmp file which has 3 sprites in it and putting them into the sprite list.

Code: Select all | TOGGLE FULL SIZE
# Load horizontal sprite sheet if running with a display
if display is not None:
    import adafruit_imageload
    s_bit, s_pal = adafruit_imageload.load("rps-sprites-ind4.bmp",
                                           bitmap=displayio.Bitmap,
                                           palette=displayio.Palette)
    SPRITE_SIZE = s_bit.height
    num_sprites = s_bit.width // s_bit.height
    s_pal.make_transparent(0)  ### Make the first colour (black) transparent

    sprites = []
    for idx in range(num_sprites):
        sprite = displayio.TileGrid(s_bit, pixel_shader=s_pal,
                                    width=1, height=1,
                                    tile_width=SPRITE_SIZE, tile_height=SPRITE_SIZE)
        sprite[0] = idx
        sprites.append(sprite)


Then later they are used like this (code all works but may end up being tweaked/tidied a little) from function where display is passed in as disp:

Code: Select all | TOGGLE FULL SIZE
    FONT_WIDTH, FONT_HEIGHT = terminalio.FONT.get_bounding_box()

    if disp is not None:
        emptyGroup(main_display_group)  # this should already be empty
        intro_group = Group(max_size=5)
        welcometo_dob = Label(terminalio.FONT,
                              text="Welcome To",
                              scale=3,
                              color=IWELCOME_COL_FG)
        welcometo_dob.x = (DISPLAY_WIDTH - 10 * 3 * FONT_WIDTH) // 2
        # Y pos on screen looks lower than I would expect
        welcometo_dob.y = 3 * FONT_HEIGHT // 2
        intro_group.append(welcometo_dob)

        spacing = 3 * SPRITE_SIZE + 4
        for idx, sprite in enumerate(sprites):
            s_group = Group(scale=3, max_size=1)
            s_group.x = -96   
            s_group.y = (DISPLAY_HEIGHT - 3 * SPRITE_SIZE) // 2 + (idx - 1) * spacing
            s_group.append(sprite)
            intro_group.append(s_group)

        arena_dob = Label(terminalio.FONT,
                          text="Arena",
                          scale=3,
                          color=IWELCOME_COL_FG)
        arena_dob.x = (DISPLAY_WIDTH - 5 * 3 * FONT_WIDTH) // 2
        arena_dob.y = DISPLAY_HEIGHT - 3 * FONT_HEIGHT // 2
        intro_group.append(arena_dob)

        main_display_group = intro_group
        disp.show(main_display_group)


The -96 is placing them off screen as they are later moved in steps to 96 to animated them in a sliding motion onto the screen. I think these need to be ints btw so you'll need to round() or similar if you are working with float values.

The emptyGroup is only needed if you've used the sprite (TileGrid objects) in a previous Group. You won't need that initially. I'm not sure if it's the best approach here but you can see the code and the reasons for it discussed on displayio and Layer already in a group.

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Stage and Ugame on Clue

by kevinjwalters on Mon Jun 15, 2020 5:40 pm

As another example, there's some fairly straightforward displayio code with commentary in Adafruit Learn: CLUE Step Counter with ST LSM6DS33: CircuitPython Code Walkthrough

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Re: Stage and Ugame on Clue

by kevinjwalters on Mon Jul 13, 2020 1:13 pm

This might be of interest too. I wrote some more very simple label code (clue-label-test.py) to test out different versions of the Label. It's been evolving and it's now slower than it was and renders differently when background is used. CircuitPython Label test with three versions (YouTube) shows this and how Label / displayio and physical screen interact.

displayio here has more work to do with the CLUE's 240x240 screens than MakeCode Arcade at 160x120 but there are some clear limitations for change, movement and animation which will prescribe the type of games that can be written.

kevinjwalters
 
Posts: 960
Joined: Sun Oct 01, 2017 3:15 pm

Please be positive and constructive with your questions and comments.