Cocos2d-x scroll ScrollView while pressing button - scrollview

using cocos2d-x-3.13.1
I have create ScrollView with 88 buttons to start different in game levels.
Functionality i have: User can starts selected level. But only can scroll if initial tap position is not on button.
Functionality i want: User can scroll a ScrollView if his initial touch position is on button.
Creating ScrollView
containerLayer = cocos2d::LayerColor::create();
containerLayer->setContentSize(Size(visibleSize.width, visibleSize.height * 4.5));
containerLayer->setPosition(Point(0, -visibleSize.height * 3.7));
auto scrollView = cocos2d::extension::ScrollView::create();
scrollView->setContentSize(Size(containerLayer->getContentSize().width, containerLayer->getContentSize().height));
scrollView->setPosition(Point(visibleSize.width * 0.05, visibleSize.height * 0.05));
// set the scroll-direction for scroll-view
scrollView->setDirection(cocos2d::extension::ScrollView::Direction::VERTICAL);
scrollView->setViewSize(Size(visibleSize.width * 0.90, visibleSize.height * 0.8));
// set the content offset of the scrollview
scrollView->setContentOffset(Vec2(0, 0));
scrollView->setTouchEnabled(true);
// add / set the container-layer to the scrollview.
scrollView->setContainer(containerLayer);
// add scroll-view to your scene-layer.
this->addChild(scrollView, 100);
Adding buttons
int level = 1;
const Size buttonSize(100,50);
for (int h = 0; h < 22; h++) {
for (int w = 0; w < 4; w++) {
const Color4B buttonColor(random(0, 255), random(0, 255), random(0, 255), 255);
auto button = ui::Widget::create();
button->setContentSize(buttonSize);
button->setPosition(Point(containerLayer->getContentSize().width * 0.15 + this->getContentSize().width * 0.2 * w, containerLayer->getContentSize().height - containerLayer->getContentSize().height / 23 * (h + 1) + containerLayer->getContentSize().height / 46));
button->setTouchEnabled(true);
button->addClickEventListener([=](Ref* _sender)
{
auto scene = GameScene::createSceneWithLevel(level);
Director::getInstance()->replaceScene(TransitionFade::create(1.0, scene, Color3B(0, 0, 0)));
});
button->addChild(LayerColor::create(buttonColor, buttonSize.width, buttonSize.height));
scrollView->addChild(button);
level++;
}
}

One dirty way is to create a subclass of button, in which you could store the pointer of a ScrollView as the member variable:
auto button = _YourBtnClass_::create(pScrollView);
and you need to disable touch of that ScrollView:
pScrollView->setTouchEnabled(false);
finally, override onTouchBegan,onTouchMoved,onTouchEnded and onTouchCancelled in YourBtnClass, in which you would call the corresponding functions of pScrollView

Instead of cocos2d::extension::ScrollView I used cocos2d::ui::ScrollView, cocos2d::ui::Button and it met my requirements for ScrollView.
scrollView = cocos2d::ui::ScrollView::create();
scrollView->setDirection(ui::ScrollView::Direction::VERTICAL);
scrollView->setContentSize(Size(visibleSize.width * 0.9, visibleSize.height * 0.8)); // What user see
scrollView->setInnerContainerSize(Size(visibleSize.width * 0.9, visibleSize.height * 0.8 * 4.5));
scrollView->setBounceEnabled(true);
scrollView->setAnchorPoint(Point(0.5, 0.5));
scrollView->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height * 0.45 + origin.y));
int level = 1;
for (int h = 0; h < 22; h++) {
for (int w = 0; w < 4; w++) {
auto button = ButtonLevel::create(this, Point(scrollView->getInnerContainerSize().width / 5 * (w + 1), scrollView->getInnerContainerSize().height - scrollView->getInnerContainerSize().height / 22 * (h + 1) + scrollView->getInnerContainerSize().height / 44), level, canBePlayed);
button->addClickEventListener([=](Ref* _sender)
{
auto scene = GameScene::createSceneWithLevel(level);
Director::getInstance()->replaceScene(TransitionFade::create(1.0, scene, Color3B(0, 0, 0)));
});
scrollView->addChild(button);
level++;
}
}
this->addChild(scrollView, 100);
Also #include "ui/CocosGUI.h" is needed

Related

How to make a 2d shader working with ParallaxBackground node in Godot?

In my game I want to make a scrolling background with moving stars. I am using ParallaxBackground node with ParallaxLayer as a child, and the later has TextureRect child that display a 2d shader for the stars.
Nodes hierarchy:
ParallaxBackground -> StarsLayer -> Stars
Stars is the TextureRect and its rect_size equals the project window size.
Here is the 2d shader that it uses:
shader_type canvas_item;
uniform vec4 bg_color: hint_color;
float rand(vec2 st) {
return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
}
void fragment() {
float size = 100.0;
float prob = 0.9;
vec2 pos = floor(1.0 / size * FRAGCOORD.xy);
float color = 0.0;
float starValue = rand(pos);
if (starValue > prob)
{
vec2 center = size * pos + vec2(size, size) * 0.5;
float t = 0.9 + 0.2 * sin(TIME * 8.0 + (starValue - prob) / (1.0 - prob) * 45.0);
color = 1.0 - distance(FRAGCOORD.xy, center) / (0.5 * size);
color = color * t / (abs(FRAGCOORD.y - center.y)) * t / (abs(FRAGCOORD.x - center.x));
}
else if (rand(SCREEN_UV.xy / 20.0) > 0.996)
{
float r = rand(SCREEN_UV.xy);
color = r * (0.85 * sin(TIME * (r * 5.0) + 720.0 * r) + 0.95);
}
COLOR = vec4(vec3(color),1.0) + bg_color;
}
Here is ParallaxBackground script:
extends ParallaxBackground
onready var stars_layer = $StarsLayer
var bg_offset = 0.0
func _ready():
stars_layer.motion_mirroring = Vector2(0, Helpers.WINDOW_SIZE.y)
func _process(delta):
bg_offset += 30 * delta
scroll_offset = Vector2(0, bg_offset)
The problem is that the stars are being showed but not moving at all.
Use motion_offset instead of scroll_offset
func _process(delta):
motion_offset += 30 * delta

OpenGL for OSX not perfect circumferences

I am developing a app that use picking selection using color depth in OpenGL for Mac. The selection works great, but I observed that OpenGL not draw perfect circles (circunferences). I use GL_LINE_LOOP for render 360 segments for complete a close circunference. But if, I see the render in SELECTION mode I observe some kind of bites (triangles in white) over the circunference, 4 in total for each circle.
Is a OpenGL problem or I am doing something wrong?
This is the code for draw each circunference.
glLineWidth(10.0f); // Exaggerated for image.
glBegin(GL_LINE_LOOP);
for (int i = 0; i <= 360; i++) {
calcX = radio * cos((i * M_PI) / 180) + offset_x;
calcY = radio * sin((i * M_PI) / 180) + offset_y;
glVertex3f(calcX, calcY, offset_z);
}
glEnd();
Thanks "radical7, for the the suggest to use Triangles instead lines. I was able to obtain a perfect RING, works as smooth .
This is the code:
color = 0.00277778;
glBegin(GL_TRIANGLE_STRIP);
for (int i = 0; i <= 360; i++) {
glColor4f(color, 0, 0, 1.0f);
calcX = radio * cos((i * M_PI) / 180) + offset_x;
calcY = radio * sin((i * M_PI) / 180) + offset_y;
glVertex3f(calcX, calcY, offset_z);
radio +=20;
calcX = radio * cos((i * M_PI) / 180) + offset_x;
calcY = radio * sin((i * M_PI) / 180) + offset_y;
glVertex3f(calcX, calcY, offset_z);
radio -=20;
color += 0.00277778;
}
glEnd();
Result:

Path Tracing - Generate Camera Rays with a Left Handed coordinate system

Been having some issues implementing a camera for my renderer. As the question states,I would like to know the necessary steps to generate such a camera.With field of view and aspect ratio included.Its important that the Coordinate system be left handed such that -z pushes the camera away from the screen(as I understand it).I have tried looking online but most of the implementations are incomplete or have failed me.Any help is appreciated.Thank You.
I had trouble with this and took a long time to figure out. Here is the code for camera class.
#ifndef CAMERA_H_
#define CAMERA_H_
#include "common.h"
struct Camera {
Vec3fa position, direction;
float fovDist, aspectRatio;
double imgWidth, imgHeight;
Mat4 camMatrix;
Camera(Vec3fa pos, Vec3fa cRot, Vec3fa cDir, float cfov, int width, int height) {
position = pos;
aspectRatio = width / (float)height;
imgWidth = width;
imgHeight = height;
Vec3fa angle = Vec3fa(cRot.x, cRot.y, -cRot.z);
camMatrix.setRotationRadians(angle * M_PI / 180.0f);
direction = Vec3fa(0.0f, 0.0f, -1.0f);
camMatrix.rotateVect(direction);
fovDist = 2.0f * tan(M_PI * 0.5f * cfov / 180.0);
}
Vec3fa getRayDirection(float x, float y) {
Vec3fa delta = Vec3fa((x-0.5f) * fovDist * aspectRatio, (y-0.5f) * fovDist, 0.0f);
camMatrix.rotateVect(delta);
return (direction + delta);
}
};
#endif
Incase if you need the rotateVect() code in the Mat4 class
void Mat4::rotateVect(Vector3& vect) const
{
Vector3 tmp = vect;
vect.x = tmp.x * (*this)[0] + tmp.y * (*this)[4] + tmp.z * (*this)[8];
vect.y = tmp.x * (*this)[1] + tmp.y * (*this)[5] + tmp.z * (*this)[9];
vect.z = tmp.x * (*this)[2] + tmp.y * (*this)[6] + tmp.z * (*this)[10];
}
Here is our setRotationRadians code
void Mat4::setRotationRadians(Vector3 rotation)
{
const float cr = cos(rotation.x);
const float sr = sin(rotation.x);
const float cp = cos(rotation.y);
const float sp = sin(rotation.y);
const float cy = cos(rotation.z);
const float sy = sin(rotation.z);
(*this)[0] = (cp * cy);
(*this)[1] = (cp * sy);
(*this)[2] = (-sp);
const float srsp = sr * sp;
const float crsp = cr * sp;
(*this)[4] = (srsp * cy - cr * sy);
(*this)[5] = (srsp * sy + cr * cy);
(*this)[6] = (sr * cp);
(*this)[8] = (crsp * cy + sr * sy);
(*this)[9] = (crsp * sy - sr * cy);
(*this)[10] = (cr * cp);
}

What is the most optimized way of creating a ray tracer?

Currently, I am working with a ray tracer that takes an iterative approach towards developing the scenes. My goal is to turn it into a recursive ray tracer.
At the moment, I have a ray tracer defined to do the following operation to create the bitmap it is stored in:
int WIDTH = 640;
int HEIGHT = 640;
BMP Image(WIDTH, HEIGHT); // create new bitmap
// Slightly shoot rays left of right camera direction
double xAMT, yAMT;
*/
Color blue(0.1, 0.61, 0.76, 0);
for (int x = 0; x < WIDTH; x++) {
for (int y = 0; y < HEIGHT; y++) {
if (WIDTH > HEIGHT) {
xAMT = ((x + 0.5) / WIDTH) * aspectRatio - (((WIDTH - HEIGHT) / (double)HEIGHT) / 2);
yAMT = ((HEIGHT - y) + 0.5) / HEIGHT;
}
else if (HEIGHT > WIDTH) {
xAMT = (x + 0.5) / WIDTH;
yAMT = (((HEIGHT - y) + 0.5) / HEIGHT) / aspectRatio - (((HEIGHT - WIDTH) / (double)WIDTH) / 2);
}
else {
xAMT = (x + 0.5) / WIDTH;
yAMT = ((HEIGHT - y) + 0.5) / HEIGHT;
}
..... // calculate intersections, shading, reflectiveness.... etc
Image.setPixel(x, y, blue); // this is here just as an example
}
}
Is there another approach to calculating the reflective and refractive child rays outside the double for-loop?
Are the for-loops necessary? // yes because of the bitmap?
What approaches can be taken to minimize/optimize an iterative ray tracer?

three.js: Rotate around origin after panning camera

I have a plane/board, with a grid, that is about 1100 x 1100. I have panning, zooming, and rotating working except for the fact that the board moves back to the center of the screen after it has been panned. So, if I don't pan the board at all then everything works. After I pan the board it moves back to the center of the screen when I try to rotate it. I cannot figure out how to change the origin of the camera so that it rotates around the center of the board. It seems like it rotates around the center of the camera.
var radius = 1500, theta = 45 * 0.5, onMouseDownTheta = 45 * 0.5;
var fov = 45;
var mouse2D = new THREE.Vector3(0, 10000, 0.5);
cameraX = radius * Math.sin(THREE.Math.degToRad(theta));
cameraY = 1000;
cameraZ = radius * Math.cos(THREE.Math.degToRad(theta));
camera = new THREE.PerspectiveCamera(fov, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(cameraX, cameraY, cameraZ);
scene = new THREE.Scene();
camera.lookAt(scene.position);
render();
ThreeBoard.prototype.render = function() {
mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse2D.y = - (event.clientY / window.innerHeight) * 2 + 1;
// rotate
if (isMouseDown && isShiftPressed && !isCtrlPressed) {
theta = ((event.pageX - mouse2D.x) * 0.5) + onMouseDownTheta;
cameraX = radius * Math.sin(THREE.Math.degToRad(theta));
cameraZ = radius * Math.cos(THREE.Math.degToRad(theta));
camera.position.set(cameraX, cameraY, cameraZ);
camera.lookAt(scene.position);
}
// pan
if (isMouseDown && isShiftPressed && isCtrlPressed) {
theta = ((event.pageX - mouse2D.x) * 0.5) + onMouseDownTheta;
cameraX += 10 * mouse2D.x;
// cameraY += 10;
cameraZ -= 10 * mouse2D.y;
camera.position.set(cameraX, cameraY, cameraZ);
// camera.lookAt(scene.position);
}
renderer.render(scene, camera);
};