Bob example

This example shows how to use graphic objects.

Compilation

Easiest way to get this example running is to go to examples directory in package root, and run:

$ ./build.sh gui_bobs

build.sh script compiles Ano script to C, copies source files in place and pops up instructions what to do next. Follow them. Check also examples/README for more info.

Preview

; ------------------------------------------------------------------------------
; gui_bobs.ano
;
; To compile:
;
; $ ./build/ano ./examples/gui_bobs/gui_bobs.ano > \
;     engine/dsl_ano.h
; ------------------------------------------------------------------------------
;
@ANO_SCRIPT_NAME		gui_bobs
@ANO_SCRIPT_VERSION		0.0.6
@ANO_SCRIPT_DESCRIPTION	Example how to draw some bobs to window
;
@ANO_FLAGS_USE_PROTOS		[ ]
@ANO_FLAGS_VAR_NAME_SUBS	[ ]
@ANO_FLAGS_VAR_WARN_UNUSED	[ ]
;
; List of files to unveil if unveil() support is in use:
;
@ANO_UNVEIL_FILES		"examples/datafiles/bob_background.bob = r", \
;				"examples/datafiles/bob_test.bob = r"
;
; Copyright © 2016-2026, Jani Salonen <salojan@goto10.co>
; All rights reserved.
;

main {
	; Global uninitialized variables.
	;
	var	[handle] hnd_wnd
	var	[handle] hnd_container
	var	[handle] hnd_file
	var	[handle] hnd_bcg
	var	[handle] hnd_bob

	; Global initialized variables.
	;
	mov	x (1)
	mov	y (1)
	mov	dx (4.5)
	mov	dy (0.1)
	mov	gravity (0.2)
	mov	resistance (0.99999)

	bob_enabled {
		; Initialize windowing system…
		;
		window_init

		; …and open main window.
		;
		window_open (\
			title_name:		"Fun with bobs", \
			title_charset:		NULL, \
			flags:			0, \
			parent_handle:		NOPARENT, \
			widget_stack_id:	NOWIDGET, \
			widget_set:		NOWIDGET, \
			window_refresh_divider:	ACTIVE_REFRESH, \
			position_x:		POS_CENTERED, \
			position_y:		POS_CENTERED, \
			size_width:		640, \
			size_height:		480, \
			cb_main_loop:		"cb_mainloop", \
			cb_expose:		NULL, \
			cb_key_press:		NULL, \
			cb_key_release:		NULL, \
			cb_button_press:	NULL, \
			cb_button_release:	NULL, \
			cb_client_message:	NULL, \
			cb_save_yourself:	NULL, \
			cb_configure_notify:	NULL, \
			cb_destroy_notify:	"cb_destroy", \
			cb_motion_notify:	NULL, \
			cb_map_notify:		NULL, \
			cb_unmap_notify:	NULL, \
			cb_open_notify:		"cb_open")
	}
}

callback cb_open (_hnd) {
	; Create one bob container, for background and one bob.
	;
	hnd_container = bob_create_container (\
		handle: _hnd, \
		depth: 0)

	if hnd_container == INVALID : cb_destroy

	; Create background.
	;
	_hnd_file = bob_init_file (\
		name: "examples/datafiles/bob_background.bob")

	if _hnd_file == INVALID : cb_destroy

	hnd_bcg = bob_create_background (\
		file: _hnd_file, \
		container: hnd_container, \
		opaque: 1, \
		depth: -1)

	if hnd_bcg == INVALID : cb_destroy

	; Background is now ready to use and image can be freed.
	;
	bob_free_file (\
		file: _hnd_file)

	; Create bob to go with the background.
	;
	hnd_file = bob_init_file (\
		name: "examples/datafiles/bob_test.bob")

	if hnd_file == INVALID : cb_destroy

	hnd_bob = bob_create(\
		file: hnd_file, \
		container: hnd_container, \
		altitude: 0, \
		x: 640, \
		y: 480, \
		depth: 0)

	if hnd_bob == INVALID : cb_destroy

	bob_set_playdirection (\
		container: hnd_container, \
		bob: hnd_bob, \
		playdirection: PLAY_DIRECTION_FORWARD)

	bob_set_playmode (\
		container: hnd_container, \
		bob: hnd_bob, \
		playmode: PLAY_MODE_LOOP)

	bob_set_playskip (\
		container: hnd_container, \
		bob: hnd_bob, \
		playskip: 0)

	bob_set_playspeed (\
		container: hnd_container, \
		bob: hnd_bob, \
		playspeed: 0.25)

	; Map background and bob to display them.
	;
	bob_set_map (\
		container: hnd_container, \
		bob: hnd_bcg, \
		map: MAPPED_VISIBLE)

	bob_set_map (\
		container: hnd_container, \
		bob: hnd_bob, \
		map: MAPPED_VISIBLE)

	; Map main window.
	;
	_hnd.map()
}

callback cb_destroy (_hnd) {
	; Free bobs, bob files and the container.
	;
	bob_delete (\
		container: hnd_container, \
		bob: hnd_bob)

	bob_delete (\
		container: hnd_container, \
		bob: hnd_bcg)

	bob_free_file (\
		file: hnd_file)

	bob_delete_container (\
		container: hnd_container)

	_hnd.destroy()

	exit
}

callback cb_mainloop (_hnd) {
	; Bounce the bob.
	;
	mul	dx (resistance)
	add	dy (gravity)
	mul	dy (resistance)

	add	x (dx)
	add	y (dy)

	if x >= 1 : no_a

	neg	dx
no_a:
	if x < 600 : no_b

	neg	dx
no_b:
	if y >= 1 : no_c

	neg	dy
no_c:
	if y < 440 : no_d

	neg	dy
no_d:
	bob_set_position (\
		container: hnd_container, \
		bob: hnd_bob, \
		x: x, \
		y: y)
}
; ------------------------------------------------------------------------------
; gui_bobs.w2c
;
; To compile:
;
; $ ./build/widget ./examples/gui_bobs/gui_bobs.w2c > \
;     engine/widget_defs.h
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; gui_bobs.m2c
;
; To compile:
;
; $ ./build/menu ./examples/gui_bobs/gui_bobs.m2c > \
;     engine/menu_defs.h
; ------------------------------------------------------------------------------

Copyright © 2026, Jani Salonen <salojan at goto10 piste co>. Piste is finnish word and means dot. All rights reserved.