How to draw interactively with Pen on a Morph in Squeak? - smalltalk

It can't get the Pen to work properly in a Morph.
I arrived at the snippet below but I don't understand how to update the view of the Morph after I moved the pen. I tried to send "changed" in various (sm, pen, (sm owner)) object but it does not solve it.
In the snippet below the line gets drawn if I resize the window. Or, also, if i put "openInWindow" as last line.
sm := SketchMorph new.
sm clearExtent: 600#600 fillColor: (Color yellow) darker darker.
sm position: 100#100.
sm openInWindow.
pen := sm penOnMyForm.
pen defaultNib: 4; color: (Color red).
pen up.
pen goto: 10#10.
pen down.
pen goto: 100#100.

The message you should send to the SketchMorph, instead of #layoutChanged, is
sm revealPenStrokes
which is -pun intended- quite intention revealing; isn't it?
How did I find it
Using the hint provided by Nicola, I debugged sm layoutChanged trying to understand why it showed the line. I had tried sm changed before with no luck, so I knew that the clue had to be in generateRotatedForm. And since this method redefines the ivar rotatedForm, I looked for all methods that changed it, as I suspected that the problem was in some cache not being invalidated by changed. Quickly enough, the selector revealPenStrokes emerged victorious from the rather short list of methods modifying rotatedForm.

I found the method, but I don't understand the logic.
Just add this at the end.
sm layoutChanged.
pen goto: 150#100.
sm layoutChanged.
" ... and so on "
If I look into the "layoutChanged" definition and I try to send those methods myself I see the command that rules is "generateRotatedForm" ... Umm ... why ?
If some Morphic expert would like to shed some light into this I would be grateful.
bye
Nicola

Related

I have a question about a YT tutorial because I wanna customize it a little

in this video, https://youtu.be/klBvssJE5Qg I shows you how to spawn enemies outside of a fixed camera. (this is in GDscript by the way) How could I make this work with a moving camera? I wanna make a zombie fighting game with a moving camera and zombies spawning outside that.
I would really appreciate help with this.
I've tried researching on the internet about how to do it, but I just didn't find it.
N/A..................................
After looking at the video, I see they are using this line to spawn:
Global.instance_node(enemy_1, enemy_position, self)
This suggest to me a couple thing:
The position is probably either relative to the self passed as argument or global.
There must be an Autoload called Global that I need to check to make sure.
And the answer is in another castle video.
In the video Godot Wave Shooter Tutorial #2 - Player Shooting we find this code:
extends Node
func instance_node(node, location, parent):
var node_isntance = node.instance()
parent.add_child(node_instance)
node_instance.global_position = location
return node_instance
And thus, we are working with global coordinates global_position. Thus enemy_position is used as global coordinates.
Ok, instead of using enemy_position as global coordinates we are going to use it as local coordinates of the Camera2D (or a child of it). Which means you need a reference to the Camera2D (which I don't know where do you have it).
You could make your code in a child of the Camera2D, or take the transform of the Camera2D using a RemoteTransform2D. Either way, you could then work in its local coordinates. Thus you would do this:
Global.instance_node(enemy_1, to_global(enemy_position), self)
Or you could have a reference by exporting a NodePath (or in the newest Godot you can export a Camera2D) from your script and set it via the inspector. So you can do this:
Global.instance_node(enemy_1, camera.to_global(enemy_position), self)
Where camera is your reference to the Camera2D.
In the following section of Arena.gd:
func _on_Enemy_spawn_timer_timeout():
var enemy_position = Vector2(rand_range(-160, 670), rand_range(-90, 390))
I believe you can add the X and Y coordinates of the camera to their corresponding random ranges in the enemy position Vector2. This will displace the enemy depending on where the camera is currently located.
You can get the position of the camera with this:
get_parent().get_node("Name of your camera").position
When this is all put together:
func _on_Enemy_spawn_timer_timeout():
var enemy_position = Vector2(rand_range(-160, 670) + get_parent().get_node("Name of your camera").position.x, rand_range(-90, 390) + get_parent().get_node("Name of your camera").position.y)
Keep in mind that you might need to displace the values in the following while loop as well. I hope this helps.

change CAMetalLayer background color

My CAMetalLayer background color is black, even if i'm assigning new color as the backgroundColor property.
Am i missing something? Thanks!
Link to the original project :
https://github.com/audiokit/MetalParticles
This project takes a rather unconventional approach to clearing the drawable's texture each frame: it replaces the textures contents with an array of zeros that is the same size as the texture (width * height * 4). Subsequently, it encodes some compute work that actually draws the particles. This is almost certainly not the most efficient way to achieve this effect, but if you want to make the smallest change that could possibly work (as opposed to experimenting with making the code as efficient as possible), Just fill the blankBitmapRawData array with your desired clear color (near line 82 of ParticleLab.swift).
I have gone through your code and can not see a place where you are setting background Color.
The metal layer is added as a sublayer to it, so you have to set it explicitly.
Add this line at the end of your init method in ParticialLab class and see if it works.
self.backgroundColor = UIColor.redColor().CGColor
I found that self.isOpaque = false was needed on the layer.

Cocos2d / CCDrawNode - How to draw a line?

I see there is functionality to draw circles, polys, dot and segments. I dont see one for drawing an A-B line (with given thickness), like ccDrawLine() (which seems to be deprecated).
I need to draw a 'network' between connected nodes. I have the code to draw the network, however ccDrawLine doesn't seem to support aliasing or opacity, like CCDrawNode. It also, without manual intervention, doesn't seem to support batching.
Any suggetions? Would I need to do a load of maths to draw a 2 tri-poly rectangle at the right angle between points?
UPDATE:
Based on comments below... I have an idea on how to do a 'Line' 0,0 to 10,0 with thickness 2, I'd have to do a rect at {0,0.5}, {10,0.5}, {10,-0.5}, {0,-0.5}... I can work out the clockwise triangle points to make a polygon from that easily. I, therefore, could even do horiz/vert ones easily. But how do you do that between {4,5}, {10,7}? Would you do a normal rectangle and apply a transformation matrix to it? Or would you still precalculate each 4 points and then make 2 triangles from it?
UPDATE:
Maybe it'd be better to use a scaled "line" sprite?! Eg: https://stackoverflow.com/a/8760462/224707
UPDATE:
How about a Ribbon? Would that work? Eg: https://stackoverflow.com/a/8178729/224707
Not sure a Ribbon would work for a "network" of points though...
CLARIFICATION:
Imagine this image, but with straight lines and no intersections... Something like this:
(source: relenet.com)
UPDATE:
Apparantly, my post to the Forum did go though last night just before it went down... http://www.cocos2d-iphone.org/forum/topic/224498
A line is a segment. You can take it from here... ;)
Update:
CCDrawNode can draw segments. Segments are lines with defined start and end points.

Squeak Circle Section

I'm trying to draw a quarter of a circle with Morphic in Squeak-Smalltalk.
How does it work?
Thanks in advance!
The best teacher is the the image itself. If you open a browser on CircleMorph, you'll see that its superclass, EllipseMorph, defines #drawOn:, which is how morphs draw themselves. From there, you can get all the information and inspiration to make your custom morph.
Update: My first thought was to draw it by hand (totally override #drawOn:), but there weren't any obvious candidates in Canvas. By letting the circle draw itself while setting the clipping rectangle to a quarter of it, it became almost a one-liner.
Update 2: The trick with a quarter-circle is getting CircleMorph to do most of the work for you! The best I came up with is:
QuarterCircleMorph>>drawOn: aCanvas
| realBounds |
"Save the actual bounds of the morph"
realBounds := bounds.
"Pretend the bounds are 4x as big"
bounds := bounds bottom: bounds bottom + bounds height.
bounds := bounds right: bounds right + bounds width.
"Let CircleMorph handle the drawing"
super drawOn: aCanvas.
"Restore the actual bounds"
bounds := realBounds.
Where QuarterCircleMorph is a subclass of CircleMorph. Because you can't draw past it's real bounds, everything works out. n.b. in actual code, the comments would be overkill (except maybe the 4x one, but then, that's a sign to maybe refactor :))

Unity 3D Physics

I'm having trouble with physics in unity 3d. I'm wanting my ball to bounce off of walls and go another direction. When the ball hits the wall it just bounces straight back. I have tried changing the direction to be orthogonal to the direction it hits the wall but it doesn't change direction. Due to this, the ball just keeps hitting the wall and bouncing straight back.
Secondly, sometimes the ball goes through the wall. The walls have box colliders while the ball has a sphere collider. They all have continuous dynamic as the collision detection mode.
Here's a link to a similar thread:
http://forum.unity3d.com/threads/22063-I-shot-an-arrow-up-in-the-air...?highlight=shooting+arrow
Personally, I would code the rotation using LookAt as GargarathSunman suggests in this link, but if you want to do it with physics, you'll probably need to build the javelin in at least a couple of parts, as the others suggest in the link, and add different drag and angular drag values to each part,perhaps density as well. If you threw a javelin in a vacuum, it would never land point down because air drag plays such an important part (all things fall at the same rate regardless of mass, thank you Sir Isaac Newton). It's a difficult simulation for the physics engine to get right.
Maybe try to get the collider point between your sphere and your wall then catch your rigidbody velocity and revert it by the collision point normal.
an example of a script to do that ---> (put this script on a wall with collider )
C# script:
public class WallBumper : MonoBehaviour
{
private Vector3 _revertDirection;
public int speedReflectionVector = 2;
/***********************************************
* name : OnCollisionEnter
* return type : void
* Make every gameObject with a RigidBody bounce againt this platform
* ********************************************/
void OnCollisionEnter(Collision e)
{
ContactPoint cp = e.contacts[0];
_revertDirection = Vector3.Reflect(e.rigidbody.velocity, cp.normal * -1);
e.rigidbody.velocity = (_revertDirection.normalized * speedReflectionVector);
}
}
I recently has an issue with a rocket going through targets due to speed and even with continuous dynamic collision detection I couldn't keep this from happening a lot.
I solved this using a script "DontGoThroughThings" posted in wiki.unity3d.com. This uses raycasting between current and previous positions and then ensures the frame ends with the colliders connected for messages an OnTrigger event. Has worked everytime since and it's just a matter of attaching the script so super easy to use.
I think the physics answer is as others have suggested to use multiple components with different drag although typically I think you only want a single RigidBody on the parent. Instead of direction using transform.LookAt you could try and calculate using Quaternion.LookRotation from the rigidbody.velocity. Then use Vector3.Angle to find out how much are are off. The greater the angle diference the more force should be experienced and then use RigidBody.ApplyTorque. Maybe use the Sin(angleDifference) * a constant so less force is applied to torque as you approach proper rotation.
Here is some code I used on my rocket although you'll have to substitute some things as I was pointing toward a fixed target and you'll want to use your velocity.
var rotationDirection = Quaternion.LookRotation(lockedTarget.transform.position - this.transform.position);
var anglesToGo = Vector3.Angle(this.transform.rotation.eulerAngles, rotationDirection.eulerAngles);
if (anglesToGo > RotationVelocity)
{
var rotationDirectionToMake = (rotationDirection * Quaternion.Inverse(this.transform.rotation)).eulerAngles.normalized * RotationVelocity;
transform.Rotate(rotationDirectionToMake);
}