experimenting with sprites

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

experimenting with sprites

Post by ron77 »

hello all :) good day...

today i have started to experiment with sprites and sprite sheets - i've downloaded a free sprite from itch.io assets and i took BasicCoder2 code from the forum and played with it and modified it here is what i came up with so far...

first here is the sprite sheet for you to download from dropbox https://www.dropbox.com/s/6jtx7fcw4ux80 ... 9.bmp?dl=0
please tell me if you succeed in downloading it from dropbox it's a 768x64 (64x64) pixel bmp file (modified from png file with MS-3d-paint (it seems that when you convert it from png format to bmp the background is no longer transparent like it was in the original png file format...

and here is the code originally borrowed from BasicCoder2 code from the forum :

Code: Select all

#include "fbgfx.bi" 
using FB


screenres 640,480,32
color rgb(0,0,0),rgb(120,120,120):CLS
'Const xk = Chr(255)
'Const key_up = xk + "H"
'Const key_dn = xk + "P"
'Const key_rt = xk + "M"
'Const key_lt = xk + "K"

dim shared as any ptr Sheet   'create pointer
Sheet = imagecreate(768,64) 'point at new bitmap
bload "Holly\Aerial_swing (64 x 64).bmp",Sheet    'load image into bitmap

dim shared as integer frame      'current animation frame

dim as double st   'start of time
st = TIMER         'st = current time
DIM AS INTEGER x = 360, y = 140
DIM k AS STRING
DO
   'k = INKEY
   IF MULTIKEY(SC_UP) THEN y -= 5
   IF MULTIKEY(SC_LEFT) THEN x -= 5
   IF MULTIKEY(SC_RIGHT) THEN x += 5
   IF MULTIKEY(SC_DOWN) THEN y += 5
    if TIMER-st > 0.05 then  'next frame
        st = TIMER            'reset start
        screenlock
        cls
        put (x,y),Sheet,(frame*64,0)-(frame*64+63,64),trans
        screenunlock
        frame = frame + 1   'next frame
        if frame = 11 then frame = 0
    end if
    sleep 2
loop until multikey(&H01)  'loop until ESC keypress


ron77
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: experimenting with sprites

Post by ron77 »

okay now added boundaries for the character's moments so it cannot get out of the screen

updated code:

Code: Select all

#include "fbgfx.bi" 
using FB


screenres 640,480,32
color rgb(0,0,0),rgb(120,120,120):CLS
'Const xk = Chr(255)
'Const key_up = xk + "H"
'Const key_dn = xk + "P"
'Const key_rt = xk + "M"
'Const key_lt = xk + "K"

dim shared as any ptr Sheet   'create pointer
Sheet = imagecreate(768,64) 'point at new bitmap
bload "Holly\Aerial_swing (64 x 64).bmp",Sheet    'load image into bitmap

dim shared as integer frame      'current animation frame

dim as double st   'start of time
st = TIMER         'st = current time
DIM AS INTEGER x = 360, y = 140
DIM k AS STRING
DO
   'k = INKEY
   IF MULTIKEY(SC_UP) THEN y -= 5
   IF MULTIKEY(SC_LEFT) THEN x -= 5
   IF MULTIKEY(SC_RIGHT) THEN x += 5
   IF MULTIKEY(SC_DOWN) THEN y += 5
   IF x < 0 THEN x = 0
   IF x > 640 - 64 THEN x = 640 - 64
   IF y < 0 THEN y = 0 
   IF y > 480 - 64 THEN y = 480 - 64
    if TIMER-st > 0.05 then  'next frame
        st = TIMER            'reset start
        screenlock
        cls
        put (x,y),Sheet,(frame*64,0)-(frame*64+63,64),trans
        screenunlock
        frame = frame + 1   'next frame
        if frame = 11 then frame = 0
    end if
    sleep 2
loop until multikey(&H01)  'loop until ESC keypress
any advice / help / suggestions will be greatly appreciated :)

ron77
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: experimenting with sprites

Post by ron77 »

hello :) good day to every one...

i modified the code to use some UDT object and added a few variables that may come in useful further down the line... the trouble is that the sprite i'm using is limited and does not include "left or right up or down" positions it seems like the only thing this sprite character can to is fight in one direction only - so i may need to search some more after an appropriate suitable sprites sheets - if anyone has an idea for where to get a more flexible sprite sheet please let me know...

here is the code updated:

Code: Select all

#INCLUDE "fbgfx.bi" 
using FB


screenres 640,480,32
color rgb(0,0,0),rgb(120,120,120):CLS

TYPE ObjectType
X          AS SINGLE
Y          AS SINGLE
Speed      AS SINGLE
Frame      AS INTEGER
Direction  AS INTEGER
Move       AS boolean 
Attack     AS INTEGER
Alive      AS INTEGER
END TYPE

DIM SHARED Player AS ObjectType


' Warrior's(player's) initial
' position, speed(constant)
' and direction(1 = right)
Player.X = 150
Player.Y = 90
Player.Speed = 1
Player.Direction = 1

dim shared as any ptr Sheet   'create pointer
Sheet = imagecreate(768,64) 'point at new bitmap
bload "Holly\Aerial_swing (64 x 64).bmp",Sheet    'load image into bitmap

dim shared as integer frame      'current animation frame

dim as double st   'start of time
st = TIMER         'st = current time
DIM AS INTEGER x = 360, y = 140
DIM k AS STRING
DO
   Player.Move = FALSE
   IF MULTIKEY(SC_RIGHT) THEN 
Player.X = Player.X + Player.Speed
Player.Direction = 1
Player.Move = TRUE
END IF
IF MULTIKEY(SC_LEFT) THEN 
Player.X = Player.X - Player.Speed
Player.Direction = 2
Player.Move = TRUE
END IF
IF MULTIKEY(SC_DOWN) THEN 
Player.Y = Player.Y + Player.Speed
Player.Direction = 3
Player.Move = TRUE
END IF
IF MULTIKEY(SC_UP) THEN 
Player.Y = Player.Y - Player.Speed
Player.Direction = 4
Player.Move = TRUE
END IF

' The following 4 conditions prevent
' the warrior to walk off the screen.
IF Player.X < 0 THEN 
Player.Move = FALSE
Player.X = 0
END IF
IF Player.X > 640 - 64 THEN 
Player.Move = FALSE
Player.X = 640 - 64
END IF
IF Player.Y < 0 THEN 
Player.Move = FALSE
Player.Y = 0
END IF
IF Player.Y > 480 - 64 THEN 
Player.Move = FALSE
Player.Y = 480 - 64
END IF

if TIMER-st > 0.05 then  'next frame
        st = TIMER            'reset start
        screenlock
        cls
        put (player.X,player.Y),Sheet,(frame*64,0)-(frame*64+63,64),trans
        screenunlock
        frame = frame + 1   'next frame
        if frame = 11 then frame = 0
    end if
    sleep 2



loop until multikey(&H01)  'loop until ESC keypress
ron77
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: experimenting with sprites

Post by angros47 »

Years ago I wrote a tutorial for games set in multiple rooms: http://back2basic.phatcode.net/?Issue-% ... room-Games

Let me know if it helps you, both for your adventure and for your sprite-based game
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: experimenting with sprites

Post by BasicCoder2 »

If you want to learn OOP my code is not the best to reference.
https://github.com/FreeBASIC-Extended-L ... /sprite.bi
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: experimenting with sprites

Post by BasicCoder2 »

You can load and save in other file formats.
viewtopic.php?f=14&t=24105

Code: Select all

#ifndef __FBImage_bi__
#define __FBImage_bi__


#ifdef __FB_WIN32__
# libpath "lib/win"
#else
# libpath "lib/lin"
#endif

#ifndef __FB_64BIT__
# inclib "FBImage-32-static"
#else
# inclib "FBImage-64-static"
#endif


' Load BMP, PNG, JPG, TGA, DDS from file or memory as FBImage

' screenres 640,480,32 ' <--- RGBA
' var jpg = LoadRGBAFile("test_rgb.jpg")
' put (0,0),jpg,PSET
'
' var png = LoadRGBAFile("test_rgba.png")
' put (256,0),png,ALPHA

' var img = LoadRGBAFile("filenotfound.xxx")
' if img=0 then
'   print "error: loading filenotfound.xxx " & *GetLastResult()
' end if

' Save RGB image as PNG
' var ok = SavePNGFile(img,"test_rgb.png")

' Save RGBA image as PNG
' var ok = SavePNGFile(img,"test_rgba.png",true)

extern "C"

declare function LoadRGBAFile(byval filename as const zstring ptr) as any ptr

declare function LoadRGBAMemory(byval buffer as const any ptr, byval buffersize as long) as any ptr

declare function GetLastResult() as const zstring ptr

declare function SavePNGFile (byval img as any ptr, byval filename as const zstring ptr,byval saveAlpha as boolean=false) as boolean

end extern

' load (32bit) RGBA image and convert it for 16 bit RGB mode
function Load16BitRGB(filename as const zstring ptr) as any ptr
  #define RGB16(_r,_g,_b) ((((_b) shr 3) shl 11) or (((_g) shr 2) shl 5) or ((_r) shr 3))
  var imgSrc = LoadRGBAFile(filename)
  if imgSrc=0 then return 0
  dim as integer w,h,spitch,dpitch
  dim as ubyte ptr s
  imageinfo imgSrc,w,h,,spitch,s
  var imgDst = ImageCreate(w,h,0,16)
  dim as ushort ptr d
  imageinfo imgDst,,,,dpitch,d
  dpitch shr= 1 ' pitch in bytes to pitch in pixels
  for y as integer =1 to h
    dim as integer i
    for x as integer =0 to w-1
      d[x] = RGB16(s[i],s[i+1],s[i+2])
      i+=4 ' next source pixel
    next
    s+=spitch ' next src row
    d+=dpitch ' next dst row
  next
  ImageDestroy imgSrc
  return imgDst
  #undef RGB16
end function

namespace Base64
  static as string*64 B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" _
                          & "abcdefghijklmnopqrstuvwxyz" _
                          & "0123456789+/"

  Function EncodeMemory(buffer as any ptr,size as long) As String
    #define E0 (S[j] shr 2)
    #define E1 (((S[j] and &H03) shl 4) + (S[j+1] shr 4))
    #define E2 (((S[j+1] and &H0F) shl 2) + (S[j+2] shr 6))
    #define E3 (S[j+2] and &H3F)
    dim as long nChars = size
    if nChars=0 then return ""
    dim as ubyte ptr S=buffer
    dim as long j,k,m = nChars mod 3
    dim as string r=string(((nChars+2)\3)*4,"=")
    nChars-= (m+1)
    For j = 0 To nChars Step 3
      r[k]=B64[e0] : r[k+1]=B64[e1] : r[k+2]=B64[e2] : r[k+3]=B64[e3]:k+=4
    Next
    if m then
      r[k]=B64[e0] : r[k+1]=B64[e1] : r[k+3]=61
      If m = 2 Then r[k+2]=B64[e2] Else  r[k+2]=61
    end if
    return r
    #undef E0
    #undef E1
    #undef E2
    #undef E3
  End Function

  Function DecodeMemory(s As String,byref nBytes as integer) As any ptr
    #define P0(p) instr(B64,chr(s[n+p]))-1
    dim as long nChars=Len(s)
    if nChars<1 then return 0
    nBytes=nChars : nChars-=1
    dim as ubyte ptr O,buffer=callocate(nBytes)
    O=buffer
    for n As long = 0 To nChars Step 4
      var b = P0(1), c = P0(2), d = P0(3)
      if b>-1 then
        var a = P0(0) : *O = (a shl 2 + b shr 4) : O+=1
      end if
      if c>-1 then *O = (b shl 4 + c shr 2) : O+=1
      if d>-1 then *O = (c shl 6 + d) : O+=1
    next
    return buffer
    #undef P0
  end function
end namespace

#endif ' __FBImage_bi__
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: experimenting with sprites

Post by BasicCoder2 »

ron77
the trouble is that the sprite i'm using is limited and does not include "left or right up or down" positions
You could use free template sprite sheets to test your code.
The author says you can use them for your own use just don't claim them as your own.
https://forums.rpgmakerweb.com/index.ph ... ate.55842/
Such templates can be "dressed" by someone with an artistic ability for an actual game.
If you want more than one character I guess the template sprites could be colored differently.

Here is another template sprite sheet with a number of actions.
https://tradnux.com/teej-character-base-sprite-sheet/

If you want to go beyond learning to code a game to actually writing a full blown game you would then call on a partner to redo the sprites and other artwork.

You can use the spriteSheet below as a starter. I modified your code to use it. Need to convert to a .bmp file to use with code. Or you can change the code to make use of fbImage.bi to load bitmaps.

Code: Select all

#INCLUDE "fbgfx.bi"
using FB

screenres 640,480,32
color rgb(0,0,0),rgb(255,255,255):CLS

TYPE ObjectType
    X          AS SINGLE
    Y          AS SINGLE
    Speed      AS SINGLE
    Frame      AS INTEGER
    Direction  AS INTEGER
    Move       AS boolean
    Attack     AS INTEGER
    Alive      AS INTEGER
END TYPE

DIM SHARED Player AS ObjectType


' Warrior's(player's) initial
' position, speed(constant)
' and direction(1 = right)
Player.X = 150
Player.Y = 90
Player.Speed = 1
Player.Direction = 1

dim shared as any ptr walkerSheet          'create pointer
walkerSheet = imagecreate(128,128)          'point at new bitmap
bload "walkerSheet.bmp",walkerSheet   'load image into bitmap
put (0,0),walkerSheet,trans
sleep


dim shared as integer frame      'current animation frame

dim as double st   'start of time
st = TIMER         'st = current time
DIM AS INTEGER x = 360, y = 140
DIM k AS STRING
DO
    Player.Move = FALSE
    IF MULTIKEY(SC_RIGHT) THEN
        Player.X = Player.X + Player.Speed
        Player.Direction = 0
        Player.Move = TRUE
    END IF
    IF MULTIKEY(SC_LEFT) THEN
        Player.X = Player.X - Player.Speed
        Player.Direction = 1
        Player.Move = TRUE
    END IF
    IF MULTIKEY(SC_DOWN) THEN
        Player.Y = Player.Y + Player.Speed
        Player.Direction = 2
        Player.Move = TRUE
    END IF
    IF MULTIKEY(SC_UP) THEN
        Player.Y = Player.Y - Player.Speed
        Player.Direction = 3
        Player.Move = TRUE
    END IF

    ' The following 4 conditions prevent
    ' the warrior to walk off the screen.
    IF Player.X < 0 THEN
        Player.Move = FALSE
        Player.X = 0
    END IF
    IF Player.X > 640 - 32 THEN
        Player.Move = FALSE
        Player.X = 640 - 32
    END IF
    IF Player.Y < 0 THEN
        Player.Move = FALSE
        Player.Y = 0
    END IF
    IF Player.Y > 480 - 32 THEN
        Player.Move = FALSE
        Player.Y = 480 - 32
    END IF

    if TIMER-st > 0.2 then  'next frame
        st = TIMER            'reset start
        screenlock
        cls
        put (player.X,player.Y),walkerSheet,(frame*32,Player.direction*32)-(frame*32+31,Player.Direction*32+31),trans
        screenunlock
        if Player.Move = TRUE then
            frame = frame + 1   'next frame
            if frame = 4 then frame = 0
        end if
    end if
    
    sleep 2

loop until multikey(&H01)  'loop until ESC keypress

Image
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: experimenting with sprites

Post by ron77 »

hello everyone and hello @BasicCoder2

your example code and sprite sheet really help me BasicCoder2... now i'm trying to make something similar with this sprite https://www.dropbox.com/s/zsavh3kf8oe6a ... S.bmp?dl=0 however the sprite seems to switch position not correctly here is the code of my program...

Code: Select all

#INCLUDE "fbgfx.bi"
using FB


screenres 640,480,32
color rgb(0,0,0),rgb(120,120,120):CLS

TYPE ObjectType
X          AS SINGLE
Y          AS SINGLE
Speed      AS SINGLE
Frame      AS INTEGER
Direction  AS INTEGER
Move       AS boolean
Attack     AS INTEGER
Alive      AS INTEGER
END TYPE

DIM SHARED Player AS ObjectType


' Warrior's(player's) initial
' position, speed(constant)
' and direction(1 = right)
Player.X = 150
Player.Y = 90
Player.Speed = 1
Player.Direction = 1

dim shared as any ptr Sheet   'create pointer
Sheet = imagecreate(288,22) 'point at new bitmap
bload "SPRITES.bmp",Sheet    'load image into bitmap

dim shared as integer frame      'current animation frame
dim shared as integer frame2      'current animation frame

dim as double st   'start of time
st = TIMER         'st = current time
DIM AS INTEGER x = 360, y = 140
DIM k AS STRING
DO
   Player.Move = FALSE
   IF MULTIKEY(SC_RIGHT) THEN
Player.X = Player.X + Player.Speed
Player.Direction = 1
Player.Move = TRUE
END IF
IF MULTIKEY(SC_LEFT) THEN
Player.X = Player.X - Player.Speed
Player.Direction = 2
Player.Move = TRUE
END IF
IF MULTIKEY(SC_DOWN) THEN
Player.Y = Player.Y + Player.Speed
Player.Direction = 3
Player.Move = TRUE
END IF
IF MULTIKEY(SC_UP) THEN
Player.Y = Player.Y - Player.Speed
Player.Direction = 4
Player.Move = TRUE
END IF

' The following 4 conditions prevent
' the warrior to walk off the screen.
IF Player.X < 0 THEN
Player.Move = FALSE
Player.X = 0
END IF
IF Player.X > 640 - 22 THEN
Player.Move = FALSE
Player.X = 640 - 22
END IF
IF Player.Y < 0 THEN
Player.Move = FALSE
Player.Y = 0
END IF
IF Player.Y > 480 - 22 THEN
Player.Move = FALSE
Player.Y = 480 - 22
END IF

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

frame2 = (frame2 MOD 16) + 1
IF frame2 = 10 THEN frame = (frame MOD 2) + 1
IF Player.Move = FALSE OR frame = 0 THEN frame = 1

if TIMER-st > 0.05 then  'next frame
        st = TIMER            'reset start
        screenlock
        cls
        put (player.X,player.Y),Sheet,(frame*24,0)-(frame*24+23,22),trans
        screenunlock
        frame = frame + 1   'next frame
        if frame = 11 then frame = 0
    end if
    sleep 2



loop until multikey(&H01)  'loop until ESC keypress
any help will be greatly appreciated

ron77
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: experimenting with sprites

Post by ron77 »

here is the solution to work with this particular sprite - thanks to @Sero

Code: Select all

#INCLUDE "fbgfx.bi"
USING FB


screenres 640,480,32
color rgb(0,0,0),rgb(120,120,120):CLS

TYPE ObjectType
X          AS SINGLE
Y          AS SINGLE
Speed      AS SINGLE
Frame      AS INTEGER
Direction  AS INTEGER
Move       AS boolean
Attack     AS INTEGER
Alive      AS INTEGER
END TYPE

DIM SHARED Player AS ObjectType


' Warrior's(player's) initial
' position, speed(constant)
' and direction(1 = right)
Player.X = 150
Player.Y = 90
Player.Speed = 1
Player.Direction = 1

dim shared as any ptr Sheet   'create pointer
Sheet = imagecreate(288,22) 'point at new bitmap
bload "SPRITES.bmp",Sheet    'load image into bitmap

dim shared as integer frame      'current animation frame
dim shared as integer frame2      'current animation frame

dim as double st   'start of time
st = TIMER         'st = current time
DIM AS INTEGER x = 360, y = 140
DIM k AS STRING

DO
   Player.Move = FALSE
   IF MULTIKEY(SC_RIGHT) THEN
  Player.X = Player.X + Player.Speed
  Player.Direction = 1
  Player.Move = TRUE
  END IF
  IF MULTIKEY(SC_LEFT) THEN
  Player.X = Player.X - Player.Speed
  Player.Direction = 2
  Player.Move = TRUE
  END IF
  IF MULTIKEY(SC_DOWN) THEN
  Player.Y = Player.Y + Player.Speed
  Player.Direction = 3
  Player.Move = TRUE
  END IF
  IF MULTIKEY(SC_UP) THEN
  Player.Y = Player.Y - Player.Speed
  Player.Direction = 4
  Player.Move = TRUE
  END IF

  ' The following 4 conditions prevent
  ' the warrior to walk off the screen.
  IF Player.X < 0 THEN
  Player.Move = FALSE
  Player.X = 0
  END IF
  IF Player.X > 640 - 22 THEN
  Player.Move = FALSE
  Player.X = 640 - 22
  END IF
  IF Player.Y < 0 THEN
  Player.Move = FALSE
  Player.Y = 0
  END IF
  IF Player.Y > 480 - 22 THEN
  Player.Move = FALSE
  Player.Y = 480 - 22
  END IF

  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 Player.Move = FALSE then
    Frame = 0
  else
    frame = frame + 1
    if frame > 1 then frame = 0
  end if

  if TIMER-st > 0.05 then  'next frame
        st = TIMER            'reset start
        
        screenlock
          cls
          put (player.X,player.Y),Sheet,(player.frame*24,0)-(player.frame*24+23,21),trans
        screenunlock

  end if
  sleep 15

loop until multikey(&H01)  'loop until ESC keypress
ron77
sero
Posts: 59
Joined: Mar 06, 2018 13:26
Location: USA

Re: experimenting with sprites

Post by sero »

Glad I could help. Here is another version that locks frame increment with our timer that checks to update the screen.

original code:

Code: Select all

#INCLUDE "fbgfx.bi"
USING FB

screenres 640,480,32
color rgb(0,0,0),rgb(120,120,120):CLS

TYPE ObjectType
X          AS SINGLE
Y          AS SINGLE
Speed      AS SINGLE
Frame      AS INTEGER
Direction  AS INTEGER
Move       AS boolean
Attack     AS INTEGER
Alive      AS INTEGER
END TYPE

DIM SHARED Player AS ObjectType

Player.X = 150
Player.Y = 90
Player.Speed = 1
Player.Direction = 1

dim shared as any ptr Sheet   'create pointer
Sheet = imagecreate(288,22) 'point at new bitmap
bload "SPRITES.bmp",Sheet    'load image into bitmap

dim shared as integer frame      'current animation frame
dim shared as integer frame2      'current animation frame

dim as double st   'start of time
st = TIMER         'st = current time
DIM AS INTEGER x = 360, y = 140
DIM k AS STRING

DO
   Player.Move = FALSE
   IF MULTIKEY(SC_RIGHT) THEN
  Player.X = Player.X + Player.Speed
  Player.Direction = 1
  Player.Move = TRUE
  END IF
  IF MULTIKEY(SC_LEFT) THEN
  Player.X = Player.X - Player.Speed
  Player.Direction = 2
  Player.Move = TRUE
  END IF
  IF MULTIKEY(SC_DOWN) THEN
  Player.Y = Player.Y + Player.Speed
  Player.Direction = 3
  Player.Move = TRUE
  END IF
  IF MULTIKEY(SC_UP) THEN
  Player.Y = Player.Y - Player.Speed
  Player.Direction = 4
  Player.Move = TRUE
  END IF
  
  IF Player.X < 0 THEN
  Player.Move = FALSE
  Player.X = 0
  END IF
  IF Player.X > 640 - 22 THEN
  Player.Move = FALSE
  Player.X = 640 - 22
  END IF
  IF Player.Y < 0 THEN
  Player.Move = FALSE
  Player.Y = 0
  END IF
  IF Player.Y > 480 - 22 THEN
  Player.Move = FALSE
  Player.Y = 480 - 22
  END IF

  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-st > 0.05 then  'next frame
        st = TIMER            'reset start
        
        frame = frame + 1
        if Player.Move = FALSE or frame > 1 then Frame = 0
        
        screenlock
          cls
          put (player.X,player.Y),Sheet,(player.frame*24,0)-(player.frame*24+23,21),trans
        screenunlock

  end if
  sleep 1

loop until multikey(&H01)  'loop until ESC keypress
updated code (without "shared" or "integer"):

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

dim player as t_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

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

dim as long frame

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( 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
    screenunlock()
  end if
  sleep( 15 )
loop until multikey( &h01 ) ' escape key
Last edited by sero on Feb 12, 2021 2:07, edited 2 times in total.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: experimenting with sprites

Post by MrSwiss »

@ron77,

unfortunately the current examples given to you, are lacking in 'good coding practice'.
  • Shared variables (all over the place)
  • Procedures without passed arguments (result of using "shared")
  • Far to many "Integer" in type's definitions (results in code that isn't portable)
    ... (list as always incomplete)
For arguments sake only: Subforum/Beginners: "passing an array to a subroutine"
This is the way to deal with it, instead of "shared" variables, arrays e.t.c.
Even in example given above there is a "hair in the soup" because, it uses statics in the procedure ...
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: experimenting with sprites

Post by BasicCoder2 »

@MrSwiss
unfortunately the current examples given to you, are lacking in 'good coding practice'.
The problem is a lot of game tutorials were written before OO features were added to FreeBASIC.
sero
Posts: 59
Joined: Mar 06, 2018 13:26
Location: USA

Re: experimenting with sprites

Post by sero »

@ron77 - What MrSwiss is saying is an important thing to aim for when coding. These are basics that you should make a habit of. You'll need to follow these basics if you want to become a better coder. I updated my example for you that takes away the bad habit of using "shared" and "integer". I also left the original bad code so you can make a comparison of the differences.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: experimenting with sprites

Post by MrSwiss »

@BasicCoder2,

your "never ending story" is not, repeat NOT, related to what you call "OO"-whatever ...
It is only a convenient but also extremly cheap excuse.

It is centered on your apparent inexperience in coding procedures (Sub/Function/Macro whatever else), that
contain "passed" arguments ... (which only leaves the "shared" approach, which is "bad news" of course).

Another point is using LITERALS in procedures instead of passed variables.
This assures that their "reusability-factor" is close to zero/null/nada.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: experimenting with sprites

Post by BasicCoder2 »

ron77

Hope you are taking on board the comments made by MrSwiss for 'good coding practice'?

I seem to recognize the warrior sprites from this article?
https://games.freebasic.net/BASICGaming ... #tutorial1

The problem I see here is that the computations to display the animations are particular to this sheet.

A more general approach would enable the animations to be in anywhere on the sheet and then variables describing their position, number of frames, current frame, size of frames could be passed to the routine displaying the animation.

This is an example of what I mean,

viewtopic.php?f=15&t=25605
Post Reply