simple game framework for scripting languages

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

simple game framework for scripting languages

#1 Post by technosaurus »

You can get free game resources (sprites, tilesets, sounds, backgrounds...) here:
http://funplosion.com/free-assets.html
http://stackoverflow.com/questions/143050/

Here is what I have so far:

Code: Select all

#include <sys/inotify.h>
#include <gtk/gtk.h>
#define IMAGE "svgame.svg"
void refresh(gpointer si, gint fd, GdkInputCondition c){
	char buffer[sizeof (struct inotify_event)];
	read( fd, buffer, sizeof(buffer) ); /* just clearing, don't care the type */
	gtk_image_set_from_file(si,IMAGE);} /* force redraw of image*/

int main(int argc, char *argv[]){
	int watch, fd;	GtkWidget *window, *image;
gtk_init (&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
fd = inotify_init();
image = gtk_image_new_from_file(IMAGE);
gtk_container_add(GTK_CONTAINER(window), image);
watch = inotify_add_watch( fd, IMAGE, IN_MODIFY ); /* more events? */
gdk_input_add( fd, GDK_INPUT_READ, refresh, image ); /* refresh on inotify */
g_signal_connect((gpointer) window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main ();}
Yes, it is intentionally sparse by design, just the minimum to allow a scripting language to do the rest.
TODO add a callback to printf key-presses and mouse-clicks (until then, control is decoupled)

EDIT: see my next post for the mouse/key actions

Just to give you an idea, you can do something like this:

Code: Select all

<svg width="640" height="480">
<image x="1" y="1" width="640" height="480"
     xlink:href="/usr/share/backgrounds/default.jpg" />
<image x="1" y="1" width="64" height="48"
     xlink:href="/usr/share/pixmaps/buddy.png" />
</svg>
and use your favorite scripting language to move your "sprite" (buddy) around on the background just by changing the x and y, for instance for a move right, the new code is:

Code: Select all

<svg width="640" height="480">
<image x="1" y="1" width="640" height="480"
     xlink:href="/usr/share/backgrounds/default.jpg" />
<image x="65" y="49" width="64" height="48"
     xlink:href="/usr/share/pixmaps/buddy.png" />
</svg>
types of games: matching, block pushing, maze, strategy,... probably a lot more, but then you also need to figure out the game logic (sold separately)

(oops I accidently created a webcam viewer - use ffmpeg to generate images of the same name defined by IMAGE)
(oops2 ... can do a slideshow also)
(oops3 ... and presentations via svg)
(oops4 ... someone on IRC also suggested using svg to build a nicer widget/toolkit)

Eventually this could be shifted to using libtinysvg and cairo-xcb?? for a multithread capable 2d toolkit.

P.S. If Thunor is reading this, it would be nice to have a autorefresh="true" flag on images in gtkdialog to do the same thing I am doing here. I could help come up with a patch, but this was just a quick proof of concept, no frills adaptation of my simple icon tray.
Attachments
svgame.tar.gz
Here is a precompiled version.that takes an input filename as 1st arg.
usage:
svgame /path/to/image.svg | your_controls
(2.19 KiB) Downloaded 584 times
Last edited by technosaurus on Thu 16 Aug 2012, 23:24, edited 3 times in total.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
vovchik
Posts: 1507
Joined: Tue 24 Oct 2006, 00:02
Location: Ukraine

#2 Post by vovchik »

Dear technosaurus,

Looks very clever and useful. Thanks....

With kind regards,
vovchik

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

#3 Post by seaside »

technosaurus,

Another great seed for expansion. They just keep coming.

Regards and thanks,
s
(Now if I could only think of some unusual game - perhaps one where you can cheat, but it doesn't appear that way :D )

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#4 Post by technosaurus »

Added key and mouse events - now you can pipe the output to a while read LINE; do case *)... stlye event handler

Code: Select all

#include <sys/inotify.h>
#include <gtk/gtk.h>
#define IMAGE "svgame.svg"

void key_press_event(GtkWidget *widget, GdkEventKey *event){
	g_print("KEY=%s\n",gdk_keyval_name(event->keyval));}
void button_press_event(GtkWidget *widget, GdkEventButton *event){
	g_print("BUTTON=%f,%f\n",event->x ,event->y);}
void refresh(gpointer si, gint fd, GdkInputCondition c){
	char buffer[sizeof (struct inotify_event)];
	read( fd, buffer, sizeof(buffer) ); /* just clearing, don't care the type */
	gtk_image_set_from_file(si,IMAGE);} /* force redraw of image*/

int main(int argc, char *argv[]){
	int watch, fd;	GtkWidget *window, *image, *eventbox;
gtk_init (&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
eventbox = gtk_event_box_new ();
gtk_container_add(GTK_CONTAINER(window), eventbox);
fd = inotify_init();
image = gtk_image_new_from_file(IMAGE);
gtk_container_add(GTK_CONTAINER(eventbox), image);
watch = inotify_add_watch( fd, IMAGE, IN_MODIFY ); /* more events? */
gdk_input_add( fd, GDK_INPUT_READ, refresh, image ); /* refresh on inotify */
g_signal_connect((gpointer)window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect((gpointer) window, "button_press_event", G_CALLBACK(button_press_event), NULL);
g_signal_connect ((gpointer) window, "key_press_event", G_CALLBACK (key_press_event), NULL);
gtk_widget_show_all(window);
gtk_main ();}
I am leaving the original code in case someone wants to keep it decoupled and use a terminal window for controls or something.

Anyone remember Adventures of Lolo? (a block pushing game like that may work well) ... assuming you are using bash or some other language with arrays you could build a grid of obstacles and use stock images in each grid (scenery) using a 2D array (strategy games would be similar, except you may need various extra dimensions )
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
vovchik
Posts: 1507
Joined: Tue 24 Oct 2006, 00:02
Location: Ukraine

#5 Post by vovchik »

Dear technosaurus,

Hats off! It is very good and interesting. I'll do a Bacon port, too. Simple and versatile. With move instructions in the svg, placement is easy. Thanks.

With kind regards,
vovchik

PS. Lately I have been using lib_rsvg so that I can keep the svg not on disk but in the script and use gdk_pixbuf to create the pixmap on the fly. I will experiment.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#6 Post by technosaurus »

I just made a patch for gtkdialog to autorefresh icons when the image file modified. So now you can use it instead if you would like more features. http://murga-linux.com/puppy/viewtopic. ... 004#647004
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

#7 Post by seaside »

technosaurus,

Started to play around with this and noticed that the background does not fill the window using the example.

Compiled in racy and I have two white bands as below.

Any ideas on how to fix?

Regards,
s
Attachments
game.png
Window background
(159.19 KiB) Downloaded 1137 times

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#8 Post by technosaurus »

In your background image use 100% for the width and height, but set the size of the svg image to fixed integers.(i am using 640x480 as the default size)
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

#9 Post by seaside »

technosaurus wrote:In your background image use 100% for the width and height, but set the size of the svg image to fixed integers.(i am using 640x480 as the default size)
technosaurus,

Thanks. I didn't realize my "/usr/share/backgrounds/default.jpg" was 1024 X 576 :D

All now works well..
regards,
s

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#10 Post by technosaurus »

here is some stuff to do some stuff ... though only about as good as this description

Code: Select all

#!/bin/ash
#use a 13x10 grid to draw a scene - very hacky
draw_svg(){
i=0
SVG='<svg width="640" height="480">
<image x="1" y="1" width="640" height="480" xlink:href="'$BACKGROUND'" />
'
while ([ $i -lt ${#1} ]) do
#replace with eval echo \${GRID:$i:1}
[ "${1:$i:1}" != " " ] && SVG=$SVG'	<image x="'$(($i % 13 * 48))'" y="'$(($i / 13 * 48))'" width="48" height="48" xlink:href="'`eval echo \$"${1:$i:1}"`'" />
'
i=$(($i+1))
done
echo "$SVG</svg>" >svgame.svg
}


BASEDIR="/usr/share/pixmaps"
BACKGROUND="/usr/share/backgrounds/default.jpg"

#faking a 12x9 2d array for bourne shells using a string and mod/div ops.
#each letter represents a 48x48 pixel square on a 640x480 grid
GRID=""
GRID="${GRID}             "
GRID="${GRID}             "
GRID="${GRID}             "
GRID="${GRID}             "
GRID="${GRID}      p      "
GRID="${GRID}          q  "
GRID="${GRID}             "
GRID="${GRID}             "
GRID="${GRID}             "
GRID="${GRID}             "
#Sprites and Tilesets
p="$BASEDIR/ayttm.png"
q="$BASEDIR/buddy.png"
draw_svg "${GRID}"
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

#11 Post by seaside »

technosaurus wrote:here is some stuff to do some stuff ...
technosaurus,

Sounds like a perfect description to me, and might even be a good candidate forum category itself :D

Thanks for this handy tool.

Regards,
s
(This is especially useful for me because I keep forgetting that x,y coordinates for drawing start in the upper left corner :? )

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#12 Post by technosaurus »

Looks like we can even use this for creating tray applets using the swallow tag.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

#13 Post by seaside »

technosaurus wrote:Looks like we can even use this for creating tray applets using the swallow tag.
technosaurus,

Just wondering what you had in mind? Would this be instead of or in addition to SIT.

Regards,
s

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#14 Post by technosaurus »

seaside wrote:
technosaurus wrote:Looks like we can even use this for creating tray applets using the swallow tag.
technosaurus,

Just wondering what you had in mind? Would this be instead of or in addition to SIT.

Regards
s
either, but also for goingnuts' gtkdialog1 to have "attached" controls (or use my patch for gtkdialog4)... Swallow can have non-square dimensions though
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

#15 Post by seaside »

technosaurus,

Thanks for the explanation for SIT and svgame.

I tried this-

Code: Select all

svgame  /root/svgame.svg  2>/dev/null  | \
while read LINE; do
case "$LINE" in
KEY=F3)  geany ;;
*) exit
;;
esac
done
The geany command did not run until after the image window was closed when detecting key F3. Is there a way to execute commands and keep the image window open?

Regards,
s

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

svg-placer

#16 Post by seaside »

Here's a GUI tool for technosaurus' svgame and 13x10 grid where you can try out images and text on each square. Just click in the upper left corner of any square where you want an image or text to start and then close the window. A dialog follows asking if you want an image, press enter and a fileselect dialog for the directory "/usr/share/pixmaps" opens. Press cancel and a text entry box opens. The program then rerenders the new svg. Repeat until done (sounds like a recipe :D )

Kind of a kludge because commands don't run inside the case statements until the window is closed. Best run in a terminal, since the program calls itself, you have to kill it to stop.

Cheers,
s

Code: Select all

 #!/bin/sh
# requires technosaurus' svgame
# svg-placer -click on location & close window
# run in terminal to kill

 if ! [ -f /tmp/svgame.svg ]; then 
echo '
<svg  width="640" height="480">
  <defs> 
    <pattern id="grid" width="48" height="48" patternUnits="userSpaceOnUse">
      <rect fill="white" stroke="black" x="0" y="0" width="48" height="48"/>
    </pattern>
  </defs>
  <rect fill="url(#grid)" stroke="black" x="0" y="0" width="640" height="480"/>
</svg>'  >/tmp/svgame.svg

fi

svgame  /tmp/svgame.svg  2>/dev/null  | \
while read LINE; do
case "$LINE" in
BUTTON*) 
LINE="${LINE//BUTTON=/}"
 x="${LINE%,*}" 
 y="${LINE##*,}" ;;
 *) exit 
;;
esac

Xdialog --title "Image or Text dialog" --stdout  --yesno "Is this an image file?" 0 0

case $? in
  0)
    FILE="`Xdialog --backtitle "Please choose Image." --title "Image selector" --stdout --no-buttons --fselect  /usr/share/pixmaps 0 0`"
	sed -i 's|</svg>||' /tmp/svgame.svg 
	
	echo '
	<image x="'$x'" y="'$y'" width="48" height="48"
	     xlink:href="'$FILE'" />
	</svg>' >>/tmp/svgame.svg ;;

  1)
	 TEXT="`Xdialog --backtitle "Please type text below" --title "Text Select" --stdout --no-wrap --inputbox "short text no wrap" 0 0`" 
	 sed -i 's|</svg>||' /tmp/svgame.svg 
	
	  echo ' 
	 <text x="'$x'" y="'$y'" 
	     style="font-size:20" fill="black"
	>'"$TEXT"'</text>
	</svg>' >>/tmp/svgame.svg ;;
   
  255)
       exit ;;
esac
done
$0 
Attachments
svg-placer.png
(17.9 KiB) Downloaded 735 times

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

Case statements

#17 Post by seaside »

technosaurus,

I just noticed that everything runs fine for the case statements in the 2nd version of the source code that included key and mouse events (but not /path/to/image) when I compiled it under Racy.

The other posting of svgame.tar.gz which was a compiled version, allowing a file to be passed on the command line, is the one that Racy is not handling the same way.

Would you be kind enough to post the source code for that compiled version
Description Here is a precompiled version.that takes an input filename as 1st arg.
usage:
svgame /path/to/image.svg | your_controls
I'd like to compile that in Racy and see if that cures the "case statements not being run problem"

Thanks,
s
(Can this be a gtk version level problem?)

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#18 Post by technosaurus »

formatting is scrunched, but here it is:

Code: Select all

#include <sys/inotify.h>
#include <gtk/gtk.h>
#include <string.h>
typedef struct _variable { char Name[ 512 ]; GtkWidget *Widget; } variable;
void key_press_event(GtkWidget *widget, GdkEventKey *event){printf("KEY=%s\n",gdk_keyval_name(event->keyval));}
void button_press_event(GtkWidget *widget, GdkEventButton *event){printf("BUTTON=%f,%f\n",event->x ,event->y);}
void refresh(gpointer data, gint fd, GdkInputCondition c){
char buffer[sizeof (struct inotify_event)];	variable *var; var = (variable *)data;
read( fd, buffer, sizeof(buffer) ); gtk_image_set_from_file(GTK_IMAGE(var->Widget),var->Name);}
int main(int argc, char **argv){ int watch, fd;	GtkWidget *window, *image, *eventbox; variable *var; var = g_malloc(sizeof(variable));
gtk_init (&argc, &argv); fd = inotify_init();
window = gtk_window_new(GTK_WINDOW_TOPLEVEL); eventbox = gtk_event_box_new (); image = gtk_image_new_from_file(argv[1]);
gtk_container_add(GTK_CONTAINER(window), eventbox); gtk_container_add(GTK_CONTAINER(eventbox), image);
watch = inotify_add_watch( fd, argv[1], IN_MODIFY ); var->Widget=image; strncpy(var->Name, argv[1], 512);
gdk_input_add( fd, GDK_INPUT_READ, refresh, (gpointer) var );
g_signal_connect((gpointer)window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect((gpointer) window, "button_press_event", G_CALLBACK(button_press_event), NULL);
g_signal_connect ((gpointer) window, "key_press_event", G_CALLBACK (key_press_event), NULL);
gtk_widget_show_all(window); gtk_main ();}
Note: need to replace printf with g_print and remove string.h
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

Racy5.3

#19 Post by seaside »

technosaurus,

Thank you very much for posting the source code. I compiled it in Racy5.3 and it works.

In case anyone else wants the Racy5.3 compiled version, I've attached it below.

Regards,
s
Attachments
svgame-r.tar.gz
Compiled in Racy-5.3 and named svgame-r
(2.21 KiB) Downloaded 433 times

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

svg-placer

#20 Post by seaside »

Here's a handier version of svg-placer that doesn't call itself, with the added ability to change text font size and color. Also, F3 brings up Inkscape.

Code: Select all

 #!/bin/sh
# requires technosaurus' svgame
# svg-placer -click on location 
# choose image or text
#F3 brings up inkscape

 if ! [ -f /tmp/svgame.svg ]; then 
echo '
<svg  width="640" height="480">
  <defs> 
    <pattern id="grid" width="48" height="48" patternUnits="userSpaceOnUse">
      <rect fill="white" stroke="black" x="0" y="0" width="48" height="48"/>
    </pattern>
  </defs>
  <rect fill="url(#grid)" stroke="black" x="0" y="0" width="640" height="480"/>
</svg>'  >/tmp/svgame.svg

fi

svgame  /tmp/svgame.svg  2>/dev/null  | \
while read LINE; do
case "$LINE" in
BUTTON*) 
	LINE="${LINE//BUTTON=/}"
	 x="${LINE%,*}" 
	 y="${LINE##*,}"
	 
	Xdialog --title "Image or Text dialog" --stdout  --yesno "Is this an image file?" 0 0
	
	case $? in
	  0)
	    FILE="`Xdialog --backtitle "Please choose Image." --title "Image selector" --stdout --no-buttons --fselect  /usr/share/pixmaps 0 0`"
		cp /tmp/svgame.svg /tmp/svgameNEW # need to copy else works once only
		
		sed -i 's|</svg>||' /tmp/svgameNEW 
	
		echo '
		<image x="'$x'" y="'$y'" width="48" height="48"
		     xlink:href="'$FILE'" />
		</svg>' >>/tmp/svgameNEW
		
		cp /tmp/svgameNEW /tmp/svgame.svg ;;
	
	
	  1)
		SEL=`Xdialog \
		        --title "Text Select" \
		         --stdout \
		        --3inputsbox  "Text Selector" 0 0 \
		            "Text to place" "" \
		            "Font Size" "20" \
		            "Color Name" "black"`
	
		cp /tmp/svgame.svg /tmp/svgameNEW # need to copy else works once only
		
		sed -i 's|</svg>||' /tmp/svgameNEW 
		 
		TEXT="${SEL%%/*}"
		n="${SEL#*/}"
		FONT="${n%/*}"
		COLOR="'"${SEL##*/}"'"
		
		  echo ' 
		 <text x="'$x'" y="'$y'" 
		     style="font-size:'"$FONT"'"  fill='"$COLOR"'
		>'"$TEXT"'</text>
		</svg>' >>/tmp/svgameNEW 
		
		cp /tmp/svgameNEW /tmp/svgame.svg ;;
	   
	  255)
	       exit ;;
	esac ;;
	
 KEY=F3) inkscapelite /tmp/svgame.svg ;;

*)  ;;

esac
done
Cheers,
s

Post Reply