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 |