experimenting with sprites

Game development specific discussions.
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: experimenting with sprites

Post by ron77 »

hello and good day to you @BasicCoder2 @Sero and @MrSwiss... i thank all of you together and separately for your advice and for helping me get better and improve my coding - i really appreciate your replies!...

today i will examine the correct way to work with sprites (with out "SHARED" and with as less "INTEGER" as possible) and later i plan to try to work with two or more sprites either by changing the sprites by pressing a key or by making two characters (one of the player and second by the computer)...

@MrSwiss and @Sero i will try to embrace your recommendations for coding correctly

@BasicCoder2 yes i think you spotted where this particular sprites is originally taken from and i thank you for showing me a very basics of actually dealing with sprites...

i have a question and declaring the pointer to the sprite sheet

there are two options to declare it one is:

Code: Select all

dim as any ptr sprite_sheet
the other way is by using FB.image

Code: Select all

dim sprite_sheet as FB.image ptr
what are the difference between these two? and which is the preferred option or more correct option?

it seems to me the using to declare with "FB.image" is when you use it in a UDT... am i correct?
ron77 :)
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: experimenting with sprites

Post by BasicCoder2 »

Your interest has piqued my interest in improving how I code.
Last edited by BasicCoder2 on Feb 12, 2021 15:42, edited 1 time in total.
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: experimenting with sprites

Post by ron77 »

hello @BasicCoder2 !

i'm happy you are inspired to improve the way you code!... UDT and OOP is not that hard once you experiment while reading the FB documentation and following others code - i believe everyone can improve their coding habits and style - keep trying and i'm sure you'll become a better coder and programmer :)

ron77
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: experimenting with sprites

Post by MrSwiss »

Hi ron77,

FB.image ptr is a type ptr that is defined in "fbgfx.bi".
More precisely: the type image itself is defined there ...
However, it can be substituted with: any ptr (for a generic image handle).

NOTE: FB.image [ptr] implies, that it's defined in the "FB" namespace.

For more in depth information open fbgfx.bi in your Editor/IDE (it's plain "fb"-code).
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: experimenting with sprites

Post by ron77 »

hello everyone... today i tried to add another type with a sprite and make a chase between the player and the enemy - just a simple chase between them i'm using the same sprites i gave earlier... the code had errors i didn't noticed but after a close inspection i discovered what was the errors and i made the enemy type with the sub that handles the chase

here is the updated code based on @Sero example

Code: Select all

#INCLUDE "fbgfx.bi"
using fb

type t_object
  x         as single
  y         as single
  speed     as single
  frame     as long
  direction as long
  move      as boolean
  attack    as long
  alive     as long
end type

type enemy_object
  x         as single
  y         as single
  speed     as single
  frame     as long
  direction as long
  move      as boolean
  attack    as long
  alive     as LONG
  DECLARE SUB CHASE(px AS SINGLE, py AS SINGLE)
end TYPE

SUB enemy_object.chase(px AS single, py AS SINGLE) 
   WITH THIS
   IF px > x THEN
      x = x + speed
      direction = 1
      move = TRUE
   ENDIF
      IF px < x THEN
         x = x - speed
         direction = 2
         move = TRUE
      ENDIF
   
   IF py > y THEN
      y = y + speed
      direction = 3
      move = TRUE
   ENDIF
         IF py < y THEN
         y = y - speed
         direction = 4
         move = TRUE
      ENDIF
   
   END WITH 
END SUB

DIM player as t_object
DIM enemy AS enemy_object


dim as long screen_w = 640
dim as long screen_h = 480
screenres( screen_w, screen_h, 32 )
color rgb( 0, 0, 0), rgb( 120, 120, 120 ) : cls

player.x = 150
player.y = 90
player.speed = 1
player.direction = 1

enemy.x = 20
enemy.y = 10
enemy.speed = 0.5
enemy.direction = 1

dim as any ptr sprite_sheet, sheet2
sprite_sheet = imagecreate( 288, 22 )
bload "sprites.bmp", sprite_sheet

sheet2 = IMAGECREATE(768,64)
BLOAD "Holly\Aerial_swing (64 x 64).bmp", sheet2

dim as long frame
dim as long frame2

dim as double start_time
start_time = timer()



do
  player.move = false
  if( multikey( SC_RIGHT ) ) then
    player.x = player.x + player.speed
    player.direction = 1
    player.move = true
  else
    if( multikey( SC_LEFT ) ) then
      player.x = player.x - player.speed
      player.direction = 2
      player.move = true
    end if
  end if
  if( multikey( SC_DOWN ) ) then
    player.y = player.y + player.speed
    player.direction = 3
    player.move = true
  else
    if( multikey( SC_UP ) ) then
      player.y = player.y - player.speed
      player.direction = 4
      player.move = true
    end if
  end if
   
   
   
  if( player.x < 0 ) then
    player.move = false
    player.x = 0
  else
    if( player.x > 640 - 22 ) then
      player.move = false
      player.x = 640 - 22
    end if
  end if
  if( player.y < 0 ) then
    player.move = false
    player.y = 0
  else
    if( player.y > 480 - 22 ) then
      player.move = false
      player.y = 480 - 22
    end if
  end if
  
  IF enemy.x < 0 THEN
     enemy.x = 0
  ELSE
     IF enemy.x > 640 - 64 THEN
        enemy.x = 640 - 64
     ENDIF
  ENDIF
  IF enemy.y < 0 THEN
     enemy.y = 0
  ELSE
     IF enemy.y > 480 - 64 THEN
        enemy.y = 480 - 64
     ENDIF
  ENDIF
  
  
  if( player.direction = 1 ) then player.frame = 6 + frame
  if( player.direction = 2 ) then player.frame = 4 + frame
  if( player.direction = 3 ) then player.frame = 0 + frame
  if( player.direction = 4 ) then player.frame = 2 + frame
 
  
  
  if( timer() - start_time > 0.05 ) then ' next frame
    start_time = timer() ' reset start_time
   
    frame += 1 ' advance our frame
    if( player.move = false ) or ( frame > 1 ) then frame = 0 ' check for idle state and if frame has gone too far
   
    screenlock()
      cls
      put( player.x, player.y ), sprite_sheet, ( player.frame * 24, 0 )-( player.frame * 24 + 23, 21 ), trans
      'line( player.x, player.y )-( player.x + 23, player.y + 21 ), rgb( 255, 0, 0 ), b ' this outlines the sprite graphic
      PUT (enemy.x, enemy.y), sheet2, (frame2*64,0)-(frame2*64+63,64), TRANS
      
    screenunlock()
     frame2 += 1
     IF frame2 > 11 THEN frame2 = 0
  end if
  sleep( 15 )
  enemy.CHASE(player.x,player.y)
loop until multikey( &h01 ) ' escape key
ron77
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: experimenting with sprites

Post by ron77 »

hello everybody and a good day :)

in this example i'm using the same sprites for the player and the enemy and the enemy is chasing the player...

Code: Select all

#INCLUDE "fbgfx.bi"
using fb

type t_object
  x         as single
  y         as single
  speed     as single
  frame     as long
  direction as long
  move      as boolean
  attack    as long
  alive     as long
end type

type enemy_object
  x         as single
  y         as single
  speed     as single
  frame     as long
  direction as long
  move      as boolean
  attack    as long
  alive     as LONG
  DECLARE SUB CHASE(px AS SINGLE, py AS SINGLE)
end TYPE

SUB enemy_object.chase(px AS single, py AS SINGLE) 
   WITH THIS
   IF px > x THEN
      x = x + speed
      direction = 1
      move = TRUE
   ENDIF
      IF px < x THEN
         x = x - speed
         direction = 2
         move = TRUE
      ENDIF
   
   IF py > y THEN
      y = y + speed
      direction = 3
      move = TRUE
   ENDIF
         IF py < y THEN
         y = y - speed
         direction = 4
         move = TRUE
      ENDIF
   
   END WITH 
END SUB

DIM player as t_object
DIM enemy AS enemy_object


dim as long screen_w = 640
dim as long screen_h = 480
screenres( screen_w, screen_h, 32 )
color rgb( 0, 0, 0), rgb( 120, 120, 120 ) : cls

player.x = 150
player.y = 90
player.speed = 1
player.direction = 1

enemy.x = 20
enemy.y = 10
enemy.speed = 0.5
enemy.direction = 1

dim as any ptr sprite_sheet, sheet2
sprite_sheet = imagecreate( 288, 22 )
BLOAD "sprites.bmp", sprite_sheet
sheet2 = IMAGECREATE(288,22)
BLOAD "sprites.bmp", sheet2
'sheet2 = IMAGECREATE(768,64)
'BLOAD "Holly\Aerial_swing (64 x 64).bmp", sheet2

dim as long frame
dim as long frame2

dim as double start_time
start_time = timer()



do
  player.move = false
  if( multikey( SC_RIGHT ) ) then
    player.x = player.x + player.speed
    player.direction = 1
    player.move = true
  else
    if( multikey( SC_LEFT ) ) then
      player.x = player.x - player.speed
      player.direction = 2
      player.move = true
    end if
  end if
  if( multikey( SC_DOWN ) ) then
    player.y = player.y + player.speed
    player.direction = 3
    player.move = true
  else
    if( multikey( SC_UP ) ) then
      player.y = player.y - player.speed
      player.direction = 4
      player.move = true
    end if
  end if
   
   
   
  if( player.x < 0 ) then
    player.move = false
    player.x = 0
  else
    if( player.x > 640 - 22 ) then
      player.move = false
      player.x = 640 - 22
    end if
  end if
  if( player.y < 0 ) then
    player.move = false
    player.y = 0
  else
    if( player.y > 480 - 22 ) then
      player.move = false
      player.y = 480 - 22
    end if
  end if
  
  IF enemy.x < 0 THEN
     enemy.x = 0
  ELSE
     IF enemy.x > 640 - 64 THEN
        enemy.x = 640 - 64
     ENDIF
  ENDIF
  IF enemy.y < 0 THEN
     enemy.y = 0
  ELSE
     IF enemy.y > 480 - 64 THEN
        enemy.y = 480 - 64
     ENDIF
  ENDIF
  
  
  if( player.direction = 1 ) then player.frame = 6 + frame
  if( player.direction = 2 ) then player.frame = 4 + frame
  if( player.direction = 3 ) then player.frame = 0 + frame
  if( player.direction = 4 ) then player.frame = 2 + frame
  
  IF enemy.direction = 1 THEN enemy.frame = 6 + frame2
  IF enemy.direction = 2 THEN enemy.frame = 4 + frame2
  IF enemy.direction = 3 THEN enemy.frame = 0 + frame2
  IF enemy.direction = 4 THEN enemy.frame = 2 + frame2
  
  if( timer() - start_time > 0.05 ) then ' next frame
    start_time = timer() ' reset start_time
   
    frame += 1 ' advance our frame
    frame2 += 1
    if( player.move = false ) or ( frame > 1 ) then frame = 0 ' check for idle state and if frame has gone too far
    IF (frame2 >1 ) THEN frame2 = 0
    screenlock()
      cls
      put( player.x, player.y ), sprite_sheet, ( player.frame * 24, 0 )-( player.frame * 24 + 23, 21 ), trans
      'line( player.x, player.y )-( player.x + 23, player.y + 21 ), rgb( 255, 0, 0 ), b ' this outlines the sprite graphic
      'PUT (enemy.x, enemy.y), sheet2, (frame2*64,0)-(frame2*64+63,64), TRANS
      put( enemy.x, enemy.y ), sheet2, ( enemy.frame * 24, 0 )-( enemy.frame * 24 + 23, 21 ), TRANS
    screenunlock()
     'frame2 += 1
     'IF frame2 > 11 THEN frame2 = 0
  end if
  sleep( 15 )
  enemy.CHASE(player.x,player.y)
loop until multikey( &h01 ) ' escape key
ron77 :)
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: experimenting with sprites

Post by BasicCoder2 »

@ron77

You only need one SPRITE class

Code below is a move in that direction.

Remember literals are not a good thing. You need to be able to handle different sized sprites.

Attached are larger sprites as they are easier for me to see :)

If you want to try the large sprites just edit these lines,

Code: Select all

const SPRW = 24
const SPRH = 22
'const SPRW = 48
'const SPRH = 44
and

Code: Select all

sheet = imagecreate( 288, 22 )
BLOAD "sprites.bmp", sheet
'sheet = imagecreate( 576, 78 )
'BLOAD "warriorLarge.bmp", sheet

Code: Select all

#INCLUDE "fbgfx.bi"
using fb
const SPRW = 24
const SPRH = 22
'const SPRW = 48
'const SPRH = 44

const screen_w = 640
const screen_h = 480

type SPRITE
  x         as single
  y         as single
  speed     as single
  frame     as long
  direction as long
  xpos      as integer   'position on sprite sheet
  move      as boolean
  attack    as long
  alive     as long
  
  sheet     as any ptr
  
  declare sub chase(s as SPRITE)
  declare sub Initialize(sheet as any ptr, x as single, y as single, s as single, d as long)
  declare sub Update()
  declare sub Draw()
  
end type

SUB SPRITE.chase(s as SPRITE)

     IF this.x < s.x THEN
         this.x = this.x + this.speed
         this.direction = 1
         this.move = TRUE
     END IF
   
     IF this.x > s.x THEN
         this.x = this.x - this.speed
         this.direction = 2
         this.move = TRUE
    END IF
   
    IF this.y < s.y THEN
       this.y = this.y + this.speed
       this.direction = 3
       this.move = TRUE
    END IF
    
    IF this.y > s.y THEN
         this.y = this.y - this.speed
         this.direction = 4
         this.move = TRUE
    END IF
   

END SUB

Sub SPRITE.Initialize(sheet as any ptr, x as single,y as single,s as single,d as long)
    this.x = x
    this.y = y
    this.speed = s
    this.direction = d
    this.sheet = sheet
End SUb

sub SPRITE.Draw()
      put( this.x, this.y ), this.sheet, ( this.xpos + this.frame * SPRW, 0 )-( this.xpos + this.frame * SPRW + SPRW-1, SPRH-1 ), trans
end sub

sub SPRITE.update()
    'test for border overlap
    if( this.x < 0 ) then
        this.move = false
        this.x = 0
    else
        if( this.x > screen_w - SPRW ) then
           this.move = false
           this.x = screen_w - SPRW
        end if
    end if
    if( this.y < 0 ) then
        this.move = false
        this.y = 0
    else
        if( this.y > screen_h - SPRH ) then
          this.move = false
          this.y = screen_h - SPRH
        end if
    end if
    'set xpos number for given direction
    if( this.direction = 1 ) then this.xpos = 6 * SPRW
    if( this.direction = 2 ) then this.xpos = 4 * SPRW
    if( this.direction = 3 ) then this.xpos = 0 * SPRW
    if( this.direction = 4 ) then this.xpos = 2 * SPRW
    'update frame
    this.frame = this.frame + 1
    if this.frame=2 then this.frame = 0

end sub


DIM player as SPRITE
DIM enemy AS SPRITE

screenres( screen_w, screen_h, 32 )
color rgb( 0, 0, 0), rgb( 120, 120, 120 ) : cls

dim as any ptr sheet
sheet = imagecreate( 288, 22 )
BLOAD "sprites.bmp", sheet
'sheet = imagecreate( 576, 78 )
'BLOAD "warriorLarge.bmp", sheet

player.Initialize(sheet,150,90,1,1)
enemy.Initialize(sheet,20,10,0.5,1)

dim as double start_time
start_time = timer()

do
    
    'USER INPUT
    player.move = false
    if( multikey( SC_RIGHT ) ) then
        player.x = player.x + player.speed
        player.direction = 1
        player.move = true
    else
        if( multikey( SC_LEFT ) ) then
            player.x = player.x - player.speed
            player.direction = 2
            player.move = true
        end if
    end if
    if( multikey( SC_DOWN ) ) then
        player.y = player.y + player.speed
        player.direction = 3
        player.move = true
    else
        if( multikey( SC_UP ) ) then
          player.y = player.y - player.speed
          player.direction = 4
          player.move = true
        end if
    end if
 
    if( timer() - start_time > 0.05 ) then ' next frame
        start_time = timer() ' reset start_time
    
        player.update()
        enemy.update()
        screenlock()
        cls
        player.Draw()
        enemy.Draw()
        screenunlock()
    
    end if
  
    sleep( 15 )

  
    enemy.CHASE(player)  'chase the player
  
loop until multikey(SC_ESCAPE) ' escape key

Image
Post Reply