Random Movement

BlitzPlus Forums/BlitzPlus Beginners Area/Random Movement

ShaunVonSuffern(Posted 2008) [#1]
Im a little new to blitzplus and a I am trying to program a basic game where you move a ship and there is a another that the computer controls. If the two collide then the player lose health. (This program is text based.) So I need help with this:
1. Stop the computer just frezzing up and when it hits the wall to speed up.
2. When the two ships meet the player loses help and level restarts.
3. The ships dont have to be right on top of each other to collide.
4. More ships can apperar after a set time limit.
Here is the code. It is still a work in progress.

Graphics 640, 480
SeedRnd MilliSecs()
Const Ship$ = "<|>"
Const Esc = 1, Space = 57, Up = 200, LeftK = 203, RightK = 205, Down = 208, Shift = 54
Const Startx = 320, Starty = 240
Global EStartx = Rand(1,640)
Global EStarty = Rand(1,480)


Type Ship
Field x, y
Field Ship$
Field directionx
Field directiony
Field hitpoints
End Type

Global cont = 1

Global Player.Ship = New Ship
Player\x = Startx
Player\y = Starty
Player\Ship$ = Ship$
player\hitpoints = 3

Global enemy.ship = New ship
enemy\ship$ = ship$
enemy\x = EStartx
enemy\y = EStarty
enemy\directionx = Rand(1,-1)
enemy\directiony = Rand(1,-1)
enemy\hitpoints = 3


While Not KeyHit(1)
Cls
DrawLevel()
TestInput()
TestEnemy()
TestCollision()
DrawHUD()
Flip
Wend

Function DrawLevel()
Text Player\x, Player\y, Player\Ship$
Text enemy\x, enemy\y, enemy\ship$
End Function

Function TestInput()

If KeyDown(LeftK)
Player\x = Player\x - 1
If Player\x <= 0
Player\x = 10
End If
End If

If KeyDown(RightK)
Player\x = Player\x + 1
If Player\x >= 635
Player\x = 610
End If
End If

If KeyDown(Up)
Player\y = Player\y - 1
If Player\y <= 0
Player\y = 10
End If
End If

If KeyDown(Down)
Player\y = Player\y + 1
If Player\y >= 475
Player\y = 450
End If
End If

End Function

Function TestEnemy()

enemy\x = enemy\x + enemy\directionx

If enemy\x <= 0
enemy\x = 10
enemy\directionx = enemy\directionx * -1
enemy\directionx = enemy\directionx + Rand(1,-1)
End If

If enemy\x >= 635
enemy\x = 610
enemy\directionx = enemy\directionx * -1
enemy\directionx = enemy\directionx + Rand(1,-1)
End If

enemy\y = enemy\y + enemy\directiony

If enemy\y <= 0
enemy\y = 10
enemy\directiony = enemy\directiony * -1
enemy\directiony = enemy\directiony + Rand(1,-1)
End If

If enemy\y >= 475
enemy\y = 450
enemy\directiony = enemy\directiony * -1
enemy\directiony = enemy\directiony + Rand(1,-1)
End If

End Function

Function TestCollision()
If enemy\x = player\x And enemy\y = player\y Then
DrawLevel()
Player\Hitpoints = Player\Hitpoints - 1
If player\hitpoints <= 0 Then
Delete player
End If
End If
End Function

Function DrawHUD()
Text 0, 435, "HitPoints: " + player\hitpoints + ""
Text 0, 450, "X Position: " + Player\x + ""
Text 0, 465, "Y Position: " + Player\y + ""
Text 0, 420, "X Position: " + enemy\x + ""
Text 0, 405, "Y Position: " + enemy\y + ""
End Function


Sauer(Posted 2008) [#2]
To answer your questions...

1. My computer didn't freeze up when the enemy ship hit an edge, but I do have a suggestion:

Whenever checking for collisions on an edge, you want to move the ship to the same number you're checking. For example, you have;
If enemy\x <= 0
enemy\x = 10
enemy\directionx = enemy\directionx * -1
enemy\directionx = enemy\directionx + Rand(1,-1)
End If


You want to change the 10 to a zero. What you have now causes the ship to "jump" to x=10, when it should appear to bounce.

Also, the line "enemy\directionx = enemy\directionx + Rand(1,-1)" is not needed, because it basically counter acts the previous line.

2 and 3. You have the idea of checking of both x's and y's are equal, but this will only register a collision if the points meet exactly, as I'm sure you already know. What you need to do is check if the strings themselves are colliding, and you do this using the StringWidth command. This should help:
If player\x >= enemy\x And player\x <= enemey\x+StringWidth("<|>">
If player\y >= enemy\y And player\y <= enemy\y+12
player\hitpoints=player\hitpoints-1
Endif
Endif


Basically here you want to see if your x is between the enemy's x and the point that is x+ the width of the enemy, and the y is between the enemy y and the y+ the height of the font. When your x and y is between these points, you have a collision.

4. You're getting into some type manipulation, which you'll get with more experience. Focus on getting this off the ground :)

So far you have a solid start for a game, I hope this helped.


ShaunVonSuffern(Posted 2008) [#3]
thank you very much


ShaunVonSuffern(Posted 2008) [#4]
One more thing, how do i get the ship to speed up after it hits the wall?


Sauer(Posted 2008) [#5]
Well, what you would want to do is have a speed variable. So, when moving the enemy, you'd do:
enemy\x= enemy\x + (speed * enemy\directionx)


That way, the direction will make speed positive or negative, causing a change of direction, but you can also make speed bigger or smaller.

You'll want to do the same thing to the y movement as well.

Now all you have to do is just add a speed=speed+1 every time it hits a wall.


ShaunVonSuffern(Posted 2008) [#6]
One more thing, I have a ship that bounces off the walls but sometimes it will either get stuck, move up or down, or not at all, what do i do.


Sauer(Posted 2008) [#7]
That could be caused by the line

enemy\directionx = enemy\directionx + Rand(1,-1)


Which should probably be eliminated, along with all the lines with it.


ShaunVonSuffern(Posted 2008) [#8]
I did that, here is the code for movement

;Enemy 2 - Bounces Off Walls
enemy2\x = enemy2\x + (EnemySpeed * enemy2\directionx)

If enemy2\x <= 0
enemy2\x = 0
enemy2\x= enemy2\x + (EnemySpeed * enemy2\directionx) * -1
End If

If enemy2\x >= 615
enemy2\x = 615
enemy2\x= enemy2\x + (EnemySpeed * enemy2\directionx) * -1
End If

enemy2\y = enemy2\y + (EnemySpeed * enemy2\directiony)

If enemy2\y <= 0
enemy2\y = 0
enemy2\y= enemy2\y + (EnemySpeed * enemy2\directiony) * -1
End If


If enemy2\y >= 455
enemy2\y = 455
enemy2\y= enemy2\y + (EnemySpeed * enemy2\directiony) * -1
End If


Newcomer(Posted 2008) [#9]
i would suggest that you replace the function testcollision() with

Function TestCollision()
If enemy\x < player\x +10 And enemy\y < player\y +10
If enemy\x > player\x - 10 And enemy\y > player\y - 10
DrawLevel()
Player\Hitpoints = Player\Hitpoints - 1
If player\hitpoints <= 0 Then
Delete player
End If
End If
EndIf
End Function

now you have it so if the player is within a 10 pixel square, then it counts as collision as opposed to when its exactly on opponent


Sauer(Posted 2008) [#10]
@ Newcomer

With testing StringWidth() and the height of the font, he already has a perfect collision with the text.

Anyway, along with the problem at hand...
When you test the collision on a wall, instead of:
enemy2\x= enemy2\x + (EnemySpeed * enemy2\directionx) * -1
Just multiply enemy2\directionx by -1. This will change the direction, and since you already have a line for moving the enemy before you check all the collisions, you'll be all set.


ShaunVonSuffern(Posted 2008) [#11]
Ok, I probally havent been asking my questions clear enough,
My problem is that the ships that run on random movment will either not move at all, or will move only up or down, hit the wall and stop compleatly. I haven't changed my movment function at all from the last post. so what do i need to fix? tell me if i need to post anything else to help answer this problem.