LoginLogin

Can't get function to work

Root / Programming Questions / [.]

TarudahatCreated:
So I have a function in slot 3 for walking but I don't Get anything to work with sprites or saving or loading or even getting back a variable. The code (slot 0)
VAR PY
PY = 200
DIM SV[1]
VAR B'button
VAR ID'player sprite
ID= 100
VAR DEFNUM
DEFNUM= 20
'Load functions into slot 3
LOAD"GRP3:FUNCS",0
USE 3

SPSET ID,DEFNUM

While 1
VSYNC
SPOFS ID,10,PY
B=BUTTON()
IF B AND #UP THEN UP'UP is a function in slot 3
WEND
Code (slot 3)
COMMON DEF UP
 SPCHR ID,100' gives an error
 DEC PY,1
 RETURN PY
END
Problem I don't get PY back And anything sprite related gives a syntax error

Your DEF function returns PY, so you need the proper syntax.
COMMON DEF UP()
 SPCHR ID,100
 DEC PY,1
 RETURN PY
END
Functions in the form of Function(X) return variables, while functions like Function X don't return values, but can manipulate them. But uh, I'm not sure if you can manipulate sprites from another program. Someone else might have to chip in. But, because you're accessing variables from another slot (ID and PY are variables declared in slot 0, your code runs in slot 3) you need to reference them using VAR("0:ID") and VAR("0:PY). Referencing vars from other slots takes the form of VAR("Slot:VarName"). Notice how the information is contained in a string.

Referencing a VAR does not work I had
VAR("0:ID")
And it just gave a ffffffff syntax error

I had better stop before I gold-plate things any more. Anyway, the problem is in slot 3 you can't see the variables in slot 0, so ID and PY mean nothing and default to zero. I tested the VAR("0:ID") syntax suggested, while it worked I decided against it (more below). Also as stated earlier if you want to return a value you need to call the function with parenthesis (). I wouldn't read variables in another file's globals, that make me feel dirty and gross. It tightly couples the two files and makes them less reusable. Instead of reading ID from slot 0 which makes slot 3 dependent on the particulars of your game and tied to a specific sprite in it. You should instead pass in the ID number that you want to operate on. This lets you reuse the functions in a different game and for different sprites in the same game. I had contemplated passing in PY too, but you can get the current sprite x and y coordinate with SPOFS ID OUT X, Y. I wasn't sure what you were doing with SPCHR and again 100 is tied to a specific sprite so I had that value passed in as a parameter too. Got to avoid those evil magic numbers. Then I started gold plating things and added a left, right, and down function as well as a background, background music and turned the player into a boat. Anyway here is what I came up with. The first is code for slot 0, the second is for slot 3. Feel free to ask questions. Also forgive any type-os I make in retyping it. Slot 0
VAR SCREEN_W = 400, SCREEN_H = 240
VAR BOAT_RIGHT = 365, BOAT_DOWN = 366
VAR BOAT_LEFT = 367, BOAT_UP = 368
VAR WATER = 147
VAR TILE_SIZE = 16, MUSIC = 9

VAR TILES_W, TILES_H 'Background size (iles)
VAR PX, PY 'Player position
VAR U, V, W, H 'For sprite width and height
VAR B 'Button
VAR ID 'Player sprite

'Load functions into slot 3
LOAD "PRG3:FUNCS", 0
USE 3

TILES_W = SCREEN_W / TILE_SIZE
TILES_H = SCREEN_H / TILE_SIZE

'Clear junk off the screen
ACLS
BGSCREEN 0, TILES_W, TILES_H
BGFILL 0, 0, 0, TILES_W - 1, TILES_H - 1, WATER
BGMPLAY MUSIC

'Create the player sprite
SPSET BOAT_DOWN OUT ID
SPCHR ID OUT U, V, W, H
PX = (SCREEN_W - W) / 2
PY = (SCREEN_H - H) / 2

LOCATE 0, 0
COLOR #TWHITE, #TBLUE
PRINT "Press X to exit";
WHILE TRUE
 SPCHR ID OUT U, V, W, H
 B = BUTTON()
 'UP, DOWN, LEFT and RIGHT are functions in slot 3
 IF B AND #UP THEN PY = UP(ID, BOAT_UP)
 IF B AND #DOWN THEN PY = DOWN(ID, BOAT_DOWN)
 IF B AND #LEFT THEN PX = LEFT(ID, BOAT_LEFT)
 IF B AND #RIGHT THEN PX = RIGHT(ID, BOAT_RIGHT)

 IF B AND #X THEN BREAK 'Exit game

 'Clip to screen coordinates
 PX = MAX(0, MIN(SCREEN_W - W - 1, PX))
 PY = MAX(0, MIN(SCREEN_H - H - 1, PY))

 SPOFS ID, PX, PY
 VSYNC
WEND

'Cleanup
BGMSTOP
BGCLR
SPCLR
COLOR #TWHITE, 0 '0 = Transparent background
END 
Slot 3
COMMON DEF UP(ID, SPRITE_ID)
 VAR X, Y
 SPOFS ID OUT X, Y
 SPCHR ID, SPRITE_ID
 DEC Y, 1
 RETURN Y
END

COMMON DEF DOWN(ID, SPRITE_ID)
 VAR X, Y
 SPOFS ID OUT X, Y
 SPCHR ID, SPRITE_ID
 INC Y, 1
 RETURN Y
END

COMMON DEF LEFT(ID, SPRITE_ID)
 VAR X, Y
 SPOFS ID OUT X, Y
 SPCHR ID, SPRITE_ID
 DEC X, 1
 RETURN X
END

COMMON DEF RIGHT(ID, SPRITE_ID)
 VAR X, Y
 SPOFS ID OUT X, Y
 SPCHR ID, SPRITE_ID
 INC X, 1
 RETURN X
END


But is it even worth keeping all functions in 1 file ?(most of them except loading and saving are only used in 1 specific program)

If you write your Code like seggiepants done for Slot 3, you can use the same code in each programm, without retyping it. In most of cases you need to move a Sprites (Player1, Enemy1, Enemy2, etc.). So you can save much time and code, because you can use it for every moving you need.

I had assumed you put things in slot 3 on purpose so you could make a reusable library of sorts. In which case you should only put reusable code into the library, and keep the game specific code with the game. For reusable code it is best to keep things as general purpose as possible. The functions should need only what you pass to them and shouldn't be reading or expecting specific global state or variables. If you don't intend to re-use the code I don't know why you broke it out into a separate file. In just about any other language that would not be a bad thing, but in SmileBasic you only have four slots and it complicates things. BASIC can be well.... bad compared to most other languages and not having a good library/include system is one of those bad points.

Yeah ill probably make the functions not be in 1 file only. But still thanks everyone