Snake game inside a single PowerBuilder DataWindow

Ramón San Félix Ramón
CODE AUTHOR
Posts: 43
 3 days 15 hours ago #646 by Ramón San Félix Ramón
Ramón San Félix Ramón created the code: Snake game inside a single PowerBuilder DataWindow

Hi everyone,

  I wanted to share a small weekend experiment: a fully playable Snake game where the entire playfield is a single DataWindow,
  with no external graphics, no images, and no third-party controls. This project was developed by Claude Code following my
  ideas and direction.

  The idea came from a Minesweeper clone I built a while ago using the same approach — dynamically generating shapes inside a
  DataWindow detail band via Modify() — and I wanted to see how far that technique could be pushed for something that needs to
  redraw several times per second.

  First version

  - A DataWindow object (dw_snake) with a single detail band as a black canvas.
  - A 31×21 logical grid stored in the window as two long arrays for the snake body coordinates plus an integer for the
  direction.
  - The window Timer event fires every 0.12s, computes the new head, handles wall wrap-around, self-collision and food.
  - wf_render() rebuilt the visible state by issuing dw_1.Modify("destroy rect_N") for every segment and then
  dw_1.Modify('create rectangle ...') to recreate them on each tick.
  - Keyboard handled in the window's Key event, with a guard against 180° reversals.

  It worked, but redrawing the whole snake by destroying and recreating every rectangle on each tick caused visible flicker and
  was wasteful.

  Borrowing from "Three Simple Games"

  I then found René Ullrich's Three Simple Games on Appeon CodeExchange
  (https://community.appeon.com/codeexchange/powerbuilder/114-three-simple-games), which contains another DataWindow-based
  Snake. His implementation is much smarter than mine in one key area: instead of destroying and recreating rectangles per tick,
   the cells are created once and their visibility/color is bound to a DataWindow expression that reads from a string column.

  I refactored my version to adopt that idea:

  - The DataWindow now has one row per game row, with a single char(40) column called cells. Each character encodes the state of
   one cell: 0 = empty, 1 = body, 2 = head, 9 = food.
  - At window open, wf_init_grid() creates once 31 rectangles cell_1..cell_31 in the detail band with expressions:
    - visible="0~tIf(long(mid(cells,N,1))>0,1,0)"
    - brush.color="65280~tCASE(long(mid(cells,N,1)) WHEN 2 THEN 65535 WHEN 9 THEN 255 ELSE 65280)"
  - Each tick now only issues 2-3 SetItem calls (new head, old head → body, old tail → empty). No Modify() per frame, no
  flicker.
  - I also added a small ib_intimer reentrancy guard, also inspired by his code, to avoid the timer event running into itself.

  Source

  Two files only — w_snake.srw and dw_snake.srd, around 280 lines total. PowerBuilder 2025 (release 25). Happy to share the
  source if anyone is interested, and big thanks to René for the elegant cell-binding trick — that one idea turned the project
  from a curiosity into something that actually feels smooth.

Stay Connected!

To be aware of what I publish you can follow my blog in Spanish:
rsrsystem.blogspot.com

Follow for more PowerBuilder tips, tricks, and modern integrations! 

This message has an attachment file.
Please log in or register to see it.

Please Log in or Create an account to join the conversation.