I have problem with smooth map rotation. I use Sensor and onSensorChanged to get direction which side the user is looking at. Then I put it to math degrees (rage -180 : 180)
degres = Math.toDegrees(mOrientation.get(0).toDouble())
and then pass it to other function
if (gps != null) {
if(degres!! !in lastDegres!!-10..lastDegres!!+10 && degres!!>0 || degres!! !in lastDegres!!-10 ..lastDegres!!+10 && degres!!<0 ){
//here
lastDegres = degres
}
}
if statement avoid shaking map when sensor get a little movement.
My problem is what I have type in this if statement to smoothly rotate map. I already trying something like this :
if (gps != null) {
if(degres!! !in lastDegres!!-10..lastDegres!!+10 && degres!!>0 || degres!! !in lastDegres!!-10 ..lastDegres!!+10 && degres!!<0 ){
var result = (lastDegres!! - (degres!! )).toInt()
for (i in 0..result) {
setOrientation(((180 + lastDegres!! + i ).toFloat()))
update()
}
lastDegres = degres
}
}
but it's work only in only right direction, any advices how to allow to rotate smoothly to left and right ?
// ANSWER
if u want use this next step is find closest site left or right to actually position
if (gps != null) {
realpos = degres!! * -1
if (realpos < 0) realpos += 360
dif = if (realpos > lastDegres!!) { realpos - lastDegres!! } else { (lastDegres!! - realpos) }
if (dif > 10) {
if(realpos > lastDegres!!){
for (i in 1..dif.toInt()*50000) {
orientation = (lastDegres!!.toFloat()+i/50000)
update()
}
}else if (lastDegres!! > realpos) {
for (i in 1..dif.toInt()*50000){
orientation = (lastDegres!!.toFloat()-i/50000)
update()
}
}
lastDegres = realpos
}
Related
I'm writing a game of checkers with QML, and I have this component which encompasses the player piece and it's mouse area.
When the mouse is pressed, and the user moves the mouse, the cell underneath is highlighted yellow. This and snapping works on Ubuntu, but when I test it on Android, only dragging pieces seems to work.
This is it working on Ubuntu
Here's the code for the player piece:
Component {
id: playerPiece
Image {
id: image
property int cx: 0
property int cy: 0
x: board.x + (cx * window.cellSize)
y: board.y + (cy * window.cellSize)
property int pieceIndex: -1
property int pieceType: 0
MouseArea {
id: ma
anchors.fill: parent
enabled: GameState.playerTurnId == 1 && (pieceType & 1) == 1
drag.target: parent
drag.axis: Drag.XAxis | Drag.YAxis
property int targetCellX: -1
property int targetCellY: -1
onReleased: {
// console.log("released")
if (GameState.lastHighlightedIndex != -1
&& GameState.lastHighlightedY != -1) {
board.children[GameState.lastHighlightedY].children[GameState.lastHighlightedX].children[0].visible = false
if (targetCellX != -1 && targetCellY != -1) {
console.log(targetCellX)
var piece = GameState.playerPieceQMLItems[image.pieceIndex]
console.log(`cx ${targetCellX} cy ${targetCellY}`)
piece.cx = targetCellX
piece.cy = targetCellY
//hack to recalculate positions
board.x++
board.x--
board.y++
board.y--
targetCellX = -1
targetCellY = -1
}
}
}
onPositionChanged: {
if (drag.active) {
// console.log("dragging")
var mousePos = NativeFunctions.globalMousePos()
targetCellX = Math.floor(
(mousePos.x - window.x - board.x) / window.cellSize)
targetCellY = Math.floor(
(mousePos.y - window.y - board.y) / window.cellSize)
if ((targetCellX > -1 && targetCellX < 8) && (targetCellY > -1
&& targetCellY < 8)) {
GameState.tileState[targetCellX + (targetCellY * 8)] = 3
//update the board row column child item
var item = board.children[targetCellY].children[targetCellX]
if (item instanceof Rectangle) {
//remove the highlight from the last highlighted cell
if (GameState.lastHighlightedIndex != -1
&& GameState.lastHighlightedY != -1) {
board.children[GameState.lastHighlightedY].children[GameState.lastHighlightedX].children[0].visible = false
}
item.children[0].visible = true
//console.log(`selected ${GameState.playerPieceQMLItems[image.pieceIndex]}, pieceIndex ${image.pieceIndex}`)
//console.log(`${item.children[1].id}`)
GameState.lastHighlightedX = targetCellX
GameState.lastHighlightedY = targetCellY
}
}
}
}
}
sourceClipRect: {
if (GameState.cf(pieceType, GameState.TS_P1)) {
//king flag set
if (GameState.cf(pieceType, GameState.TS_PK)) {
return Qt.rect(0, 326, 338, 338)
} else {
return Qt.rect(0, 0, 338, 338)
}
} else if (GameState.cf(pieceType, GameState.TS_P2)) {
//king flag set
if (GameState.cf(pieceType, GameState.TS_PK)) {
return Qt.rect(0, 326, 338, 338)
} else {
return Qt.rect(534, 0, 338, 338)
}
}
}
source: "qrc:/pieces.png"
}
}
Which is a part of https://github.com/ben-cottrell-nz/checkers/blob/master/main.qml.
Why is the highlighting and snapping functionality not working when I test my application on Android?
I found out that my method exposed from C++, NativeMethods::globalMousePos was the issue: on Android it was returning -2147483648 for x and y, this was being returned from QCursor::pos.
I changed mousePos in my QML code to use the builtin function mapToGlobal:
var mousePos = mapToGlobal(mouse.x, mouse.y)
Highlighting and snapping to Rectangles works on Android now.
I'm working on an online multiplayer fps game for android devices.
I have 12 player in my game , 6 player in one side and 6 player in other side and they kill each other.
Evrything is fine but there is an issue in my game and that is , When players are in the scene , Mouse look is laggy.
here is my code :
public void MyUpdate()
{
the_time = Time.deltaTime;
if (Input.touches.Length > 0)
{
foreach (Touch t in Input.touches)
{
if (t.position.x > Screen.width / 2)
{
if (t.phase == TouchPhase.Began)
{
delta = t.deltaPosition;
}
if (t.phase == TouchPhase.Began || t.phase == TouchPhase.Moved)
{
delta = -t.deltaPosition;
ROTX_ROTY.x += (delta.y * sensitivityX * current_speed_offset_vertical * the_time);
ROTX_ROTY.y -= delta.x * sensitivityY * current_speed_offset * the_time;
ROTX_ROTY.x = Mathf.Clamp(ROTX_ROTY.x, -clampAngle, clampAngle);
MyTransform.rotation = Quaternion.AngleAxis(ROTX_ROTY.y,Vector3.up);
x_rot_transform.localRotation = Quaternion.AngleAxis(ROTX_ROTY.x, Vector3.right);
}
else if (t.phase == TouchPhase.Ended)
{
delta = t.deltaPosition;
}
}
}
}
}
Anybody knows how can i solve this problem ?
Because this lag is only in my mouse look . Other things like walking, shooting works fine !
Is there any way to I optimize this code for mobiles?
For example I use Quaternion.AngleAxis instead of Quaternion.Euler because it's little faster... But after all this , I have lag every few second in my game.
/////////////////////
UPDATES :
I changed part of my code and change IF statement to switch case , but my problem not solved.
if (Input.touches.Length > 0)
{
foreach (Touch t in Input.touches)
{
if (t.position.x > Screen.width / 2)
{
switch (t.phase)
{
case TouchPhase.Moved:
delta = -t.deltaPosition;
ROTX_ROTY.x += (delta.y * sensitivityX * current_speed_offset_vertical * the_time);
ROTX_ROTY.y -= delta.x * sensitivityY * current_speed_offset * the_time;
ROTX_ROTY.x = Mathf.Clamp(ROTX_ROTY.x, -clampAngle, clampAngle);
MyTransform.rotation = Quaternion.AngleAxis(ROTX_ROTY.y, Vector3.up);
x_rot_transform.localRotation = Quaternion.AngleAxis(ROTX_ROTY.x, Vector3.right);
break;
default:
delta = t.deltaPosition;
break;
}
}
}
}
I'm creating an Android game with Unity. There are only three ways to control the movement of the character:
Tap in the right half of the screen: jump to the right
Tap in the left half of the screen: jump to the left
Swipe upwards: character dashes forward
In theory, I know that I can differentiate the touches with the TouchPhases (began, moved, stationary and ended). When only detecting the taps without caring for swipes, I just checked if the phase of the touch began and made the player jump. That felt fast on my device.
However, because I have to consider that a swipe may follow, I can not initiate the jump action until I detected ThouchPhase.Ended. This leads to a very slow responding character, which doesnt jump until the user rises his finger of the screen.
I tried to use ThouchPhase.Moved and ThouchPhase.Stationary instead to simulate a immediate response but my solution is pretty bad in terms of detecting the difference between a tap and a swipe:
Vector2 startTouchPosition;
Vector2 endTouchPosition;
Vector2 currentSwipe;
void Update()
{
if (Input.touches.Length > 0)
{
for (int i = 0; i < Input.touchCount; i++)
{
Touch touch = Input.GetTouch(i);
if (touch.phase == TouchPhase.Began)
{
//save began touch 2d point
startTouchPosition = new Vector2(touch.position.x, touch.position.y);
}
if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary)
{
//save ended touch 2d point
endTouchPosition = new Vector2(touch.position.x, touch.position.y);
if (endTouchPosition.y - startTouchPosition.y < 5)
{
if (touch.position.x > (Screen.width / 2))
{
JumpToRight();
}
else if (touch.position.x < (Screen.width / 2))
{
JumpToLeft();
}
}
else
{
//create vector from the two points
currentSwipe = new Vector2(endTouchPosition.x - startTouchPosition.x, endTouchPosition.y - startTouchPosition.y);
//normalize the 2d vector
currentSwipe.Normalize();
//swipe upwards
if (currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f)
{
DashForward();
}
}
}
}
}
}
Here is the code I used. I tested and it works but sometimes, I noted a delay. Let me know if it is good enough for you. Basically you dont need to go through all touches if you dont need multi-touch. And you just need Begin and End touch phases.
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
public class touch : MonoBehaviour {
private Vector2 startTouchPosition;
private Vector2 endTouchPosition;
private Vector2 currentSwipe;
public Text textbox;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.touches.Length > 0)
{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
//save began touch 2d point
startTouchPosition = new Vector2(touch.position.x, touch.position.y);
}
if (touch.phase == TouchPhase.Ended)
{
//save ended touch 2d point
endTouchPosition = new Vector2(touch.position.x, touch.position.y);
//create vector from the two points
currentSwipe = new Vector2(endTouchPosition.x - startTouchPosition.x, endTouchPosition.y - startTouchPosition.y);
//normalize the 2d vector
currentSwipe.Normalize();
if(Mathf.Abs(currentSwipe.y) < 0.1f && Mathf.Abs(currentSwipe.x) < 0.1f)
{
if (touch.position.x > (Screen.width / 2))
{
textbox.text= "jump right";
}
else if (touch.position.x < (Screen.width / 2))
{
textbox.text= "jump left";
}
}
if (currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f)
{
textbox.text= "Dash forward";
}
}
}
}
}
Right now I've been developing a game which will make the character move up or down if either swipe up or down on the left side of the screen. Then, he can also, shoot projectiles if I tap the right side of the screen. I've succeeded on making it work but the problem is that the swipe function do not works while I tap the the right screen. Both only works if I do one of them. I cannot move the character if I am firing projectiles. Any suggestions? Appreciate it in advanced.
Here's the code:
For the swipe movement function:
void Swipe() {
if (Input.touchCount > 0) {
Touch t = Input.GetTouch(0);
if (t.phase == TouchPhase.Began)
{
lp = t.position;
fp = t.position;
text.text = fp.x.ToString();
}
else if (t.phase == TouchPhase.Ended)
{
lp = t.position;
//Swipe Up
if (fp.y < lp.y && fp.x < 400)
{
currentLane += 1;
}
//Swipe Down
else if (fp.y > lp.y && fp.x < 400)
{
currentLane -= 1;
}
}
}
}
And here's the code for the tap or firing projectiles function:
void FireBullets() {
interval += 2 * Time.deltaTime;
anim.SetBool("Attacking", firing);
if (Input.touchCount > 0 && interval > .75f) {
Vector3 bulletTouchPos;
Touch bulletT = Input.GetTouch(0);
bulletTouchPos = bulletT.position;
if (bulletT.phase == TouchPhase.Began) {
if (bulletTouchPos.x > 400)
{
interval = 0;
firing = true;
//Fire Bullets
Instantiate(bullets, new Vector3(transform.position.x + 1.2f, transform.position.y + .3f, transform.position.z), Quaternion.identity);
}
}
}else
{
firing = false;
}
}
Your lp and fp values don't care which finger is being checked.
If you want to detect multiple touch gestures at once, you need to discriminate your detection based on which finger that is.
You can do this by looking at the Touch.fingerId value, which is unique for each finger. Fingers are just an ID assigned to a given touching point as it moves across the screen in order to identify it from other touching points currently also on the screen.
You'll need to adjust your code to handle how to store the information you need in order to do what you need, but this should get you started.
I have been making endless jumping game.
It is lacking powerbar.. I have managed to make one but it does not scale with the screen change.. I tried to use canvas to world screen but bar won't face the direction you click..
So like the longer you hold left mouse click, more power it has and it faces the direction you click.. Atleast it should do that, and i does but only on one screen size.
It looks likes this:
http://prntscr.com/b6z5wn
So this is the code i am currently using..
function Start ()
{
powerFill_startPos = powerFill.transform.localPosition.x;
powerFillAccel = 770 * Time.deltaTime;
}
function Update ()
{
if(Input.GetMouseButton(0) && collision.onPlatform == true && delete.jurinoFlag == true)
{
bar_back.enabled = true;
powerFill_Image.enabled = true;
var moveDirection : Vector3 = gameObject.transform.position - Input.mousePosition;
if (moveDirection != Vector3.zero)
{
var angle : float = Mathf.Atan2(moveDirection.y, moveDirection.x) * Mathf.Rad2Deg;
angle -= 180;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
powerFill.transform.localPosition.x += powerFillAccel;
}
else
{
bar_back.enabled = false;
powerFill.transform.localPosition.x = powerFill_startPos;
powerFill_Image.enabled = false;
}
}
I would very much appreciate any help i can get so i can finish the game and publish it :)
Thanks for taking time and replying. Have a nice day!