an attempt to create a Tamagotchi cat program

Game development specific discussions.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: an attempt to create a Tamagotchi cat program

Post by MrSwiss »

@ron77,
ron77 wrote:AND can anyone give me any more ideas as to how to improve ...
Well, I suppose you're meaning the code, correct?

Let's face it, there are quite some 'building sites' left for impovements.
A non-exhaustive list could be:
  • 1) instead of binary comparison 'Or' use short-cut operator 'OrElse' (AndAlso)
    2) for better readability when using 'With This' prepend . (dot) on type-members (distiction from proc-local variables)
    3) encapsulate all type-local variables ('Public:' only after all of them)
    4) use 'Select Case As Const' with small numeric variables (more speed)
    4.1) remove colon on all 'Case' statements (numeric eval. | NOT a LABEL) whenever you are NOT having code on the same line
    5) fiori (no purpose in defining it "SHARED"), generally: types are used to eliminate "SHARED" variables
    6) use single-line IF where possible (especially when there is NO Else clause), shortens code
    6.1) use colon if there are two/more statements after 'Then' (statement separator on the same line)
    ....
IMO you'd better clean up the current code first, before adding new features.
Otherwise it'll never be donne (the bigger the code, the lesser you're inclined to do it = experience says so).
Last edited by MrSwiss on Feb 03, 2021 18:15, edited 1 time in total.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: an attempt to create a Tamagotchi cat program

Post by BasicCoder2 »

@ron77
When first run after a meow it immediately ends with,
IT'S BEEN 44231 MINUTES SINCE YOU LAST OPEN THE PROGRAM
CAT DIED FROM NEGLECT!!!
I assume because the file does not yet exist on first run.
It works normally after that.

On line 355 mixed boolean and non-boolean operands warnings presumably because FILEEXISTS returns a long not a boolean value.

Yes a link to the image repository would be good.

I wonder if the hunger, napping and pet time would be better as a percentage?
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: an attempt to create a Tamagotchi cat program

Post by MrSwiss »

The first improvement to game play, should IMO be:

being able to quit the game at any time ... fast (no longish delay).
Currently cat_napping() prevents that totally, which is honestly a pain in the rear.
(maybe other procs could also be improved for faster reaction on user input)
ron77
Posts: 213
Joined: Feb 21, 2019 19:24

Re: an attempt to create a Tamagotchi cat program

Post by ron77 »

thank you @MrSwiss for the helpful advice how to improve the code...

i tried to implement and follow your advices - here is the updated code:

i guess by tomorrow i will post a link to the repository of the project :)

file "main.bas"

Code: Select all

#INCLUDE ONCE "fbsound_dynamic.bi"
#INCLUDE "vbcompat.bi"
#INCLUDE "fbgfx.bi"


CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants
CONST file AS STRING = "cat_log.txt"

ENUM age
   kitten
   young
   adult
   old
END ENUM

TYPE cat
   PRIVATE:
   AS STRING cat_name
   'PUBLIC:
   AS FB.Image PTR imge(1 TO 10)
   AS DOUBLE d1, d2
   AS STRING text1, text2, text3, text4, text5, text6, cat_age
   AS boolean isOut, isneglect
   AS INTEGER hunger, pet_count, nap_count
   PUBLIC:
   DECLARE PROPERTY cat_name1() AS STRING
   DECLARE PROPERTY cat_name1(BYVAL cat_name AS STRING)
   DECLARE SUB time_diff()
   DECLARE SUB settings(i AS age)
   DECLARE SUB pet_cat(key AS STRING)
   DECLARE SUB CP(row AS INTEGER, s AS STRING)
   DECLARE SUB display_screen(index AS INTEGER)
   DECLARE SUB make_sound(f AS STRING, hWave AS INTEGER,t AS INTEGER)
   DECLARE SUB animation(f AS STRING, t AS INTEGER)
   DECLARE SUB cat_hunger(key AS STRING)
   DECLARE SUB nap_time(inx AS INTEGER)
   DECLARE SUB cat_napping(key AS STRING)
   DECLARE SUB write_file(filename AS STRING)
   DECLARE SUB read_file(filename AS STRING)
   DECLARE CONSTRUCTOR()
   DECLARE DESTRUCTOR()
   
END TYPE

CONSTRUCTOR cat
this.isOut = FALSE
THIS.text1 = ""
this.text2 = ""
this.text3 = ""
this.text4 = ""
this.text5 = ""

for i as integer = 1 to 10
  this.imge(i) = ImageCreate(800,600)
next i
END CONSTRUCTOR

DESTRUCTOR cat
IMAGEDESTROY(imge(1))
IMAGEDESTROY(imge(2))
IMAGEDESTROY(imge(3))
IMAGEDESTROY(imge(4))
IMAGEDESTROY(imge(5))
IMAGEDESTROY(imge(6))
IMAGEDESTROY(imge(7))
IMAGEDESTROY(imge(8))
IMAGEDESTROY(imge(9))
IMAGEDESTROY(imge(10))
END DESTRUCTOR

PROPERTY cat.cat_name1() AS STRING
RETURN this.cat_name
END PROPERTY

PROPERTY cat.cat_name1(BYVAL cat_name AS STRING)
this.cat_name = cat_name
END PROPERTY

SUB cat.write_file(filename AS STRING)
   this.d1 = NOW()
   
   DIM f AS LONG = FREEFILE()
   OPEN filename FOR OUTPUT AS #f
   WRITE #f, cat_name1
   WRITE #f, this.hunger
   WRITE #f, THIS.pet_count
   WRITE #f, this.nap_count
   WRITE #f, this.isOut
   WRITE #f, this.cat_age
   write #f, this.d1
   CLOSE #f
END SUB

SUB cat.read_file(filename AS STRING)
   DIM h AS LONG = FREEFILE()
   DIM fline AS STRING
   OPEN filename FOR INPUT AS #h
   INPUT #h, fline
   cat_name1 = fline
   INPUT #h, this.hunger
   INPUT #h, THIS.pet_count
   INPUT #h, this.nap_count
   INPUT #h, this.isOut
   INPUT #h, this.cat_age
   INPUT #h, this.d1
   CLOSE #h
   
END SUB

sub cat.time_diff()
   this.d2 = NOW()
   IF DATEDIFF("d", this.d1, this.d2) > 7 THEN
      this.isneglect = TRUE
   ENDIF
END sub


SUB cat.nap_time(inx AS INTEGER)
   SELECT CASE inx
      CASE 0
   CLS
   CP 4, "------------"
   CP 5, "          / "
   CP 6, "         /  "
   CP 7, "        /   "
   CP 8, "       /    "
   CP 9, "      /     "
   CP 10, "     /      "
   CP 11, "    /       "
   CP 12, "   /        "
   CP 13, "  /         "
   CP 13, " /          "
   CP 14, "------------"
   CP 35, text5
   CP 1, this.cat_age & " " & cat_name1
      CASE 1
CLS
CP 4, "%%%%%%%%%%%%"
CP 5, "          % "
CP 6, "         %  "
CP 7, "        %   "
CP 8, "       %    "
CP 9, "      %     "
CP 10, "     %      "
CP 11, "    %       "
CP 12, "   %        "
CP 13, "  %         "
CP 13, " %          "
CP 14, "%%%%%%%%%%%%"
CP 35, text5
CP 1, this.cat_age & " " & cat_name1
CASE 2
CLS
CP 4, "zzzzzzzzzzzz"
CP 5, "          z "
CP 6, "         z  "
CP 7, "        z   "
CP 8, "       z    "
CP 9, "      z     "
CP 10, "     z      "
CP 11, "    z       "
CP 12, "   z        "
CP 13, "  z         "
CP 13, " z          "
CP 14, "zzzzzzzzzzzz"
CP 35, text5
CP 1, this.cat_age & " " & cat_name1
END SELECT
END SUB

SUB cat.settings(i AS age)
   SELECT CASE i
      CASE 0
         this.hunger = INT(RND*501)
         this.pet_count = INT(RND*501)
         this.nap_count = INT(RND*601)
         this.cat_age = "kitten"
      CASE 1
         this.hunger = INT(RND*601)
         this.pet_count = INT(RND*501)
         this.nap_count = INT(RND*601)
         this.cat_age = "young cat"
      CASE 2
         this.hunger = INT(RND*601)
         this.pet_count = INT(RND*501)
         this.nap_count = INT(RND*601)
         this.cat_age = "adult cat"
      CASE 3
         this.hunger = INT(RND*601)
         this.pet_count = INT(RND*601)
         this.nap_count = INT(RND*601)
         this.cat_age = "old cat"   
END SELECT
END SUB




SUB cat.pet_cat(key AS STRING)
   
   THIS.pet_count -= 1
   
   IF THIS.pet_count <= 50 THEN
      this.text4 = "the cat need some petting press key 'p' to pet cat!"
      
   ELSE
      this.text4 = ""
      
      ENDIF
      IF key = CHR(112) THEN 
         THIS.pet_count += 1000
         this.text4 = ""
         ENDIF
         
      END SUB
      
SUB cat.CP(row AS INTEGER, s AS STRING)
   LOCATE row, (100 - LEN(s)) / 2 : PRINT s
   'DIM AS INTEGER tx, ty 
   'tx = (800 / 2) - (Len(s) / 2)
   'ty = row
   'Draw String (tx * 8, ty * 8), s, RGB(0,0,0)
END SUB
      
SUB cat.display_screen(index AS INTEGER)

BLOAD ("catsheet\Idle (" & index & ").bmp"), imge(index)  

SCREENLOCK

put (0,0),imge(index), TRANS
CP 1, this.cat_age & " " &cat_name1
CP 34, text1
CP 35, text2
CP 32, text4
CP 33, text3
CP 31, text6
SCREENUNLOCK
SLEEP 1

END SUB

SUB cat.cat_napping(key AS STRING)
   
   DIM x AS INTEGER = 0
   DIM xx AS INTEGER = 30
   
   DO
      nap_time(x)
      this.text5 = "NAP TIME!"
      x += 1
      xx -= 1
      IF key = CHR(27) THEN 
         write_file(file): END
      ENDIF
      SLEEP 250
      IF x >= 3 THEN x = 0
   LOOP UNTIL xx <= 0
   
END SUB
SUB cat.cat_hunger(key AS STRING)
   
   IF this.hunger < 25 THEN
      this.text1 = "cat is hungry! press key 'f' to feed it"
   ELSE
      this.text1 = ""

   ENDIF
   IF this.hunger <= -450 THEN
     isOut = TRUE
   
   ENDIF
   IF key = CHR(102) THEN
      this.hunger += 1000
   ENDIF
END SUB
         
         
         
SUB cat.make_sound(f AS STRING, hWave AS INTEGER, t AS INTEGER)
   
   fbs_Load_WAVFile(f , @hWave)
   fbs_Play_Wave(hWave , t)
   
END SUB
         
SUB CAT.ANIMATION(f AS STRING, t AS INTEGER)
         VAR key = "" , hwave = 0
         DO
      WITH THIS
            IF .isOut = TRUE ORELSE cbool(NOT FILEEXISTS(file)) ORELSE .isNeglect = TRUE THEN 
               DIM AS STRING catname, age1
               INPUT "enter cat name or enter 'quit' to exit: ", catname
               IF catname = "quit" THEN
                  .write_file(file)
                  END
               ENDIF
               .cat_name1 = catname
               INPUT "select age of cat - 0 for kitten, 1 for young, 2 for adult, 3 for old: ", age1
               .settings(VALINT(age1))
            
            ELSE 
               .read_file(file)
            ENDIF
               .isOut = FALSE
               .isNeglect = FALSE 
            DIM i AS INTEGER = 1
            .make_sound(f,hWave, t)
                        
            
            DO
                  key = INKEY
               IF .nap_count > 50 THEN
                  IF key = CHR(115) THEN
                     .make_sound(f,hWave, t)
                  ENDIF
                  
                  IF i >= 11 THEN i = 1
                     .DISPLAY_SCREEN(i)
                     SLEEP 100
                     i += 1
                     .cat_hunger(key)
                     .pet_cat(key)
                     .time_diff()
                  IF .isOut = TRUE OR .isneglect = TRUE THEN EXIT DO
                     .text2 = " cat hunger is: " & .hunger & " cat napping counter is: " & .nap_count & _
                     " cat pet time is: " & .pet_count
                     .nap_count -= 1
                     .hunger -= 1
                  IF key = CHR(27) THEN
                     .write_file(file)
                     END
                  ENDIF
               ELSEIF .nap_count <= 50 THEN
                  .cat_napping(key)
                  .nap_count = INT(RND*3001)
               ENDIF  
                                 
            LOOP
               fbs_Destroy_Wave(@hWave)
         IF .isOut = TRUE ORELSE .isNeglect = TRUE THEN
            CLS
               
            .text2 = "IT'S BEEN " & DATEDIFF("d", this.d1, this.d2) & " DAYS SINCE YOU LAST OPEN THE PROGRAM"
            .text1 = "CAT DIED FROM NEGLECT!!!"
            .text4 = "PRESS ANY KEY TO START OVER WITH A NEW CAT!"
            CP 31, .text1
            CP 34, .text4
            CP 30, .text2
            SLEEP 
            cls
            .write_file(file)
         ENDIF
      END WITH
   LOOP UNTIL INKEY() = CHR(27)
                           
END SUB


IF fbs_Init()=false THEN
PRINT "error: FBS_INIT() " & FBS_Get_PlugError()
BEEP : SLEEP : END 1
END IF

SCREENRES scr_w, scr_h, 32
WINDOWTITLE("CAT TAMAGOTCHI V 0.1.0")
WIDTH scr_w \ 8, scr_h \ 16
DIM fiori AS cat
fiori.animation("cat_sound.wav", 1)
ron77 :)
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: an attempt to create a Tamagotchi cat program

Post by MrSwiss »

ron77 wrote:i tried to implement and follow your advices - here is the updated code
You are slowly but surely getting there ... very good!

A few more ideas:
  • a) using unsigned integer-types, is faster than their signed counterparts, e.g. loop-iterator (on all positive up-counting FOR loops)
    b) using 'U/Integer' in type's is dangerous (if ever written to file) since, the size changes with compiler bitness!
    c) using fixed-size int-types, on the other hand, is no problem (code is portable)
See also: FB's numeric data-type(s)

Simplyfied DTOR (static method):

Code: Select all

Destructor cat()
    For i As UInteger = 1 To 10	' unsigned iterator
        ImageDestroy(this.imge(i))
    Next								  ' i = isn't required in FB
End Destructor
However, the safer way whould be (dynamic method):

Code: Select all

' whenever the array size is unknown or may change during run-time (dynamic arrays)
Destructor cat()
    For i As Integer = LBound(this.imge) To UBound(this.imge) ' we don't know if positive or negative
        ImageDestroy(this.imge(i))
    Next
End Destructor
ron77
Posts: 213
Joined: Feb 21, 2019 19:24

Re: an attempt to create a Tamagotchi cat program

Post by ron77 »

hello...

today i would like to replace the hunger, pet and nap counters with bars preferred verticals one...

here is a test run on a code that suppose to make remapping of the counters and display them in horizontal bar... the code does work *kinda* and i need someone's help to make is work vertically

here is the code:
file "help.bas"

Code: Select all

'PRINT ASC("s")
'sleep
#INCLUDE "fbgfx.bi"

SCREENRES 800,600,32

'#include "vbcompat.bi"
'
'Dim s As String, d1 As Double, d2 As Double
'
'Line Input "Enter your birthday: ", s
'
'If IsDate( s ) Then
'  d1 = DateValue( s )
'  d2 = Now()
'
'  Print "You are " & DateDiff( "yyyy", d1, d2 ) & " years old."
'  Print "You are " & DateDiff( "d", d1, d2 ) & " days old."
'  Print "You are " & DateDiff( "s", d1, d2 ) & " seconds old."
'
'Else
'  Print "Invalid date"
'
'End If
'sleep


FUNCTION MapRange(s As Integer, a1 As Integer, a2 As Integer, b1 As Integer, b2 As Integer) As Double
    Return b1+(s-a1)*(b2-b1)/(a2-a1)
End Function
 
'FOR i As Integer = 0 To 10
'    Print Using "## maps to ##.#"; i; MapRange(i,0,10,-1,0)
'Next i
'SLEEP

sub drawBar( v as integer, x as integer, y as integer )
  dim as integer w = 100
  
  line( x, y ) - ( x + w - 1, y + 10 ), rgba( 255, 255, 0, 255 ), b
  line( x + 2, y + 2 ) - ( x + v, y + 8 ), rgba( 255, 255, 0, 255 ), bf
end SUB

'screenRes( 800, 600, 32 )
'
'drawBar( 25, 100, 100 )
'
'sleep()

DIM i AS INTEGER = 100
DIM sec AS INTEGER 
DO 
  
   i -= 1
   SLEEP 100
   sec = MAPRANGE(i, 0, 1000, 0, 100)
   SCREENLOCK
   DRAWBAR(sec, 100, 100)
   SCREENUNLOCK
   SLEEP 1
   
LOOP UNTIL INKEY = CHR(27)

BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: an attempt to create a Tamagotchi cat program

Post by BasicCoder2 »

My suggestion in my last post was to represent hunger, pet and nap as a percentage? Numbers don't really tell you how hungry or sleepy or desirable for a pet the cat is. Is 3984 really hungry or just slightly hungry as opposed to the cat being 50% hungry.

A full bar is then just say 100 or some multiple of 100 maximum.

hungry = 60%

line (0,0)-(100,10),rgb(0,0,0),b 'black border
line (0,0)-(hungry,10),rgb(0,0,255),bf 'blue bar
Last edited by BasicCoder2 on Feb 04, 2021 13:26, edited 1 time in total.
ron77
Posts: 213
Joined: Feb 21, 2019 19:24

Re: an attempt to create a Tamagotchi cat program

Post by ron77 »

hello everyone and hello @BasicCoder2

paul doe gave me this code using a remapping function it shows two bars one vertical the second horizontal yet the vertical bar get's filled upside down... and i don't know how to modify it...

Code: Select all

'v = value you want to represent
'x = x coordinate of the bar
'y = y coordinate of the bar
'w/h = width/height of the bar (depends on if you want to draw a horizontal or vertical bar)

DIM AS INTEGER x = 100, y = 100, h = 100



'' Remaps a value from one range into another
private function remap( _
  x as single, startF as single, endF as single, startT as single, endT as single ) as single
  
  return( ( x - startF ) * ( endT - startT ) / ( endF - startF ) + startT )
end function
 
sub drawHBar( v as integer, x as integer, y as integer, w as integer )
  line( x, y ) - ( x + w - 1, y + 10 ), rgba( 255, 255, 0, 255 ), b
  line( x + 2, y + 2 ) - ( x + v, y + 8 ), rgba( 255, 255, 0, 255 ), bf
end SUB

sub drawVBar( v as integer, x as integer, y as integer, h as integer )
  line( x, y ) - ( x + 10, y + h ), rgba( 255, 255, 0, 255 ), b
  line( x + 2, y + 2 ) - ( x + 8, y + v ), rgba( 255, 255, 0, 255 ), bf
end SUB

SCREENRES 800,600,32

DIM v AS INTEGER = 0

DO 
   v += 1
   SLEEP 10
   
   SCREENLOCK
   DRAWHBAR( remap(v, 0, 1000, 0, 100), 100, 100, 100 )
   DRAWVBAR( remap(v, 0, 1000, 0, 100), 300, 100, 100 )
   SCREENUNLOCK
   SLEEP 1
LOOP UNTIL INKEY = CHR(27)
ron77
ron77
Posts: 213
Joined: Feb 21, 2019 19:24

Re: an attempt to create a Tamagotchi cat program

Post by ron77 »

okay i did what i could with horizontal bars...

Image

here is the updated code:

file"main.bas"

Code: Select all

#INCLUDE ONCE "fbsound_dynamic.bi"
#INCLUDE "vbcompat.bi"
#INCLUDE "fbgfx.bi"


CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants
CONST file AS STRING = "cat_log.txt"

ENUM age
   kitten
   young
   adult
   old
END ENUM

TYPE cat
   PRIVATE:
   AS STRING cat_name
   'PUBLIC:
   AS FB.Image PTR imge(1 TO 10)
   AS DOUBLE d1, d2
   AS STRING text1, text2, text3, text4, text5, text6, cat_age
   AS boolean isOut, isneglect
   AS INTEGER hunger, pet_count, nap_count
   PUBLIC:
   DECLARE PROPERTY cat_name1() AS STRING
   DECLARE PROPERTY cat_name1(BYVAL cat_name AS STRING)
   DECLARE FUNCTION REMAP(x as single, startF as single, endF as single, startT as single, endT as single ) as single
   DECLARE SUB drawHBar( v as integer, x as integer, y as integer, w as integer )
   DECLARE SUB time_diff()
   DECLARE SUB settings(i AS age)
   DECLARE SUB pet_cat(key AS STRING)
   DECLARE SUB CP(row AS INTEGER, s AS STRING)
   DECLARE SUB display_screen(index AS INTEGER)
   DECLARE SUB make_sound(f AS STRING, hWave AS INTEGER,t AS INTEGER)
   DECLARE SUB animation(f AS STRING, t AS INTEGER)
   DECLARE SUB cat_hunger(key AS STRING)
   DECLARE SUB nap_time(inx AS INTEGER)
   DECLARE SUB cat_napping(key AS STRING)
   DECLARE SUB write_file(filename AS STRING)
   DECLARE SUB read_file(filename AS STRING)
   DECLARE CONSTRUCTOR()
   DECLARE DESTRUCTOR()
   
END TYPE

CONSTRUCTOR cat
this.isOut = FALSE
THIS.text1 = ""
this.text2 = ""
this.text3 = ""
this.text4 = ""
this.text5 = ""

for i as integer = 1 to 10
  this.imge(i) = ImageCreate(800,600)
next i
END CONSTRUCTOR

DESTRUCTOR cat
FOR i AS INTEGER = 1 TO 10
   IMAGEDESTROY(imge(i))
NEXT
'IMAGEDESTROY(imge(1))
'IMAGEDESTROY(imge(2))
'IMAGEDESTROY(imge(3))
'IMAGEDESTROY(imge(4))
'IMAGEDESTROY(imge(5))
'IMAGEDESTROY(imge(6))
'IMAGEDESTROY(imge(7))
'IMAGEDESTROY(imge(8))
'IMAGEDESTROY(imge(9))
'IMAGEDESTROY(imge(10))
END DESTRUCTOR

PROPERTY cat.cat_name1() AS STRING
RETURN this.cat_name
END PROPERTY

PROPERTY cat.cat_name1(BYVAL cat_name AS STRING)
this.cat_name = cat_name
END PROPERTY

SUB cat.write_file(filename AS STRING)
   this.d1 = NOW()
   
   DIM f AS LONG = FREEFILE()
   OPEN filename FOR OUTPUT AS #f
   WRITE #f, cat_name1
   WRITE #f, this.hunger
   WRITE #f, THIS.pet_count
   WRITE #f, this.nap_count
   WRITE #f, this.isOut
   WRITE #f, this.cat_age
   write #f, this.d1
   CLOSE #f
END SUB

SUB cat.read_file(filename AS STRING)
   DIM h AS LONG = FREEFILE()
   DIM fline AS STRING
   OPEN filename FOR INPUT AS #h
   INPUT #h, fline
   cat_name1 = fline
   INPUT #h, this.hunger
   INPUT #h, THIS.pet_count
   INPUT #h, this.nap_count
   INPUT #h, this.isOut
   INPUT #h, this.cat_age
   INPUT #h, this.d1
   CLOSE #h
   
END SUB

sub cat.time_diff()
   this.d2 = NOW()
   IF DATEDIFF("d", this.d1, this.d2) > 7 THEN
      this.isneglect = TRUE
   ENDIF
END sub

FUNCTION cat.REMAP(x as single, startF as single, endF as single, startT as single, endT as single ) as single
  return( ( x - startF ) * ( endT - startT ) / ( endF - startF ) + startT )

END FUNCTION

SUB cat.drawHBar( v as integer, x as integer, y as integer, w as integer )
   line( x, y ) - ( x + w - 1, y + 10 ), rgba( 255, 255, 0, 255 ), b
  line( x + 2, y + 2 ) - ( x + v, y + 8 ), rgba( 255, 255, 0, 255 ), bf
END SUB

SUB cat.nap_time(inx AS INTEGER)
   SELECT CASE inx
      CASE 0
   CLS
   CP 4, "------------"
   CP 5, "          / "
   CP 6, "         /  "
   CP 7, "        /   "
   CP 8, "       /    "
   CP 9, "      /     "
   CP 10, "     /      "
   CP 11, "    /       "
   CP 12, "   /        "
   CP 13, "  /         "
   CP 13, " /          "
   CP 14, "------------"
   CP 35, text5
   CP 1, this.cat_age & " " & cat_name1
      CASE 1
CLS
CP 4, "%%%%%%%%%%%%"
CP 5, "          % "
CP 6, "         %  "
CP 7, "        %   "
CP 8, "       %    "
CP 9, "      %     "
CP 10, "     %      "
CP 11, "    %       "
CP 12, "   %        "
CP 13, "  %         "
CP 13, " %          "
CP 14, "%%%%%%%%%%%%"
CP 35, text5
CP 1, this.cat_age & " " & cat_name1
CASE 2
CLS
CP 4, "zzzzzzzzzzzz"
CP 5, "          z "
CP 6, "         z  "
CP 7, "        z   "
CP 8, "       z    "
CP 9, "      z     "
CP 10, "     z      "
CP 11, "    z       "
CP 12, "   z        "
CP 13, "  z         "
CP 13, " z          "
CP 14, "zzzzzzzzzzzz"
CP 35, text5
CP 1, this.cat_age & " " & cat_name1
END SELECT
END SUB

SUB cat.settings(i AS age)
   SELECT CASE i
      CASE 0
         this.hunger = INT(RND*501)
         this.pet_count = INT(RND*501)
         this.nap_count = INT(RND*601)
         this.cat_age = "kitten"
      CASE 1
         this.hunger = INT(RND*601)
         this.pet_count = INT(RND*501)
         this.nap_count = INT(RND*601)
         this.cat_age = "young cat"
      CASE 2
         this.hunger = INT(RND*601)
         this.pet_count = INT(RND*501)
         this.nap_count = INT(RND*601)
         this.cat_age = "adult cat"
      CASE 3
         this.hunger = INT(RND*601)
         this.pet_count = INT(RND*601)
         this.nap_count = INT(RND*601)
         this.cat_age = "old cat"   
END SELECT
END SUB




SUB cat.pet_cat(key AS STRING)
   
   THIS.pet_count -= 1
   
   IF THIS.pet_count <= 50 THEN
      this.text4 = "the cat need some petting press key 'p' to pet cat!"
      
   ELSE
      this.text4 = ""
      
      ENDIF
      IF key = CHR(112) THEN 
         THIS.pet_count += 1000
         this.text4 = ""
         ENDIF
         
      END SUB
      
SUB cat.CP(row AS INTEGER, s AS STRING)
   LOCATE row, (100 - LEN(s)) / 2 : PRINT s
   'DIM AS INTEGER tx, ty 
   'tx = (800 / 2) - (Len(s) / 2)
   'ty = row
   'Draw String (tx * 8, ty * 8), s, RGB(0,0,0)
END SUB
      
SUB cat.display_screen(index AS INTEGER)

BLOAD ("catsheet\Idle (" & index & ").bmp"), imge(index)  

SCREENLOCK

put (0,0),imge(index), TRANS
CP 1, this.cat_age & " " &cat_name1
CP 34, text1
CP 35, text2
CP 32, text4
CP 33, text3
CP 31, text6
DRAWHBAR( remap(this.hunger, 0, 10000, 0, 100), 50, 100, 100 )
DRAW STRING (50, 120), "hunger rate", RGBA(0, 0, 255, 255)
DRAWHBAR( remap(this.nap_count, 0, 3001, 0, 100), 50, 140, 100 )
DRAW STRING (50, 160), "nap timer", RGBA(0, 255, 0, 255)
DRAWHBAR( remap(this.pet_count, 0, 10000, 0, 100), 50, 180, 100 )
DRAW STRING (50, 200), "pet counter", RGBA(255, 0, 0, 255) 
SCREENUNLOCK
SLEEP 1

END SUB

SUB cat.cat_napping(key AS STRING)
   
   DIM x AS INTEGER = 0
   DIM xx AS INTEGER = 30
   
   DO
      nap_time(x)
      this.text5 = "NAP TIME!"
      x += 1
      xx -= 1
      IF key = CHR(27) THEN 
         write_file(file): END
      ENDIF
      SLEEP 250
      IF x >= 3 THEN x = 0
   LOOP UNTIL xx <= 0
   
END SUB
SUB cat.cat_hunger(key AS STRING)
   
   IF this.hunger < 25 THEN
      this.text1 = "cat is hungry! press key 'f' to feed it"
   ELSE
      this.text1 = ""

   ENDIF
   IF this.hunger <= -450 THEN
     isOut = TRUE
   
   ENDIF
   IF key = CHR(102) THEN
      this.hunger += 1000
   ENDIF
END SUB
         
         
         
SUB cat.make_sound(f AS STRING, hWave AS INTEGER, t AS INTEGER)
   
   fbs_Load_WAVFile(f , @hWave)
   fbs_Play_Wave(hWave , t)
   
END SUB
         
SUB CAT.ANIMATION(f AS STRING, t AS INTEGER)
         VAR key = "" , hwave = 0
         DO
      WITH THIS
            IF .isOut = TRUE ORELSE cbool(NOT FILEEXISTS(file)) ORELSE .isNeglect = TRUE THEN 
               DIM AS STRING catname, age1
               INPUT "enter cat name or enter 'quit' to exit: ", catname
               IF catname = "quit" THEN
                  .write_file(file)
                  END
               ENDIF
               .cat_name1 = catname
               INPUT "select age of cat - 0 for kitten, 1 for young, 2 for adult, 3 for old: ", age1
               .settings(VALINT(age1))
            
            ELSE 
               .read_file(file)
            ENDIF
               .isOut = FALSE
               .isNeglect = FALSE 
            DIM i AS INTEGER = 1
            .make_sound(f,hWave, t)
                        
            
            DO
                  key = INKEY
               IF .nap_count > 50 THEN
                  IF key = CHR(115) THEN
                     .make_sound(f,hWave, t)
                  ENDIF
                  
                  IF i >= 11 THEN i = 1
                     .DISPLAY_SCREEN(i)
                     SLEEP 100
                     i += 1
                     .cat_hunger(key)
                     .pet_cat(key)
                     .time_diff()
                  IF .isOut = TRUE OR .isneglect = TRUE THEN EXIT DO
                     '.text2 = " cat hunger is: " & .hunger & " cat napping counter is: " & .nap_count & _
                     '" cat pet time is: " & .pet_count
                     
                     .nap_count -= 1
                     .hunger -= 1
                  IF key = CHR(27) THEN
                     .write_file(file)
                     END
                  ENDIF
               ELSEIF .nap_count <= 50 THEN
                  .cat_napping(key)
                  .nap_count = INT(RND*3001)
               ENDIF  
                                 
            LOOP
               fbs_Destroy_Wave(@hWave)
         IF .isOut = TRUE ORELSE .isNeglect = TRUE THEN
            CLS
               
            .text2 = "IT'S BEEN " & DATEDIFF("d", this.d1, this.d2) & " DAYS SINCE YOU LAST OPEN THE PROGRAM"
            .text1 = "CAT DIED FROM NEGLECT!!!"
            .text4 = "PRESS ANY KEY TO START OVER WITH A NEW CAT!"
            CP 31, .text1
            CP 34, .text4
            CP 30, .text2
            SLEEP 
            cls
            .write_file(file)
         ENDIF
      END WITH
   LOOP UNTIL INKEY() = CHR(27)
                           
END SUB


IF fbs_Init()=false THEN
PRINT "error: FBS_INIT() " & FBS_Get_PlugError()
BEEP : SLEEP : END 1
END IF

SCREENRES scr_w, scr_h, 32
WINDOWTITLE("CAT TAMAGOTCHI V 0.1.0")
WIDTH scr_w \ 8, scr_h \ 16
DIM fiori AS cat
fiori.animation("cat_sound.wav", 1)
THIS IS BETTER - :

Image


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

Re: an attempt to create a Tamagotchi cat program

Post by ron77 »

hello everyone here is the final version of the cat Tamagotchi program

Image

here is the url to the project repository on github: https://github.com/ronblue/fb_fiori_digital_cat_pet

thanks to all of you wonderful people in the forum and FB discord server! your help was greatly important!

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

Re: an attempt to create a Tamagotchi cat program

Post by MrSwiss »

@ron77,

Excuse me saying so but, its not really finished, from my point of view.
Now you can rework everything to put the 'spit & polish' on it.
IOW, make it really shiny ...

You've attempted to use Draw String to get rid of background change, I suppose.
Below code shows you, how to get that working.
It is a 're-work' of your oringinal 'CP' procedure.
Actually a 'bad choice of name' because it usually referres to 'Code Page' short-cut.

I've therefore renamed it to 'RowCPrtC(row, txt, clr)' (row based, centered, colored, print):

Code: Select all

' RowCPrtC_Sub-test1.bas -- 

Const As Short  scr_w = 1024, scr_h = 768, _    ' change for testing ...
                scr_cd = 32, scr_pg = 2, scr_flg = 64   ' here: don't change anything

Declare Sub RowCPrtC(ByVal row As UShort=1, ByVal txt As String="", ByVal clr As ULong=&hFF7F7F7F)

' ===== Test1 =====
ScreenRes(scr_w, scr_h, scr_cd, scr_pg, scr_flg)    ' using double-buffering
ScreenSet(1, 0)                         ' required for double-buffering
Width scr_w \ 8, scr_h \ 16             ' Font: 8 x 16 (w / h)
Color(&hFF000000, &hFFFFFFFF) : Cls     ' black on white background | set it

For i As UInteger = 1 To HiWord(Width)
    RowCPrtC(i, "test-test", &hcF7F3F00)' color = gold (well, sort of)
    'RowCPrtC(i, "test-test")            ' default color = medium grey
Next
Flip                                    ' IMPORTANT: won't show anything w/o it!

Sleep
' ===== end Test1 =====

'
Sub RowCPrtC( _                         ' row based, centered, colored print (using draw string)
    ByVal row   As UShort = 1,         _' row to print on
    ByVal txt   As String = "",        _' string to print
    ByVal clr   As ULong  = &hFF7F7F7F _' color to print with
    )
    Var mxr = HiWord(Width), _          ' number of rows (BASE 1)
        mxc = LoWord(Width)             ' number of columns (BASE 1)
    ' error checking & correcting (where possible)
    If Len(txt) > mxc Then Exit Sub     ' string too long: quit
    If row > mxr Then row = mxr         ' user error: correct it
    If row < 1 Then row = 1             ' dito (as above)
    ' works for all 8 pixel wide Fonts (FB's internals only)
    Var x = scr_w \ 2 - Len(txt) * 4, _ ' calc. vertical pixel-pos.
        y = (scr_h \ mxr) * (row - 1)   ' calc. horziontal pixel-pos.
    Draw String (x, y), txt, clr        ' out: to graphics screen only
End Sub
' ----- EOF -----
It is totally standalone (not put into your proggy) ... but good, to give it a 'work-out'.
It also shows how to use double-buffering on graphics screens.
ron77
Posts: 213
Joined: Feb 21, 2019 19:24

Re: an attempt to create a Tamagotchi cat program

Post by ron77 »

hello... here is a last minute update on the code...

i've changed the BLOAD of the images of the cat from inside DISPLAY_SCREEN sub to the CONSTRUCTOR since the loading of each image to the array of imge() need to happen once only and once loaded it can be reuse in the sub - so there is no need to BLOAD each image over and over again...

here are the changes:

Code: Select all

SUB cat.display_screen(index AS INTEGER)

'BLOAD ("catsheet\Idle (" & index & ").bmp"), imge(index)  

SCREENLOCK

put (0,0),imge(index), TRANS
CP 1, this.cat_age & " " &cat_name1
CP 34, text1
CP 35, text2
CP 32, text4
CP 33, text3
CP 31, text6
DRAWHBAR( remap(this.hunger, 0, 10000, 0, 100), 50, 100, 100, colors.blue )
DRAW STRING (50, 80), "hunger rate", RGBA(0, 0, 255, 255)
DRAWHBAR( remap(this.nap_count, 0, 3001, 0, 100), 50, 140, 100, colors.blueRed )
DRAW STRING (50, 120), "nap timer", colors.blueRed
DRAWHBAR( remap(this.pet_count, 0, 10000, 0, 100), 50, 180, 100, colors.red )
DRAW STRING (50, 160), "pet counter", RGBA(255, 0, 0, 255) 
SCREENUNLOCK
SLEEP 1

END SUB

Code: Select all

CONSTRUCTOR cat
this.isOut = FALSE
THIS.text1 = ""
this.text2 = ""
this.text3 = ""
this.text4 = ""
this.text5 = ""

for i as integer = 1 to 10
  this.imge(i) = ImageCreate(800,600)
  BLOAD ("catsheet\Idle (" & i & ").bmp"), imge(i)
next i
END CONSTRUCTOR
ron77
Post Reply