Thursday, April 26, 2012

Kid Icarus Uprising 3DS Review

Kid Icarus Uprising 3DS Review

I have just finished throwing the greatest shot possible in the Universe, aimed at Hades. Predictably, he disintegrated into nothingness. It feels good to save the Universe. Now, onto difficulty challenge level 1.0!

Yep, it was Kid Icarus Uprising 3DS game, and it's brilliant! The story is engaging. The imageries mesmerizing. The game pace is pitch perfect, mainly because it is adjustable in very fine increment. The amount of weapons available is just mind-boggling, and the special challenges are extremely tricky, indeed. And the control, well, it can be better. A lot better.

There is a reason why they keep saying that you need to get used to the control ... a lot. They say that because you need to get used to the control. I would like to say that the control scheme is defective, but I can't. Not when just about everything else is brilliantly done. This isn't a game designed by some idiot-savant. This is a game designed by a master.

So, then, why, if everything else is perfect, the controls aren't good? Thinking about it carefully, I come to the conclusion that the control is great for the flying sequences where you can just float around and pick enemies one by one. When it comes to the ground fight, however, we have a problem. You need to move and dash and fire, not necessarily at the same direction. Move and dash is taken care of by the Circle Pad. L button fires the weapon. Looking around is touch screen. Aiming is touch screen. Okay, so we have looking around and aiming using the same touch screen. That's problematic.

How do we solve this? Looking around and aiming can be split into 2 different controls. That would work well, if people have 3 hands. Oops.

What else can we do? I like to Resident Evil Revelations solution: Use the gyroscope control to look around. It works really well in that game. I think it will work really well here, too. Until we get to Internet melee, that is. I can just imagine it, people rotating wildly, screaming "I've been hit! I've been hit! Where is he? I can't see him!"

Not a good solution.

Criticizing bad solution is easy. Any monkey can do that. But coming up with a good solution isn't. I'm not convinced that there is a good solution for this game. It is possible that you may have to use 3 different control schemes for this one game.

Which shows you just how expansive, and encompassing this game is. This is really 3 games in one, and it is all brilliantly combined. You have shooting game, adventure game, and FPS game. I like that. I don't like the control, but I can see that it isn't from stupidity or laziness. It's trying to have a consistent control across different gameplay.

I really like this game, easy and challenging in one game. I do wish that they would let me have different control schemes and perhaps the option to separate the flying scenes and the adventure scenes. They do provide boss challenge at the end, but I'd rather have selectable scenes, similar to that of the DVD movies.

All in all, everybody should play this game. The better for me to beat you on the Internet. ;)

Tuesday, April 24, 2012

Small Basic Analog Clock


I wrote a Small Basic Analog Clock. Since I really want to have background pictures, I use Shapes. The rotation is a mess. Lots of trial and error. I also put in time offset, although you have to muddle with the source code to do it. Maybe an update will allow you to do it without modifying the source code. The sample picture has random picture from Flickr. I do wish I know who took it, so it can be properly credited.

'Analog Clock - MHR140
'A Shape example
'by Harry Hardjono
' April 2012
'
'Init
GraphicsWindow.Width=400
GraphicsWindow.Height=400
GraphicsWindow.Show()
GraphicsWindow.Clear()
screen_x=GraphicsWindow.Width
screen_y=GraphicsWindow.Height

'Commented out because it hangs on my SilverLight
'BPic=Flickr.GetRandomPicture("clock")
'BImg=ImageList.LoadImage(BPic)
'BGP=Shapes.AddImage(BImg)


For i=1 to 12
Digits[i]=Shapes.AddRectangle(10,40)
mx1=1
mx2=i
mx3=12
my1=30
my3=360
map()
DAngle=my2
Dx=(screen_x/2)+150*Math.Sin(Math.GetRadians(DAngle))
Dy=(screen_y/2)-150*Math.Cos(Math.GetRadians(DAngle))
Shapes.Rotate(Digits[i],DAngle)
Shapes.Move(Digits[i],Dx,Dy)
Program.Delay(100)
endfor

GraphicsWindow.BrushColor="White"
Hand[1]=Shapes.AddRectangle(20,90) 'Hour hand
Hand[2]=Shapes.AddRectangle(12,150) 'Minute hand
Hand[3]=Shapes.AddRectangle(2,180) 'Second hand

GraphicsWindow.FontSize=15
GraphicsWindow.BrushColor="Black"
TT=Shapes.AddText(Clock.Time)
Shapes.Move(TT,150,5)

OffsetHour=0
OffsetMin=0
OffsetSec=0

Loop:
OnTick()
Program.Delay(1000)
Goto Loop

Sub OnTick
Shapes.SetText(TT,Clock.Time)
THour=Clock.Hour
mx1=0
mx2=Math.Remainder(THour+OffsetHour,12)
mx3=12
my1=0
my3=360
map()
DAngle=my2
Dx=((screen_x/2)+10)+40*Math.Sin(Math.GetRadians(DAngle))
Dy=((screen_y/2)-22.5)-40*Math.Cos(Math.GetRadians(DAngle))
Shapes.Rotate(Hand[1],DAngle)
Shapes.Move(Hand[1],Dx-15,Dy)

TMin=Clock.Minute
mx1=0
mx2=Math.Remainder(TMin+OffsetMin,60)
mx3=60
my1=0
my3=360
map()
DAngle=my2
Dx=((screen_x/2)+6)+60*Math.Sin(Math.GetRadians(DAngle))
Dy=((screen_y/2)-75)-60*Math.Cos(Math.GetRadians(DAngle))
Shapes.Rotate(Hand[2],DAngle)
Shapes.Move(Hand[2],Dx-8,Dy+20)

TSec=Clock.Second
mx1=0
mx2=Math.Remainder(TSec+OffsetSec,60)
mx3=60
my1=0
my3=360
map()
DAngle=my2
Dx=((screen_x/2)+1)+70*Math.Sin(Math.GetRadians(DAngle))
Dy=((screen_y/2)-90)-70*Math.Cos(Math.GetRadians(DAngle))
Shapes.Rotate(Hand[3],DAngle)
Shapes.Move(Hand[3],Dx+3,Dy+20)
Endsub


Sub map 'map function
'x1-x2-x3 y1-y2-y3
my2=((my3-my1)*(mx2-mx1)/(mx3-mx1))+my1
EndSub


Tuesday, April 17, 2012

Small Basic Dice Roller

If it takes me less than one hour of programming, it is a good project for beginner! That in mind, this is an example of a dice roller. Obviously, it's just a lot of variable assignments. You can change the source code if you want, say D100. An example of using the GUI (Control) elements.

Also, I put in a picture loader. Push the "0" button to check it out.












'Dice Roller - MWH959
'A GUI example
'by Harry Hardjono
' April 2012
'
'Init
GraphicsWindow.Show()
GraphicsWindow.Clear()
backpic=""

screen_x=GraphicsWindow.Width
screen_y=GraphicsWindow.Height
NumDice=1
ValDice=6

Button[0]=Controls.AddButton("0",50,50)
Button[1]=Controls.AddButton("1",80,50)
Button[2]=Controls.AddButton("2",110,50)
Button[3]=Controls.AddButton("3",140,50)
Button[4]=Controls.AddButton("4",170,50)
Button[5]=Controls.AddButton("5",50,90)
Button[6]=Controls.AddButton("6",80,90)
Button[7]=Controls.AddButton("7",110,90)
Button[8]=Controls.AddButton("8",140,90)
Button[9]=Controls.AddButton("9",170,90)

Dice[2]=Controls.AddButton("D2",50,150)
Dice[3]=Controls.AddButton("D3",90,150)
Dice[4]=Controls.AddButton("D4",130,150)
Dice[5]=Controls.AddButton("D5",170,150)
Dice[6]=Controls.AddButton("D6",50,190)
Dice[7]=Controls.AddButton("D7",90,190)
Dice[8]=Controls.AddButton("D8",130,190)
Dice[9]=Controls.AddButton("D9",170,190)
Dice[10]=Controls.AddButton("D10",50,230)
Dice[11]=Controls.AddButton("D11",90,230)
Dice[12]=Controls.AddButton("D12",130,230)
Dice[13]=Controls.AddButton("D13",170,230)
Dice[14]=Controls.AddButton("D14",50,270)
Dice[15]=Controls.AddButton("D15",90,270)
Dice[16]=Controls.AddButton("D16",130,270)
Dice[17]=Controls.AddButton("D17",170,270)
Dice[18]=Controls.AddButton("D18",50,310)
Dice[19]=Controls.AddButton("D19",90,310)
Dice[20]=Controls.AddButton("D20",130,310)
Dice[21]=Controls.AddButton("D21",170,310)

Controls.ButtonClicked=OnButtonClicked

'Event
Sub OnButtonClicked
LastButton=Controls.LastClickedButton
GraphicsWindow.BrushColor="white"
GraphicsWindow.FillRectangle(240,50,400,400)
If (backpic<>"") Then
GraphicsWindow.DrawResizedImage(backpic,0,0,screen_x,screen_y)
EndIf
GraphicsWindow.BrushColor="black"
GraphicsWindow.FontSize=30
If (LastButton=Button[0]) Then 'Use sparingly. Picture is loaded every screen redraw!
backpic=Flickr.GetRandomPicture("dice")
GraphicsWindow.DrawResizedImage(backpic,0,0,screen_x,screen_y)
NumDice=1
ElseIf (LastButton=Button[1]) then
NumDice=1
ElseIf (LastButton=Button[2]) then
NumDice=2
ElseIf (LastButton=Button[3]) then
NumDice=3
ElseIf (LastButton=Button[4]) then
NumDice=4
ElseIf (LastButton=Button[5]) then
NumDice=5
ElseIf (LastButton=Button[6]) then
NumDice=6
ElseIf (LastButton=Button[7]) then
NumDice=7
ElseIf (LastButton=Button[8]) then
NumDice=8
ElseIf (LastButton=Button[9]) then
NumDice=9
Else
'Do nothing
endif

If (LastButton=Dice[2]) Then
ValDice=2
ElseIf (LastButton=Dice[3]) then
ValDice=3
ElseIf (LastButton=Dice[4]) then
ValDice=4
ElseIf (LastButton=Dice[5]) then
ValDice=5
ElseIf (LastButton=Dice[6]) then
ValDice=6
ElseIf (LastButton=Dice[7]) then
ValDice=7
ElseIf (LastButton=Dice[8]) then
ValDice=8
ElseIf (LastButton=Dice[9]) then
ValDice=9
ElseIf (LastButton=Dice[10]) then
ValDice=10
ElseIf (LastButton=Dice[11]) then
ValDice=11
ElseIf (LastButton=Dice[12]) then
ValDice=12
ElseIf (LastButton=Dice[13]) then
ValDice=13
ElseIf (LastButton=Dice[14]) then
ValDice=14
ElseIf (LastButton=Dice[15]) then
ValDice=15
ElseIf (LastButton=Dice[16]) then
ValDice=16
ElseIf (LastButton=Dice[17]) then
ValDice=17
ElseIf (LastButton=Dice[18]) then
ValDice=18
ElseIf (LastButton=Dice[19]) then
ValDice=19
ElseIf (LastButton=Dice[20]) then
ValDice=20
ElseIf (LastButton=Dice[21]) then
ValDice=21
Else
EndIf

GraphicsWindow.DrawText(260,70,NumDice)
GraphicsWindow.DrawText(290,70,("D"+ValDice))


Result=0
For i=1 To NumDice
Result=Result+Math.Floor(Math.GetRandomNumber(ValDice))
EndFor
GraphicsWindow.FontSize=70
GraphicsWindow.DrawText(290,120,Result)
EndSub

Thursday, April 12, 2012

Kindle Fire and speck FitFolio review

I have always loved my Kindle 3, that is the model with keyboard. It is light, handy, can be read in harsh sunlight, and the battery lasts a very long time. I subscribed to various blogs and never without materials to read. However, when it comes to Kindle Fire, the only question that I have is "Why bother?"

I blame it on Jeff Bezos, who in an interview, advises people to get both. One to read, and the other for "media consumption." Although I didn't go out and buy a Kindle Fire, the seed was planted.

And so it was that Michael Gallagher's blog, Free Kindle Books and Tips, mentioned buying practically new Kindle Fire for $139 a piece. Refurbished Christmas returns, he called it. Something clicked. The process took about 5 minutes. I ordered Kindle Fire through the mail. There are things that I bought because I need them. There are things that I bought because I want them. This is neither. This is impulse buying, pure and simple.

In less than a week, I got my package. A simple box. Opened. There is the Kindle Fire. There is the charger. And there is the package they came in. That's it. No docs, no cards, no nothing. It was not until later that I found the Kindle Fire manual to be electronic document inside the Kindle Fire itself.

The first thing I noticed is that it is heavy! Much heavier than my Kindle 3 for sure. Another thing is that it has only one button. On/Off button. That's it. The user interface does take getting used to. However, within 2 hours after I opened it, I watch movies, read magazine, newspaper, go to YouTube, watch TV, borrow a book. Generally do what media consumption is all about.

And it is all very beautiful. To be fair, it doesn't have memory card, bluetooth, camera, or any of the other tablet standard features. It consumes media. That's it. It is a very specialized device, set at a low price. It does have micro USB cable that you can connect to the computer for file transfer. It also have a nice touch screen, so much so, that I downloaded a few drawing apps for it. Jeff Bezo is very wily, to give me a free Amazon Prime subscription for a month. I will have to investigate it further, but I think I will keep it.

The experience is very pleasant. I do have to worry about being in cloud and device. And I worry constantly about bandwidth consumption. I will not be downloading movies every day, or every week for that matter. That 5 GB per month limit will be pushed pretty hard. On 4G, that is. There are only 2 4G spots that I know of. The rest is covered by 3G. 3G is slow. 3G is inconvenient.

Never use Kindle Fire with 3G if you can help it, because once you have tasted what 4G can give you, you do not want to wait on 3G. It took a whole minute to download a 256kb app! Can you imagine it? A whole minute! Okay, so it is much better than the past. Still, with 4G, there was no waiting. So, get 4G.

Another thing that I did, is getting a cover for it. FitFolio for Kindle Fire by (*)speck. It is a nice cover. Very solid. The claim "Slim, lightweight folio with form-fitting cradle and multiple viewing angles" is true. I like it very much. I had some trouble folding it to "typing keyboard" angle. But once I figured it out, there was no problem. Everything works as expected.

I watched movie, I surfed, I drew, I typed. Everything works fine, and very beautifully at that. Do yourself a favor, get that cover, or something like it. Did I mention Kindle Fire is heavy? Get this cover, and use it as a stand to put on a table.

I didn't check the battery life. I imagine that it would be shorter than e-ink. I will not get rid of the old Kindle just yet! It does that charge from the same micro USB connection as my phone. So, whenever I'm charging my phone, I can just charge Kindle the same way.

Kindle Fire is a keeper for me. It is heavily dependent on cloud, though. Make sure you have large bandwidth capacity before you get one. If you have broadband Wifi connection, or 4G, do give it a try. Who knows? You may just like it enough to keep it.

Tuesday, April 10, 2012

SmallBasic Turtle Logo Source Code 3

This is my polished version of Logo Turtle example code implementation in Small Basic. I hope you can easily understand the code. The code is optimized for simplicity, not execution speed. I will be bringing you more examples as time goes by. I don't really teach, but hopefully, by showing you the source codes, this can be a self-guided tutorial for you.

'Turtle Logo in Small Basic - NMC672
'by Harry Hardjono
'Turtle angle speed x1 y1 x0 y0
'Turtle move moveto penup pendown
'Turtle turn turnleft turnright
'Turtle show hide
'
' I hope this program is a good tutorial on how you can do your own programs!

GraphicsWindow.Show()
GraphicsWindow.Clear()

'----------------------------------------------
' Example Turtle Operation Code
'----------------------------------------------

cmd1="init"
Toitle()
cmd1="size"
cmd2=10
Toitle()
Program.Delay(1000)
cmd1="color"
cmd2="green"
Toitle()
Program.Delay(1000)
cmd1="color"
cmd2="red"
Toitle()
Program.Delay(1000)
cmd1="size"
cmd2=4
Toitle()
Program.Delay(1000)
cmd1="size"
cmd2=8
Toitle()



For loop=0 to 360 Step 20
cmd1="moveto"
cmd2=sx/2
cmd3=sy/2
Toitle()
cmd1="turn"
cmd2=loop
Toitle()
cmd1="move"
cmd2=200
Toitle()
Program.Delay(1000)
endfor



beginloop:
GraphicsWindow.Clear()
cmd1="init"
Toitle()
Program.Delay(2000)
cmd1="show"
Toitle()

For loop=1 to 50
cmd1="penup"
Toitle()
cmd1="moveto"
cmd2=Math.GetRandomNumber(sx)
cmd3=Math.GetRandomNumber(sy)
Toitle()
cmd1="pendown"
Toitle()
cmd1="color"
cmd2=GraphicsWindow.GetRandomColor()
Toitle()
cmd1="size"
cmd2=Math.GetRandomNumber(10)
Toitle()
For loop2=1 to Math.GetRandomNumber(6)
cmd1="turn"
cmd2=Math.GetRandomNumber(360)
Toitle()
cmd1="move"
cmd2=Math.GetRandomNumber(1000)
Toitle()
endfor
endfor
Program.Delay(15000)
Goto beginloop

'----------------------------------------------
' Main Turtle function.
'----------------------------------------------


Sub Toitle
'cmd1=command (input)
'cmd2=param1 (input)
'cmd3=param2 (input)
If (cmd1="init") then
sy=GraphicsWindow.Height
sx=GraphicsWindow.Width
x0=0
y0=0
x1=sx/2
y1=sy/2
px=x1
py=y1
p=1
angle=180
col="blue"
speed=100
siz=1
ts=1
DrawTurtle()
elseif (cmd1="penup") then
p=0
elseif (cmd1="pendown") then
p=1
elseif (cmd1="move") then
'forward
x0=x1
y0=y1
x1=x0+cmd2*Math.Sin(Math.GetRadians(angle))
y1=y0+cmd2*Math.Cos(Math.GetRadians(angle))
draw()
elseif (cmd1="moveto") then
x0=x1
y0=y1
x1=cmd2
y1=cmd3
draw()
elseif (cmd1="turn") then
angle=cmd2
DrawTurtle()
elseif (cmd1="turnleft") then
angle=angle+cmd2
DrawTurtle()
elseif (cmd1="turnright") then
angle=angle-cmd2
DrawTurtle()
elseif (cmd1="color") then
col=cmd2
DrawTurtle()
elseif (cmd1="size") then
siz=math.Max(1,cmd2)
siz=math.Min(10,siz)
DrawTurtle()
elseif (cmd1="speed") then
speed=cmd2
speed=Math.Max(0,speed)
speed=Math.Min(100,speed)
elseif (cmd1="show") then
ts=1
elseif (cmd1="hide") then
ts=0
endif

If (ts=1) then
MoveTurtle()
ShowTurtle()
Else
HideTurtle()
endif
endsub

'Draw
Sub Draw
If (p>0) then
If (x0<>x1 or y0<>y1) then
m=math.Max(math.Abs(x1-x0),math.Abs(y1-y0))
map_var["mx1"]=0
map_var["mx3"]=m
For i=0 To m
map_var["my1"]=x0
map_var["my3"]=x1
map_var["mx2"]=i
map()
px=map_var["my2"]
map_var["my1"]=y0
map_var["my3"]=y1
map_var["mx2"]=i
map()
py=map_var["my2"]
RemBugFix()
px=Math.Remainder(px,sx)
py=Math.Remainder(py,sy)
GraphicsWindow.BrushColor=col
GraphicsWindow.FillEllipse(px,py,siz,siz)
MoveTurtle()
If (speed<100) then
Program.Delay(100-speed)
endif
EndFor
endif
endif

'These really need to be Mod
'Seems buggy - doesn't work with negative number?
RemBugFix2()
x1=Math.Remainder(x1,sx)
y1=Math.Remainder(y1,sy)
angle=Math.Remainder(angle,360)

endsub

'----------------------------------------------
'map function
'----------------------------------------------
Sub map
'x1-x2-x3 y1-y2-y3
'(x2-x1)/(x3-x1)=(y2-y1)/(y3-y1)
'y1+(y3-y1)*(x2-x1)/(x3-x1)=y2
map_var["my2"]=((map_var["my3"]-map_var["my1"])*(map_var["mx2"]-map_var["mx1"])/(map_var["mx3"]-map_var["mx1"]))+map_var["my1"]
EndSub


'----------------------------------------------
'Turtle Operations - Could've been Shape Operation had Rotate Triangle not buggy
'----------------------------------------------
Sub DrawTurtle
'Sets size, color, and rotation of Turtle
Shapes.Remove(TT) 'Nothing happens if you remove empty shape. Good!
DrawTurtle_local["tx1"]=(10+siz)*Math.Sin(Math.GetRadians(angle))
DrawTurtle_local["ty1"]=(10+siz)*Math.Cos(Math.GetRadians(angle))
DrawTurtle_local["tx2"]=(10+siz)*Math.Sin(Math.GetRadians(angle+140))
DrawTurtle_local["ty2"]=(10+siz)*Math.Cos(Math.GetRadians(angle+140))
DrawTurtle_local["tx3"]=(10+siz)*Math.Sin(Math.GetRadians(angle+220))
DrawTurtle_local["ty3"]=(10+siz)*Math.Cos(Math.GetRadians(angle+220))
GraphicsWindow.BrushColor=col
TT=Shapes.AddTriangle(DrawTurtle_local["tx1"],DrawTurtle_local["ty1"],DrawTurtle_local["tx2"],DrawTurtle_local["ty2"],DrawTurtle_local["tx3"],DrawTurtle_local["ty3"])
endsub

Sub MoveTurtle
'Move the turtle
Shapes.Move(TT,px+(siz/2),py+(siz/2))
endsub

Sub ShowTurtle
Shapes.ShowShape(TT)
endsub

Sub HideTurtle
Shapes.HideShape(TT)
endsub
'----------------------------------------------
' Various bug fix
'----------------------------------------------

Sub RemBugFix
While (px<0)
px=px+sx
EndWhile
While (py<0)
py=py+sy
EndWhile
endsub
Sub RemBugFix2
While (x1<0)
x1=x1+sx
EndWhile
While (y1<0)
y1=y1+sy
EndWhile
While (angle<0)
angle=angle+360
EndWhile
endsub

Monday, April 9, 2012

Florence Ambrose meets Reggie Fils-Aime



For Nintendo 3DS anniversary, guess who comes to Mii Plaza? Reggie Fils-Aime himself! Guess who is on hand to greet him? Florence Ambrose of Freefall by Mark Stanley.

Tuesday, April 3, 2012

SmallBasic Turtle Logo Source Code 2

'Turtle Logo in Small Basic
'by Harry Hardjono
'Turtle angle speed x1 y1 x0 y0
'Turtle move moveto penup pendown
'Turtle turn turnleft turnright
'Turtle show hide
'
' I did this in one afternoon. Could've been faster if I ignore Show/Hide Turtle
' Updated with Shapes. Sure is a lot faster had I known this earlier!

GraphicsWindow.Show()
GraphicsWindow.Clear()

cmd1="init"
Toitle()
cmd1="size"
cmd2=8
Toitle()



For loop=1 to 360 Step 20
cmd1="moveto"
cmd2=sx/2
cmd3=sy/2
Toitle()
cmd1="turn"
cmd2=loop
Toitle()
cmd1="move"
cmd2=200
Toitle()
Program.Delay(1000)
endfor



beginloop:
GraphicsWindow.Clear()
cmd1="init"
Toitle()
Program.Delay(2000)
cmd1="show"
Toitle()

For loop=1 to 50
cmd1="penup"
Toitle()
cmd1="moveto"
cmd2=Math.GetRandomNumber(sx)
cmd3=Math.GetRandomNumber(sy)
Toitle()
cmd1="pendown"
Toitle()
cmd1="color"
cmd2=GraphicsWindow.GetRandomColor()
Toitle()
cmd1="size"
cmd2=Math.GetRandomNumber(10)
Toitle()
' Show Turtle is very slow!
' If (loop=10) Then
' cmd1="show"
' Toitle()
' ElseIf (loop=30) then
' cmd1="hide"
' Toitle()
' EndIf
For loop2=1 to Math.GetRandomNumber(6)
cmd1="turn"
cmd2=Math.GetRandomNumber(360)
Toitle()
cmd1="move"
cmd2=Math.GetRandomNumber(1000)
Toitle()
endfor
endfor
Program.Delay(15000)
Goto beginloop



Sub Toitle
'cmd1=command (input)
'cmd2=param1 (input)
'cmd3=param2 (input)
If (cmd1="init") then
sy=GraphicsWindow.Height
sx=GraphicsWindow.Width
'Bug: GetPixel does not take Background color
GraphicsWindow.BrushColor="white"
GraphicsWindow.FillRectangle(0,0,sx,sy)
x1=sx/2
y1=sy/2
x0=x1
y0=y1
p=1
angle=180
col="blue"
GraphicsWindow.BrushColor=col
siz=1
ts=1
SaveBG()
elseif (cmd1="penup") then
p=0
elseif (cmd1="pendown") then
p=1
elseif (cmd1="move") then
'forward
' LoadBG()
x0=x1
y0=y1
x1=x0+cmd2*Math.Sin(Math.GetRadians(angle))
y1=y0+cmd2*Math.Cos(Math.GetRadians(angle))
draw()
' SaveBG()
elseif (cmd1="moveto") then
' LoadBG()
x0=x1
y0=y1
x1=cmd2
y1=cmd3
draw()
' SaveBG()
elseif (cmd1="turn") then
LoadBG()
angle=cmd2
SaveBG()
elseif (cmd1="turnleft") then
LoadBG()
angle=angle+cmd2
SaveBG()
elseif (cmd1="turnright") then
LoadBG()
angle=angle-cmd2
SaveBG()
elseif (cmd1="color") then
col=cmd2
elseif (cmd1="size") then
siz=math.Max(1,cmd2)
siz=math.Min(10,siz)
elseif (cmd1="show") then
if (ts<>1) then
ts=1
SaveBG()
endif
elseif (cmd1="hide") then
LoadBG()
ts=0
endif

'These really need to be Mod
'Seems buggy - doesn't work with negative number?
' RemBugFix2()
'x1=Math.Remainder(x1,sx)
'y1=Math.Remainder(y1,sy)
'angle=Math.Remainder(angle,360)

If (ts=1) then
' DrawTurtle()
' Shapes.Move(TT,x1,y1)
Shapes.Move(TT,px+(siz/2),py+(siz/2))
endif

endsub

Sub DrawTurtle
tx1=10*Math.Sin(Math.GetRadians(angle))
ty1=10*Math.Cos(Math.GetRadians(angle))
tx2=10*Math.Sin(Math.GetRadians(angle+140))
ty2=10*Math.Cos(Math.GetRadians(angle+140))
tx3=10*Math.Sin(Math.GetRadians(angle+220))
ty3=10*Math.Cos(Math.GetRadians(angle+220))
TT=Shapes.AddTriangle(tx1,ty1,tx2,ty2,tx3,ty3)
endsub


Sub RemBugFix
While (px<0) px=px+sx EndWhile While (py<0) py=py+sy EndWhile endsub Sub RemBugFix2 While (x1<0) x1=x1+sx EndWhile While (y1<0) y1=y1+sy EndWhile While (angle<0) angle=angle+360 EndWhile endsub 'Draw Sub Draw If (p>0) then
If (x0<>x1 or y0<>y1) then
m=math.Max(math.Abs(x1-x0),math.Abs(y1-y0))
mx1=0
mx3=m
For i=0 To m
my1=x0
my3=x1
mx2=i
map()
px=my2
my1=y0
my3=y1
mx2=i
map()
py=my2
RemBugFix()
px=Math.Remainder(px,sx)
py=Math.Remainder(py,sy)
If (siz>1) then
GraphicsWindow.BrushColor=col
GraphicsWindow.FillEllipse(px,py,siz,siz)
else
GraphicsWindow.SetPixel(px,py,col)
endif
Shapes.Move(TT,px+(siz/2),py+(siz/2))
EndFor
endif
endif

'These really need to be Mod
'Seems buggy - doesn't work with negative number?
RemBugFix2()
x1=Math.Remainder(x1,sx)
y1=Math.Remainder(y1,sy)
angle=Math.Remainder(angle,360)

endsub

'map function
Sub map
'x1-x2-x3 y1-y2-y3
'(x2-x1)/(x3-x1)=(y2-y1)/(y3-y1)
'(y3-y1)*(x2-x1)/(x3-x1)=(y2-y1)
'y1+(y3-y1)*(x2-x1)/(x3-x1)=y2
my2=((my3-my1)*(mx2-mx1)/(mx3-mx1))+my1
EndSub


sub SaveBG
If (ts=1) then
DrawTurtle()



' BGc=0
' BGx1=Math.Floor(Math.Max(0,x1-10))
' BGx1=Math.Floor(Math.Min(sx,BGx1))
' BGy1=Math.Floor(Math.Max(0,y1-10))
' BGy1=Math.Floor(Math.Min(sy,BGy1))
' BGx2=Math.Floor(Math.Max(0,x1+10))
' BGx2=Math.Floor(Math.Min(sx,BGx2))
' BGy2=Math.Floor(Math.Max(0,y1+10))
' BGy2=Math.Floor(Math.Min(sy,BGy2))
' For BGy=BGy1 To BGy2
' For BGx=BGx1 To BGx2
' BGc=BGc+1
' BG_Array[BGc]=GraphicsWindow.GetPixel(BGx,BGy)
' EndFor
' endfor
' TextWindow.Write("SaveBG ")
' TextWindow.Write(BGx1)
' TextWindow.Write(" ")
' TextWindow.Write(BGy1)
' TextWindow.Write(" ")
' TextWindow.Write(BGx2)
' TextWindow.Write(" ")
' TextWindow.Write(BGy2)
' TextWindow.WriteLine(" ")
endif
endsub

Sub LoadBG
If (ts=1) then
Shapes.Remove(TT)

' BGc=0
' For BGy=BGy1 To BGy2
' For BGx=BGx1 To BGx2
' BGc=BGc+1
' GraphicsWindow.SetPixel(BGx,BGy,BG_Array[BGc])
' EndFor
' endfor
' TextWindow.Write("LoadBG")
' TextWindow.Write(BGx1)
' TextWindow.Write(" ")
' TextWindow.Write(BGy1)
' TextWindow.Write(" ")
' TextWindow.Write(BGx2)
' TextWindow.Write(" ")
' TextWindow.Write(BGy2)
' TextWindow.WriteLine(" ")
endif
EndSub

SmallBasic Turtle Logo Source Code 2

The bit about Show/Hide Turtle was very time consuming. I do wish Small Basic has better Screen Buffer capabilities.










Turtle Logo in Small Basic
'by Harry Hardjono
'Turtle angle speed x1 y1 x0 y0
'Turtle move moveto penup pendown
'Turtle turn turnleft turnright
'Turtle show hide
'
' I did this in one afternoon. Could've been faster if I ignore Show/Hide Turtle

GraphicsWindow.Show()
GraphicsWindow.Clear()


beginloop:
GraphicsWindow.Clear()
cmd1="init"
Toitle()
Program.Delay(2000)
cmd1="hide"
Toitle()

For loop=1 to 50
cmd1="penup"
Toitle()
cmd1="moveto"
cmd2=Math.GetRandomNumber(sx)
cmd3=Math.GetRandomNumber(sy)
Toitle()
cmd1="pendown"
Toitle()
cmd1="color"
cmd2=GraphicsWindow.GetRandomColor()
Toitle()
cmd1="size"
cmd2=Math.GetRandomNumber(10)
Toitle()
' Show Turtle is very slow!
' If (loop=10) Then
' cmd1="show"
' Toitle()
' ElseIf (loop=30) then
' cmd1="hide"
' Toitle()
' EndIf
For loop2=1 to Math.GetRandomNumber(6)
cmd1="turn"
cmd2=Math.GetRandomNumber(360)
Toitle()
cmd1="move"
cmd2=Math.GetRandomNumber(1000)
Toitle()
endfor
endfor
Program.Delay(5000)
Goto beginloop



Sub Toitle
'cmd1=command (input)
'cmd2=param1 (input)
'cmd3=param2 (input)
If (cmd1="init") then
sy=GraphicsWindow.Height
sx=GraphicsWindow.Width
'Bug: GetPixel does not take Background color
GraphicsWindow.BrushColor="white"
GraphicsWindow.FillRectangle(0,0,sx,sy)
x1=sx/2
y1=sy/2
x0=x1
y0=y1
p=1
angle=180
col="blue"
GraphicsWindow.BrushColor=col
siz=1
ts=1
SaveBG()
elseif (cmd1="penup") then
p=0
elseif (cmd1="pendown") then
p=1
elseif (cmd1="move") then
'forward
LoadBG()
x0=x1
y0=y1
x1=x0+cmd2*Math.Sin(Math.GetRadians(angle))
y1=y0+cmd2*Math.Cos(Math.GetRadians(angle))
draw()
SaveBG()
elseif (cmd1="moveto") then
LoadBG()
x0=x1
y0=y1
x1=cmd2
y1=cmd3
draw()
SaveBG()
elseif (cmd1="turn") then
LoadBG()
angle=cmd2
SaveBG()
elseif (cmd1="turnleft") then
LoadBG()
angle=angle+cmd2
SaveBG()
elseif (cmd1="turnright") then
LoadBG()
angle=angle-cmd2
SaveBG()
elseif (cmd1="color") then
col=cmd2
elseif (cmd1="size") then
siz=math.Max(1,cmd2)
siz=math.Min(10,siz)
elseif (cmd1="show") then
if (ts<>1) then
ts=1
SaveBG()
endif
elseif (cmd1="hide") then
LoadBG()
ts=0
endif

'These really need to be Mod
'Seems buggy - doesn't work with negative number?
' RemBugFix2()
'x1=Math.Remainder(x1,sx)
'y1=Math.Remainder(y1,sy)
'angle=Math.Remainder(angle,360)

If (ts=1) then
DrawTurtle()
endif

endsub

Sub DrawTurtle
tx1=x1+10*Math.Sin(Math.GetRadians(angle))
ty1=y1+10*Math.Cos(Math.GetRadians(angle))
tx2=x1+10*Math.Sin(Math.GetRadians(angle+140))
ty2=y1+10*Math.Cos(Math.GetRadians(angle+140))
tx3=x1+10*Math.Sin(Math.GetRadians(angle+220))
ty3=y1+10*Math.Cos(Math.GetRadians(angle+220))
GraphicsWindow.FillTriangle(tx1,ty1,tx2,ty2,tx3,ty3)
endsub


Sub RemBugFix
While (px<0) px=px+sx EndWhile While (py<0) py=py+sy EndWhile endsub Sub RemBugFix2 While (x1<0) x1=x1+sx EndWhile While (y1<0) y1=y1+sy EndWhile While (angle<0) angle=angle+360 EndWhile endsub 'Draw Sub Draw If (p>0) then
If (x0<>x1 or y0<>y1) then
m=math.Max(math.Abs(x1-x0),math.Abs(y1-y0))
mx1=0
mx3=m
For i=0 To m
my1=x0
my3=x1
mx2=i
map()
px=my2
my1=y0
my3=y1
mx2=i
map()
py=my2
RemBugFix()
px=Math.Remainder(px,sx)
py=Math.Remainder(py,sy)
If (siz>1) then
GraphicsWindow.BrushColor=col
GraphicsWindow.FillEllipse(px,py,siz,siz)
else
GraphicsWindow.SetPixel(px,py,col)
endif
EndFor
endif
endif

'These really need to be Mod
'Seems buggy - doesn't work with negative number?
RemBugFix2()
x1=Math.Remainder(x1,sx)
y1=Math.Remainder(y1,sy)
angle=Math.Remainder(angle,360)

endsub

'map function
Sub map
'x1-x2-x3 y1-y2-y3
'(x2-x1)/(x3-x1)=(y2-y1)/(y3-y1)
'(y3-y1)*(x2-x1)/(x3-x1)=(y2-y1)
'y1+(y3-y1)*(x2-x1)/(x3-x1)=y2
my2=((my3-my1)*(mx2-mx1)/(mx3-mx1))+my1
EndSub


sub SaveBG
If (ts=1) then
BGc=0
BGx1=Math.Floor(Math.Max(0,x1-10))
BGx1=Math.Floor(Math.Min(sx,BGx1))
BGy1=Math.Floor(Math.Max(0,y1-10))
BGy1=Math.Floor(Math.Min(sy,BGy1))
BGx2=Math.Floor(Math.Max(0,x1+10))
BGx2=Math.Floor(Math.Min(sx,BGx2))
BGy2=Math.Floor(Math.Max(0,y1+10))
BGy2=Math.Floor(Math.Min(sy,BGy2))
For BGy=BGy1 To BGy2
For BGx=BGx1 To BGx2
BGc=BGc+1
BG_Array[BGc]=GraphicsWindow.GetPixel(BGx,BGy)
EndFor
endfor
' TextWindow.Write("SaveBG ")
' TextWindow.Write(BGx1)
' TextWindow.Write(" ")
' TextWindow.Write(BGy1)
' TextWindow.Write(" ")
' TextWindow.Write(BGx2)
' TextWindow.Write(" ")
' TextWindow.Write(BGy2)
' TextWindow.WriteLine(" ")
endif
endsub

Sub LoadBG
If (ts=1) then
BGc=0
For BGy=BGy1 To BGy2
For BGx=BGx1 To BGx2
BGc=BGc+1
GraphicsWindow.SetPixel(BGx,BGy,BG_Array[BGc])
EndFor
endfor
' TextWindow.Write("LoadBG")
' TextWindow.Write(BGx1)
' TextWindow.Write(" ")
' TextWindow.Write(BGy1)
' TextWindow.Write(" ")
' TextWindow.Write(BGx2)
' TextWindow.Write(" ")
' TextWindow.Write(BGy2)
' TextWindow.WriteLine(" ")
endif
EndSub

Monday, April 2, 2012

SmallBasic Turtle Logo Source Code

Just how hard is it to code a turtle? Not hard at all, if one hour is all it takes to code this. I'm still missing Show and Hide Turtle, but hey, it's only one hour!















'Turtle Logo in Small Basic
'by Harry Hardjono
'Turtle angle speed x1 y1 x0 y0
'Turtle move moveto penup pendown
'Turtle turn turnleft turnright
' Only took me 1 hour to do this. :)
'
GraphicsWindow.Show()
GraphicsWindow.Clear()

cmd1="init"
Toitle()
cmd1="move"
cmd2="50"
Toitle()
cmd1="turnright"
cmd2="90"
Toitle()
cmd1="move"
cmd2="50"
Toitle()
cmd1="turnright"
cmd2="90"
Toitle()
cmd1="move"
cmd2="50"
Toitle()
cmd1="turnright"
cmd2="90"
Toitle()
cmd1="move"
cmd2="150"
Toitle()
cmd1="turnleft"
cmd2="90"
Toitle()
cmd1="move"
cmd2="50"
Toitle()
cmd1="turnright"
cmd2="90"
Toitle()
cmd1="moveto"
cmd2="20"
cmd3="50"
Toitle()
cmd1="turn"
cmd2="20"
Toitle()
cmd1="move"
cmd2="1500"
Toitle()
cmd1="turnright"
cmd2="100"
Toitle()
cmd1="move"
cmd2="1500"
Toitle()
cmd1="turnright"
cmd2="100"
Toitle()
cmd1="move"
cmd2="1500"
Toitle()
cmd1="turnright"
cmd2="100"
Toitle()
cmd1="move"
cmd2="1500"
Toitle()



Sub Toitle
'cmd1=command (input)
'cmd2=param1 (input)
'cmd3=param2 (input)
If (cmd1="init") then
sy=GraphicsWindow.Height
sx=GraphicsWindow.Width
x1=sx/2
y1=sy/2
x0=x1
y0=y1
p=1
angle=90
elseif (cmd1="penup") then
p=0
elseif (cmd1="pendown") then
p=1
elseif (cmd1="move") then
'forward
x0=x1
y0=y1
x1=x0+cmd2*Math.Sin(Math.GetRadians(angle))
y1=y0+cmd2*Math.Cos(Math.GetRadians(angle))
draw()
elseif (cmd1="moveto") then
x0=x1
y0=y1
x1=cmd2
y1=cmd3
draw()
elseif (cmd1="turn") then
angle=cmd2
elseif (cmd1="turnleft") then
angle=angle+cmd2
elseif (cmd1="turnright") then
angle=angle-cmd2
endif


'These really need to be Mod
'Seems buggy - doesn't work with negative number?
RemBugFix2()
x1=Math.Remainder(x1,sx)
y1=Math.Remainder(y1,sy)
angle=Math.Remainder(angle,360)
endsub

Sub RemBugFix
While (px<0)
px=px+sx
EndWhile
While (py<0)
py=py+sy
EndWhile
endsub
Sub RemBugFix2
While (x1<0)
x1=x1+sx
EndWhile
While (y1<0)
y1=y1+sy
EndWhile
While (angle<0)
angle=angle+360
EndWhile
endsub
'Draw
Sub Draw
If (p>0) then
If (x0<>x1 or y0<>y1) then
m=math.Max(math.Abs(x1-x0),math.Abs(y1-y0))
mx1=0
mx3=m
For i=0 To m
my1=x0
my3=x1
mx2=i
map()
px=my2
my1=y0
my3=y1
mx2=i
map()
py=my2
RemBugFix()
px=Math.Remainder(px,sx)
py=Math.Remainder(py,sy)
GraphicsWindow.SetPixel(px,py,"blue")
EndFor
endif
endif
endsub


'map function
Sub map
'x1-x2-x3 y1-y2-y3
'(x2-x1)/(x3-x1)=(y2-y1)/(y3-y1)
'(y3-y1)*(x2-x1)/(x3-x1)=(y2-y1)
'y1+(y3-y1)*(x2-x1)/(x3-x1)=y2
my2=((my3-my1)*(mx2-mx1)/(mx3-mx1))+my1
EndSub