Page 1 of 1

Making a spider bounce in qbasic

Posted: Thu May 11, 2006 7:37 pm
by jasonkidd007
how do you make a spider bounce off the edge without leaving the screen?

Posted: Thu May 11, 2006 8:39 pm
by {Nathan}
I do not understand what you are trying to ask us. Please elaborate so we can all help you to our fullest potential.

Also, please post you code if you have any. If you do post your code, please use the code button you see under the subject line when you post a topic. Press thee button again at the end of your code, or when you finish typing it.

Posted: Thu May 11, 2006 9:25 pm
by Theophage
ummmmm....Get him drunk?

Posted: Fri May 12, 2006 11:36 am
by Zim
Mathematically...

As the ball hits the edge you have to revearse the direction, so the "X" travel now gets multiplied by -1 and the "Y" travel doesn't change.

If the bounce is off the top or bottom then it's the Y that revearses, not the X.

If it bounces out of a corner, then they both revearse.

Posted: Fri May 12, 2006 2:54 pm
by AlienQB
How to make a spider bounce of a wall? You asked for it...

For a more realistic approach, you'll need to use newtonian mechanics that takes in consideration both the mass and momentum of the spider as it bounces off the wall. This way the spider will bounce off the wall differently (and realistically) depending on it's mass and speed.

Let a = (ax, ay) be the acceleration of the spider and integrate to obtain the velocity v = (vx, vy) and location s = (sx, sy). Also let m denote it's mass. You can calculate the angle of acceleration or velocity with trigonometry:

Angle = atan( y / x )

A spider, like all objects near earth, is affected by gravity. Although the earth is round, we can regard a small portion of the earth's surface as a place where the gravity vector field is homogeneous, similiar to the regard that we regard light from the sun to be parallell as it falls down here. At any instance, the spider will gain an acceleration "downwards" equal to 9.82 meters per second. Of course, in a QB game that can be measured in pixels instead, if you like. This is done with the operation

a = (0, -9.82) (in meters)

(actually a = (0, -G*M/y^2) where G is the universal constant of gravity and M is the mass of the earth)

When doing this, you need to make sure that the spider does not fall through any floor. If the spider is given acceleration in any direction by the player, it will give the spider a new velocity:

v = v + adt

where dt is the discreet time element (equals to 1 if your loop if your program lacks time control otherwise could be measured in either seconds or milliseconds). The new position can then be determined with:

s = s + vdt

Now, when that's in place, if the spider hits a wall, the total momentum will be preserved ? meaning that the spider will strike the wall with equal power as the wall strikes back. Since the wall is quite solid and unmoveable, the x-component of the velocity will reverse.

Now the power of working this way is that you can extend the program to involve bouncing into angled walls, even create boxes that the spider can bounce into (and create movement for the box, reducing the spider's momentum). You can create other spiders and let them bounce into each other and off, and introducing a moment of inertia and rendering the rotation of the spider you can show off how the spider's rotation changes when it bounces into something.

For these operations to work, you'll need to work with the TYPE command to introduce vectors. Vector operations are not like common aritmethics, so it will be necessary to write these for yourself. An example of a type that would work:

Code: Select all

' Create a vector of random angle and give it a length specified

TYPE Vector

	x AS DOUBLE
	y AS DOUBLE

END TYPE

CONST PI = 3.141592654
DIM a AS Vector
DIM angle AS DOUBLE

SUB Multiply (a AS Vector, Factor AS DOUBLE)
	a.x = a.x*Times
	a.y = a.y*Times
END SUB

FUNCTION PrintOut$ (a AS Vector)
	DIM b AS STRING
	b = "("+STR$(a.x)+","+STR$(a.y)+")"
	Return b
END FUNCTION

SUB Add (a AS Vector, b AS Vector)
	a.x = a.x + b.x	
	a.y = a.y + b.y
END SUB

'Randomize an angle
Print "Randomized angle was: "; RND*2; "*pi"
angle = RND(0)*2*PI
a.y = SIN(angle)
a.x = COS(angle)
PRINT STR$(angle)

'Ask for a length
DIM Factor AS DOUBLE
INPUT "Please input length:", Factor

'Multiply
CALL Multiply(a, Factor)

'Print out the result
PRINT "Result: ";PrintOut$(a)
...or just do what Zim said. ;)

Posted: Fri May 12, 2006 8:57 pm
by Theophage
I hate to ask, AlienQB, but could you throw the vector idea into a little ball bouncing program for me? I'd like to see it in action while I disect the code. It sounds pretty spiffy...

Posted: Sat May 13, 2006 3:22 am
by AlienQB
I'd love to give it a shot ? after this term's exams ! Mechanics for the win, but right now they're forcing me to learn electormagnetism and differential equations. :wink:

i still cant get my spider to bounce at a certain angle

Posted: Thu May 18, 2006 8:11 pm
by jasonkidd007
this spider is not done. could you check to see if there are errors? because i only could make it go up and down at a spot which is not what i wanted.

Code: Select all

cls
SCREEN 12

highbounce = 460
lowbounce = 1
highx = 640
lowx = 1

count = 1
x = INT((highx - lowx + 1) * RND + lowx)
y = INT((highy - lowy + 1) * RND + lowy)

DO
 
  CIRCLE (x, y - 5), 5, 4
  PAINT (x, y - 5), 4, 4

  CIRCLE (x + 30, y - 5), 5, 4
  PAINT (x + 30, y - 5), 5, 4


  LINE (x, y)-(x + 30, y + 30), 14, BF
  FOR count = 1 TO 20000
  NEXT count
  LINE (x, y)-(x + 30, y + 30), 0, BF
 
  CIRCLE (x, y - 5), 5, 0
  PAINT (x, y - 5), 0, 0
  CIRCLE (x + 30, y - 5), 5, 0
  PAINT (x + 30, y - 5), 0, 0

  

  y = y + 1
  IF y > 460 THEN

    DO
      y = y - 1
      CIRCLE (x, y - 5), 5, 4
      PAINT (x, y - 5), 4, 4
     
      CIRCLE (x + 30, y - 5), 5, 4
      PAINT (x + 30, y - 5), 4, 4
     
      LINE (x, y)-(x + 30, y + 30), 14, BF
      FOR count = 1 TO 2000
      NEXT

      LINE (x, y)-(x + 30, y + 30), 0, BF
      CIRCLE (x, y - 5), 5, 0
      PAINT (x, y - 5), 0, 0
      CIRCLE (x + 30, y - 5), 5, 0
      PAINT (x + 30, y - 5), 0, 0

      IF bounce = y THEN EXIT DO
     
     


    LOOP
    bounce = INT((highbounce - lowbounce + 1) * RND + lowbounce)
    IF bounce > 460 THEN EXIT DO
   

    


  END IF

LOOP

END


Posted: Wed May 24, 2006 2:25 am
by Theophage
I started a post pointing out the errors in your code, Jason, but gave up. Let's just say, it's quite a mess :)

Given this, It might be better if we start over from the beginning. From what I could gather, you want to make a program that: 1) Randomly places a spider graphic on the screen, 2) assigns it a random direction, and 3) shows that spider bouncing off the walls, right? IF I've missed anything or stated something different from what you wanted, please let me know.

So in order to do this we need a spider graphic. I see that you've got a simple one already in your program, so we'll use that. Your code for that is:

Code: Select all

CIRCLE (x, y - 5), 5, 4
PAINT (x, y - 5), 4, 4
     
CIRCLE (x + 30, y - 5), 5, 4
PAINT (x + 30, y - 5), 4, 4
     
LINE (x, y)-(x + 30, y + 30), 14, BF
I also notice that when you "undraw" the spider back to the black background, you undraw each part of him in turn. A simpler and quicker way to do that would be to simply draw a black box over the entire thing like so:

Code: Select all

LINE (x - 5, y - 10) - (x + 35, y + 30), 0, BF
Your way worked fine, and you can still keep it if you want, but for my example, I'm going to use the above. You also want to try to blank the spider out at the very last possible moment before it is drawn in at the new location. For this, we will use another couple of variables called oldxpos and oldypos and we will blank the spider at the old position out right before drawing the spider in at the new position.

Now, I note that we are already using the variables x and y for the x and y position of the spider. Those variable names are again okay, but they would be better if they were a bit more descriptive. I will change them to xposition and yposition.

Two more values that we should keep track of for the spider are its direction along the x axis and its direction along the y axis. We will use the variables xdirection and ydirection for these. The values of these variables will be either -1 or 1. A -1 in the x direction means the spider moves to the left, and a 1 means it moves to the right. A -1 in the y direction means the spider moves up, while a 1 means the spider moves down. We will pick random values for these variables as well as for the x ans y position variables at the beginning of the program.

Whenever you are using random numbers in your programs, however, you need to include the statement RANDOMIZE TIMER at the beginning of your program. The reason is that QBASIC generates random numbers by way of a formula from a certain starting value or "seed". Unfortunately, this seed is the same everytime you run your program, so all of the "random" numbers will always be the same. When you include the RANDOMIZE TIMER statement, it changes this seed to the value of TIMER, the internal clock. This has a different value every second of the day, so it mixes the numbers up good enough for us.

During our program loop, we simply add the values of xdirection and ydirection to xposition and yposition, and then check to see if they've hit the edge of the screen. As Zim mentioned earlier, if the spider does hit an edge, you just multply the value in either xdirection or ydirection (or both if it hits right in a corner) by -1 to make the spider go the other way.

I notice that you used an empty FOR ... NEXT loop to control how fast the spider moves. The problem with this is different machines may be able to go through those loops much slower or much faster than yours. To keep the timing exact, we will use the TIMER again, this time to count the hundredths of a second between movements.

Finally, we will make it so that the user can press the escape key whenever they like and exit the program. You had another condition for exiting in your program example that I didn't really understand. That's okay, we can add that condition later if you'd like.

So now our program should look something like this:

Code: Select all

SCREEN 12
CLS
RANDOMIZE TIMER

xposition = INT(RND * 640)
yposition = INT(RND * 480)
oldxpos = xposition
oldypos = yposition
escapekey$ = CHR$(27)

xdirection = 1
IF INT(RND * 2) = 0 then xdirection = -1
ydirection = 1
IF INT(RND * 2) = 0 then ydirection = -1

DO
   LINE (oldxpos - 5, oldypos - 10) - (oldxpos + 35, oldypos + 30), 0, BF

   CIRCLE (xposition, yposition - 5), 5, 4
   PAINT (xposition, yposition - 5), 4, 4
   CIRCLE (xposition + 30, yposition - 5), 5, 4
   PAINT (xposition + 30, yposition - 5), 4, 4
   LINE (xposition, yposition)-(xposition + 30, yposition + 30), 14, BF

   pausetime = TIMER
   DO
   LOOP UNTIL TIMER >= pausetime + .01

   oldxpos = xposition
   oldypos = yposition
   xposition = xposition + xdirection
   yposition = yposition + ydirection

   IF xposition <0 or xposition > 640 THEN xdirection = xdirection * -1
   IF yposition <0 or yposition > 480 THEN ydirection = ydirection * -1
LOOP UNTIL INKEY$ = escapekey$

END
I didn't set the edges of the spider's movements very well, so it will go partly off the screen before it bounces back, but hopefully you will fix that. If you have any other questions about what my code above does, let me know.