2D particle code...just a test

Advanced game related topics
Krylar
User
User
Posts: 88
Joined: Thu Apr 15, 2004 3:17 pm

2D particle code...just a test

Post by Krylar »

Heya,

In an effort to learn more and more about PB, I coded up a quick little particle thingy in 2D. It's probably not one somebody would want to use as a final in a game or anything, at least not without some optimization and such, but it may be mildly useful for something.

Code: Select all

;/////////////////////////
; Particle Test
; Author: Krylar
; Last Update: 07/26/04
;/////////////////////////

Global SCREEN_WIDTH
Global SCREEN_HEIGHT
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600


; Toss a Particles struct together
Structure Particles
  fX.f                  ; X location of the particle
  fY.f                  ; Y location of the particle
  fSpeedX.f             ; How fast we're moving on the X-Axis
  fSpeedY.f             ; How fast we're moving on the Y-Axis
  wRed.w                ; Red value
  wGreen.w              ; Green value
  wBlue.w               ; Blue value
  fStartTime.f          ; When the particle was born
  fFadeSpeed.f          ; How quickly does it fade?
EndStructure

; init the list
NewList Particle.Particles() 

; Delcare the Procedures
Declare LaunchParticles(fX.f,fY.f,wAmount.w,wDir.w)
Declare UpdateParticles()


; Set our defaults
CurrentDirection = 0
ParticleAmount = 4


; init stuff. 
InitSprite()
InitKeyboard()
InitMouse()
Result = OpenScreen(SCREEN_WIDTH,SCREEN_HEIGHT,32,"")
If Result = 0
   End
EndIf

; setup the FPS stuff
FPS_Timer = ElapsedMilliseconds() 
FPS = 0 
FPS_Counter = 0 
FramesPerSecond.s = "" 

; Stick the mouse in the middle of the screen
MouseLocate(SCREEN_WIDTH / 2,SCREEN_HEIGHT / 2)

ExitCondition=0
While ExitCondition = 0

   ; clear the screen
   ClearScreen(0,0,0)

   ExamineMouse()
   ; if the user clicks/holds the mouse, launch particles
   If MouseButton(1) <> 0
      LaunchParticles(MouseX(),MouseY(),ParticleAmount,CurrentDirection)
   EndIf

   ; just keep moving the direction so the effect isn't 
   ; just floating in one direction...just visual
   CurrentDirection = CurrentDirection + 1
   If CurrentDirection > 359
       CurrentDirection = 0
   EndIf

   ExamineKeyboard()
   If KeyboardReleased(#PB_Key_Add)
      ParticleAmount = ParticleAmount + 1
   EndIf

   If KeyboardReleased(#PB_Key_Subtract)
      ParticleAmount = ParticleAmount - 1
      If ParticleAmount < 1
         ParticleAmount = 1
      EndIf
   EndIf

   If KeyboardPushed(#PB_Key_Escape)
      ExitCondition = 1
   EndIf

   ; go through and update the particles
   UpdateParticles()

   If ElapsedMilliseconds() > FPS_Timer + 1000 
      FPS = FPS_Counter 
      FPS_Counter = 0 
      FPS_Timer = ElapsedMilliseconds() 
   Else 
      FPS_Counter = FPS_Counter + 1 
   EndIf 

   ; put up a little yellow dot to show where the mouse is and toss up some basic info while we're at it
   StartDrawing(ScreenOutput())
     Plot(MouseX(),MouseY(),RGB(255,255,0))
     Locate(0,0)
     DrawText("Click and Hold Left Mouse Button to Launch Particles -- ESC to Exit, + to Increase Particles, - to Descrease")
     Locate(0,580)
     StatusText.s = "Particle Release Rate = " + Str(ParticleAmount) + ", Active Particles = " + Str(CountList(Particle())) + ", FPS = " + Str(FPS)
     DrawText(StatusText)
   StopDrawing()

   ; Flip the pages
   FlipBuffers()
Wend

End ; End of the program



; Adds particles to our list
Procedure LaunchParticles(fX.f,fY.f,wAmount.w,wDir.w)
   For i = 0 To wAmount - 1
       AddElement(Particle())
       Particle()\fX = fX
       Particle()\fY = fY
       
       ; 
       Particle()\fSpeedX = -(Sin(wDir) * (Random(1) + 0.5))
       Particle()\fSpeedY = Cos(wDir) * (Random(1) + 0.5)
       
       Particle()\wRed = Random(75) + 180
       Particle()\wGreen = Random(75) + 180
       Particle()\wBlue = Random(75) + 180
       
       Particle()\fStartTime = ElapsedMilliseconds()
       Particle()\fFadeSpeed = Random(1) + 0.00001
   Next
EndProcedure

; run through and update the particles, and draw them too
Procedure UpdateParticles()
   CurrentT = ElapsedMilliseconds()
   StartDrawing(ScreenOutput())
   
   ForEach Particle()

      ; if the fade speed has been hit for this particle, dim it a bit
      If CurrentT > Particle()\fStartTime + Particle()\fFadeSpeed
         Particle()\fStartTime = ElapsedMilliseconds()

         Particle()\wRed = Particle()\wRed - 1
         If Particle()\wRed <= 0
            Particle()\wRed = 0
         EndIf         

         Particle()\wGreen = Particle()\wGreen - 1
         If Particle()\wGreen <= 0
            Particle()\wGreen = 0
         EndIf         

         Particle()\wBlue = Particle()\wBlue - 1
         If Particle()\wBlue <= 0
            Particle()\wBlue = 0
         EndIf         
      EndIf

      ; update its position based on the speed its moving
      Particle()\fX = Particle()\fX - Particle()\fSpeedX
      Particle()\fY = Particle()\fY - Particle()\fSpeedY
      ; if we go outside the view area, nuke the element
      If Particle()\fX < 0 Or Particle()\fX >= SCREEN_WIDTH Or Particle()\fY < 0 Or Particle()\fY >= SCREEN_HEIGHT 
         DeleteElement(Particle())
      Else
         ; see if the colors are all at 0, and if so nuke the element
         If Particle()\wRed = 0 And Particle()\wGreen = 0 And Particle()\wBlue = 0
            DeleteElement(Particle())
         Else
            ; draw that particle
            Plot(Particle()\fX,Particle()\fY,RGB(Particle()\wRed,Particle()\wGreen,Particle()\wBlue))
         EndIf
      EndIf   
   Next
   StopDrawing()

EndProcedure
Hope that's useful for someone!

-Krylar
aaron_at_work
User
User
Posts: 11
Joined: Tue Jun 01, 2004 7:24 pm

Post by aaron_at_work »

One little bug in there somewhere.... if I sit right on screen edge on the right and generate particles, sometimes a couple show up on the left side of the screen heading vertically up or down. 8)

But then again, I'm a picky sort of guy. :wink:
Krylar
User
User
Posts: 88
Joined: Thu Apr 15, 2004 3:17 pm

Post by Krylar »

Hmmm...that's weird. This bit:

Code: Select all

If Particle()\fX < 0 Or Particle()\fX >= SCREEN_WIDTH Or Particle()\fY < 0 Or Particle()\fY >= SCREEN_HEIGHT 
         DeleteElement(Particle()) 
...should kill the particle.

I didn't know that PB did screen wrapping on Plots. Thought it would crash on an attempt to Plot outside of the screen. I guess it could wrap the creation point to 0, but that would really be kooky :D

Thanks for the feedback. If I find anything, I'll let ya know.

-Krylar
benny
Enthusiast
Enthusiast
Posts: 465
Joined: Fri Apr 25, 2003 7:44 pm
Location: end of www
Contact:

Post by benny »

Hmm ... I can not confirm this bug. Krylar's code runs without any
problems on my machine :!:

Strange :?: :roll:
regards,
benny!
-
pe0ple ar3 str4nge!!!
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

i dont have any use of it, but it look cool :)
aaron
Enthusiast
Enthusiast
Posts: 267
Joined: Mon Apr 19, 2004 3:04 am
Location: Canada
Contact:

Post by aaron »

Hmmmm.... it doesn't do it on my home machine either, just my work machine. My work computer is a Dell something-or-other with an ATI card. Maybe the ATI driver is plotting pixels in the wrong place on the edge! Very strange. I'll poke around with it tomorrow at work to see what is up.
Post Reply