Unable to draw multiple instace of same Image with GraphicsContext - scala

Hi guys this is my first question, so feel free to give constructive criticism.
I am making a space shooter game with ScalaFX and I'm facing a problem where when I am drawing the bullet laser in my AnimationTimer loop, whenever the player shoots another bullet, the program only renders the newest bullet and the old bullet just disappears.
For the sake of brevity, I'm going to post the main AnimationTimer loop related to the bullet input and rendering only:
//List of stuffs (Bullets, enemies etc)
var laserListB : ListBuffer[Laser] = ListBuffer()
val timer = AnimationTimer( currentNanoTime => {
//Calculating time since last frame for frame independant rendering
var elapsedTime : Double = (currentNanoTime - lastNanoTime) / 1000000000.0;
lastNanoTime = currentNanoTime;
//Input check
//SKIPPED PLAYER MOVEMENT CODE
if(shootPress){
var now = System.nanoTime()
//Checking for atkSpeed cooldwon
if((lastShootNano <= 0L) || ((now - lastShootNano) >= player.atkSpeed)){
laserListB += player.shoot()
}
lastShootNano = now
}
//Updating position
for(laser <- laserListB){
laser.sprite.velocityX = 0
laser.sprite.velocityY = -400
laser.sprite.update(elapsedTime)
}
//Rendering
//Bullets
for(laser <- laserListB){
laser.sprite.render(gc)
}
})
And the following is my Sprite class:
import scalafx.scene.image.Image
import scalafx.scene.canvas.GraphicsContext
import scalafx.geometry.Rectangle2D
class Sprite(
private var _image : Image,
private var _positionX : Double,
private var _positionY : Double,
private var _velocityX : Double,
private var _velocityY : Double,
private var _width : Double,
private var _height : Double){
//Functions
def render(gc : GraphicsContext){
gc.drawImage(_image, _positionX, _positionY);
}
}
And if you need, here's my player's shoot function:
def shoot() = {
//Setting up laser sprite
val laser = new Laser(_atkSprite, damage, true)
laser.sprite.velocityX = 0
laser.sprite.velocityY = -400
laser.sprite.positionX = _sprite.positionX + (_sprite.width / 2) //Center laser horizontally on player sprite
laser.sprite.positionY = _sprite.positionY - 10 //Slight offset to be a bit higher than the player sprite
laser
}
Thank you for reading this far :D
Edit 1:
Here's a video demonstrating the problem: https://youtu.be/DliNyBoa1DI

Ok I solved it, it wasn't a problem with GraphicsContext but rather due to the fact, Laser is instantiated with the same Sprite in player.shoot(), therefore all Lasers will have the same X and Y, and be overlapped, thus appearing as if it "disappeared".
The new code instantiates a new Sprite everytime Laser is instantiated as follows:
def shoot() = {
//Laser sprites
val atkImg = new Image(getClass.getResourceAsStream("/Images/small_laser_blue.png"))
val atkSprite = new Sprite(atkImg, 0, 0, 0, 0, atkImg.getWidth(), atkImg.getHeight())
val laser_ = new Laser(atkSprite, _damage, true)
laser_.sprite.velocityX = 0
laser_.sprite.velocityY = -400
laser_.sprite.positionX = _sprite.positionX + (_sprite.width / 2) //Center laser horizontally on player sprite
laser_.sprite.positionY = _sprite.positionY - 10 //Slight offset to be a bit higher than the player sprite
}

Related

ARCore unity - Place objects between two objects

Using ARCore on Unity, I'm trying to place one gameObject between two gameObjects. Unfortunately it doesn't display, it seems it is a problem with Anchor.
*Using Vuforia, i didn't had problem to position game objects.
What i try to achieve is:
Place two objects (A and B) on the ground when i touch the surface. It Works
Place a gameObject (C) between the two objects (A and B).Not displaying
// Place target objects A and B on surface touch
GameObject prefab;
GameObject prefab2;
prefab = AndyPointPrefab;
prefab2 = AndyPlanePrefab;
hitpoint= hitpoint + 1;
// Place object A
if (hitpoint==1){
target1 = Instantiate(prefab, hit.Pose.position, hit.Pose.rotation);
target1.transform.Rotate(0, k_ModelRotation, 0, Space.Self);
var anchor = hit.Trackable.CreateAnchor(hit.Pose);
target1.transform.parent = anchor.transform;
mIsFirsttargetVisible=true;
}
else if (hitpoint==2){ // Place object B
target2 = Instantiate(prefab2, hit.Pose.position, hit.Pose.rotation);
target2.transform.Rotate(0, k_ModelRotation, 0, Space.Self);
var anchor = hit.Trackable.CreateAnchor(hit.Pose);
target2.transform.parent = anchor.transform;
mIsSecondTargetVisible=true;
hitpoint=-1;
}
//Update function : todisplay point C in-between.
Update() {
// Place object C
if(mIsFirsttargetVisible && mIsSecondTargetVisible){
GameObject objectMiddle = GameObject.CreatePrimitive(PrimitiveType.Sphere);
Vector3 middlePosition = (target1.transform.position+target2.transform.position)/2;
objectMiddle.transform.position = middlePosition;
objectMiddle.transform.localScale = new Vector3(200.0f, 10.0f, 200.0f);
}
}
EDIT
I successfully arrived to place the gameobject in between.
i added this last line in my code: target1.transform.parent = objectMiddle.transform;
if(mIsFirsttargetVisible && mIsSecondTargetVisible){
GameObject objectMiddle = GameObject.CreatePrimitive(PrimitiveType.Sphere);
Vector3 middlePosition = (target1.transform.position+target2.transform.position)/2;
objectMiddle.transform.position = middlePosition;
objectMiddle.transform.localScale = new Vector3(200.0f, 10.0f, 200.0f);
target1.transform.parent = objectMiddle.transform;
}

Using leapmotion to control Unity3d interface

I understand that I can use leapmotion in game with Unity3D.
What I can't see any information on, is if I can use it to actual interact with assets, models etc as I build the game. For example revolving a game object around the x axis or zooming in or out of the view.
Is this possible?
Yes, it is possible, but requires some scripts that nobody has written yet (ASFAIK). Here is a VERY rough example that I worked up today since I've been curious about this question, too.
All it does is move, scale, and rotate a selected game object -- it doesn't try to do this in a good way -- it is a proof of concept only. To make it work you would have to do a sensible conversion of Leap coordinates and rotations to Unity values. To try it, put this script in a folder called "Editor", select a game object in the scene view and hold a key down while moving your hand above your Leap. As I said, none of these movements really work to edit an object, but you can see that it is possible with some sensible logic.
#CustomEditor (Transform)
class RotationHandleJS extends Editor {
var controller = new Leap.Controller();
var position;
var localScale;
var localRotation;
var active = false;
function OnSceneGUI () {
e = Event.current;
switch (e.type) {
case EventType.KeyDown:
position = target.transform.position;
localScale = target.transform.localScale;
localRotation = target.transform.localRotation;
active = true;
Debug.Log("editing");
break;
case EventType.KeyUp:
active = false;
target.transform.position = position;
target.transform.localScale = localScale;
EditorUtility.SetDirty (target);
break;
}
if(active){
frame = controller.Frame();
ten = controller.Frame(10);
scale = frame.ScaleFactor(ten);
translate = frame.Translation(ten);
target.transform.localScale = localScale + new Vector3(scale, scale, scale);
target.transform.position = position + new Vector3(translate.x, translate.y, translate.z);
leapRot = frame.RotationMatrix(ten);
quats = convertRotation(leapRot);
target.transform.localRotation = quats;
}
}
var LEAP_UP = new Leap.Vector(0, 1, 0);
var LEAP_FORWARD = new Leap.Vector(0, 0, -1);
var LEAP_ORIGIN = new Leap.Vector(0, 0, 0);
function convertRotation(matrix:Leap.Matrix) {
var up = matrix.TransformDirection(LEAP_UP);
var forward = matrix.TransformDirection(LEAP_FORWARD);
return Quaternion.LookRotation(new Vector3(forward.x, forward.y,forward.z), new Vector3(up.x, up.y, up.z));
}
}

unity2d instantiate prefab animator working partly

okay so my enemies are being instantiated in my main.js
but the animator is attached to this prefab of enemy ( it is a sprite animation )
it works on certian enemies
for instance
0will work
1 wont work
1,1,0,1,0,1,0,0,0,1,0,1,0 and so on it seems random
also my enemies spawn between 6 and 9 seconds.
i just cant figure this out
one problem after another.:( (guess this sums up a beginers game dev).
nearly done though.
thanks for your help stackoverflow community.
#pragma strict
var enemy : GameObject;
var speed : float = 1.0;
var enemanim : Animator;
var isdying : boolean = false;
function Start () {
this.transform.position.x = 8.325;
this.transform.position.y = -1.3;
enemanim = GetComponent(Animator);
enemanim.SetFloat("isdead",0);
}
function OnCollisionEnter2D(coll: Collision2D) {
if(coll.gameObject.CompareTag("distroy")){
Destroy(enemy.gameObject);
}
if(coll.gameObject.CompareTag("Player") && main.jumped == true){
isdying=true;
}
}
function Update () {
this.transform.Translate(Vector3(Input.GetAxis("Horizontal") * speed * Time.deltaTime, 0, 0));
this.rigidbody2D.velocity = Vector2(-5,0);
if (isdying==true){
enemanim.SetFloat("isdead",1);
}
}
You are missing
enemanim.Play();
It is working on and off because some of your Enemies are set to play automatically through the Editor.

Falling through terrain everytime i crouch UNITY3d

in unity i made a script for my guy to crouch, run , and have his regular speed but when i crouch i just fall forever into the terrain was wondering if it is my code or i have to put a check on the terrain.
var walkSpeed: float = 7; // regular speed
var crchSpeed: float = 3; // crouching speed
var runSpeed: float = 20; // run speed
private var chMotor: CharacterMotor;
private var ch: CharacterController;
private var tr: Transform;
private var height: float; // initial height
function Start(){
chMotor = GetComponent(CharacterMotor);
tr = transform;
ch = GetComponent(CharacterController);
height = ch.height;
}
function Update(){
var h = height;
var speed = walkSpeed;
if (ch.isGrounded && Input.GetKey("left shift") || Input.GetKey("right shift")){
speed = runSpeed;
}
if (Input.GetKey("c")){ // press C to crouch
h = 0.5 * height;
speed = crchSpeed; // slow down when crouching
}
chMotor.movement.maxForwardSpeed = speed; // set max speed
var lastHeight = ch.height; // crouch/stand up smoothly
ch.height = Mathf.Lerp(ch.height, h, 5*Time.deltaTime);
tr.position.y += (ch.height-lastHeight)/2; // fix vertical position
}
This line could be responsible:
tr.position.y += (ch.height-lastHeight)/2;
you might want to let gravity take care of this or add a downward Force here. Changing the transform directly makes the Object dont care about colliders in the way.
edit: a better way would probably be to change the CharacterController though, as "falling down" when crouching doesnt make much sense. Maybe you dont even need this? The way i would implement this is the root at the feet, and height goes upwards from there.

Make cube follow character five steps behind unity

At the moment I have a script which when you hit a cube, it follows the player...but when you stand still it overlaps you. What I want is to be able to set the position of the cube to five steps behind the player at all times...how would i do this?
GameObject.Find("Cube2").transform.position = Vector3(0.5, 0.5, 0.5);
That is what I have tried so far, but that just makes the cube disappear?
the script in its entirety:
static var target : Transform; //the enemy's target
var moveSpeed = 3; //move speed
var rotationSpeed = 3; //speed of turning
var Player = GameObject.Find("Player").transform.position;
var Cube2 = GameObject.Find("Cube2").transform.position;
var myTransform : Transform; //current transform data of this enemy
function Awake()
{
//myTransform = transform; //cache transform data for easy access/preformance
}
function Start()
{
//target = GameObject.FindWithTag("Player1").transform; //target the player
}
//var distance = Vector3.Distance(Player.transform.position, Cube2.transform.position);
//Debug.Log(distance);
function Update () {
Debug.Log(Player);
//var distance = Vector3.Distance(Player.transform.position, Cube2.transform.position);
//var distance = Vector3.Distance(player_distance, cube_distance);
// if (distance > 5)
// {
if (target == GameObject.FindWithTag("Player").transform)
{
//rotate to look at the player
GameObject.Find("Cube2").transform.position = Vector3(0.5, 0.5, 0.5);
myTransform.rotation = Quaternion.Slerp(myTransform.rotation,
Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed*Time.deltaTime);
//move towards the player
myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
}
//}
}
Like I said, I don't know unity really (had a 5 minute play with it)
In honesty it looks like you've pretty much got it - not sure why you can't get it working:
This is what should work: (assuming the quarternion calls are correct) - this is using latest Unity reference from the site so it might be diff to what works for you (what version of Unity you on?)
// Params
var moveSpeed = 3; // Move speed
var rotationSpeed = 3; // Speed of turning
// Find game objects
var Player = GameObject.Find("Player");
var Cube2 = GameObject.Find("Cube2");
function Update ()
{
// Vector from cube pos to player pos (vector math: target - position = vector to target from pos)
var dir = Player.transform.position - Cube2.transform.position;
// If the distance is over 5 units
if(dir.magnitude > 5.0f)
{
// Rotate towards player
Cube2.transform.rotation = Quaternion.Slerp(Cube2.transform.rotation, Quaternion.LookRotation(dir), rotationSpeed * Time.deltaTime);
// Move forward at specified speed
Cube2.transform.position += Cube2.transform.forward * moveSpeed * Time.deltaTime;
}
}
That should do it - if not let me know what happens (or if you get compilation errors) - like I said I don't really know Unity but I've had a look and I'm familiar with 3D/game programming