Simple AI Help
Blitz3D Forums/Blitz3D Programming/Simple AI Help
| ||
I was a bit bored and i made a program: a Ship that flies and dodge Asteroids automatically. It uses 4 sensors to check if there's a near an Asteroid. For example: if left sensor is activated the Ship will moves to the right. If both left and right sensors are activated it will relays on two sensors of it's sides. The problem it's, idk what to do if all sensors are activated LOL. I hope you help me to improve it, any suggestion will be nice :) F1: Toggle Debug Space: Center Ship Enter: Reset game(when game over screen) Images(2 kb): http://www.mediafire.com/download/17zuu8bmfal64r5/img.rar ;------------------------- ;- Title: Simple AI Test - ;------------------------- ;- Author: Chispon - ;------------------------- ;- Created: 09/01/2014 - ;------------------------- ;- Edited: 10/01/2014 - ;------------------------- AppTitle "Simple AI" Graphics 320, 240, 32, 2 SetBuffer BackBuffer() SeedRnd MilliSecs() SetFont LoadFont("Courier New", 14) ;---------- ;- Images - ;---------- Global gfx_ship = LoadImage("ship.bmp"): MaskImage gfx_ship, 255, 0, 255 Global gfx_life = LoadImage("life.bmp"): MaskImage gfx_life, 255, 0, 255 Global gfx_background = LoadImage("background_stars.bmp") ;--------- ;- Types - ;--------- Type obj_ast Field x# Field y# Field r# ;radius End Type Type obj_exp Field x# Field y# Field a# Field l ;life End Type ;------------- ;- Variables - ;------------- Global debug = 1 Global speed# = 2 Global player_x# = 155 Global player_y# = 220 Global player_lives = 2 Global player_score = 0 Global player_dead = 0 Global sensors_size = 50 Global time, old_time Global background_y = 0 fpslock = CreateTimer(60) While Not KeyDown(1) If MouseDown(1) Then CreateExplosion(MouseX(), MouseY()) If KeyHit(57) Then player_x# = 155 If KeyHit(59) Then debug = 1 - debug Color 255, 255, 255 Rect 0, 0, 320, 240, 0 TileImage gfx_background, 0, background_y: background_y = background_y + speed# Select player_dead Case 0 If Rand(20) = 5 Then obj_r = Rand(10, 25) obj_x = Rand(0, 320 / obj_r) * obj_r SpawnObj(obj_x, -20, obj_r) EndIf For obj_ast.obj_ast = Each obj_ast If debug = 1 Then Color 255, 255, 0 Rect obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, 0 EndIf If Distance2D(obj_ast\x#, obj_ast\y#, player_x#, player_y#) < obj_ast\r# Then Color 255, 0, 0 ;player_score = player_score - 5 player_dead = 1 CreateExplosion(player_x#, player_y#) old_time = MilliSecs() Else Color 180, 120, 80 EndIf Oval obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2 Color 130, 0, 20 Oval obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, 0 If ( RectsOverlap(obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, player_x# - 5 , player_y# - sensors_size, 1, sensors_size) And RectsOverlap(obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, player_x# + 15, player_y# - sensors_size, 1, sensors_size) ) = 0 Then ;Left Sensor If RectsOverlap(obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, player_x# - 5 , player_y# - sensors_size, 1, sensors_size) Then player_x# = player_x# + speed# ;Right Sensor If RectsOverlap(obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, player_x# + 15, player_y# - sensors_size, 1, sensors_size) Then player_x# = player_x# - speed# Else If ( RectsOverlap(obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, player_x# - 35, player_y# - sensors_size, 30, 1) And RectsOverlap(obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, player_x# + 15, player_y# - sensors_size, 30, 1) ) = 0 Then ;Down Left Sensor If RectsOverlap(obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, player_x# - 35, player_y#, 30, 1) Then player_x# = player_x# + speed# ;Down Right Sensor If RectsOverlap(obj_ast\x# - obj_ast\r#, obj_ast\y# - obj_ast\r#, obj_ast\r# * 2, obj_ast\r# * 2, player_x# + 15, player_y#, 30, 1) Then player_x# = player_x# - speed# Else If player_x# < 155 Then player_x# = player_x# + speed# If player_x# > 155 Then player_x# = player_x# - speed# EndIf EndIf obj_ast\y# = obj_ast\y# + speed# If obj_ast\y# > 260 Then player_score = player_score + 10: Delete obj_ast Next Case 1 If player_lives > 0 Then For obj_ast.obj_ast = Each obj_ast Delete obj_Ast Next time = MilliSecs() - old_time If time > 3000 Then player_dead = 0 player_lives = player_lives - 1 player_x# = 155 EndIf Else player_lives = -1 For obj_ast.obj_ast = Each obj_ast Delete obj_Ast Next time = MilliSecs() - old_time Color 255, 0, 0 Text 160, 120, "GAME OVER!", 1, 1 If KeyHit(28) Or time > 10000 Then player_dead = 0 player_lives = 2 player_x# = 155 player_score = 0 EndIf EndIf End Select For obj_exp.obj_exp = Each obj_exp Color 255, 0, 0 Rect obj_exp\x#, obj_exp\y#, 3, 3 obj_exp\x# = obj_exp\x# + 1 * Cos(obj_exp\a#) obj_exp\y# = obj_exp\y# + 1 * Sin(obj_exp\a#) obj_exp\l = obj_exp\l - 1 If obj_exp\l <= 0 Then Delete obj_exp Next If debug = 1 Then Color 0, 255, 0 ;Rect player_x# + 5, player_y# - 80, 1, 80 ;Middle Sensor Rect player_x# - 5, player_y# - sensors_size, 1, sensors_size ;Left Sensor Rect player_x# + 15, player_y# - sensors_size, 1, sensors_size ;Right Sensor Rect player_x# - 35, player_y#, 30, 1 ;Down Left Sensor Rect player_x# + 15, player_y#, 30, 1 ;Down Right Sensor EndIf If player_dead = 0 Then DrawImage gfx_ship, player_x#, player_y# Color 255, 255, 255 Text 5, 5, "Score: " + player_score If player_lives > -1 Then For i = 0 To player_lives DrawImage gfx_life, 280 + i * 10, 5 Next EndIf WaitTimer(fpslock) Flip Cls Wend End Function CreateExplosion(x, y) Local i For i = 0 To Rand(25, 50) obj_exp.obj_exp = New obj_exp obj_exp\x# = x obj_exp\y# = y obj_exp\a# = Rnd(360) obj_exp\l = Rand(25, 50) Next End Function Function SpawnObj(x, y, r) obj_ast.obj_ast = New obj_ast obj_ast\x = x obj_ast\y = y obj_ast\r = r End Function Function Distance2D#(x1, y1, x2, y2) Local xd# = x2 - x1 Local yd# = y2 - y1 Return (xd# * xd# + yd# * yd#)^0.5 End Function |
| ||
It would be more useful for your sensors to return how far away the nearest object is. Set a maximum range for each sensor. For each sensor, start at the ships position and move it forward in the vector direction of the sensor relative to the ships orientation and do a rectsoverlap check at each stage. If a contact is made prior to the sensor reaching the maximum range then store the distance to this contact, otherwise set to -1 (no contact). Once you have contact distances for all sensors the best direction to turn would be the one where the sensor has no contact or the contact is the furthest away. You could also use this sensor information to slow down or speed up etc... |
| ||
Cheap and dirty way to do it would be to split the 3D space near the ship into grids and change heading towards the grid with the least density of objects to avoid. |
| ||
Ok, thanks for your suggestions guys :D |