跳转到内容

Ring/教程/使用 RingAllegro 进行图形和 2D 游戏编程

来自维基教科书,开放世界中的开放书籍

使用 RingAllegro 进行图形和 2D 游戏编程

[编辑 | 编辑源代码]

在本章中,我们将学习如何在我们的 Ring 应用程序中使用 allegro 游戏编程库。

我们有 gamelib.ring 文件,它加载包含 Allegro 函数包装器的 DLL 库。

	Load "allegro.rh"
	Loadlib("ring_allegro.dll")

gamelib.ring 文件使用 Load 指令执行 allegro.rh 文件,该文件是包含要在我们的程序中使用的常量的 Ring 源代码文件。然后使用 LoadLib() 函数,我们可以加载 DLL 库 "ring_allegro.dll"。

为了编写可移植的代码,我们可以更改 gamelib.ring 以在加载 DLL/So 文件之前检查平台。



绘图、动画和输入

[编辑 | 编辑源代码]

下面的示例使用 Allegro 库来绘制、在屏幕上移动对象以及从键盘和鼠标获取输入。

	Load "gamelib.ring"

	al_init()
	al_init_image_addon()

	display = al_create_display(640,480)

	al_show_native_message_box(display, "Hello", "Welcome",
				"Using Allegro from the Ring programming language", 
				"", 0);

	al_clear_to_color(al_map_rgb(0,0,255))

	BOUNCER_SIZE = 40
	bouncer_x = 10
	bouncer_y = 20
	bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE)
	al_set_target_bitmap(bouncer)
	al_clear_to_color(al_map_rgb(255,0,255))

	for x = 1 to 30
		bouncer_x += x 
		bouncer_y += x
		al_set_target_bitmap(al_get_backbuffer(display))
		al_clear_to_color(al_map_rgb(0,0,0))
		al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0)
		al_draw_bitmap(bouncer, 200+bouncer_x,200+ bouncer_y, 0)
		al_flip_display()
		al_rest(0.1)
	next

	al_clear_to_color(al_map_rgb(255,255,255))
	image = al_load_bitmap("man2.jpg")
	al_draw_bitmap(image,200,200,0)
	al_flip_display()
	al_rest(2)

	event_queue = al_create_event_queue()
	al_register_event_source(event_queue, al_get_display_event_source(display))

	ev = al_new_allegro_event()
	timeout = al_new_allegro_timeout()
	al_init_timeout(timeout, 0.06)

	FPS = 60
	timer = al_create_timer(1.0 / FPS)
	al_register_event_source(event_queue, al_get_timer_event_source(timer))
	al_start_timer(timer)
	redraw = true

	SCREEN_W = 640
	SCREEN_H = 480
	BOUNCER_SIZE = 32
	bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0
	bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0
	bouncer_dx = -4.0
	bouncer_dy = 4.0

	al_install_mouse()
	al_register_event_source(event_queue, al_get_mouse_event_source())

	al_install_keyboard()
	al_register_event_source(event_queue, al_get_keyboard_event_source())

	KEY_UP = 1
	KEY_DOWN = 2
	KEY_LEFT = 3
	KEY_RIGHT = 4
	Key = [false,false,false,false]

	while true
		al_wait_for_event_until(event_queue, ev, timeout)
		switch al_get_allegro_event_type(ev)
		on ALLEGRO_EVENT_DISPLAY_CLOSE
			exit
		on ALLEGRO_EVENT_TIMER
			
			# Animation
			if bouncer_x < 0 or bouncer_x > SCREEN_W - BOUNCER_SIZE
				bouncer_dx = -bouncer_dx
			ok
	 
			if bouncer_y < 0 or bouncer_y > SCREEN_H - BOUNCER_SIZE
				bouncer_dy = -bouncer_dy
			ok
	 
			bouncer_x += bouncer_dx
			bouncer_y += bouncer_dy
			
			# Keyboard
			if key[KEY_UP] and bouncer_y >= 4.0
				bouncer_y -= 4.0
			ok 
			if key[KEY_DOWN] and bouncer_y <= SCREEN_H - BOUNCER_SIZE - 4.0
				bouncer_y += 4.0
			ok 
			if key[KEY_LEFT] and bouncer_x >= 4.0
				bouncer_x -= 4.0
			ok 
			if key[KEY_RIGHT] and bouncer_x <= SCREEN_W - BOUNCER_SIZE - 4.0
				bouncer_x += 4.0
			ok
	 
			redraw = true
			
		on ALLEGRO_EVENT_MOUSE_AXES
			bouncer_x = al_get_allegro_event_mouse_x(ev)
			bouncer_y = al_get_allegro_event_mouse_y(ev)
		on ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY
			bouncer_x = al_get_allegro_event_mouse_x(ev)
			bouncer_y = al_get_allegro_event_mouse_y(ev)
		on ALLEGRO_EVENT_MOUSE_BUTTON_UP
			exit
		on ALLEGRO_EVENT_KEY_DOWN
			switch al_get_allegro_event_keyboard_keycode(ev)
				on ALLEGRO_KEY_UP
					key[KEY_UP] = true
				on ALLEGRO_KEY_DOWN
					key[KEY_DOWN] = true
				on ALLEGRO_KEY_LEFT
					key[KEY_LEFT] = true
				on ALLEGRO_KEY_RIGHT
					key[KEY_RIGHT] = true
			off
		on ALLEGRO_EVENT_KEY_UP
			switch al_get_allegro_event_keyboard_keycode(ev)
				on ALLEGRO_KEY_UP
					key[KEY_UP] = false
				on ALLEGRO_KEY_DOWN
					key[KEY_DOWN] = false
				on ALLEGRO_KEY_LEFT
					key[KEY_LEFT] = false
				on ALLEGRO_KEY_RIGHT
					key[KEY_RIGHT] = false
				on ALLEGRO_KEY_ESCAPE
					exit
			off
		off
		if redraw and al_is_event_queue_empty(event_queue)
			redraw = false		
			al_clear_to_color(al_map_rgb(0,0,0))
			al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0)
			al_flip_display()
		ok
		callgc()
	end

	al_destroy_timer(timer)
	al_destroy_allegro_event(ev)
	al_destroy_allegro_timeout(timeout)
	al_destroy_event_queue(event_queue)
	al_destroy_bitmap(bouncer)
	al_destroy_bitmap(image)
	al_destroy_display(display)


.. 注意:在前面的示例中,我们使用了函数 callgc(),它是 Ring 函数,用于强制在 While/End 循环内调用垃圾收集器。

程序输出

首先,程序显示一个消息框

然后,我们看到两个矩形在屏幕上移动

然后,我们看到一个图像显示在屏幕上

最后,我们有一个矩形,我们看到它一直在屏幕上移动,但我们可以使用鼠标和/或键盘控制它

使用 TrueType 字体

[编辑 | 编辑源代码]

在本示例中,我们将看到如何在我们的游戏中使用 TrueType 字体 *.ttf。

	Load "gamelib.ring"

	al_init()
	al_init_font_addon()
	al_init_ttf_addon()

	display = al_create_display(800,600)

	al_clear_to_color(al_map_rgb(0,0,255))
	font = al_load_ttf_font("pirulen.ttf",14,0 )
	al_draw_text(font, al_map_rgb(255,255,255), 10, 10,ALLEGRO_ALIGN_LEFT,
		 "Welcome to the Ring programming language")
	al_flip_display()
	al_rest(2)

	al_destroy_display(display)

屏幕截图

播放声音文件

[编辑 | 编辑源代码]

下面的示例播放一个声音文件

	Load "gamelib.ring"

	al_init()
	al_install_audio()
	al_init_acodec_addon()
	al_reserve_samples(1) 

	sample = al_load_sample( "footstep.wav" )

	sampleid = al_new_allegro_sample_id()
	al_play_sample(sample, 1.0, 0.0,1.0,ALLEGRO_PLAYMODE_LOOP,sampleid)

	display = al_create_display(640,480)
	al_clear_to_color(al_map_rgb(0,0,255))
	al_flip_display()
	al_rest(10)

	al_destroy_allegro_sample_id(sampleid)
	al_destroy_sample(sample)
	al_destroy_display(display)

	al_exit()



缩放和旋转图像

[编辑 | 编辑源代码]

下面的示例显示并旋转一个图像

	Load "gamelib.ring"

	al_init()
	al_init_image_addon()

	display = al_create_display(640,480)
	al_set_target_bitmap(al_get_backbuffer(display))
	al_clear_to_color(al_map_rgb(255,255,255))

	image = al_load_bitmap("man2.jpg")
	al_draw_rotated_bitmap(image,0,0,250,250,150,0)
	al_draw_scaled_bitmap(image,0,0,250,250,20,20,400,400,0)

	al_flip_display()
	al_rest(2)

	al_destroy_bitmap(image)
	al_destroy_display(display)

屏幕截图

显示透明图像

[编辑 | 编辑源代码]

下面的示例在另一个图像上显示具有白色背景的图像

	Load "gamelib.ring"

	al_init()
	al_init_image_addon()

	display = al_create_display(640,480)	
	imageback = al_load_bitmap("palace.jpg")
	al_draw_bitmap(imageback,0,0,0)

	image = al_load_bitmap("man4.png")
	al_convert_mask_to_alpha(image,al_map_rgb(255,255,255))
	al_draw_bitmap(image,0,0,0)
	al_flip_display()
	al_rest(10)

	al_destroy_bitmap(image)
	al_destroy_display(display)

屏幕截图

使用线程

[编辑 | 编辑源代码]

在本示例中,我们将学习如何使用 Allegro 库中的用户线程

	Load "gamelib.ring"

	o1 = new mythreads 

	Func Main
		al_init()
		for k = 1 to 5
			al_create_thread("o1.thread1()")
			al_create_thread("o1.thread2()")
			al_create_thread("o1.thread3()")
		next
		al_rest(2)

	Class Mythreads

		cAppName = "Threads Application"

		Func Thread1
			for x = 1 to 5
				see x + nl	
			next
			See 'Thread(1) : Application Name : '  + cAppName + nl

		Func Thread2
			for x = 1 to 5
				see '*****' + x + nl	
			next
			See 'Thread(2) : Application Name : '  + cAppName + nl

		Func Thread3
			for x = 1 to 5
				see '!!!!' + x + nl	
			next
			See 'Thread(3) : Application Name : '  + cAppName + nl

输出

	1
	2
	3
	4
	5
	Thread(1) : Application Name : Threads Application
	*****1
	*****2
	*****3
	*****4
	*****5
	Thread(2) : Application Name : Threads Application
	!!!!1
	!!!!2
	!!!!3
	!!!!4
	!!!!5
	Thread(3) : Application Name : Threads Application
	1
	2
	3
	4
	5
	Thread(1) : Application Name : Threads Application
	!!!!1
	!!!!2
	!!!!3
	!!!!4
	!!!!5
	Thread(3) : Application Name : Threads Application
	*****1
	*****2
	*****3
	*****4
	*****5
	Thread(2) : Application Name : Threads Application
	*****1
	*****2
	*****3
	*****4
	*****5
	Thread(2) : Application Name : Threads Application
	!!!!1
	!!!!2
	!!!!3
	!!!!4
	!!!!5
	Thread(3) : Application Name : Threads Application
	1
	2
	3
	4
	5
	Thread(1) : Application Name : Threads Application
	*****1
	*****2
	*****3
	*****1
	*****4
	*****2
	!!!!1
	*****5
	*****3
	1
	!!!!2
	Thread(2) : Application Name : Threads Application
	1
	*****4
	!!!!1
	2
	!!!!3
	!!!!4
	*****5
	!!!!2
	3
	2
	!!!!5
	Thread(2) : Application Name : Threads Application
	!!!!3
	4
	3
	Thread(3) : Application Name : Threads Application
	!!!!4
	5
	4
	!!!!5
	Thread(1) : Application Name : Threads Application
	5
	Thread(3) : Application Name : Threads Application
	Thread(1) : Application Name : Threads Application


华夏公益教科书