Page 2 of 4

Posted: Fri 31 Aug 2012, 03:41
by technosaurus
Here is some portable collision detection code:

Code: Select all

#!/bin/ash
ALPHAS=" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
#alphas can represent tiles, sprites etc...
WIDTH=3
HEIGHT=3
GRID="   bbb   "
#so the grid looks like:
#   #
#bbb#
#   #
no_collision(){
	#x=$1 y=$2
	pos=${GRID:$(($1+$2*$HEIGHT)):1}
	retval=${ALPHAS%${pos}*}
	return ${#retval}
}
no_collision 1 1 || echo ${ALPHAS:$?:1}
basically collision detection would tell you if you are trying to place something where something else already exists... moving a character, placing a game piece etc...

Posted: Thu 06 Dec 2012, 03:28
by jamesbond
The code on the first post doesn't work for me (and thus by extension all the other newer revisions because the part that doesn't work is the same for all revisions).

This part:

Code: Select all

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*/
only works once because if the file is deleted and re-created, the watch is lost after the first trigger.

The fix that works for me:

Code: Select all

void refresh(gpointer si, gint fd, GdkInputCondition c) {
	char buffer[sizeof (struct inotify_event)];
	gtk_image_set_from_file(si,IMAGE);  /* force redraw of image*/
		
	read( fd, buffer, sizeof(buffer) ); /* just clearing, don't care the type */
	inotify_rm_watch(fd, watch);
	watch = inotify_add_watch( fd, IMAGE, IN_MODIFY ); /* re-trigger watch in case file is deleted / recreated */
} 

Posted: Thu 06 Dec 2012, 05:32
by technosaurus
That's why none of my examples deleted the file, only modified them by ln/cp/mv -f or echo > my.svg

I had tried something similar, but gtk would sometimes hiccup on remove/replace (depending on timing) ... there are events for delete (and create in watched directory) too. Watching the directory may be a better idea anyhow - would allow you to redraw the svg if one of the include images changes (for instance a character uses a weapon while standing still)

I may try testing it with the file watch mechanism that I started using in sit (basically so it works on win32 and mac as well)

Posted: Thu 06 Dec 2012, 10:56
by jamesbond
technosaurus wrote:That's why none of my examples deleted the file, only modified them by ln/cp/mv -f or echo > my.svg
I wasn't trying to do anything fancy. I was doing a rox-clock http://murga-linux.com/puppy/viewtopic.php?t=82734 and it dawned upon me that svgame would be an excellent platform for it. I used sed -i to update the svg, and it only worked the first time. Only upon strace-ing sed -i, I realised that it worked by creating a new file, and moving that file over the old one ... As it happens geany also works this way.
I had tried something similar, but gtk would sometimes hiccup on remove/replace (depending on timing) ... there are events for delete (and create in watched directory) too. Watching the directory may be a better idea anyhow - would allow you to redraw the svg if one of the include images changes (for instance a character uses a weapon while standing still)
Yes, but the problem with watching a directory is that you'll get notified for anything that happens in the directory. If you only need to watch a specific file then you will have to filter these events.
I may try testing it with the file watch mechanism that I started using in sit (basically so it works on win32 and mac as well)
I thought you're using the same mechanism there?

Posted: Thu 06 Dec 2012, 19:59
by technosaurus
lets say your svg file is mygame/mygame.svg and you are watching the directory mygame. if a file is modified or created in that directory you simply redraw mygame.svg (not caring what file it is - it could be an included sub-image)

for sit I made a win32 version, meaning I couldn't use the linux specific inotify, so I used a glib/gio wrapper pseudo-equivalent

rather than using sed, you could probably just store the strings in variables and echo > them for redraws (it will be faster anyways)

Posted: Fri 07 Dec 2012, 00:44
by seaside
technosaurus wrote:
rather than using sed, you could probably just store the strings in variables and echo > them for redraws (it will be faster anyways)
jamesbond,

Not only works with svgame but on your very nicely done rox-clock as well -

Code: Select all

j#!/bin/sh
# Copyright (C) jamesbond 2012
# License: GNU GPL Version 3 or later
#
# called by AppRun
#exec 2> /tmp/log-clock
APPDIR=${0%/*}

update_clock() {
	# date
	sed -i -e "s/ary>.*</ary>$(date +"%A %e %B %Y")</" \
${APPDIR}/AppInfo.xml
	
	# time
	time=$(date +%I-%M)
	hour=${time%-*} 
	minute=${time#*-}
	hour=${hour#0}	
	minute=${minute#0}

	HROTATE=$(( $hour*30 + $minute/2 ))
	MROTATE=$(( $minute*6 ))
	#echo $hour_rot $min_rot
	
	echo '<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     viewBox="-1024 -1024 2048 2048" width="600" height="600">
  <title>Swiss Railway Clock</title>
  <style type="text/css">
    .bg {stroke: none; fill: white;}
    .fc {stroke: none; fill: black;}
    .h1 {stroke: none; fill: black;}
    .h2 {stroke: none; fill: #aa0000;}
  </style>
  <defs>
    <path id="mark1" d="M -20,-1000 l 40,0 0,100 -40,0 z" />
    <path id="mark2" d="M -40,-1000 l 80,0 0,240 -80,0 z" />
    <path id="mark3" d="M -40,-1000 l 80,0 0,300 -80,0 z" />
    <path id="handh" d="M -50,-600  l 50,-50 50,50 0,800  -100,0 z" />
    <path id="handm" d="M -40,-900  l 40,-40 40,40 0,1180 -80,0  z" />
    <g    id="hands">
      <path d="M -10,-910 l  10,-10 10,10 2,300 -24,0 z
               M -13,-390 l  26,0         7,690 -40,0 z" />
      <path d="M   0,-620 a 120,120 0 0 1 0,240
                          a 120,120 0 0 1 0,-240 z
               M   0,-560 a  60,60  0 0 0 0,120
                          a  60,60  0 0 0 0,-120 z" />
    </g>
    <g id="face1">
      <use xlink:href="#mark1" transform="rotate(06)" />
      <use xlink:href="#mark1" transform="rotate(12)" />
      <use xlink:href="#mark1" transform="rotate(18)" />
      <use xlink:href="#mark1" transform="rotate(24)" />
    </g>
    <g id="face2">
      <use xlink:href="#face1" />
      <use xlink:href="#face1" transform="rotate(30)" />
      <use xlink:href="#face1" transform="rotate(60)" />
      <use xlink:href="#mark3" />
      <use xlink:href="#mark2" transform="rotate(30)" />
      <use xlink:href="#mark2" transform="rotate(60)" />
    </g>
    <g id="face">
      <use xlink:href="#face2" />
      <use xlink:href="#face2" transform="rotate(90)"  />
      <use xlink:href="#face2" transform="rotate(180)" />
      <use xlink:href="#face2" transform="rotate(270)" />
    </g>
  </defs>
  <circle class="bg" r="1024" />
  <use xlink:href="#face"  class="fc" />
  <use xlink:href="#handh" class="h1" transform="rotate('"$HROTATE"')" />
  <use xlink:href="#handm" class="h1" transform="rotate('"$MROTATE"')" />
  <!-- <use xlink:href="#hands" class="h2" transform="rotate(168)" /> -->
</svg> ' > ${APPDIR}/clock.svg	
	
	#sed -i -e "
#/\#handh/ s/rotate(.*)/rotate($hour_rot)/
#/\#handm/ s/rotate(.*)/rotate($min_rot)/
#" ${APPDIR}/clock.svg
	rox -x ${APPDIR}	
}

# 1. initial update
update_clock

# 2. sync to the start of the minute
while [ $(date +"%S") -ne 0 ]; do sleep 1; done 

# 3. run the clock proper
while true; do
	update_clock
	sleep 60
done 
Cheers,
s

Posted: Fri 07 Dec 2012, 23:25
by jamesbond
technosaurus, seaside,

Thanks for the info :)

cheers!

Posted: Sun 23 Dec 2012, 21:36
by technosaurus
Todo: example of output mouse position on click

Maybe a dialog button.

Posted: Mon 24 Dec 2012, 03:37
by linuph
I call this script 'control':
<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>
With 'svgame | control' I get an error:
./control: line 1: syntax error near unexpected token 'newline'
./control: line 1: '<svg width="300" height="300">'

The web is full with questions about this but I can't find a solution. Has it to to with line endings? Geany shows 'LF'. What should this script be? Just a script, or .xml or with #!/bin/sh in the top line.

A lot to learn here...

Posted: Mon 24 Dec 2012, 04:04
by linuph
Double post

Posted: Mon 24 Dec 2012, 05:38
by technosaurus
It's an svg image. Scripts begin with #!/bin/something and need to have the executable bit set.

Posted: Mon 24 Dec 2012, 06:53
by linuph
Using #!/bin/sh now, but the 'newline' error remains. Same in #!/bin/ash, if that means anything. I understand that '<' has special meaning in Bash, reason for the error. What could be the problem?

Posted: Mon 24 Dec 2012, 14:01
by Keef
I'm just guessing here, but after looking at other examples on the page, is your code sequence quoted properly?
eg

Code: Select all

 echo ' < blah blah> '

Posted: Tue 25 Dec 2012, 00:39
by linuph
Thanks Keef. Being not quoted was the problem. I had a thorough misunderstanding of how the svgame program works. Solved.

Posted: Mon 31 Dec 2012, 19:43
by technosaurus
to further confuse everyone new to this topic, here is my latest research results for svg and "sprites"... I found it easier to include a second svg rather than the more complicated method of filling a rectangle with a pattern from an image (it may be slower to render but I couldn't figure out a good way to slice the png sprites for fill patterns)

Code: Select all

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="354" viewBox="0 176 256 176">

<image xlink:href="zelda-map.png" height="1408" width="4096" />

<svg x="32" y="240" width="16" height="16" viewBox="0 0 16 16">
<image xlink:href="link.png" width="432" height="303" />
</svg>

</svg>
Note: the <image> width and height are the total width and height of the image whereas the <svg> width and height are the displayed width and height
Note2: the viewbox is xoffset yoffset width height of the image "slice"
Note3: the link.png image has an x and y attribute that are relative to the actual image size from the parent viewbox (0 and 176 in this case) ... thus the image will be scaled to 32x32 since the parent is scaled 2x2 (width='512' height='354' with viewport width of 256 and 176 ... such that the main width and height can be set to 100% for full scale rendering without having to calculate the values for all of the sprites)

Posted: Tue 01 Jan 2013, 20:11
by seaside
technosaurus wrote:to further confuse everyone new to this topic, here is my latest research results for svg and "sprites"... I found it easier to include a second svg rather than the more complicated method of filling a rectangle with a pattern from an image (it may be slower to render but I couldn't figure out a good way to slice the png sprites for fill patterns)
technosaurus,

Thanks for your latest which will take me some time to digest :D

Do you have by any chance, a small game you could show using this technique?

Your experimentation with this stuff is always fascinating.

Happy New Year,
s

Posted: Wed 02 Jan 2013, 01:47
by technosaurus
seaside wrote:Do you have by any chance, a small game you could show using this technique?
Not that I would be comfortable publishing due to copyrights (as the last example shows, I have been just using existing tilesets, maps and sprites for experimenting, but more than that would fall outside of "fair use"). I would like to make a block pushing puzzle game along the lines of Adventures of Lolo, an RPG reminiscent of Final Fantasy (the original NES version), an adventure game similar to Zelda or possibly a strategy game like Civilizations, Warcraft or Sim City. These top view 2D (or 2.5D) games were always the most fun (for me at least), perhaps because less resources were spent developing the game engine and graphics and more effort was put into developing the game play?

There are several free tile and sprite sets available, but at the time I looked at them, I didn't have a good way of slicing the sprites/tiles. I would actually recommend using the tilesets to pre-generate the map from some type of array though, so that static tiles don't need to be separately parsed and rendered during game play... the array could still be used during gameplay for collision detection etc... Imagine how slow the Zelda example could be if all of the tiles for the large map had to be rendered as separate svg images. Only rendering the changeable objects in the currently visible screen rather than the whole map also helps for the Zelda case, but for some game types the off screen actions are important (real time strategy games for example)

Edit: I've also considered a method of implementing some type of gravity physics for side scrollers. The simplest I can come up with is to set a time it takes to fall 1 grid section and divide it by 4 for each additional section it falls until it gets to some minimum (terminal velocity)... That would open up a few extra genres.

Posted: Wed 09 Jan 2013, 21:13
by technosaurus
If anyone would like to do a side scroller, this is a good reference:
http://www.khanacademy.org/cs/jumpgirl/939844470

It is written in javascript, but the concepts are pretty similar.

Posted: Sat 12 Jan 2013, 15:02
by linuph
@technosaurus

A bit off topic...

I have mutilated your original C script just to enable a windowless svg image. I don't need a watch (inotify) or anything else, except that it is there in the background until my program decides to kill it. I run it from BASH with 'runbgrpic3' (after compilation) and kill it by killing its pidof.

The script is attached. It works but there's needless code in it, I suppose. Since I'm a total noob in C/GTK, I don't know how to optimize it. Not that it is a problem, but I don't like stupid code.

Can you advise?

Code: Select all

#include <gtk/gtk.h> 
#define IMAGE "GPSr2-bgr3.svg"

int main(int argc, char *argv[]){ 
	int watch,fd; GtkWidget *window, *image;
gtk_init (&argc, &argv); 
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/* leave out window decoration */
gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
image = gtk_image_new_from_file(IMAGE); 
gtk_container_add(GTK_CONTAINER(window), image); 
gtk_widget_show_all(window); 
gtk_main ();}

Posted: Sun 13 Jan 2013, 17:56
by seaside
linuph wrote:@technosaurus

The script is attached. It works but there's needless code in it, I suppose. Since I'm a total noob in C/GTK, I don't know how to optimize it. Not that it is a problem, but I don't like stupid code.
linuph,

As far as I can see the only item you could eliminate is the line

Code: Select all

int watch,fd;
since you don't need it.

Everything else seems to me to be the minimum necessary to show your image.

Cheers,
s