Cloning DEBRIS32 game

Advanced game related topics
User avatar
TheAutomator
Enthusiast
Enthusiast
Posts: 112
Joined: Tue Dec 01, 2020 8:33 pm

Cloning DEBRIS32 game

Post by TheAutomator »

I'm making a clone of an old asteroids game, it's called Debris32:

https://www.youtube.com/watch?v=grr7xluRmp0&t=1s

* Backstory alert! Skip if not interested! *

I played the demo of this nice game A LOT as a kid, the game was way ahead of it's time too!
Drove my dad crazy when i wanted to buy the game, he explained to me the game was to old and the "buy now" form was not valid anymore...

After looking for the full version for many many years i gave up for a while, i looked everywhere...
When I started to lose hope after countless years of messaging to retro game forums, even tried contacting MVP software (the company who used to sell this game)
it looked like i was never gonna find it...

It became a bit of an obsession for me, as a kid i always wanted to play the full version but the game was first released in 1996, in 1999 MVP software declared the game abandonware and it got lost... What can i say, childhood memories are very important for me. Dang i miss the early 2000's!

In the meantime I managed to find a cracked version, this modified version allowed you to use special cheat-codes and you were free from the 30 day limit in the demo version. However, this was still not the full version and it was missing graphics, extra's and levels...

I Also found some very old versions of Debris, you could only open those with a dos emulator ...and they kind of suck compared to the latest version haha.

One day I bumped onto a seller on a secondhand app who, unbelievably but true, still had a final release CD of this game!
It's even compatible with windows 7, 8 and 10!

* End of backstory *

Because i had so much fun with this game i wanna try to clone it and maybe add some new stuff too :D

The first step of cloning this game was extracting the graphics and sounds.
Those files are not embedded inside the EXE-file of Debris, but they are stored inside *.DAT-files. Extracting the soundfiles from "sounds.dat" was easy, just drag the file into a nice little tool called ResHacker and bam! You have the soundfiles.

But what about the graphics? Those seem to be stored in "graphics.dat", dragging it into ResHacker just gives me an error... I had no clue what to do so i started a new topic on this forum asking for help. I recently got a lot of help from a great guy here on the PB forum, he managed to extract some files and helped me WITH EVERY DAT-FILE here:

viewtopic.php?f=7&t=76636

@infratec, I can't thank you enough for this!

Thanks to the help of @infratec I have all the graphics now. The backgrounds of the game are also extracted (old *.PCX-files i had to convert to *.BMP-files somehow).

Getting started working with some little code i made, the spaceships and enemy's seem to use exactly 32 little sprites, each sprite is a slight rotation with different lighting to give it a 3D effect (pretty nifty).

360° / 32 sprites = 11.25°, that value seems to be the golden value for this game, every ship, rock and alien that needs to move or rotate to a certain direction does this with steps of 11.25 degrees at a time, this was designed so that they could align the rotation with one of the 32 sprites:

Image

I will reply on my own post with small updates and problems I'm bumping into for those who are interested or feel like helping me out :)
The files for this project will be uploaded to a google drive folder, for now it only contains everything i need to get started:

https://drive.google.com/drive/folders/ ... sp=sharing

And finally my code that I will update on the fly:

Code: Select all

; This is a copy of the game Debris32.
; It's programmed by TheAutomator (nickname) with the help of the purebasic forum members:
; https://www.purebasic.fr/english/viewtopic.php?f=16&t=76679&p=565219#p565219
; Search for "[TO DO]" to find code that is still under construction.

InitMouse()		; The functions here try to open DirectX (v3.0 With NT4.0 compatibility or v7.0 else).
InitSound()		; Returns nonzero if the mouse functions are availables, zero otherwise.
InitSprite()	; If it fails then DirectX is either not available or is too old be used.
InitKeyboard()	; Needs an IF-check! [TO DO]

; Declaring math constants:

#PI2 = #PI * 2
#Angle32 = 11.25 ; 360 degrees / 32 sprite images
#MaxAngle32 = 348.75

; Declaring game constants:

#Game_Width = 640
#Game_Height = 480
#Game_Center_X = 320
#Game_Center_Y = 240

; Opening a window for the game with a canvas to draw the graphics on:

OpenWindow(0, 0, 0, #Game_Width, #Game_Height, "Debris64", #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #Game_Width, #Game_Height, 0, 0, 0)

; We want a lower framerate for the game, still need to implement deltatime! [TO DO]

SetFrameRate(24)

; Loading sprites and sounds:

LoadSprite(0, "graphics\ship\newship1.bmp")
LoadSprite(1, "graphics\backgrounds\" + Random(14) + ".bmp")
LoadSprite(2, "graphics\frame\3_FRAMESET.bmp")

LoadSound(0, "sounds\Sound_009.wav")

; Structures:

Structure Craft
	ID.i		; Sprite ID
	Size.i	; Sprite size
	Index.i	; Sprite clipping index
	Center.i	; Sprite center
	X.f		; X-axis
	Y.f		; Y-axis
	Angle.f	; Angle
	Accel.f	; Acceleration
	Fric.f	; Friction
	VX.F		; X-velocity
	VY.F		; Y-velocity
	AI.i		; Computer controlled?
EndStructure

Structure Rock
	ID.i			; Sprite ID
	Size.i		; Size of rock / mine
	Index.i		; Sprite clipping index
	Center.i		; Sprite center
	X.f			; X-axis
	Y.f			; Y-axis
	VX.F			; X-velocity
	VY.F			; Y-velocity
	Type.i		; Type of rock / mine
	MaxHits.i	; Maximum amount of hits before it explodes
	Hits.i		; Amount of hits taken
EndStructure

; Creating objects for the game:

NewShip1.Craft
With NewShip1
	\ID = 0
	\X = #Game_Center_X
	\Y = #Game_Center_Y
	\Accel = 0.5
	\Fric = 0.98
	\Size = 32
	\Center = 16
EndWith

; Functions:

Procedure ThrusterSound()
	If SoundStatus(0) = #PB_Sound_Playing
		If GetSoundPosition(0) > 2500
			SetSoundPosition(0, 474)
		EndIf
	Else
		PlaySound(0)
	EndIf
EndProcedure

Procedure RotateCraft(*Ship.Craft)
	If *Ship\Angle < 0
		*Ship\Angle = #MaxAngle32
	EndIf
	If *Ship\Angle > #MaxAngle32
		*Ship\Angle = 0
	EndIf
	*Ship\Index = *Ship\Angle / #Angle32
	ClipSprite(*Ship\ID, *Ship\Size * *Ship\Index, 0, *Ship\Size, *Ship\Size)
EndProcedure

Procedure.f AngleDifference(*Aiming.craft, ObjectX, ObjectY)
	DeltaX.f = ObjectX - *Aiming\X
	DeltaY.f = ObjectY - *Aiming\Y
	Target.f = ATan2(-DeltaY, DeltaX) ; Y must be negative and comes first in 'Atan2'
	
	Target = Degree(Target)
	
	Angle.f = Mod(Target - *Aiming\Angle, 360)
	If Angle < -180
		Angle + 360
	ElseIf Angle > 180
		Angle - 360
	EndIf
	
	ProcedureReturn Angle
EndProcedure

Procedure.f Distance(*Aiming.craft, ObjectX, ObjectY)
	DeltaX.f = ObjectX - *Aiming\X
	DeltaY.f = ObjectY - *Aiming\Y
	ProcedureReturn Sqr(DeltaX * DeltaX + DeltaY * DeltaY)
EndProcedure

Procedure RenderShip(*Ship.Craft)
	*Ship\VX * *Ship\Fric
	*Ship\VY * *Ship\Fric
	
	*Ship\X + *Ship\VX
	*Ship\Y + *Ship\VY
	
	If *Ship\X < 0
		*Ship\X = #Game_Width
	ElseIf *Ship\X > #Game_Width
		*Ship\X = 0
	EndIf
	If *Ship\Y < 0
		*Ship\Y = #Game_Height
	ElseIf *Ship\Y > #Game_Height
		*Ship\Y = 0
	EndIf
	
	CX.f = *Ship\X-*Ship\Center
	CY.f = *Ship\Y-*Ship\Center
	
	DisplayTransparentSprite(*Ship\ID,	CX						, CY						)
	; Need to change this so it only draws more objects if necessary for speed! [TO DO]
	DisplayTransparentSprite(*Ship\ID,	CX - #Game_Width	, CY						)
	DisplayTransparentSprite(*Ship\ID,	CX + #Game_Width	, CY						)
	DisplayTransparentSprite(*Ship\ID,	CX						, CY - #Game_Height	)
	DisplayTransparentSprite(*Ship\ID,	CX						, CY + #Game_Height	)
	DisplayTransparentSprite(*Ship\ID,	CX - #Game_Width	, CY - #Game_Height	)
	DisplayTransparentSprite(*Ship\ID,	CX + #Game_Width	, CY + #Game_Height	)
	DisplayTransparentSprite(*Ship\ID,	CX - #Game_Width	, CY + #Game_Height	)
	DisplayTransparentSprite(*Ship\ID,	CX + #Game_Width	, CY - #Game_Height	)
EndProcedure

; Main loop:

RotateCraft(@NewShip1) ; Must do this once before we render the ships!

Repeat
	
	ExamineMouse()
	ExamineKeyboard()
	
	If KeyboardPushed(#PB_Key_Left)
		NewShip1\Angle - #Angle32
		RotateCraft(@NewShip1)
	EndIf
	If KeyboardPushed(#PB_Key_Right)
		NewShip1\Angle + #Angle32
		RotateCraft(@NewShip1)
	EndIf
	If KeyboardPushed(#PB_Key_Up)
		NewShip1\VX + NewShip1\Accel * Sin(Radian(NewShip1\Angle))
		NewShip1\VY - NewShip1\Accel * Cos(Radian(NewShip1\Angle))
		ThrusterSound()
	EndIf
	If KeyboardPushed(#PB_Key_Down)
		NewShip1\VX - NewShip1\Accel * Sin(Radian(NewShip1\Angle))
		NewShip1\VY + NewShip1\Accel * Cos(Radian(NewShip1\Angle))
		ThrusterSound()
	EndIf
	
	Dist.f = Distance(@NewShip1, MouseX(), MouseY())
	
	If Dist < 100
		
		Diff.f = AngleDifference(@NewShip1, MouseX(), MouseY())
		
		If Diff > 6
			NewShip1\Angle + #Angle32
			RotateCraft(@NewShip1)
		ElseIf Diff < -6
			NewShip1\Angle - #Angle32
			RotateCraft(@NewShip1)
		EndIf
		
		If Dist < 50
			
			NewShip1\VX - NewShip1\Accel * Sin(Radian(NewShip1\Angle))
			NewShip1\VY + NewShip1\Accel * Cos(Radian(NewShip1\Angle))
			ThrusterSound()
			
		ElseIf Dist < 300
		
			NewShip1\VX + NewShip1\Accel * Sin(Radian(NewShip1\Angle))
			NewShip1\VY - NewShip1\Accel * Cos(Radian(NewShip1\Angle))
			ThrusterSound()
		
		EndIf
		
	EndIf
	
	DisplaySprite(1, 0, 0) ; Stars overlay [TO DO]
	RenderShip(@NewShip1)
	DisplayTransparentSprite(2, MouseX()-7, MouseY()-6)
	
	StartDrawing(ScreenOutput())
	DrawText(50, 50, "Angle: " + Diff)
	DrawText(50, 70, "Distance: " + Dist)
	StopDrawing()
	
	FlipBuffers()
	
Until KeyboardPushed(#PB_Key_Escape)
Last edited by TheAutomator on Sat Feb 27, 2021 6:10 pm, edited 13 times in total.
User avatar
TheAutomator
Enthusiast
Enthusiast
Posts: 112
Joined: Tue Dec 01, 2020 8:33 pm

Re: Cloning DEBRIS32 game

Post by TheAutomator »

This works pretty well, but i need to change the framerate to delta time and timer stuff, for now this is good enough to start coding the spaceship's movements.

I will have to make an AI version for this ship too, here's where i'm a little stuck for now.
I know how to get the angle to aim at for an enemy or object (in this case i use the mouse):

Code: Select all

Repeat
	
	FlipBuffers() : ExamineKeyboard() : ExamineMouse()
	
	deltaX.f = MouseX() - ship\x
	deltay.f = MouseY() - ship\y
	angle.f = Degree(ATan2(deltaY, deltaX)) + 180 ; not sure this is the best way
	
	ship\Rotation = 360 - angle ; not sure this is the best way
	Debug ship\Rotation
	
; 	If ship\Rotation < angle
; 		ship\Rotation - #RotationStep
; 		If ship\Rotation < 0
; 			ship\Rotation = #RotationMax
; 		EndIf
; 	Else
; 		ship\Rotation + #RotationStep
; 		If ship\Rotation > #RotationMax
; 			ship\Rotation = 0
; 		EndIf
; 	EndIf
but i'm not sure how I would convert that angle so that it can snap to steps of 11.25°.
Maybe i'm missing something here? Maybe the original programmers had some kind of conversion system that simplified the 0 to 31 step system?
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Cloning DEBRIS32 game

Post by Mijikai »

Why even do it like that?
I would not risk using those sounds and sprites - u might get in trouble.
User avatar
TheAutomator
Enthusiast
Enthusiast
Posts: 112
Joined: Tue Dec 01, 2020 8:33 pm

Re: Cloning DEBRIS32 game

Post by TheAutomator »

Mijikai wrote:Why even do it like that?
I would not risk using those sounds and sprites - u might get in trouble.
For a game that's abandonware for years now, pretty much undefinable, that uses 16 bit quality sounds?
Rights of the game are from 1996 to 1999, i feel pretty safe :mrgreen:
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Cloning DEBRIS32 game

Post by STARGÅTE »

To calculate the direction or difference of one angle to the other you can use:

Code: Select all

	Procedure.f AngleDifference(fAngle1.f, fAngle2.f) ; Angles in units of radian!
		
		Protected fAngle.f = Mod(fAngle2 - fAngle1, 2*#PI)
		
		If fAngle > #PI
			ProcedureReturn fAngle - 2*#PI
		ElseIf fAngle < -#PI
			ProcedureReturn fAngle + 2*#PI
		Else
			ProcedureReturn fAngle
		EndIf
		
	EndProcedure
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cloning DEBRIS32 game

Post by infratec »

Code: Select all

          Case 46800
            XPixels = 312
            YPixels = 150
            Pictures = 1
GameOver
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cloning DEBRIS32 game

Post by infratec »

With Sprites, you need only one Ship:

Code: Select all

EnableExplicit

#w = 640
#h = 480
#RotationStep = 11.25
#RotationMax = 348.75

Enumeration
  #Sprite_Ship
  #Sprite_Background
  #Sprite_Background_End = #Sprite_Background + 4
  #Sprite_GameOver
  #Font_5x9
  #Font_5x9_End = #Font_5x9 + 96
  #Font_7x11
  #Font_7x11_End = #Font_7x11 + 96
  #ThruSet
  #Thruset_End = #ThruSet + 8
EndEnumeration


Structure Object
  Rotation.f
  Image.i
  Size.i
  X.f
  Y.f
  VelocityX.f
  VelocityY.f
  Acceleration.f
  Friction.f
EndStructure



Procedure.i DisplayText(Font.i, x.i, y.i, *Text.Character)
  
  Protected.i i, Width
  Protected *Ptr.Character
  
  
  Width = SpriteWidth(Font)
  
  *Ptr = *Text
  While *Ptr\c
    DisplayTransparentSprite(Font + *Ptr\c - ' ', x + Width * i, y)
    *Ptr + 2
    i + 1
  Wend
  
EndProcedure


Procedure ThrusterSound()
  If SoundStatus(0) = #PB_Sound_Playing
    If GetSoundPosition(0) > 2500
      SetSoundPosition(0, 474)
    EndIf
  Else
    PlaySound(0)
  EndIf
EndProcedure




Define.i GameOver, Exit, i, Img, Score, ThrustIndex, BackgroundIndex
Define Score$
Define Ship.Object


InitSound()
InitSprite()
InitMouse()
InitKeyboard()

UsePNGImageDecoder()

OpenWindow(0, 0, 0, #w, #h, "Debris64", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #w, #h)

SetFrameRate(30)


LoadSprite(#Sprite_Ship, "Images/NEWSHIP1.png")
For i = 0 To 3
  LoadSprite(#Sprite_Background + i, "Images/BKGND0" + Str(i + 1) + ".png")
Next i
LoadSprite(#Sprite_GameOver, "Images/GAMEOVER.png")
LoadSound(0, "Sound/Sound_009.wav")

If LoadImage(#Font_5x9, "Images/FONT5X9.png")
  For i = 0 To 95
    Img = GrabImage(#Font_5x9, #PB_Any, 5 * i, 0, 5, 9)
    If Img
      If CreateSprite(#Font_5x9 + i, 5, 9)
        If StartDrawing(SpriteOutput(#Font_5x9 + i))
          DrawImage(ImageID(Img), 0, 0)
          StopDrawing()
        EndIf
      EndIf
      FreeImage(Img)
    EndIf
  Next i
  FreeImage(#Font_5x9)
EndIf

If LoadImage(#Font_7x11, "Images/FONT7X11.png")
  For i = 0 To 95
    Img = GrabImage(#Font_7x11, #PB_Any, 7 * i, 0, 7, 11)
    StopDrawing()
    If Img
      If CreateSprite(#Font_7x11 + i, 7, 11)
        If StartDrawing(SpriteOutput(#Font_7x11 + i))
          DrawImage(ImageID(Img), 0, 0)
          StopDrawing()
        EndIf
      EndIf
      FreeImage(Img)
    EndIf
  Next i
  FreeImage(#Font_7x11)
EndIf

If LoadImage(#ThruSet, "Images/THRUSET1.png")
  
  Img = GrabImage(#ThruSet, #PB_Any, 0, 0, 9, 8)
  If Img
    CreateSprite(#ThruSet + 0, 9, 8)
    If StartDrawing(SpriteOutput(#ThruSet + 0))
      DrawImage(ImageID(Img), 0, 0)
      StopDrawing()
    EndIf
    FreeImage(Img)
  EndIf
  
  Img = GrabImage(#ThruSet, #PB_Any, 9, 0, 9, 8)
  If Img
    CreateSprite(#ThruSet + 1, 9, 8)
    If StartDrawing(SpriteOutput(#ThruSet + 1))
      DrawImage(ImageID(Img), 0, 0)
      StopDrawing()
    EndIf
    FreeImage(Img)
  EndIf
  
  Img = GrabImage(#ThruSet, #PB_Any, 0, 8, 9, 8)
  If Img
    CreateSprite(#ThruSet + 2, 9, 8)
    If StartDrawing(SpriteOutput(#ThruSet + 2))
      DrawImage(ImageID(Img), 0, 0)
      StopDrawing()
    EndIf
    FreeImage(Img)
  EndIf
  
  Img = GrabImage(#ThruSet, #PB_Any, 9, 8, 9, 8)
  If Img
    CreateSprite(#ThruSet + 3, 9, 8)
    If StartDrawing(SpriteOutput(#ThruSet + 3))
      DrawImage(ImageID(Img), 0, 0)
      StopDrawing()
    EndIf
    FreeImage(Img)
  EndIf
  
  Img = GrabImage(#ThruSet, #PB_Any, 0, 16, 9, 4)
  If Img
    CreateSprite(#ThruSet + 4, 9, 8)
    If StartDrawing(SpriteOutput(#ThruSet + 4))
      DrawImage(ImageID(Img), 0, 0)
      StopDrawing()
    EndIf
    FreeImage(Img)
  EndIf
  
  Img = GrabImage(#ThruSet, #PB_Any, 9, 16, 9, 4)
  If Img
    CreateSprite(#ThruSet + 5, 9, 8)
    If StartDrawing(SpriteOutput(#ThruSet + 5))
      DrawImage(ImageID(Img), 0, 0)
      StopDrawing()
    EndIf
    FreeImage(Img)
  EndIf
  
  Img = GrabImage(#ThruSet, #PB_Any, 0, 20, 9, 4)
  If Img
    CreateSprite(#ThruSet + 6, 9, 8)
    If StartDrawing(SpriteOutput(#ThruSet + 6))
      DrawImage(ImageID(Img), 0, 0)
      StopDrawing()
    EndIf
    FreeImage(Img)
  EndIf
  
  Img = GrabImage(#ThruSet, #PB_Any, 9, 20, 9, 4)
  If Img
    CreateSprite(#ThruSet + 7, 9, 8)
    If StartDrawing(SpriteOutput(#ThruSet + 7))
      DrawImage(ImageID(Img), 0, 0)
      StopDrawing()
    EndIf
    FreeImage(Img)
  EndIf
  
  FreeImage(#ThruSet)
EndIf


ship\X = #w / 2
ship\Y = #h / 2
ship\Size = SpriteWidth(1)
ship\Acceleration = 0.5
ship\Friction = 0.98
ship\Image = #Sprite_Ship



;--------------------------------------------------------------------------------------------------------

Repeat
  
  FlipBuffers() : ExamineKeyboard() : ExamineMouse()
  
  If KeyboardReleased(#PB_Key_LeftAlt)
    BackgroundIndex + 1
    If BackgroundIndex = 4
      BackgroundIndex = 0
    EndIf
  EndIf
  
  DisplaySprite(#Sprite_Background + BackgroundIndex, 0, 0)
  
  Score + 1
  
  Score$ = "Score: " + Str(Score)
  DisplayText(#Font_7x11, 10, 10, @Score$)
  DisplayText(#Font_5x9, 10, 30, @Score$)
  
  If KeyboardPushed(#PB_Key_Right)
    ship\Rotation + #RotationStep
    If ship\Rotation > #RotationMax
      ship\Rotation = 0
    EndIf
  EndIf
  
  If KeyboardPushed(#PB_Key_Left)
    ship\Rotation - #RotationStep
    If ship\Rotation < 0
      ship\Rotation = #RotationMax
    EndIf
  EndIf
  
  If KeyboardPushed(#PB_Key_Up)
    ship\VelocityX + ship\Acceleration * Sin(Radian(ship\Rotation))
    ship\VelocityY - ship\Acceleration * Cos(Radian(ship\Rotation))
    ThrustIndex = 0
    DisplaySprite(#ThruSet + ThrustIndex, ship\X, ship\Y)
    ThrusterSound()
  EndIf
  
  If KeyboardReleased(#PB_Key_Up)
    
  EndIf
  
  If KeyboardPushed(#PB_Key_Down)
    ship\VelocityX - ship\Acceleration * Sin(Radian(ship\Rotation))
    ship\VelocityY + ship\Acceleration * Cos(Radian(ship\Rotation))
    ThrusterSound()
  EndIf
  
  If KeyboardPushed(#PB_Key_Escape)
    GameOver = #True
  EndIf
  
  
  
  If ship\x < 0
    ship\x = #w
  ElseIf ship\x > #w
    ship\x = 0
  EndIf
  
  If ship\y < 0
    ship\y = #h
  ElseIf ship\y > #h
    ship\y = 0
  EndIf
  
  ship\x + ship\VelocityX
  ship\y + ship\VelocityY
  
  ship\VelocityX * ship\Friction
  ship\VelocityY * ship\Friction
  
  
  If GameOver
    
    DisplayTransparentSprite(#Sprite_GameOver, 164, 165)
    
    If KeyboardReleased(#PB_Key_Escape)
      Exit = #True
    EndIf
    
  Else
    
    RotateSprite(ship\Image, ship\Rotation, #PB_Absolute)
    DisplayTransparentSprite(ship\Image, ship\X, ship\Y)
    
    ; screen wrapping effect:
    
    If ship\X + ship\Size > #w
      DisplayTransparentSprite(ship\Image, ship\X - #w, ship\Y)
    EndIf
    If ship\Y + ship\Size > #h
      DisplayTransparentSprite(ship\Image, ship\X, ship\Y - #h)
    EndIf
    If ship\X + ship\Size > #w And ship\Y + ship\Size > #h
      DisplayTransparentSprite(ship\Image, ship\X - #w, ship\Y - #h)
    EndIf
    
  EndIf
  
Until Exit
Last edited by infratec on Wed Feb 03, 2021 9:46 am, edited 2 times in total.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Cloning DEBRIS32 game

Post by infratec »

With the new Fontextracor you can create one Font png file.
This is now used above to display text.
ricardo_sdl
Enthusiast
Enthusiast
Posts: 109
Joined: Sat Sep 21, 2019 4:24 pm

Re: Cloning DEBRIS32 game

Post by ricardo_sdl »

Nice project! :)
For a single sprite I thinks it's easier to store the sprite at the 0° degree angle (pointing straight right), and use RotateSprite(#Sprite, Angle.f, Mode) to whatever angle you want.
I created this example to show how to handle negative and positive angles, you can set CurrentShipAngle to any angle you want:

Code: Select all

EnableExplicit

#Game_Width = 640
#Game_Height = 360
#Num_Ship_Sprites = 32
#Angle_Interval = 360.0 / #Num_Ship_Sprites
Debug #Angle_Interval
Global Event, ElapsedTimneInS.f, LastTimeInMs, Time.f = 0
;the ship angle starts at zero (the sprite pointing straight right)
;positive angles go down (or clockwise ), negative angles go up (or counter clockwise)
Global CurrentShipAngle.f = 0
Global AngleDirection = 1, AngularSpeed.f = 60


Procedure LoadShipSprites()
  Protected i
  For i = 0 To 31
    ;the sprite that we are using as the 0 angle is the 8th sprite, so the
    ;sprite 0 will the the Ship/8.bmp, sprite 1 will be Ship/9.bmp...
    ;sprite 31 will be Ship/7.bmp, the module make the numbers wrap around,
    ;so the 24th sprite will be the file Ship/0.bmp ((24 + 8) % 32 = 0)
    LoadSprite(i, "Ship/" + Str((i + 8) % 32) + ".bmp")
  Next
EndProcedure




InitSprite()
InitKeyboard()

OpenWindow(1, 0, 0, #Game_Width, #Game_Height,"Ship Rotation", #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(1), 0, 0, #Game_Width, #Game_Height, 0, 0, 0)


LoadShipSprites()

ClearScreen(#Black)

Repeat
  ElapsedTimneInS = (ElapsedMilliseconds() - LastTimeInMs) / 1000.0
  
  LastTimeInMs = ElapsedMilliseconds()
  ExamineKeyboard()
  event = WindowEvent()
  ;you can use the left and right keys to change the direction of
  ;rotation
  If KeyboardReleased(#PB_Key_Left)
    AngleDirection = -1
  EndIf
  If KeyboardReleased(#PB_Key_Right)
    AngleDirection = 1
  EndIf
  
  If KeyboardPushed(#PB_Key_Up)
    AngularSpeed + 10
  EndIf
  If KeyboardReleased(#PB_Key_Down)
    AngularSpeed - 10
    If AngularSpeed < 0
      AngularSpeed = 0
    EndIf
    
  EndIf
  
  
  
  ;update
  ;for only positive angles we could do:
  ;CurrentSprite = CurrentShipAngle / #Angle_Interval
  ;this is to allow negative angles
  Define CurrentSprite = (360 + Mod(CurrentShipAngle, 360)) / #Angle_Interval
  
  CurrentSprite % #Num_Ship_Sprites
  CurrentShipAngle + AngularSpeed * AngleDirection * ElapsedTimneInS
  ;draw
  ClearScreen(#Black)
  DisplaySprite(CurrentSprite, #Game_Width / 2 - SpriteWidth(CurrentSprite) / 2,
                #Game_Height / 2 - SpriteHeight(CurrentSprite) / 2)
  
  StartDrawing(ScreenOutput())
  DrawText(50, 50, "Current Angle:" + StrF(CurrentShipAngle))
  DrawText(50, 70, "Current Angular Speed:" + StrF(AngularSpeed))
  StopDrawing()
  
  FlipBuffers()
  
Until event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
End
Just put it at the same directory as Ship directory.
I hope it can help! Good luck!
You can check my games at:
https://ricardo-sdl.itch.io/
User avatar
TheAutomator
Enthusiast
Enthusiast
Posts: 112
Joined: Tue Dec 01, 2020 8:33 pm

Re: Cloning DEBRIS32 game

Post by TheAutomator »

STARGÅTE wrote:To calculate the direction or difference of one angle to the other you can use...
So how would i implement this code for this game actually?
What other angle should it be compared to? the previous one?

Code: Select all

Debug Degree(AngleDifference(Angle, ship\Rotation))
gives me:
-68.195409050967015
15.270909625557829
32.874656701755171
-50.646006374900871
37.773459619785079
179.25577393661339
172.2726021895707
-47.586938815475996
81.211283910720937
-46.676529240626657
-82.781592212231061
127.45724485625917
User avatar
TheAutomator
Enthusiast
Enthusiast
Posts: 112
Joined: Tue Dec 01, 2020 8:33 pm

Re: Cloning DEBRIS32 game

Post by TheAutomator »

infratec wrote:

Code: Select all

          Case 46800
            XPixels = 312
            YPixels = 150
            Pictures = 1
GameOver
Added! Thanks :)

Can you show me how you get those values? I'm trying to figure out how to get the tiny rocks, at the moment.. (graphics from full version in drive folder)
They are distorted when I run your code (because they differ in size i guess) and i want to see if i can figure this out without having to bother you with it all the time :)
Last edited by TheAutomator on Wed Feb 03, 2021 5:07 pm, edited 1 time in total.
User avatar
TheAutomator
Enthusiast
Enthusiast
Posts: 112
Joined: Tue Dec 01, 2020 8:33 pm

Re: Cloning DEBRIS32 game

Post by TheAutomator »

infratec wrote:With the new Fontextracor you can create one Font png file.
This is now used above to display text.
Nice! That's awesome!! :D
User avatar
TheAutomator
Enthusiast
Enthusiast
Posts: 112
Joined: Tue Dec 01, 2020 8:33 pm

Re: Cloning DEBRIS32 game

Post by TheAutomator »

infratec wrote:With Sprites, you need only one Ship...
Not true actually, then you lose the cool 3D effect and the ship looks weird in some angles..

I tested the new font code you posted and it woks like a charm! :)
Why do you prefer PNG images?

although i don't get why you added the THRUSET1 image next to the ship, those are used as particles:
https://www.youtube.com/watch?v=grr7xluRmp0&t=274s
For that i'm gonna make some particle generator i think.
User avatar
TheAutomator
Enthusiast
Enthusiast
Posts: 112
Joined: Tue Dec 01, 2020 8:33 pm

Re: Cloning DEBRIS32 game

Post by TheAutomator »

ricardo_sdl wrote:Nice project! :)
For a single sprite I thinks it's easier to store the sprite at the 0° degree angle (pointing straight right), and use RotateSprite(#Sprite, Angle.f, Mode) to whatever angle you want.
I created this example to show how to handle negative and positive angles, you can set CurrentShipAngle to any angle you want...

Just put it at the same directory as Ship directory.
I hope it can help! Good luck!
Awesome! Thanks man! I'm gonna implement this after work :)
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Cloning DEBRIS32 game

Post by STARGÅTE »

TheAutomator wrote:
STARGÅTE wrote:To calculate the direction or difference of one angle to the other you can use...
So how would i implement this code for this game actually?
What other angle should it be compared to? the previous one?
You have to compare the current angle of the ship, with the angle directed from ship to the your cursor. Then the results gives you the difference of rotation to look to the cursor. This value can be used to change the rotation either in one or in the other direction.
TheAutomator wrote:
infratec wrote:With Sprites, you need only one Ship...
Not true actually, then you lose the cool 3D effect and the ship looks weird in some angles..
Have you checked out this 2D render engine UB2D - 2D Physically Based Rendering Engine.
There you can create a single sprite with normal map and light sources, which generated a 3D effect.

! Please do not make double post, you can edit your last post !
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Post Reply