Please help: collisions
Blitz3D Forums/Blitz3D Beginners Area/Please help: collisions
| ||
i am working on a "game" but i have some problems. Here is my code so far, it isnt complete and i havnt added the text that displays the score. Dont laugh at my bad coding ;)
welcome()
Function welcome()
Graphics 1024, 768
screen=LoadImage("ice_escape1.bmp")
DrawImage screen, 0,0
While Not KeyDown(1)
If KeyDown(28) Then Return
If KeyDown(57) Then Return
Wend
End Function
.start
Graphics3D 1280,1024
SetBuffer BackBuffer()
SeedRnd MilliSecs()
;collisions
type_player=1
type_obstacle=2
type_sphere=3
type_ring=4
;camera
camera=CreateCamera()
PositionEntity camera, -360.132,5,692.037
RotateEntity camera, 0,180, 0
EntityType camera, type_player
EntityRadius camera, 2
CameraClsColor camera, 0,0,0
;sound
sound=LoadSound("phaser.wav")
;lights
light=CreateLight()
RotateEntity light,90,0,0
;heightmap and the terrain
maze=LoadTerrain("heightmap6.bmp")
ScaleEntity maze, 5,100,5
PositionEntity maze, -500,0,-500
tex1=LoadTexture("ice1.jpg")
ScaleTexture tex1, 50,50
EntityTexture maze, tex1
;penguins
Dim spheres(10000)
For s=0 To 100
spheres(s)=LoadMesh("penguin.3ds")
ScaleEntity spheres(s), 0.05,0.05,0.05
PositionEntity spheres(s), Rand(500,-500), 3,Rand(500,-500)
EntityColor spheres(s), 95,95,95
EntityType spheres(s), type_sphere
EntityRadius spheres(s), 1
RotateEntity spheres(s), 0,-80,0
Next
;making rings(gems)
Dim rings(1000)
For r=0 To 100
rings(r)=LoadMesh("ring1.3ds")
ScaleEntity rings(r), 0.05,0.05,0.05
PositionEntity rings(r), Rand(500,-500), 3,Rand(500,-500)
EntityColor rings(r), 255,255,26
EntityType rings(r), type_ring
EntityRadius rings(r), 0.3
Next
;destination uncone...
cone=CreateCone()
PositionEntity cone, -407, 15, -16.5
EntityColor cone, 255,0,0
ScaleEntity cone, 5,5,5
EntityType maze, type_obstacle
EntityRadius maze, 0.1
;collisions
Collisions type_player, type_obstacle,2,1
Collisions type_player,type_sphere,2,1
Collisions type_sphere,type_player,2,1
Collisions type_player, type_ring,2,1
Collisions type_ring, type_player,2,1
;the timer
starttime=MilliSecs()
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;makes game run
While Not KeyDown(1)
If KeyDown (72)=True Then velocity#=velocity#+0.02
If KeyDown (76)=True Then velocity#=velocity#-0.02
If KeyDown (77)=True Then TurnEntity camera, 0,-1,0
If KeyDown (75)=True Then TurnEntity camera, 0,1,0
MoveEntity camera, 0,0,velocity#
;pausing
If KeyDown(25) Then
Cls
pause=LoadImage ("ice_pause.bmp")
DrawImage pause,0,0
Flip
WaitKey()
EndIf
If KeyHit(57) Then PlaySound sound
;making spheres move randomly
For i=0 To 100
MoveEntity spheres(i), Rnd(-0.5,0.5), 0, Rnd(-1.2,1.2)
Next
;ending game
For b=0 To 100
If timeleft < 0 Or crash#=1 Then
Cls
Graphics 1024,768
End=LoadImage ("ice_end.bmp")
DrawImage End,0,0
Flip
WaitKey()
If KeyDown(1) Or (57) Or (28) Then End
If KeyHit (57) Then Goto start
EndIf
If CountCollisions (spheres(b))
crash=CollisionEntity (spheres(b),1)
HideEntity crash
crash#=crash#+1
EndIf
If CountCollisions (rings(b))
ring=CollisionEntity (rings(b),2)
HideEntity ring
score#=score#+1
EndIf
Next
UpdateWorld
RenderWorld
;the time
CurrentTime = MilliSecs()
timeleft= 240000 - ((CurrentTime - starttime))
Text 800,10,"Time Remaining: "+TimeLeft /1000
Flip
Wend
End
What i would like is that when the player(camera) touches a ring, the ring dissapears and the score goes up by one. i've made some penguins which you cant touch , if you do then you lose. The problem is that i do not know how to make the collision with the rings and the score thing. When i tried, the collisions with the rings acted exactly the same as with the penguins. In other words, when i touched a ring, i lost... Please help me.. i have been trying for too long and need some advice. thanks Olo |
| ||
Have you tried using EntityCollided ( entity,type ) to get what entity has collided? Then you can determine whether it's a ring or a penguin.If EntityCollided( player, type_ring) > 0 then ; An entity with the specified collision type, has collided with the player. You can identify this entity by querying EntityCollided(player,type_ring) End if |
| ||
| ok thanx for posting some help but i do not understand :( here is the game (what is want it to be): -it is a maze -there are penguins which you cannot touch and you also cannot touch the walls -there are rings..when you touch one, you get one point and the ring dissapears problems (many): -when i touch the wall, the whole terrain dissapears If timeleft < 0 Or crash#=1 Then
Cls
Graphics 1024,768
End=LoadImage ("ice_end.bmp")
DrawImage End,0,0
Flip
WaitKey()
If KeyDown(1) Or (57) Or (28) Then End
If KeyHit (57) Then Goto start
EndIf
If CountCollisions (camera)
crash=CollisionEntity (camera,1)
HideEntity crash
crash#=crash#+1
EndIf
-when i touch a penguin it also dissapears and nothing else happens (using same code as above) -the only thing i have that i want is the dissapearing rings..when i touch them i would really apreciate it you could help me solve any of these problems i have. Thanks again and please try to help me. Olo |
| ||
| Don't use count collisions at all :o) There is no need. Do you store your rings in types? Or arrays? |
| ||
| arrays.. what would i use insted of countcollisions? |
| ||
| please help me, i really need some suggestions or advice...anyone just give me some suggestions or things i could try |
| ||
| EntityCollided(). It returns whether an entity was collided with. It would be a bit easier to use types to store your rings. But, instead of blitz collisions, for the rings, i'd say it would be easier to use entitydistance() to check for collisions with coins. What i do notice is your placing your coins but only storing the entity in the array. If you use types, you can store more information about your entities alot easier. You can do this with arrays, but it's not as readable i don't think. I'll knock something together. |
| ||
| ok thank you so much i really appreciate your help ;) |
| ||
| i have come up with something although it is not exactly what i was looking for.. Now whenever i touch a ring it dissapears but when i touch a penguin or the walls nothing happens. The collision is there, not allowing me to go through but i dont get the 'you lose screen'. Thanks to you, Ross C, i solved one problem, a couple to go. |
| ||
| i still have some probelms :( Thanks to Ross C, i have made the disapearing rings but whenever i crash into a penguin or the wall nothing happens except that i stop due to the collision. What i was aiming for is: -i hit a penguin -there is a collision detection -the 'game over' screen pops up i had it before but when i added the rings it stopped working here is the code that i am using..Please correct any mistakes:
If timeleft < 0 Or crash#=1 Then
Cls
Graphics 1024,768
End=LoadImage ("ice_end.bmp")
DrawImage End,0,0
Flip
WaitKey()
If KeyDown(1) Or (57) Or (28) Then End
If KeyHit (57) Then Goto start
EndIf
If EntityCollided (camera, type_sphere) > 0 Then
crash=CollisionEntity (camera,1)
crash#=crash#+1
EndIf
thanks again, Olo |
| ||
| There is a good few things wrong here. For instance:
;ending game
For b=0 To 100
If timeleft < 0 Or crash#=1 Then
Cls
Graphics 1024,768
End=LoadImage ("ice_end.bmp")
DrawImage End,0,0
Flip
WaitKey()
If KeyDown(1) Or (57) Or (28) Then End
If KeyHit (57) Then Goto start
EndIf
Just won't work. "END" is a also a blitz command. You can assign things to it and use it to draw, but to avoid confusion, you should probably change this to something else. Also, try and avoid loading images whilst the game has started. Preload as much as possible.
If KeyDown(1) Or (57) Or (28) Then End
If KeyHit (57) Then Goto start
Your program will never go back to the beginning, as the first IF statement will catch the spacebar being pressed first and end the application. The penguins are disappearing because:
If CountCollisions (spheres(b))
crash=CollisionEntity (spheres(b),1)
HideEntity crash
crash#=crash#+1
EndIf
Again, confused about the coding used :o) Your assigning the entity that has crashed, to the "crash" variable, then hiding it, THEN setting it to 1 more and making the number a floating point number with the #. Firstly, when you set an entity to a variable, the variable will hold a handle (presumably a memory location) of the entity. This will usually be quite a large number (eg. 1034293). So adding one to this, doesn't make much sense... Anyway, the reason the penguin is disappearing, is because you saying:
crash=CollisionEntity (spheres(b),1)
HideEntity crash
Get the entity that has collided with the player. Then hide it. Also, you NEED to set your variables to GLOBAL before you run the main loop that runs the game. That way you can access them from within functions if need be, and they will always retain their values. Again, remember the # after a variable is used to making the variable into a float. Only use this if you actually need a floating point value. Else, stick to integers. So, i have recoded some parts, moved some parts into functions to keep the main loops cleaner and easier to understand. I have used distance checking on the rings instead of blitz collisions. Should work better. I don't have the media, but it should work fine :o)
welcome()
.start
Graphics3D 1280,1024
SetBuffer BackBuffer()
SeedRnd MilliSecs()
;collisions
Const type_player=1
Const type_penguin=2
Const type_sphere=3
Const type_ring=4
;Set up camera
Global camera = CreateCamera()
PositionEntity camera, -360.132,5,692.037
RotateEntity camera, 0,180, 0
CameraClsColor camera, 0,0,0
EntityType camera, type_player
EntityRadius camera, 2
;sound
Global sound=LoadSound("phaser.wav")
;lights
Global light=CreateLight()
RotateEntity light,90,0,0
;heightmap and the terrain
Global maze=LoadTerrain("heightmap6.bmp")
ScaleEntity maze, 5,100,5
PositionEntity maze, -500,0,-500
Global tex1=LoadTexture("ice1.jpg")
ScaleTexture tex1, 50,50
EntityTexture maze, tex1
;destination uncone...
Global cone=CreateCone()
PositionEntity cone, -407, 15, -16.5
EntityColor cone, 255,0,0
ScaleEntity cone, 5,5,5
EntityType maze, type_obstacle
EntityRadius maze, 0.1
; set up the rings
Type ring
Field entity
Field size ; use this for distance checking
End Type
For loop = 0 To 100
r.ring = New ring
r\entity = LoadMesh("ring1.3ds")
r\size = 0.3
ScaleEntity r\entity, 0.05, 0.05, 0.05
PositionEntity r\entity, Rand(-500,500), 3, Rand(-500,500)
EntityColor r\entity, 255,255,26
EntityType r\entity, type_ring
EntityRadius r\entity, 0.3
Next
; Set up the penguins
Type penguin
Field entity
End Type
For loop = 0 To 100
p.penguin = New penguin
p\entity = LoadMesh("penguin.3ds")
ScaleEntity p\entity, 0.05, 0.05, 0.05
PositionEntity p\entity, Rand(-500,500), 3, Rand(-500,500)
EntityColor p\entity, 95,95,95
RotateEntity p\entity,0,-80,0
EntityType p\entity, type_penguin
EntityRadius p\entity, 1
Next
Global end_image = LoadImage("ice_end.bmp")
Global pause = LoadImage ("ice_pause.bmp")
;collisions
Collisions type_player, type_obstacle,2,1
Collisions type_player,type_sphere,2,1
Collisions type_sphere,type_player,2,1
Collisions type_player, type_ring,2,1
;Collisions type_ring, type_player,2,1 ; no need to set up this collision boths ways, since the rings don't move.
;the timer and other variables
Global starttime=MilliSecs()
Global crash = 0
Global score = 0
Global velocity# = 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;makes game run
While Not KeyDown(1)
If KeyDown (72)=True Then velocity#=velocity#+0.02
If KeyDown (76)=True Then velocity#=velocity#-0.02
If KeyDown (77)=True Then TurnEntity camera, 0,-1,0
If KeyDown (75)=True Then TurnEntity camera, 0,1,0
MoveEntity camera, 0,0,velocity#
;pausing
If KeyDown(25) Then
Cls
DrawImage pause,0,0
Flip
WaitKey()
EndIf
If KeyHit(57) Then PlaySound sound
move_penguins()
check_ring_collisions()
check_penguin_collisions()
If timeleft < 0 Or crash = 1 Then
end_game()
End If
UpdateWorld
RenderWorld
;the time
CurrentTime = MilliSecs()
timeleft= 240000 - ((CurrentTime - starttime))
Text 800,10,"Time Remaining: "+TimeLeft /1000
Flip
Wend
End
Function welcome()
Graphics 1024, 768
screen=LoadImage("ice_escape1.bmp")
DrawImage screen, 0,0
While Not KeyDown(1)
If KeyDown(28) Then Return
If KeyDown(57) Then Return
Wend
End Function
Function end_game()
Cls
Graphics 1024,768
DrawImage end_image,0,0
Flip
; keep repeating until one of the keys is pressed below.
Repeat
WaitKey()
If KeyHit (57) Then Goto start
Until KeyHit(1) Or KeyHit(28)
End
End Function
; move the penguins randomly.
Function move_penguins()
For p.penguin = Each penguin
MoveEntity p\entity, Rnd(-0.5,0.5), 0, Rnd(-1.2,1.2)
Next
End Function
; Use distance checking, instead of blitz collisions. Quicker i say :o) And cleaner.
Function check_ring_collisions()
For r.ring = Each ring
If EntityDistance#(camera,r\entity) < r\size Then
FreeEntity r\entity
Delete r.ring
score = score + 1
End If
Next
End Function
Function check_penguin_collisions()
Local temp_entity = EntityCollided(camera,type_penguin)
If temp_entity > 0 Then ; if you have touched a penguin, then
crash = 1 ; set the crash variable.
End If
End Function
|
| ||
| thanks so much, it works now. i really appreciate you writing so much to help me. Thanks again, Olo |
| ||
| No worries man :o) |
| ||
| ------------------------------------------------------------ i have got everything how i wanted it to be and everything is great (thanks to Ross) but i would like to add one more thing to my "game". Right now whenever i touch the wall or a 'penguin' then i automatically lose. I would like to add some "lives" for the player so that he can hit the wall severall times before he loses. here is the code but it doesnt work :(..please correct the mistakes
crash=5
If timeleft < 0 Or crash=0 Then
Cls
Graphics 1024,768
End=LoadImage ("ice_end.bmp")
DrawImage End,0,0
Flip
WaitKey()
If KeyDown(1) Or (57) Or (28) Then End
If KeyHit (57) Then Goto start
EndIf
If EntityCollided (camera, type_sphere) > 0 Then
sphere=CollisionEntity (camera,1)
crash=crash-1
EndIf
If EntityCollided (camera, type_obstacle) > 0 Then
wall=CollisionEntity (camera,1)
crash=crash-1
EndIf
and here i display the amount of lives left, so that the player can see how many times he can touch the wall or 'penguin' again: Text 450,10, "Lives Left: "+crash So the problem is that whenever i touch the wall or penguin, the amount of lives goes down by 1. The bad thing is that when i move away from the object, my amount of lives go back up. :( please help...anyone |
| ||
| here is an example i made which is basically the same problem- I would like that when the sphere touches the cube the life goes down by one and stays that way. PLEASE TRY THIS YOURSELF BY COPYING THIS CODE TO YOUR B3D ---use the left and right arrow keys to move sphere--- Graphics3D 800,600 type_cube=1 type_sphere=2 SetBuffer BackBuffer() camera=CreateCamera() CameraViewport camera,0,0,800,600 PositionEntity camera,0,0,-5 light=CreateLight() cube=CreateCube() PositionEntity cube,-5,0,5 EntityColor cube,70,80,190 EntityType cube,type_cube sphere=CreateSphere(12) PositionEntity sphere,5,0,5 EntityColor sphere,170,80,90 EntityType sphere,type_sphere Collisions type_sphere,type_cube,3,1 While Not KeyHit(1) If KeyDown(205)=True Then MoveEntity sphere, 0.5,0,0 If KeyDown(203)=True Then MoveEntity sphere, -0.5,0,0 lives=5 If EntityCollided(sphere,type_cube)> 0 Then ball=CollisionEntity (sphere, 1) lives=lives-1 EndIf UpdateWorld RenderWorld Text 335,500,"Lives Left: "+lives Flip Wend End |
| ||
| remove lives=5 from your loop and put where you load your camera and such. currently you are reseting lives to 5 every time the code gets to that point and then you are subtracting from that. |
| ||
| Thanks so much man, :D I have been trying for ages |
| ||
You Should Replace
For loop = 0 To 100
p.penguin = New penguin
p\entity = LoadMesh("penguin.3ds")
ScaleEntity p\entity, 0.05, 0.05, 0.05
PositionEntity p\entity, Rand(-500,500), 3, Rand(-500,500)
EntityColor p\entity, 95,95,95
RotateEntity p\entity,0,-80,0
EntityType p\entity, type_penguin
EntityRadius p\entity, 1
Next
with
Penguin = LoadMesh("penguin.3ds")
ScaleEntity Penguin, 0.05, 0.05, 0.05
EntityColor Penguin, 95,95,95
RotateEntity Penguin,0,-80,0
EntityType Penguin, type_penguin
EntityRadius Penguin, 1
For loop = 0 To 100
p.penguin = New penguin
p\entity = CopyEntity(penguin)
PositionEntity p\entity, Rand(-500,500), 3, Rand(-500,500)
Next
FreeEntity Penguin
It will run faster. |
| ||
| oh thanks, my game was starting to get a bit slow..thanks again :D |
| ||
| Yep sorry, bad programming on my part there! Copyentity is a dam sight faster! Good spot. |