- Joined
- Jan 2, 2020
- Messages
- 1,414
Hey everyone, I must be tired but I just can't see the error here, I tried to convert Blobmonster example to Mojo2 but it looks
well not as it should. I'm sure I missed something simple but right now I just don't see it?
There seem to be some kind of relative coordinate thing going on?
well not as it should. I'm sure I missed something simple but right now I just don't see it?
There seem to be some kind of relative coordinate thing going on?
Cerberus:
Import mojo2
Function Main:Int()
New blob_monster
Return 0
End
Class blob_monster Extends App
Field blobimage:Image
Field theMonster:BlobMonster
Field canvas:Canvas
Method OnCreate:Int()
canvas=New Canvas
blobimage=Image.Load("blob.png",0,0,0) ; MidHandle blobimage
theMonster=New BlobMonster(10,10,blobimage)
SetSwapInterval 1 ; SetUpdateRate 0
Return 0
End
Method OnUpdate ()
theMonster.Update()
Return 0
End
Method OnRender ()
canvas.Clear 0,0,0
theMonster.Draw(canvas)
canvas.Flush
Return 0
End
End
Class point
Field x:Float,y:Float
End
Function MidHandle (image:Image)
image.SetHandle image.Width () * 0.5, image.Height () * 0.5
End
Class BlobMonster
Field x:Float, y:Float
Field speed:Float = 1
Field segments:Float = 10
Field tail:point[10]
Field time:Float = 0
Field blob:Image
Method New(inx:Float,iny:Float,inimage:Image)
x = inx ; y = iny
For Local i:Int = 0 To segments - 1
tail[i] = New point
tail[i].x = inx
tail[i].y = iny
Next
blob=inimage
End
Method Update:Int()
time+=speed
y = (15 * Cos(time * -6)) + (DeviceHeight/2 + (180 * Sin(time * 1.3)))
x = (15 * Sin(time * -6)) + (DeviceWidth/2 + (200 * Cos(time / 1.5)))
tail[0].x = x
tail[0].y = y
For Local i:Int = 1 To segments - 1
Local distX:Float = (tail[i - 1].x - tail[i].x)
Local distY:Float = (tail[i - 1].y - tail[i].y)
Local dist:Float = Sqrt(distX * distX + distY * distY)
If dist > 7 Then
tail[i].x = tail[i].x + (distX * (0.3))
tail[i].y = tail[i].y + (distY * (0.3))
Endif
Next
Return False
End Method
Method Draw(canvas:Canvas)
canvas.SetBlendMode BlendMode.Additive
blob.SetHandle(blob.Width()*0.5,blob.Height()*0.5)
For Local i:Int = 0 To segments - 1
canvas.SetAlpha 0.15
canvas.DrawImage blob, tail[i].x, tail[i].y,0,1 + (0.5 * Sin(i * 35)), 1 + (0.5 * Sin(i * 35))
canvas.SetAlpha 0.8
canvas.DrawImage blob, tail[i].x, tail[i].y,0,0.1, 0.1
Next
blob.SetHandle 0,blob.Height()*0.5
canvas.DrawImage blob, tail[segments - 1].x, tail[segments - 1].y,10 * Sin(time * 10) + -calculateAngle(tail[segments - 1].x, tail[segments - 1].y, tail[segments - 5].x, tail[segments - 5].y) + 270,0.6, 0.1
canvas.DrawImage blob, tail[segments - 1].x, tail[segments - 1].y,10 * Sin(-time * 10) + -calculateAngle(tail[segments - 1].x, tail[segments - 1].y, tail[segments - 5].x, tail[segments - 5].y) + 270,0.6, 0.1
canvas.SetAlpha 1
For Local i:Int = 1 To segments - 2
canvas.DrawImage blob, tail[i].x, tail[i].y,33 * Sin(time * 5 + i * 30) + -calculateAngle(tail[i].x, tail[i].y, tail[i - 1].x, tail[i - 1].y),0.1 + (0.6 * Sin(i * 30)), 0.0
canvas.DrawImage blob, tail[i].x, tail[i].y,33 * Sin(-time * 5 - i * 30) + -calculateAngle(tail[i].x, tail[i].y, tail[i - 1].x, tail[i - 1].y) + 180,0.1 + (0.6 * Sin(i * 30)), 0.05
Next
MidHandle blob
canvas.SetAlpha 0.1
Local ang:Float = calculateAngle(tail[0].x, tail[0].y, tail[1].x, tail[1].y)
canvas.DrawImage blob, x + (7 * Cos(ang + 50)), y + (7 * Sin(ang + 50)),0,0.6, 0.6
canvas.DrawImage blob, x + (7 * Cos(ang + 140)), y + (7 * Sin(ang + 140)),0,0.6, 0.6
canvas.SetAlpha 0.5
canvas.DrawImage blob, x + (7 * Cos(ang + 50)), y + (7 * Sin(ang + 50)),0,0.1, 0.1
canvas.DrawImage blob, x + (7 * Cos(ang + 140)), y + (7 * Sin(ang + 140)),0,0.1, 0.1
canvas.SetAlpha 0.8
blob.SetHandle 0, blob.Height()*0.5
canvas.DrawImage blob, x, y,-ang + 275,0.3, 0.1
MidHandle blob
canvas.SetAlpha 0.2
canvas.DrawImage blob, x, y,0,4, 4
End Method
End
Function calculateAngle:Float(x1:Float,y1:Float,x2:Float,y2:Float)
Local theX:Float=x1-x2
Local theY:Float=y1-y2
Local theAngle:Float=-ATan2(theX,theY)
Return theAngle
End Function
Code:
Import mojo.app
Import mojo.graphics
Import cerberus.math
' The overall Game object, handling loading, mouse position, high-level game control and rendering...
Class point
Field x:Float,y:Float
End
Function MidHandle (image:Image)
image.SetHandle image.Width () * 0.5, image.Height () * 0.5
End
Class BlobMonster
'x and y coords
Field x:Float, y:Float
'speed, try changing it
Field speed:Float = 1
'number of nodes along the body, try changing it to 100
Field segments:Float = 10
'array to hold the points along the body
Field tail:point[10]
Field time:Float = 0
Field blob:Image
Method New(inx:Float,iny:Float,inimage:Image)
x = inx
y = iny
'give the tail some coordinates, just make them the same as the main x and y for now
For Local i:Int = 0 To segments - 1
tail[i] = New point
tail[i].x = inx
tail[i].y = iny
Next
blob=inimage
End
Method Update:Int()
'time is a bit misleading, it's used for all sorts of things
time+=speed
'here the x and y coordinates are updated.
'this uses the following as a basic rule for moving things
'around a point in 2d space:
'x=radius*cos(angle)+xOrigin
'y=raduis*sin(angle)+yOrigin
'this basically is the basis for anything that moves in this example
'
'the 2 lines of code below make the monster move around, but
'you can change this to anything you like, try setting x and y to the mouse
'coordinates for example
y = (15 * Cos(time * -6)) + (DeviceHeight/2 + (180 * Sin(time * 1.3)))
x = (15 * Sin(time * -6)) + (DeviceWidth/2 + (200 * Cos(time / 1.5)))
'put the head of the tail at x,y coords
tail[0].x = x
tail[0].y = y
'update the tail
'basically, the points don't move unless they're further that 7 pixels
'from the previous point. this gives the kind of springy effect as the
'body stretches
For Local i:Int = 1 To segments - 1
'calculate distance between the current point and the previous
Local distX:Float = (tail[i - 1].x - tail[i].x)
Local distY:Float = (tail[i - 1].y - tail[i].y)
Local dist:Float = Sqrt(distX * distX + distY * distY)
'move if too far away
If dist > 7 Then
'the (distX*0.2) bit makes the point move
'just 20% of the distance. this makes the
'movement smoother, and the point decelerate
'as it gets closer to the target point.
'try changing it to 1 (i.e 100%) to see what happens
tail[i].x = tail[i].x + (distX * (0.3))
tail[i].y = tail[i].y + (distY * (0.3))
Endif
Next
Return False
End Method
Method Draw()
'time to draw stuff!
'this sets the blend mode to LIGHTBLEND, or additive blending, which makes
'the images progressively more bright as they overlap
SetBlend 1
'###########
'draw the main bit of the body
'start by setting the images handle (i.e the origin of the image) to it's center
blob.SetHandle(blob.Width()*0.5,blob.Height()*0.5)
'begin looping through the segments of the body
For Local i:Int = 0 To segments - 1
'set the alpha transparency vaue to 0.15, pretty transparent
SetAlpha 0.15
'the (0.5*sin(i*35)) bit basically bulges the size of the images being
'drawn as it gets closer to the center of the monsters body, and tapers off in size as it gets
'to the end. try changing the 0.5 to a higher number to see the effect.
'draw the image
DrawImage blob, tail[i].x, tail[i].y,0,1 + (0.5 * Sin(i * 35)), 1 + (0.5 * Sin(i * 35))
'this next chunk just draws smaller dots in the center of each segment of the body
SetAlpha 0.8
DrawImage blob, tail[i].x, tail[i].y,0,0.1, 0.1
Next
'#########################
'draw little spikes on tail
'note that the x and y scales are different
'move the image handle to halfway down the left edge, this'll make the image
'appear to the side of the coordinate it is drawn too, rather than the
'center as we had for the body sections
blob.SetHandle 0,blob.Height()*0.5
'rotate the 1st tail image. basically, we're calculating the angle between
'the last 2 points of the tail, and then adding an extra wobble (the 10*sin(time*10) bit)
'to make the pincer type effect.
DrawImage blob, tail[segments - 1].x, tail[segments - 1].y,10 * Sin(time * 10) + -calculateAngle(tail[segments - 1].x, tail[segments - 1].y, tail[segments - 5].x, tail[segments - 5].y) + 270,0.6, 0.1
'second tail image uses negative time to make it move in the opposite direction
DrawImage blob, tail[segments - 1].x, tail[segments - 1].y,10 * Sin(-time * 10) + -calculateAngle(tail[segments - 1].x, tail[segments - 1].y, tail[segments - 5].x, tail[segments - 5].y) + 270,0.6, 0.1
'#####################
'draw little fins/arms
SetAlpha 1
'begin looping through the body sections again. Note that we don't want fins
'on the first and last section because we want other things at those coords.
For Local i:Int = 1 To segments - 2
'like the bulging body, we want the fins to grow larger in the center, and smaller
'at the end, so the same sort of thing is used here.
'rotate the image. We want the fins to stick out sideways from the body (the calculateangle() bit)
'and also to move a little on their own. the 33 * Sin(time * 5 + i * 30) makes the
'fin rotate based in the i index variable, so that all the fins look like they're moving
'one after the other.
DrawImage blob, tail[i].x, tail[i].y,33 * Sin(time * 5 + i * 30) + -calculateAngle(tail[i].x, tail[i].y, tail[i - 1].x, tail[i - 1].y),0.1 + (0.6 * Sin(i * 30)), 0.05
'rotate the opposte fin, note that the signs have changes (-time and -i*30)
'to reflect the rotations of the other fin
DrawImage blob, tail[i].x, tail[i].y,33 * Sin(-time * 5 - i * 30) + -calculateAngle(tail[i].x, tail[i].y, tail[i - 1].x, tail[i - 1].y) + 180,0.1 + (0.6 * Sin(i * 30)), 0.05
Next
'###################
'center the image handle
MidHandle blob
'Draw the eyes. These are just at 90 degrees to the head of the tail.
SetAlpha 0.1
Local ang:Float = calculateAngle(tail[0].x, tail[0].y, tail[1].x, tail[1].y)
DrawImage blob, x + (7 * Cos(ang + 50)), y + (7 * Sin(ang + 50)),0,0.6, 0.6
DrawImage blob, x + (7 * Cos(ang + 140)), y + (7 * Sin(ang + 140)),0,0.6, 0.6
SetAlpha 0.5
DrawImage blob, x + (7 * Cos(ang + 50)), y + (7 * Sin(ang + 50)),0,0.1, 0.1
DrawImage blob, x + (7 * Cos(ang + 140)), y + (7 * Sin(ang + 140)),0,0.1, 0.1
'draw beaky thing
SetAlpha 0.8
blob.SetHandle 0, blob.Height()*0.5
DrawImage blob, x, y,-ang + 275,0.3, 0.1
'yellow light
MidHandle blob
SetAlpha 0.2
DrawImage blob, x, y,0,4, 4
'Finished!
End Method
End
'This function calculates and returns the angle between two 2d coordinates
Function calculateAngle:Float(x1:Float,y1:Float,x2:Float,y2:Float)
Local theX:Float=x1-x2
Local theY:Float=y1-y2
Local theAngle:Float=-ATan2(theX,theY)
Return theAngle
End Function
Class blob_monster Extends App
Field blobimage:Image
Field theMonster:BlobMonster
' Stuff to do on startup...
Method OnCreate ()
blobimage=LoadImage( "blob.png" )
theMonster=New BlobMonster(10,10,blobimage)
SetUpdateRate 60
End
' Stuff to do while running...
Method OnUpdate ()
theMonster.Update()
End
' Drawing code...
Method OnRender ()
Cls(0, 0, 0)
theMonster.Draw()
End
End
' Here we go!
Function Main ()
New blob_monster ' RocketGame extends App, so monkey will handle running from here...
End