Mini-Robo-Mixer generates a sprite sheet of robots.
Code: (Select All)
'Mini-Robo-Mixer v0.1
'By James D. Jarvis November 2022
'This program uses BASIMAGE coded by Dav for QB64GL 1.4, MAY/2020
'
'generate a sprite sheet of monsters
'each is 64 by 64 pixels but code here can be modified to change that
'
'press c or s to save a sprite sheet to the clipboard so you can paste it into a paint program
'and save is whatever format you desire
'pres <esc> to quit
'
'License: Share sprite sheets as long as they include generated credit bar in image
'any programs using original code or graphics from source or generated by program
' please include the following (or equivalent) line somwhere in comments and documentation:
'Includes Art and/or Code from Mini-Robo-Mixer v0.1 created by James D. Jarvis
'
Randomize Timer
Dim Shared ms&
ms& = _NewImage(512, 360, 32)
Screen ms&
_Title "Mini-Robo-Mixer V0.1"
Dim Shared part&
Dim Shared kk1 As _Unsigned Long
Dim Shared kk2 As _Unsigned Long
Dim Shared kk3 As _Unsigned Long
Dim Shared kk4 As _Unsigned Long
Dim Shared kk5 As _Unsigned Long
Dim Shared kk6 As _Unsigned Long
Dim Shared clr~&
part& = BASIMAGE1&
Type robobody_type
head As Integer
larm As Integer
rarm As Integer
torso As Integer
leg As Integer
k1 As _Unsigned Long
k2 As _Unsigned Long
k3 As _Unsigned Long
k4 As _Unsigned Long
k5 As _Unsigned Long
k6 As _Unsigned Long
xsiz As Integer
ysiz As Integer
End Type
robot_limit = 40
Dim klrset(12, 3) As Integer
Dim Shared rlook(robot_limit) As robobody_type
_Source part&
'read the colors from the color reference bar whichever color is in the top left corner will be transparent
clr~& = Point(0, 0) 'find background color of image
kk1 = Point(0, 1): kk2 = Point(0, 2): kk3 = Point(0, 3): kk4 = Point(0, 4): kk5 = Point(0, 5): kk6 = Point(0, 6)
_Dest part&
Line (0, 0)-(0, 8), clr~& 'erase the color reference bar from the bit map
_ClearColor clr~&, ms& 'set background color as transparent
_ClearColor clr~&, part&
_Source ms&
_Dest ms&
Do
Cls
'build a color set for the sprite sheet
For k = 1 To 12
klrset(k, 1) = Int(Rnd * 100 + 150)
If Rnd * 7 < 3 Then klrset(k, 2) = klrset(k, 1) Else klrset(k, 2) = Int(Rnd * 100 + 150)
If Rnd * 7 < 3 Then klrset(k, 3) = klrset(k, 1) Else klrset(k, 3) = Int(Rnd * 100 + 150)
Next k
mmx = 0: mmy = 0
For m = 1 To robot_limit
'create a new set of monster sprites
'included image source has 16 options for head,arms,torso, and legs
rlook(m).head = Int(1 + Rnd * 20)
rlook(m).larm = Int(1 + Rnd * 20)
If Rnd * 10 < 3 Then rlook(m).rarm = rlook(m).larm Else rlook(m).rarm = Int(1 + Rnd * 20)
rlook(m).torso = Int(1 + Rnd * 20)
rlook(m).leg = Int(1 + Rnd * 20)
'determing colors for this specific monster sprite
kp = 1 + Int(Rnd * 12)
kr = klrset(kp, 1): kg = klrset(kp, 2): kb = klrset(kp, 3)
kr2 = Int(kr / 2): kg2 = Int(kg / 2): kb2 = Int(kb / 2)
kp = 1 + Int(Rnd * 6)
kr3 = klrset(kp, 1) - 5: kg3 = klrset(kp, 2) - 10: kb3 = klrset(kp, 3) - 15
kr4 = Int(kr3 / 2): kg4 = Int(kg3 / 2): kb4 = Int(kb3 / 2)
kp = 1 + Int(Rnd * 6)
kr5 = klrset(kp, 1) - 20: kg5 = klrset(kp, 2) - 15: kb5 = klrset(kp, 3) - 7
kr6 = Int(kr5 / 2): kg6 = Int(kg5 / 2): kb6 = Int(kb5 / 2)
draw_robot mmx, mmy, m, 6
mmx = mmx + 64
If mmx >= _Width Then
mmx = 0
mmy = mmy + 64
End If
Next m
md$ = "Robot Sprite Sheet generated " + Date$ + " at " + Time$
md2$ = "Mini-Robot-Mixer V0.1 by James D. Jarvis"
_PrintString (0, 321), md$
_PrintString (0, 337), md2$
Do
_Limit 60
kk$ = InKey$
Loop Until kk$ <> ""
If kk$ = "C" Or kk$ = "c" Or kk$ = "S" Or kk$ = "s" Then
_ClipboardImage = ms&
_Delay 0.3
Locate 1, 1: Print "Sprite Sheet Saved to Clipboard"
Sleep 3
End If
Loop Until kk$ = Chr$(27)
_FreeImage part&
System
Sub draw_robot (Mx, my, mid, scale)
'generate a monster image from source sprite sheet part& and render to the programs main screen ms&
tempi& = _NewImage(64, 64, 32)
'tempi& creates a temporary one sprite image for rendering
_ClearColor clr~&, tempi&
_Dest tempi&
Cls
_Source tempi&
'repaint source image with generate color values for new monster sprite
For y = 0 To 63
For x = 0 To 63
Select Case Point(x, y)
Case kk1
PSet (x, y), rlook(mid).k1
Case kk2
PSet (x, y), rlook(mid).k2
Case kk3
PSet (x, y), rlook(mid).k3
Case kk4
PSet (x, y), rlook(mid).k4
Case kk5
PSet (x, y), rlook(mid).k5
Case kk6
PSet (x, y), rlook(mid).k6
End Select
Next x
Next y
'generated image in tempi& is rendered to ms& as a 64 by 64 sprite
_PutImage (Mx, my)-(Mx + 63, my + 63), tempi&, ms&
_Source ms&
_Dest ms&
_FreeImage tempi&
End Sub
Data "BIG","SMALL","LION","TIGER","CAR","TRUCK","BLACK","WHITE","WEED","FLOWER","BEDROOM","KITCHEN","COPPER","BRASS","DESERT","OASIS","MILK","HONEY","HORSE","SHEEP"
Data "BADGE","MEDAL","MARRY","DIVORCE","SHED","HOUSE","WAR","PEACE","SUIT","DRESS","BOX","CARTON","ROAD","STREET","DUNCE","GENIUS","CUP","PLATE","STEAK","EGGS"
Data "ORB","SCEPTRE","TOWN","VILLAGE","BURGER","CHIPS","YOUTH","MAIDEN","OLD","NEW","FAKE","GENUINE","TEA","COFFEE","DRESS","SKIRT","PLANTS","WEEDS","PENCIL","CRAYON"
Data "GLASS","BEAKER","GUITAR","PIANO","SLATE","STONE","CORD","ROPE","JUNGLE","DESERT","PANTRY","CUPBOARD","BROOM","SHOVEL","FOOD","DRINK","ORANGE","LEMON","SINNER","SAINT"
AlchemyDescription:
Print
Color 14
Print Tab(36); "ALCHEMY": Color 15
Print
Print " Alchemy (al/ke/mi) can be defined as the process of changing something into"
Print " something different in a mystical way, such as changing ";: Color 14: Print "STONE";: Color 15
Print " into ";: Color 14: Print "GOLD.": Color 15
Print
Print " This game calls upon your skills in this art, to change a word into a"
Print " totally different one, with the least number of changes."
Print
Print " In the usual word-swap game, you repeatedly change one letter of a word for a"
Print " different one, creating a new word, until the target word is produced."
Print
Print " But in Alchemy, you have another tool available to you for the transformation."
Print " You can also ";: Color 14: Print "add";: Color 15: Print " or ";: Color 14: Print "remove";: Color 15: Print " a letter, before re-arranging them, so the word may"
Print " change in length several times as you progress."
Print
Print " As an example, we can change STONE into GOLD with 4 changes:"
Color 14: Print Tab(23); "STONE - TONE - GONE - LONG - GOLD": Color 15
Print
Print " If the wordslists directory is present, each word entered is checked against"
Print " these. If not, they are assumed to be legitimate words."
Print " The wordlist files are the Complete Collins Scrabble Words (2019)."
Print: Color 14
Print Tab(29); "Press a key to continue"
While InKey$ = "": Wend
Play ok$
LoadPairs
Choice: ' invites replacing best scores in file with defaults
Color 14
Locate 23, 17
Print "Would you like to delete all previous results (y/n)";
Sleep
Color 15: y$ = UCase$(InKey$)
If y$ = "Y" Then
Refresh
Play ok$
LoadPairs
End If
SetPair: ' Select pair of words
LoadPairs
Color 14: Print Tab(22); "Which pair would you like, from A to T";
getpair:
pair$ = UCase$(InKey$)
If pair$ < "A" Or pair$ > "T" Then GoTo getpair
If pair$ = Chr$(27) Then Stop
pairnumber = Asc(pair$) - 64
Locate 23, 15: Print "Would you like to peek at the previous best solution (y/n)"
showchain:
k$ = InKey$
If k$ = "" Then GoTo showchain
If UCase$(k$) = "Y" Then ShowBest
StartGame:
Cls
remain = 21: tries = 0: fail = 0 ' start each game with 21 tries remaining
first$ = firstwords$(pairnumber): last$ = lastwords$(pairnumber)
train$(pairnumber) = first$
target = targets(pairnumber): name$ = names$(pairnumber) ' get selected pair details
prev$ = first$ ' pretend the first was a previous try
Color 14
Locate 1, 39 - Int(Len(first$) / 2): Print first$; Tab(52); "Record:"; target ' display the first word in yellow on row 2
Color 15
For a = 2 To maxtries + 1: Locate a, 35
Print String$(9, "."): Next ' show 9 dots for each try (rows 2 to 21)
Color 14
Locate 22, 39 - Int(Len(last$) / 2): Print last$; ' display the last word in yellow on row 23
tryvert = 2 ' row 3 will take the first try
InviteTry:
If tries = maxtries Then
Play fail$
WIPE "23": Color 3:
Locate 23, 21: Print "You've Used up all of your tries, sorry!"
WIPE "24"
Color 15
Sleep 3
GoTo StartGame ' ran out of tries, restart the same pair
Else
Locate tryvert, 35: Print String$(9, "."); Tab(46); Space$(30)
WIPE "23": Color 14 ' refresh remaining tries advice
Locate 23, 27
Print "You have"; 20 - tries; "tries remaining"
Locate tryvert, 3 ' display invite at tab 10 of current try-line
Print "Your word (q to quit)";
End If
DealWithTry:
Locate tryvert, 25
Input try$ ' show ? outside try-line and set try to first dot
Color 15
try$ = UCase$(try$)
If try$ = "Q" Then Stop
If try$ < "A" Or try$ > "Z" Then Play fail$: GoTo SetPair
tries = tries + 1
Locate tryvert, 35: Print Space$(12)
Locate tryvert, 39 - Int(Len(try$) / 2): Print try$
CheckWord ' Call Sub to Check the Player's Word
DealWithCheck:
Locate tryvert, 1: Print Space$(35)
If fail = 1 Then
Locate tryvert, 35: Print " "
Color 3
Locate tryvert, 39 - Len(try$) / 2
Print try$
Color 15
tryvert = tryvert + 1
GoTo InviteTry
Else
If try$ = last$ Then
Finished
GoTo SetPair
Else
Locate 23, 30
Print Space$(50)
tryvert = tryvert + 1
GoTo InviteTry
End If
End If
Sub Refresh
Restore
target = 21: name$ = "UNSOLVED!"
Open "alchpairs" For Output As #1
For a = 1 To 20
train$(a) = "UNSOLVED!"
Read first$, last$
Write #1, first$, last$, target, name$, train$(a)
Print first$; " "; last$; target; name$
Next
Close
Cls
End Sub
Sub WIPE (ln$) ' call with ln$ string of 2-digit line numbers only eg "012223" for lines 1, 22 and 23
For a = 1 To Len(ln$) - 1 Step 2
Locate Val(Mid$(ln$, a, 2)): Print Space$(80);
Next
End Sub
Sub LoadPairs
Restore
Cls
Color 14: Print Tab(37); "Word Pairs"
Print Tab(20); "Pair"; Tab(30); "From"; Tab(41); "To"; Tab(50); "Best"; Tab(62); "By"
Color 15
If _FileExists("alchpairs") Then
Open "alchpairs" For Input As #1
For a = 1 To 20
Input #1, firstwords$(a), lastwords$(a), targets(a), names$(a), train$(a) ' loads word-pairs from "alchpairs" file
Color 14: Print Tab(20); Chr$(a + 64);: Color 15: Print Tab(30); firstwords$(a); Tab(40); lastwords$(a); Tab(50); targets(a); Tab(60); names$(a)
Next
Close #1
Else Refresh
End If
End Sub
Sub ShowBest
Cls: Locate 12, 2
If train$(pairnumber) = "UNSOLVED!" Then Print Tab(35);
Print train$(pairnumber): Sleep 2: Cls
End Sub
Sub CheckWord
added = 0: added$ = "": removed = 0: removed$ = "": fail = 0 ' initialise added, removed and fail flag
Locate tryvert, 48: Print Space$(32)
Locate tryvert, 48
CountAdded:
temp$ = prev$ ' use temp$ as sacrificial to keep prev$ intact while checking for added
For a = 1 To Len(try$) ' for each letter in try$...
l$ = Mid$(try$, a, 1) ' take a letter l$ of temp$
po = InStr(temp$, l$) ' find its position po in temp$ (if any)
If po < 1 Then ' if not found...
added = added + 1
added$ = added$ + l$ ' count it and add to added$
Else
Mid$(temp$, po, 1) = " "
End If
Next
CountRemoved:
temp$ = try$ ' use temp$ as sacrificial to keep prev$ intact while checking for added
For a = 1 To Len(prev$) ' for each letter in try$...
l$ = Mid$(prev$, a, 1) ' take a letter l$ of temp$
po = InStr(temp$, l$) ' find its position po in temp$ (if any)
If po < 1 Then ' if not found...
removed = removed + 1
removed$ = removed$ + l$ ' add it to added$
Else
Mid$(temp$, po, 1) = " "
End If
Next
If added > 1 Then Color 3 Else Color 15
Print "Added "; added$;
If removed > 1 Then Color 3 Else Color 15
Print Tab(60); "Removed "; removed$ ' show letters that have been added or removed, colour cyan if too many
DictionaryCheck:
If Not _DirExists("wordlists") Then isaword = 1: GoTo checksfinished
WIPE "23"
filename$ = "wordlists/" + Left$(try$, 1) ' select dictionary file of first letter of try-word
Open filename$ For Input As #1
getaword:
isaword = 0
While Not EOF(1)
Input #1, dictword$ ' read each word from dictionary
If try$ = dictword$ Then isaword = 1: Exit While ' if word is found, don't look any further
Wend
Close
checksfinished:
Locate 23, 1
If added > 1 Or removed > 1 Or isaword = 0 Then ' if more than one letter added or removed, or word not found, set fail flag
Play fail$
Color 3 ' colour of try changed to cyan if word failed
Print Tab(35); "Word failed";
Color 15
fail = 1
Else
Play ok$
Print Tab(37); "Word ok"; ' otherwise, declare word as ok and make this the new prev$
prev$ = try$
train$(pairnumber) = train$(pairnumber) + "-" + try$
End If
Sleep 1
WIPE "23"
End Sub
Sub Finished
Play ok$: Play ok$
Locate tryvert, 35: Print Space$(12)
Locate tryvert, 39 - Len(try$) / 2: Print try$
WIPE "2223"
Locate 22, 21: Color 14: Print "You did it in"; tries; "changes. Target was"; targets(pairnumber)
Sleep 2
If tries >= targets(pairnumber) Then ' if target is not beaten,
Exit Sub ' go back for next game
Else
targets(pairnumber) = tries ' change the target for that pair to the new best score
Cls
Locate 10, 4
Input "Enter a name for the Best Scores list (or <ENTER> for anonymous)"; winname$ ' get the player's name
If Len(winname$) < 2 Then winname$ = "ANONYMOUS" ' if <ENTER> (or only one character) is given, name is Anonymous
names$(pairnumber) = UCase$(winname$) ' change the name for that pair to the new name
Open "alchpairs" For Output As #1
For a = 1 To 20
Write #1, firstwords$(a), lastwords$(a), targets(a), names$(a), train$(a) ' re-write the alchpairs file with the new details
Next
Close
End If
Cls
Locate 10, 40 - Len(train$(pairnumber)) / 2: Print train$(pairnumber)
Print: Print Tab(36); "Press a key"
Sleep
End Sub
Make5.bas is a small puzzle game where you try to clear the board by removing pieces of the same color. You remove them by making combinations of 5 or more pieces of the same color in the same row or column. Click on the ball to move, then click where you want to move it to. Only large balls can be moved.
Points are scored for pieces that you clear off the board. When the board gets full and no possible moves left then the game is over. See how many points you can make before it's over.
This is an updated and enhanced version of the one posted at the old forum. This new one auto sizes to fit users desktop (not hard coded to a small resolution), the Hi Score is now saved to file, matches are now found both ways at the same time (row+col), and the board and pieces have a better look.
- Dav
Code: (Select All)
'=========
'MAKE5.bas v2.1
'=========
'A board clearing puzzle game.
'Clear the board of balls and score points.
'Make rows/colums of 5 or more of same color.
'Coded by Dav, JUL/2023 for QB64-Phoenix Edition.
'New for version 2.1:
'
' - Added _ICON call for Linux users.
' (Needed for QB64PE icon to be used by program)
' - Removed slow _MOUSEINPUT polling for faster method.
' - Because mouse is faster, the board size can now be
' bigger on larger desktops (not capped out as before).
'===========
'HOW TO PLAY:
'===========
'Colored balls will appear randomly on the playing board.
'Move bigger balls of same color next to each other to form
'rows and columns of the same color. Make a row/column of 5
'or more of same color to erase them and score points.
'Three new smaller balls will appear after every move.
'The smaller balls will grow into big ones on the next move.
'You may move the big balls on top of the smaller ones.
'The goal is to see how many points you can score before
'running out of board space, in which the game will end.
'This game was originally designed in 600x650.
'Here's a way to adapt that code to adjust larger screens.
'The df is a small display fix for autosizing to desktop.
'The .80 means it will size up to 80% of desktop height
'We will add a *df to any x/y used in a command.
DIM SHARED df: df = (_DESKTOPHEIGHT / 600) * .80
'set original screen size, but use the df value.
SCREEN _NEWIMAGE(600 * df, 650 * df, 32)
DO: LOOP UNTIL _SCREENEXISTS
_TITLE "Make5 Puzzle"
'=== define board info
DIM SHARED rows, cols, size, score, hiscore
rows = 9: cols = 9: size = _WIDTH / cols
DIM SHARED box.v(rows * cols), box.s(rows * cols) 'value, size
DIM SHARED box.x(rows * cols), box.y(rows * cols) 'x/y's
DIM SHARED checks(rows * cols) 'extra array for checking
'
'=== load hi score from file
IF _FILEEXISTS("make5.dat") THEN
scr = FREEFILE
OPEN "make5.dat" FOR BINARY AS #scr
hiscore = CVL(INPUT$(4, scr))
IF hiscore < 0 THEN hiscore = 0 'a failsafe
CLOSE #scr
END IF
'=======
restart:
'=======
PLAY "MBL32O3CEGEC"
score = 0
'CLS , _RGB(13, 13, 13)
bc = 1 'counter
FOR c = 1 TO cols
FOR r = 1 TO rows
x = (r * size) '(df is already computed in the 'size')
y = (50 * df) + (c * size)
box.x(bc) = x - size
box.y(bc) = y - size
box.v(bc) = 0 'zero means no color, empty box
box.s(bc) = 1 ' 1 = small size piece
bc = bc + 1
NEXT
NEXT
MakeNewBalls 3, 1 'put 3 big balls on board
MakeNewBalls 3, 2 'put 3 small balls on board
'====
main:
'====
selected = 0
UpdateBoard
second: 'Go back here when making second choice
_DISPLAY
DO
'wait until mouse button up to continue
WHILE _MOUSEBUTTON(1) <> 0: n = _MOUSEINPUT: WEND
WHILE _MOUSEINPUT: WEND
'highlight box when a box is selected
IF selected = 1 THEN
LINE (box.x(t) + 2, box.y(t) + 2)-(box.x(t) + size - 2, box.y(t) + size - 2), _RGB(RND * 255, RND * 255, RND * 255), B
LINE (box.x(t) + 3, box.y(t) + 3)-(box.x(t) + size - 3, box.y(t) + size - 3), _RGB(RND * 255, RND * 255, RND * 255), B
LINE (box.x(t) + 4, box.y(t) + 4)-(box.x(t) + size - 4, box.y(t) + size - 4), _RGB(RND * 255, RND * 255, RND * 255), B
_DISPLAY
END IF
'If user clicked mouse
IF _MOUSEBUTTON(1) THEN
'see where they clicked
mx = _MOUSEX: my = _MOUSEY
'cycle through all Check blocks...
FOR t = 1 TO (rows * cols)
'if clicked on a box clicked
IF mx >= tx AND mx <= tx2 THEN
IF my >= ty AND my <= ty2 THEN
'if this is a first choice...
IF selected = 0 THEN
'only select boxes not empty, with big size balls
IF box.v(t) <> 0 AND box.s(t) = 2 THEN
selected = 1
SOUND 3000, .1 'made a select
oldt = t
oldtv = box.v(t) 'save picked box number color
GOTO second 'now get second choice
END IF
END IF
IF selected = 1 THEN 'making second choice
'if selected an empty box or small ball
IF box.v(t) = 0 OR box.s(t) = 1 THEN
'Grow small balls
FOR d = 1 TO rows * cols
IF box.v(d) <> 0 AND box.s(d) = 1 THEN box.s(d) = 2
NEXT
UpdateBoard
'copy current box values into checking array
FOR i = 1 TO (rows * cols)
checks(i) = box.v(i)
NEXT
'check Rows for 5 or more done
FOR i = 1 TO (rows * cols) STEP 9
CheckRow i
NEXT
'Check Cols for 5 or more
FOR i = 1 TO 9
CheckCol i
NEXT
'copy checking values back into box values
FOR i = 1 TO (rows * cols)
IF checks(i) = 0 THEN
box.v(i) = 0: box.s(i) = 1
END IF
NEXT
'See how many boxes left to use...
howmany = 0
FOR h = 1 TO rows * cols
'empty ones
IF box.v(h) = 0 THEN howmany = howmany + 1
NEXT
'If not enough spaces left, game over
IF howmany < 3 THEN
LINE (200 * df, 250 * df)-(400 * df, 350 * df), _RGB(0, 0, 0), BF
LINE (200 * df, 250 * df)-(400 * df, 350 * df), _RGB(255, 255, 255), B
PPRINT 233 * df, 285 * df, 18 * df, _RGB(255, 255, 255), 0, "GAME OVER"
PLAY "mbl16o2bagfedc"
_DISPLAY: SLEEP 6
GOTO restart
END IF
'make 3 more random small balls
MakeNewBalls 3, 1
GOTO main
ELSE
'if clicked on another big ball instead...
IF box.s(t) = 2 THEN
'clear previous highlighted selection
selected = 0
UpdateBoard
selected = 1
oldt = t
oldtv = box.v(t) 'save picked box number color
SOUND 3000, .1
GOTO second
END IF
END IF
END IF
END IF
END IF
NEXT
END IF
_DISPLAY
IF INKEY$ = " " THEN GOTO restart
LOOP
SUB CheckRow (num)
'space to hold box nums to clear
REDIM nums(9)
'found some to clear flag
rdone = 0
'set place and num
rc = 1
nums(1) = num
'step through the boxes
FOR r = (num + 1) TO (num + 8)
'if this box is same as previous...
IF box.s(r) = 2 AND box.v(r) = box.v(nums(rc)) THEN
'store this box value in nums too
nums(rc + 1) = r
'increase how many so far
rc = rc + 1
ELSE
'bot same, so reset
IF rdone = 0 THEN
'no more, so start over from here
ERASE nums
REDIM nums(9)
rc = 1: nums(1) = r
ELSE
'no more can exists on line
EXIT FOR
END IF
END IF
'if there was 5 or more found
IF rc >= 5 THEN rdone = 1
NEXT
'if group was found, clear
IF rdone = 1 THEN
PLAY "mbl32o3cdefga"
'step through nums values
FOR d = 1 TO 9
IF nums(d) <> 0 THEN
score = score + 55 '55 points per ball
x = box.x(nums(d)): y = box.y(nums(d))
LINE (x + 2, y + 2)-(x + size - 2, y + size - 2), _RGB(255, 255, 255), BF
_DELAY .025: _DISPLAY
LINE (x + 2, y + 2)-(x + size - 2, y + size - 2), _RGB(64, 64, 64), BF
_DELAY .025: _DISPLAY
checks(nums(d)) = 0 'mark checking array
END IF
NEXT
END IF
ERASE nums
END SUB
SUB CheckCol (num)
'space to hold box nums to clear
REDIM nums(9)
'found some to clear flag
rdone = 0
'set place and num
rc = 1
nums(1) = num
'step through the boxes
FOR r = (num + 9) TO (rows * cols) STEP 9
'if this box is same as previous...
IF box.s(r) = 2 AND box.v(r) = box.v(nums(rc)) THEN
'store this box value in nums too
nums(rc + 1) = r
'increase how many so far
rc = rc + 1
ELSE
'bot same, so reset
IF rdone = 0 THEN
'no more, so start over from here
ERASE nums
REDIM nums(9)
rc = 1: nums(1) = r
ELSE
'no more can exists on line
EXIT FOR
END IF
END IF
'if there was 5 or more found
IF rc >= 5 THEN rdone = 1
NEXT
'if group was found, clear
IF rdone = 1 THEN
PLAY "mbl32o3cdefga"
'step through nums values
FOR d = 1 TO 9
IF nums(d) <> 0 THEN
score = score + 55 'add to score
x = box.x(nums(d)): y = box.y(nums(d))
LINE (x + 2, y + 2)-(x + size - 2, y + size - 2), _RGB(255, 255, 255), BF
_DELAY .025: _DISPLAY
LINE (x + 2, y + 2)-(x + size - 2, y + size - 2), _RGB(64, 64, 64), BF
_DELAY .025: _DISPLAY
checks(nums(d)) = 0 'mark checking array
END IF
NEXT
END IF
'=== draw board based on box values
bc = 1 'counter
FOR cl = 1 TO cols
FOR ro = 1 TO rows
'=== if empty box
IF box.v(bc) = 0 THEN
LINE (box.x(bc) + 2, box.y(bc) + 2)-(box.x(bc) + size - 2, box.y(bc) + size - 2), _RGB(32, 32, 32), BF
ELSE
LINE (box.x(bc) + 2, box.y(bc) + 2)-(box.x(bc) + size - 2, box.y(bc) + size - 2), _RGB(32, 32, 32), BF
'=== draw color ball
x2 = box.x(bc) + (size / 2) 'find middle of box
y2 = box.y(bc) + (size / 2)
IF box.s(bc) = 1 THEN sz = size / 4 ELSE sz = size / 2
SELECT CASE box.v(bc)
CASE IS = 1: r = 255: g = 64: b = 64 'red
CASE IS = 2: r = 64: g = 232: b = 64 'green
CASE IS = 3: r = 64: g = 64: b = 255 'blue
CASE IS = 4: r = 255: g = 255: b = 0 'yellow
CASE IS = 5: r = 255: g = 255: b = 255 'white
END SELECT
'draw colored balls
FOR s = 1 TO (sz - 4) STEP .3
CIRCLE (x2, y2), s, _RGB(r, g, b)
r = r - 1: g = g - 1: b = b - 1
NEXT
END IF
bc = bc + 1
NEXT
NEXT
'overlay a very faint QB64-PE icon on board
_SETALPHA 16, , -11: _PUTIMAGE (0, 50 * df)-(_WIDTH, _HEIGHT), -11
_DISPLAY
_ICON _DISPLAY 'update app icon on taskbar
END SUB
SUB MakeNewBalls (num, ballsize)
'Assign 3 new balls
newball = 0
DO
c = INT((RND * (cols * rows)) + 1)
IF box.v(c) = 0 THEN
box.v(c) = INT((RND * 5) + 1)
box.s(c) = ballsize
newball = newball + 1
END IF
IF newball = num THEN EXIT DO
LOOP
END SUB
SUB PPRINT (x, y, size, clr&, trans&, text$)
orig& = _DEST
bit = 32: IF _PIXELSIZE(0) = 1 THEN bit = 256
FOR t = 0 TO LEN(text$) - 1
pprintimg& = _NEWIMAGE(16, 16, bit)
_DEST pprintimg&
CLS , trans&: COLOR clr&
PRINT MID$(text$, t + 1, 1);
_CLEARCOLOR _RGB(0, 0, 0), pprintimg&
_DEST orig&
x1 = x + (t * size): x2 = x1 + size
y1 = y: y2 = y + size
_PUTIMAGE (x1 - (size / 2), y1)-(x2, y2 + (size / 3)), pprintimg&
_FREEIMAGE pprintimg&
NEXT
END SUB
SUB SaveScore
'Out with the old
IF _FILEEXISTS("make5.dat") THEN KILL "make5.dat"
'In with the new
scr = FREEFILE
OPEN "make5.dat" FOR OUTPUT AS #scr
hi$ = MKL$(hiscore)
PRINT #scr, hi$;
CLOSE #scr
END SUB
Now, let's be honest -- How many of you guys think that PRESET is just a longhand version of PSET? Same command, just with more typing! After all, what's the difference between these two programs:
Code: (Select All)
$Color:32
Screen _NewImage(640, 480, 32)
For y = 0 To _Height
For x = 0 To _Width
If x Mod 10 < 5 Then
If y Mod 10 < 5 Then PSet (x, y), Red Else PSet (x, y), Purple
Else
If y Mod 10 < 5 Then PSet (x, y), Gold Else PSet (x, y), Lime
End If
Next
Next
Sleep
And code 2:
Code: (Select All)
$Color:32
Screen _NewImage(640, 480, 32)
For y = 0 To _Height
For x = 0 To _Width
If x Mod 10 < 5 Then
If y Mod 10 < 5 Then PReset (x, y), Red Else PReset (x, y), Purple
Else
If y Mod 10 < 5 Then PReset (x, y), Gold Else PReset (x, y), Lime
End If
Next
Next
Sleep
Stare at both those screens for a while -- try to focus one eye one each of them -- and see how long you can hold out before your brain melts. That's got to be two of the most annoying tiling patterns possible for the human eyes to have to deal with... Just looking at them, I somehow find them jarring and annoying.
Yet, as annoying as those two tiling patterns are, they're exactly the same pattern.
So how the heck did PRESET behave any different at all from PSET?
Quick answer: It didn't. And for most folks, with the way they tend to code explicitly nowadays, it never will.
Most folks? Code nowadays?? WTH is Steve talking about now??
Good question!
Today's modern coding practices have evolved quite a bit from back in the original days of computing. Variable names are now long and descriptive, whereas in the past they were kept as short as possible to reduce memory usage. Gotos are no longer in widespread use, as modern convention says to structure your programs better with DO..LOOPs and such. Line numbers have faded from the wayside of coding practices...
...and so has the practice of writing code that relies implicitly upon previous settings. For example:
Code: (Select All)
$Color:32
Screen _NewImage(640, 480, 32)
Color Pink
For y = 100 To 200
For x = 100 To 200
PSet (x, y)
Next
Next
Sleep
Most modern programmers would set that PSET to become PSET (x, y), Pink, defining it explicitly in their code. Old code used to use the style above, just to save a few bytes of memory when possible (not something we're so obsessed over with modern machines running 32GB+ of ram). Don't specify a color -- just use the default color...
But, now that we have this older style in mind, let's take a look at PRESET:
Code: (Select All)
$Color:32
Screen _NewImage(640, 480, 32)
Cls , White
Color Pink
For y = 100 To 200
For x = 100 To 200
PReset (x, y)
Next
Next
Sleep
If you notice, I cleared the whole screen white. Specified my color to be Pink... and somehow I drew a BLACK box??
WTH?? How'd that happen??
PSET, when no color is specified, defaults to your _DEFAULTCOLOR. PRESET, when no color is specified, defaults to your _BACKGROUNDCOLOR.
Add a simple Print "Hello World" to the last program and see what you get -- pink text on a black background.
Black is the background color, and thus PRESET plots the points specified in black.
And that's the difference in the two commands in a nutshell: PSET defaults to your primary color; PRESET defaults to your background color. As long as you specify the color yourself, they both perform exactly the same. It's only when no color is specified that you'll see the difference in the two commands.
I've been trying to make this work but I'm stumped.
I messed around with a 3d points program by MasterGy and managed to get a sense of the space and coordinates. There's something that I can't seem to grasp though...that's placing an image onto a surface (using _maptriangle).
In this program, I wanted to place an image on the 'floor'. So I started by placing about 600 small tiles in a grid, exactly where I want to place the image. But images always rotate towards the viewer. Even the small tiles do this. The grid of tiles (as a whole) doesn't do this - only each individual tile. How to lay the image flat is what I'm trying to figure out.
So if anyone here knows how this works....
I'll attach the image I'm trying to use but any 750x750 image will do.
'create spectator
Dim Shared sp(6)
sp(0) = 500
sp(1) = 1500
sp(2) = 400
sp(3) = 0 'looking in the direction of the observer XZ
sp(4) = 0 'looking in the direction of the observer YZ
sp(5) = 1 'multiplier X-Y see
sp(6) = 1 'multiplier Z see
'draw floor tiles
For ctx = 1 To 500 Step 20
For cty = 1 To 500 Step 20
ps = 2
x = 0 + ps * ctx
y = 0 + ps * cty
z = 530
rotate_to_maptriangle x, y, z 'position of floor tiles from the point of view of the observer
_MapTriangle (0, 0)-(100, 0)-(0, 100), floor To(x - ps, y - ps, z)-(x + ps, y - ps, z)-(x - ps, y + ps, z)
_MapTriangle (100, 100)-(100, 0)-(0, 100), floor To(x + ps, y + ps, z)-(x + ps, y - ps, z)-(x - ps, y + ps, z)
Next cty
Next ctx
'draw octo floor
ps = 500
x = 500
y = 500
z = 30
rotate_to_maptriangle x, y, z 'octo floor
_MapTriangle (0, 0)-(750, 0)-(0, 750), floor2 To(x - ps, y - ps, z)-(x + ps, y - ps, z)-(x - ps, y + ps, z), , _Smooth
_MapTriangle (750, 750)-(750, 0)-(0, 750), floor2 To(x + ps, y + ps, z)-(x + ps, y - ps, z)-(x - ps, y + ps, z), , _Smooth
_Display
'mouse input axis movement and mousewheel
mousex = mousex * .6
mousey = mousey * .6
mw = 0
While _MouseInput: mousex = mousex + _MouseMovementX: mousey = mousey + _MouseMovementY: mw = mw + _MouseWheel: Wend 'movement data read
Sub rotate_to_maptriangle (x, y, z)
x2 = x - sp(0)
y2 = y - sp(1)
z2 = z - sp(2)
rotate_2d x2, y2, sp(3)
rotate_2d y2, z2, sp(4) + _Pi / 2
x = x2 * sp(5)
y = y2 * sp(5)
z = z2 * sp(6)
End Sub
Sub rotate_2d (x, y, ang)
x1 = x * Cos(ang) - y * Sin(ang)
y1 = x * Sin(ang) + y * Cos(ang)
x = x1: y = y1
End Sub
I'm not sure what the commas do at the end of the line.
The same thing can be found in this example:
Code: (Select All)
Circle (400, 450), 10, _RGB32(100, 100, 100), , , .5
The only wording I've seen so far is on the circle wiki page which seems to suggest this is about "aspect". I believe this changes the circle to an ellipse. But no real mention of using 3 commas in a row as a plan of attack. I'm starting to expect to see more inexplicable multiple commas as I read more program examples.
If anyone can explain this a bit more, please do. Cheers!
EDIT: You'll notice a bit of a mixed bag of choices (like using GOSUB's and SUB's; every BAM program is an opportunity to do sanity checks on as many statements/styles I can squeeze in there without getting too messy.
Is there a fast way to test whether 2 images are exactly the same?
Code: (Select All)
' ?????????????????????????????????????????????????????????????????????????????
' HOW MIGHT WE EFFICIENTLY COMPARE TWO IMAGES?
' ?????????????????????????????????????????????????????????????????????????????
_Dest 0: Cls , cBlack
If image1& < -1 Then _PutImage , image1&, 0
Print "image1 (press any key)"
Sleep
_Dest 0: Cls , cBlack
If image2& < -1 Then _PutImage , image2&, 0
Print "image2 (press any key)"
Sleep
'compare image1& to image2&, the same?
' UPDATE image2 TO MATCH image1
_Dest image2&
Paint (55, 85), cBlue, cRed
'PAINT [STEP] (column%, row%), fillColor[, borderColor%]
_Dest 0: Cls , cBlack
If image2& < -1 Then _PutImage , image2&, 0
Print "image2 after change (press any key)"
Sleep
'compare image1& to image2&, the same?
' WAIT FOR KEYS
Sleep
' CLEAR IMAGES
Screen 0
If image1& < -1 Then _FreeImage image1&
If image2& < -1 Then _FreeImage image2&
System
Sub DrawSquare (img&, x1%, y1%, size%, fgcolor~&, bgcolor~&)
Dim x2%, y2%
If img& < -1 Then
_Dest img& ': Cls , cEmpty
x2% = (x1% + size%) - 1
y2% = (y1% + size%) - 1
Line (x1%, y1%)-(x2%, y1%), fgcolor~&, , 65535
Line (x2%, y1%)-(x2%, y2%), fgcolor~&, , 65535
Line (x2%, y2%)-(x1%, y2%), fgcolor~&, , 65535
Line (x1%, y2%)-(x1%, y1%), fgcolor~&, , 65535
If bgcolor~& <> cEmpty Then
'PAINT [STEP] (column%, row%), fillColor[, borderColor%]
Paint (x1% + 1, y1% + 1), bgcolor~&, fgcolor~&
End If
End If
End Sub ' Draw Square
Function cBlack~& ()
cBlack = _RGB32(0, 0, 0)
End Function ' cBlack~&
Function cGray~& ()
cGray = _RGB32(128, 128, 128)
End Function ' cGray~&
Function cWhite~& ()
cWhite = _RGB32(255, 255, 255)
End Function ' cWhite~&
Function cRed~& ()
cRed = _RGB32(255, 0, 0)
End Function
Function cOrange~& ()
cOrange = _RGB32(255, 165, 0)
End Function ' cOrange~&
Function cYellow~& ()
cYellow = _RGB32(255, 255, 0)
End Function ' cYellow~&
Function cLime~& ()
cLime = _RGB32(0, 255, 0)
End Function ' cLime~&
Function cCyan~& ()
cCyan = _RGB32(0, 255, 255)
End Function ' cCyan~&
Function cBlue~& ()
cBlue = _RGB32(0, 0, 255)
End Function ' cBlue~&
Function cPurple~& ()
cPurple = _RGB32(128, 0, 255)
End Function ' cPurple~&
Function cMagenta~& ()
cMagenta = _RGB32(255, 0, 255)
End Function ' cMagenta~&
Function cEmpty~& ()
cEmpty = _RGB32(0, 0, 0, 0)
End Function ' cEmpty~&