SmileBASIC 4 Discussion「プチコン4」
Root / General / [.]
What they mean is, without specifying a width and height, SAVEG will save the entire 2048x2048 page, but some of these images are actually smaller than that. For instance, you might end up loading a 64x64 image and then saving it as a 2048x2048 image with a ton of unnecessary padding. The only problem is, PNG files won't tell you what their actual size is because of a bug, so you'll have to figure it out manually.That won't work if the file isn't the default size thoughIt worked for me. It seemed to save everything. Maybe I’m wrong and some of the parts from the PNG files got cut off?
Is it possible to read data from a different slot without the "PRG" commands? I'm trying to use a large text file in multiple programs that contains different data sets.Commands that take labels will usually also take strings like "1:@MYLABEL", where 1 is the slot number. You may have to EXEC that slot first, though.
How is SB4 MML different from SB3 MML? Also, is SB2 MML different from SB3 MML in any way?That's not a very easy question to answer, since the differences can be subtle and not everything is spelled out in the documentation. The few things I've noticed:
- |ABC| plays those notes as a chord. It seems useful, but in my experience it has a tendency to clutter up MML compared to using separate channels when there's a lot of chords, so it's best used sparingly.
- Weird note lengths like 5 or 9 aren't allowed anymore. Best to use & instead.
- Some instrument numbers are different.
- Things sound... subtly different from SB3. I don't really have a background in audio stuff, so I can't really explain it. I don't think it's just better samples.
They explicitly mentioned that the soundbank is at a much higher quality this time, and it shows. With headphones, the original BGM sound new again in some ways. It also helps that the sample rate of the switch is higher, 48kHz versus the 3DS at 32. Also, you forgot to mention, there's like 30 MML drumkits now.
There's probably a few reasons, but one is that now it's closer to how music notation works. It's hard to explain why they're weird without just giving an introductory lesson in music, so I... guess that's what I'm doing! I don't have a background in music, but I do know the basics. Right, so, in the most common time signature, 4/4, songs are broken up into segments called measures, each of which is the length of four quarter notes. That makes sense, right? A quarter note is a quarter of a measure, a half note is half of a measure, a whole note is a whole measure, an eighth note is... well, you get it. In MML, you'd write a quarter note like C4, an eighth note like C8, and so on. You can also set the default length of a note with L4, after which C without a number is the same as C4. Now, that's all well and good. But notes are typically powers of two. That is, you have whole, half, quarter, eighth, sixteenth, and so on notes, but not, say, a fifth note. So, what can you do about that? Well, you can tie notes together. For instance, you can tie a half note and a quarter note together, and get a note as long as the two of them combined. In MML, you'd write this like C2&4. Furthermore, dotted notes exist. A dot lasts half as long as the previous note, and is tied to it, so it has the effect of making a note last 1.5 times as long. In MML, you'd write this like C2.. This is the same as writing C2&4 like earlier. (In fact, you can have multiple dots, each of which lasts half as long as the previous dot. In other words, two dots make a note last 1.75 times as long, three dots last 1.875 times as long, and so on. MML supports multiple dots up to a point, but you'll almost never need them.) So, we have tied notes and dotted notes. But before you start writing messy, complicated notation, there's another thing we can do. See, say we wanted three notes per measure instead of four. Sure, we could try and approximate that with complicated chains of notes tied together, but there's a much easier way. That way is: simply have a measure be three quarter notes instead of four! Remember when I mentioned the 4/4 time signature earlier? Well, it's time to explain what that means. There's a couple of ways you can read a time signature. You can read the numerator as the number of beats in a measure, and the denominator as which note length represents a beat. So, with a 4/4 time signature, there are four beats in a measure, and a quarter note represents a beat. You can also read it as how long a measure is, relative to a measure in 4/4 time. So, a time signature of 3/4 means each measure is 3/4 as long as a measure in 4/4 time, assuming they're played at the same tempo. So, as you might have guessed, if we want three notes per measure instead of four, we probably want a 3/4 time signature. So, how do you write that in MML? Well... you don't. A time signature simply tells you how notes are grouped into measures, so it's notation for the benefit of human readers, rather than something that changes how the song is played. You can, of course, keep track of measures yourself with spacing, by writing CCCC CCCC CCCC or CCC CCC CCC CCC, but that has no effect on how it's played, so it's up to you to make sure measures have the right number of beats in them. The last tool in your pocket is setting the tempo. After all, words like "quarter" or "eighth" are simply a way of dividing up a measure. What those actually mean in terms of time is determined by the tempo, which is specified in beats per minute. Now, in MML, there's no way to say which note length represents a "beat", so it's always a quarter note. In other words, setting the tempo to 80 with T80 means there's 80 quarter notes per minute. So, if you can't get a note quite the length you want, changing the tempo's your last resort. Finally... I'll confess I lied a bit earlier. See, it's true that most notes are powers of two. But, actually, triplets exist, which let you split a note into three. And, wouldn't you know it, MML supports that by... letting you use note lengths of 3, 6, 12, etc. (Specifically, MML in SB4 allows for any note length that 192 is evenly divisible by.) So, technically, if you wanted measures to have three notes instead of four, you could write C3C3C3... but you shouldn't. They're not meant to be used like that. The bottom number of your time signature should basically always be a power of two.Why aren’t these lengths allowed anymore? What made them weird?
- Weird note lengths like 5 or 9 aren't allowed anymore. Best to use & instead.
In SB3, there was a weird bug where certain note lengths weren't actually different. I believe anything from 128 to 192 was the same, for example. It's pretty likely that a lot of the "weird" notes were *already* broken.Yes, and after some more investigation, I think I know why. It seems that, internally, note lengths are all made of 1/192 note ticks. For instance, C192 takes 1 tick, C192&192 (or C96) takes 2 ticks, and so on, up to C1 which takes 192 ticks. So, anything that requires a fraction of a tick is rejected by SB4, but presumably silently rounded by SB3. So, my earlier assertion that SB4 supports up to four dots was mistaken. Actually, it allows as many as you want, as long as it doesn't result in a fraction of a tick. So it allows C1......, which is 381 ticks, but rejects C1......., which would be 382.5 ticks. Similarly, it doesn't allow any dots on C192, since that would always result in a fraction of a tick. I'm also pretty sure this is the real reason why C5 is rejected... so that whole music lesson was mostly a waste of time! Oh well! EDIT: Here's a table of all the valid note length and dot combinations, and how many ticks each takes:
0 1 2 3 4 5 6 1'192 288 336 360 372 378 381 2' 96 144 168 180 186 189 3' 64 96 112 120 124 126 127 4' 48 72 84 90 93 6' 32 48 56 60 62 63 8' 24 36 42 45 12' 16 24 28 30 31 16' 12 18 21 24' 8 12 14 15 32' 6 9 48' 4 6 7 64' 3 96' 2 3 192' 1Generated with this code:
?" 0 1 2 3 4 5 6 FOR NOTE=1 TO 192 IF 192 MOD NOTE!=0 THEN CONTINUE ?FORMAT$("%3D ",NOTE); TICKS=0:DOTS=0:DOTN=NOTE WHILE 192 MOD DOTN==0 TICKS=TICKS+192 DIV DOTN ?FORMAT$("%3D ",TICKS); DOTS=DOTS+1 DOTN=DOTN<<1 WEND ? NEXTEDIT 2: Iterated through with CHKMML and it's exactly as predicted:
1...... 2..... 3...... 4.... 6..... 8... 12.... 16.. 24... 32. 48.. 64 96. 192
FOR NOTE=1 TO 192 IF CHKMML("C"+STR$(NOTE))>=0 THEN CONTINUE ?STR$(NOTE,3) FOR DOTS=1 TO 50 IF CHKMML("C"+STR$(NOTE)+"."*DOTS)<0 THEN ?"."; ELSE ?" "; ENDIF NEXT ? NEXT
You set up collision with SPCOL (management #) then test it with something like SPHITSP (management #, colliding sprite) right? Also if a sprite is scaled you add the scale amount as a second parameter on SPCOL? What does the “mask” parameter mean?Has anyone else has trouble with collision detection? If not could you help a brother out?I know there was a bug where sprite collision didn't take SPSCALE into account, but that should be fixed as of 4.0.2. Could you be more specific about what you're having trouble with?
You set up collision with SPCOL (management #) then test it with something like SPHITSP (management #, colliding sprite) right? Also if a sprite is scaled you add the scale amount as a second parameter on SPCOL? What does the “mask” parameter mean?Yes, you'd set up collision with SPCOL. The scale parameter on SPCOL is a flag, not the scale amount. You set it to true if you want it to take the scale into account, and false if you don't. The mask parameter is a bitmask that determines which kinds of sprites should collide with each other. For example, say you're making a 2-player shoot-'em-up. Now, you don't want every pair of sprites to collide with each other. You wouldn't want the two players to coliide, and you certainly don't want them to collide with their own bullets. Basically, whenever a sprite would collide with another, their bitmasks are ANDed together to see if any bits are set in both of them. If so, they collide. In other words, we should assign a bit for each kind of collision in our game:
- Bit 0 will represent collisions between a player and an enemy.
- Bit 1 will represent collisions between a player and an enemy bullet.
- Bit 2 will represent collisions between an enemy and a player bullet.
'For each player... SPCOL sprite,#TRUE,&B011 'For each player bullet... SPCOL sprite,#TRUE,&B100 'For each enemy... SPCOL sprite,#TRUE,&B101 'For each enemy bullet... SPCOL sprite,#TRUE,&B010After setting up SPCOL, for each sprite, you'd do something like this:
'A is the sprite you're updating right now B=SPHITSP(A) WHILE B>=0 'Handle collision between A and B B=SPHITSP() WENDThis iterates through each sprite currently colliding with A.
you certainly don't want them to collide with their own bullets.Well, that depends. You could spawn the bullets in front of the player and have enemies that bounce back bullets, or implement ricocheting physics, and have the bullets be able to hit the player to make it a bit more realistic.