Help with 2D jump?

Advanced game related topics
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Help with 2D jump?

Post by Mythros »

Hello all! =) I've decided I think I ought to start on something alot easier to handle as opposed to 3D. I chose a 2D platformer. As a test, I am remaking the 1st level of Mario bros for the NES. (With mario 3 sprites of course), and I've been fine up until now. I've run into a little snag in my coding.

I've never done 2D coding much before, so I don't know how to make my player simulate a jump.

I need help to fix this math equation.

Here is what I have so far:

Code: Select all

If KeyboardReleased(#PB_Key_Space) And jump=0
    jump = 1
  EndIf
  
  If jump
    y-0.1
    inair=1
  EndIf
This is in my main loop. x & y are the player's coordinates of course. I essentially want to have mario do a moon jump, gravity-wise. HOWEVER, I want to be able to control the height of that jump. I need it to be an interpolated jump, so I THINK an equation like CurveValue() will do.

Here is the function for CurveValue() if you do not know how to calculate it.

Code: Select all

Procedure.f curveValue(current.f, target.f, P.f)
  If P > 1000.0
    P = 1000.0
  EndIf
  ProcedureReturn (current + ( (target - current) * P / 1000.0))
EndProcedure

Procedure.f CurveAngle(oldangle.f,newangle.f, increments.f)
  If increments>1
    If (oldangle+360)-newangle<newangle-oldangle
      oldangle=360+oldangle
    EndIf
    If (newangle+360)-oldangle<oldangle-newangle
      newangle=360+newangle
    EndIf
    oldangle=oldangle-(oldangle-newangle)/increments
  EndIf
  
  If increments<=1
    ProcedureReturn newangle
  EndIf
  ProcedureReturn oldangle
EndProcedure
I also decided to add CurveAngle() incase for some odd reason you would rather use that.

Thank You all & have a GREAT evening! =)

~Mythros
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Help with 2D jump?

Post by Mythros »

Cmon guys! 34 views, and not a single post?.... *Sigh* :(
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Help with 2D jump?

Post by DK_PETER »

Mythros wrote:Hello all! =) I've decided I think I ought to start on something alot easier to handle as opposed to 3D. I chose a 2D platformer.
~Mythros
Smart move :-)

Please be patience Mythros. 40 views is nothing. It all depends on, who is online at given time. Sometimes you have to wait a lot, but sooner or later - the right person will answer or - you might even come up with the answer yourself. ;-)

If I recall correctly, Mario used simple Y-axis decrement/increment while being able to move on the x-axis. (While jumping).

Try something like this: It's extremely simple, but you should be able to adapt it to your needs:

Code: Select all

InitSprite()
InitKeyboard()
InitMouse()

Structure Sprite_Data
	ID.i
	x.i
	y.i
	maxjump.i
	UpDown.i 
	jmp.i
EndStructure

Declare.i ReturnASprite()

Global sp.Sprite_Data, Img.i

Procedure.i ReturnASprite()
	Protected  spr.i
	
	spr = CreateSprite(#PB_Any, 10, 40, #PB_Sprite_AlphaBlending)
	StartDrawing(SpriteOutput(spr))
	Box(0,0,10,40,0)
	Circle(5, 5, 4, $FFFFFF)
	LineXY(5, 5, 5, 20, $FFFFFF)
	LineXY(0, 15, 5, 5, $FFFFFF)
	LineXY(5, 5, 10, 20,$FFFFFF)
	LineXY(5, 20, 0, 40,$FFFFFF)
	LineXY(5, 20, 9, 40,$FFFFFF)
	StopDrawing()
	TransparentSpriteColor(spr,0)
	ProcedureReturn spr
EndProcedure


OpenScreen(800,600,32,"Stick jump",#PB_Screen_SmartSynchronization)

Img = CreateImage(#PB_Any, 800, 600,32,0)
StartDrawing(ImageOutput(Img))
Box(0, 0, 800, 600, $FF0000)
LineXY(0, 550, 800, 550, $FFFFFF)
StopDrawing()

sp\ID = ReturnASprite()

sp\x = 40
sp\y = 510
sp\UpDown = 0 ;Up or down
sp\jmp.i = 0  ; No Jump
sp\maxjump = 490

Repeat
	
	ClearScreen(0)
	
	StartDrawing(ScreenOutput())
	DrawImage(ImageID(Img),0,0)
	StopDrawing()
	
	DisplayTransparentSprite(sp\ID, sp\x, sp\y)	
	
	ExamineKeyboard()	
	
	If KeyboardPushed(#PB_Key_Left)
		sp\x - 1
	EndIf
	
	If KeyboardPushed(#PB_Key_Right)
		sp\x + 1
	EndIf
	
	If KeyboardReleased(#PB_Key_Space) And sp\jmp = 0 ;No more jumps until a jump finishes
		sp\jmp = 1
	EndIf
	
	If sp\jmp = 1 And sp\UpDown = 0 ; Init jump still in progress
		If sp\y - 1 > 490
			sp\y - 1
		Else
			sp\UpDown = 1  ;Down down now...
		EndIf
	EndIf
	
	If sp\jmp = 1 And sp\UpDown = 1 ;Max height reached..Now return to 510
		If sp\y + 1 < 510
			sp\y  + 1
		Else
			sp\UpDown = 0
			sp\jmp = 0 ;Ready for new jump
		EndIf
	EndIf
	
	FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Best regards
Peter
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Help with 2D jump?

Post by Mythros »

Ugh, I'm having a MAJOR problem... It's saying line 84 is bugged because "2D #Sprite isn't initialized"....

How do I fix this? :( I've tried everything.

Also, I need a better way of loading animated sprites using only 1 sprite at a time, because I don't know how to return multiple sp\ID, sp\ID2's, etc.......

Here's the code:

Code: Select all

Structure Sprite3D_Data
   ID.i
   ID2.i
   x.i
   y.i
   maxjump.i
   UpDown.i 
   jmp.i
EndStructure

Structure Sprite3DCalculations
  Animate.l
  Loop.l
  LoopStart.l
EndStructure

Procedure.f curveValue(current.f, target.f, P.f)
  If P > 1000.0
    P = 1000.0
  EndIf
  ProcedureReturn (current + ( (target - current) * P / 1000.0))
EndProcedure

Procedure.f CurveAngle(oldangle.f,newangle.f, increments.f)
  If increments>1
    If (oldangle+360)-newangle<newangle-oldangle
      oldangle=360+oldangle
    EndIf
    If (newangle+360)-oldangle<oldangle-newangle
      newangle=360+newangle
    EndIf
    oldangle=oldangle-(oldangle-newangle)/increments
  EndIf
  
  If increments<=1
    ProcedureReturn newangle
  EndIf
  ProcedureReturn oldangle
EndProcedure

Global sp.Sprite3D_Data, Img.i

Global maxplayers = 1

Procedure.i Load_Player()
  
  Dim player(maxplayers)
  
  sp\ID = player(0)
  sp\ID2 = player(1)
  
  sp\UpDown = 0 ;Up or down
  sp\jmp.i = 0  ; No Jump
  sp\maxjump = 490
  
  CatchSprite(sp\ID, ?Pic1, #PB_Sprite_Memory | #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
  CatchSprite(sp\ID2, ?Pic2, #PB_Sprite_Memory | #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
  Sprite3DQuality(#PB_Sprite3D_NoFiltering | #PB_Sprite3D_BilinearFiltering)

EndProcedure

Procedure Load_Level(lvl=1)
  CatchSprite(3, ?Pic1, #PB_Sprite_Memory | #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
  Sprite3DQuality(#PB_Sprite3D_NoFiltering | #PB_Sprite3D_BilinearFiltering)
EndProcedure

Procedure Update_Player(Sprite3D, SpriteNumberFrom, SpriteNumberTo, FpsDelay) ;FpsDelay must have a value of 1 or higher in order to playback fps accurately

  Static Dim Sprites3D.Sprite3DCalculations(99) ;99 can be change to however many AnimatedSprite3D's you want to use
  
  If Sprites3D(Sprite3D)\LoopStart = 0 ;as it should when first started
      Sprites3D(Sprite3D)\Loop = FpsDelay ;we make sure we start the first sprite frame without delay or error
      Sprites3D(Sprite3D)\LoopStart = 1 ;then we kill it as this is only needed to start with
  EndIf
  
  If Sprites3D(Sprite3D)\Loop = FpsDelay ;if true we change to the next sprite frame
  
    If Sprites3D(Sprite3D)\Animate = (SpriteNumberTo - SpriteNumberFrom) +1 ;if the last sprite frame is used we need to restart from the first sprite frame
        Sprites3D(Sprite3D)\Animate = 0 ;reset Animate back to 0
    EndIf
    
      CreateSprite3D(Sprite3D, SpriteNumberFrom + Sprites3D(Sprite3D)\Animate) ;this keeps updating the sprite frames with the same Sprite3D
    
      Sprites3D(Sprite3D)\Animate +1 ;getting ready for the next sprite frame
      
      Sprites3D(Sprite3D)\Loop = 1 ;restart the FpsDelay loop
      
    Else
      
      Sprites3D(Sprite3D)\Loop +1 ;if the loop doesn't = FpsDelay we add +1 until it does
      
   EndIf
   
 EndProcedure
 
Procedure Load_Music()
  music = LoadSound(#PB_Any, "music/01-main-theme-overworld.ogg")
  PlaySound(music, #PB_Sound_Loop, 100)
EndProcedure

If InitKeyboard() = 0
   MessageRequester("Error!", "Keyboard system can not be initialized.", 0)
  End
EndIf

If InitSprite() = 0
   MessageRequester("Error!", "Sprite system can not be initialized.", 0)
  End
EndIf

If InitSprite3D() = 0
   MessageRequester("Error!", "Sprite3D system can't be initialized.", 0)
  End
EndIf

If InitMouse() = 0
   MessageRequester("Error!", "Mouse system can't be initialized.", 0)
  End
EndIf

If InitSound() = 0
   MessageRequester("Error!", "Sound system can't be initialized.", 0)
  End
EndIf

UseOGGSoundDecoder()
UsePNGImageDecoder()

OpenWindow(0, 0, 0, 800, 600, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 1, 0, 0, 0)
  
Global sp.Sprite3D_Data, Img.i
 
Load_Player()

Load_Music()

Start3D()
  Update_Player(sp\ID, 1, 1, 0) ;we use 4 as the FpsDelay, as 15fps is the actual fps. 4 / SetFrameRate(60) = 15
  Update_Player(sp\ID2, 1, 1, 0) ;we use 4 as the FpsDelay, as 15fps is the actual fps. 4 / SetFrameRate(60) = 15
Stop3D()
  
Global xoffset.f = 0
Global yoffset.f = 40

sp\x=0-xoffset
sp\y=WindowHeight(0)-SpriteHeight(1)-yoffset

Repeat
  
  Event = WindowEvent()
  
  Select Event
      
    Case #PB_Event_CloseWindow
      
      Quit = 1
      
  EndSelect
  
  ExamineKeyboard()

  SetFrameRate(60)
  FlipBuffers()
  ClearScreen(RGB(0, 0, 0))
   
  Start3D()
  
  If KeyboardPushed(#PB_Key_Right)
    Update_Player(sp\ID, 1, 2, 425) ;we use 4 as the FpsDelay, as 15fps is the actual fps. 4 / SetFrameRate(60) = 15
    Update_Player(sp\ID2, 1, 2, 425) ;we use 4 as the FpsDelay, as 15fps is the actual fps. 4 / SetFrameRate(60) = 15
    sp\x+0.07
  EndIf
  
  If KeyboardPushed(#PB_Key_Left)
    Update_Player(sp\ID, 1, 2, 425) ;we use 4 as the FpsDelay, as 15fps is the actual fps. 4 / SetFrameRate(60) = 15
    Update_Player(sp\ID2, 1, 2, 425) ;we use 4 as the FpsDelay, as 15fps is the actual fps. 4 / SetFrameRate(60) = 15
    sp\x-0.07
  EndIf
   
  If KeyboardReleased(#PB_Key_Space) And sp\jmp = 0 ;No more jumps until a jump finishes
    sp\jmp = 1
  EndIf
   
  If sp\jmp = 1 And sp\UpDown = 0 ; Init jump still in progress
    If sp\y - 1 > 490
      sp\y - 1
    Else
      sp\UpDown = 1  ;Down down now...
    EndIf
  EndIf
   
  If sp\jmp = 1 And sp\UpDown = 1 ;Max height reached..Now return to 510
    If sp\y + 1 < 510
      sp\y  + 1
    Else
      sp\UpDown = 0
      sp\jmp = 0 ;Ready for new jump
    EndIf
  EndIf
  
  DisplaySprite3D(sp\ID, sp\x, sp\y)
  DisplaySprite3D(sp\ID2, sp\x, sp\y)
  
  ;For x1 = 0 To WindowWidth(0)
    ;DisplaySprite3D(3, x1+SpriteWidth(3), WindowHeight(0)-SpriteHeight(3))
  ;Next
   
  Stop3D() 
      
  ExamineKeyboard()
  
Until KeyboardPushed(#PB_Key_Escape) Or Quit

Else
  
  MessageRequester("Error!", "Can not open an "+WindowWidth(0)+"x"+WindowHeight(0)+" - 0 bit screen.", 0)
  
EndIf

End

DataSection
  
  Pic1: IncludeBinary "images/mario00001.png"
  Pic2: IncludeBinary "images/mario00002.png"
  ;Pic3: IncludeBinary "images/block.png"
  
EndDataSection
I just can't seem to get your code to work nicely with my animation (Update_Player()) code. :(
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Help with 2D jump?

Post by DK_PETER »

Dear Mythros.

No offense intended, but you've GOT to read the manual and examine existing examples in great details.
Create small examples and reach a higher understanding of, what each function does.
Keep things very simple at the beginning and build upon the knowledge you've gained.

As I wrote:
Try something like this: It's extremely simple, but you should be able to adapt it to your needs:
Doing copy/paste like a 'pro' will definately not add any joy to your learning experience:
Understanding and having fun are the keywords here.

Best regards
Peter
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Help with 2D jump?

Post by Mythros »

Offense taken. I read the manual.. -.-
Nituvious
Addict
Addict
Posts: 999
Joined: Sat Jul 11, 2009 4:57 am
Location: United States

Re: Help with 2D jump?

Post by Nituvious »

His example works perfectly fine here. Maybe try changing his createsprite by removing the flags.
▓▓▓▓▓▒▒▒▒▒░░░░░
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Help with 2D jump?

Post by djes »

Calculated jump is always choosen by beginners, but when you're coming to collision, you have to deal with a lot of problems, the main one being to not jump through platforms or blocks. A thing to try is to create a precalculated table with a defined set of positions/speeds, and with a limited distance across two of them. This table is really easy to do with a simple sin() function for a jump, or as you did in your code. Don't forget the maximum velocity.
Post Reply